Makefile and Files under a directory - makefile

I have Makefile under a directory and directory has many .pm ( perl files )
I want to add makefile at this directory level which does perl file syntax checking.
Basically I want to add:
perl -c <filename>
How to get list of files automatically in that directory without hardcoding.

The following worked for me in the GNU makefile (Linux and Windows)
ALL_PM_FILES = $(wildcard *.pm)
Then run a for/foreach loop on them.

You can try the filter command:
PMFILES=$(filter %.pm, $(SRC))
Documentation for filter is hard to find. See here for an example.

This is the normal workaround:
check_pm_syntax:
for file in *.pm; do ${PERL} -c $$file; done
You run 'make check_pm_syntax' and it goes off and runs the shell loop for all the *.pm files it can find. You can simply list check_pm_syntax as a pre-requisite for your all target if you like (but it means you'll always do work when you build all). The only time this causes trouble is if there are no *.pm files in the directory.

Here's a slightly different approach:
.PHONY: check_%.pm
check_%.pm:
perl -c $*.pm
check_all: $(addprefix check_,$(wildcard *.pm))

Related

Makefile error make (e=2): The system cannot find the file specified

I am using a makefile in windows to push some files on a Unix server (here a text file "blob.txt" in the same folder of my makefile).
My makefile script is:
setup:
pscp blob.txt username#hostname:/folder/
I start a command prompt, go in the folder where blob.txt and the makefile are present and type:
make setup
Which results in:
pscp blob.txt username#hostname:/folder/
process_begin: CreateProcess(NULL, pscp blob.txt username#hostname:/folder/, ...) failed.
make (e=2): The system cannot find the file specified.
make: *** [setup] Error 2
In a #fail ... whereas if I enter directly the command in the command prompt:
pscp blob.txt username#hostname:/folder/
It works ... I really wonder why.
The error
process_begin: CreateProcess(NULL, pscp blob.txt username#hostname:/folder/, ...) failed.
make (e=2): The system cannot find the file specified.
is almost certainly complaining that Windows cannot find pscp.
This is almost certainly because the value of %PATH% (or whatever) is different when make spawns a shell/console then when you have it open manually.
Compare the values to confirm that. Then either use the full path to pscp in the makefile recipe or ensure that the value of PATH is set correctly for make's usage.
I didn't want to remove GIT's bin folder from the PATH variable (I am using a Windows machine), as I use it quite often. So I looked for a workaround, and here it is:
Add the <git-installation-directory>/usr/bin directory to your PATH variable too. This basically adds the rest of the linux-like commands that come with the "GIT bash" to your environment. After applying this, my makefiles ran normally again. :)
If you are curious about what shell is being invoked by make, just add $(info $(SHELL)) at the beginning of your makefile. The path/name of the shell being invoked is printed to the console as soon as you run make.
I know this is an old question that has been answered, but thought I'd and my experiences for anyone still running into this. I was getting the same cryptic error Colonel Beauvel (though with the windows MOVE command, not pscp):
process_begin: CreateProcess(NULL, move /y foo\bar.c .\baz.c, ...) failed.
make (e=2): The system cannot find the file specified.
Our CI was running the same Makefile and working perfectly. Turns out CI was using mingw32-make and I was using GNU make. Uninstalling GNU make (which got installed as part of an unrelated bulk package) and aliasing mingw32-make to 'make' works perfectly.
#user3869623's solution works for me. I'd like to share some details of mine to complete the picture.
My makefile contains below target:
clean:
#echo '$(OS)'
ifeq ($(OS),Windows_NT)
del /s *.o *.d *.elf *.map *.log
endif
When I run make clean, I see this error:
Since it says something went wrong with echo, so I change my makefile target to below:
clean:
ifeq ($(OS),Windows_NT)
del /s *.o *.d *.elf *.map *.log
endif
This time, make clean gives me this error:
I am surprised to see bash here since I am working in Windows command line.
Then I checked my %PATH%, I see this entry:
C:\DevTools\Git\bin
There's a bash.exe and sh.exe in that path. So I removed this entry, and it works fine now.
BUT I STILL DON'T KNOW WHY BASH GET INTO THIS???
ADD 1
As to why the C:\DevTools\Git\bin shows up in my %PATH%, because I am using Sublime and it always asks me for the Git binaries:
In my case, I had git\bin in my %PATH% which contains bash.exe and sh.exe.
Removing %GIT_HOME%\bin from the PATH worked for me.
To build on user3869623's response.
In my case i had git\bin in my %PATH% which contains bash.exe and sh.exe.. Removing %GIT_HOME%\bin from the PATH worked for me
While this recommendation may allow make to run, it will likely cause issues for git, especially if the makefile is installing software from a git repository.
A better solution is to simply change %GIT_HOME%\bin to %GIT_HOME%\cmd
For those who tried removing the git bin folder from PATH and it didn't work for them, search your PATH variables for any paths containing bash.exe.
In my case I found a variable linking to cygwin bin folder C:\cygwin64\bin, removed it and it worked.
I had the same issue, and this thread really helped me solve it. In my case, it was a conflict between make and the sh.exe that was visible through my path, due to both git and mingw64. To fix my issue, without breaking Git, I added these lines to the top of my batch file that calls make:
set path=%path:git\bin=;%
set path=%path:mingw64\bin=;%
set path=%path:usr\bin=;%
This hides the extra sh.exe instances from make for that instance only.
I ran into this problem recently and this question was one of the top hits for my searches.
None of the other answers here helped me. The fix, for me, was to put the binary name in quotes:
setup:
"pscp" blob.txt username#hostname:/folder/
-"pscp" blob.txt username#hostname:/folder/ # Failure is OK, `-` in front
I'm on windows.
By explicitly setting my compiler to gcc (instead of cl?) it solved my problem.
CC = gcc
I hope some people more knowledgeable than me could explain why changing the compiler would impact the makefile parsing.

make parameter to change directory before it does anything

Are there any command line parameters for make to change to a directory before it does anything?
I have a case where I have to run make from a different directory than the Makefile. But since some source header include paths are relative to the Makefile directory, it cannot find those.
'make -C ' does the trick. It tells make to change directory before reading any makefiles as commented by Etan above.

How to write a Makefile to copy scripts to server

After I finish writing scripts on my local machine, I need to copy them in the cluster to execute the codes. For example, I want to copy all the matlab files in my current directory in a directory at the server id#server.
Can anyone help to write a very basic Makefile to fulfill this purpose?
Thanks a lot!
John
Here is an adaptation of Jens's answer, together with my answer here, that takes advantage of the capabilities of Make to only copy across those files that have been modified since the last time you copied the files to the server. That way, if you have hundreds of .m files and you modify one of them, you won't copy all of them across to the server.
It makes use of an empty hidden file, .last_push, that serves only to record (through its own timestamp) the time at which we last copied files to the server.
FILES = $(shell find . -name *.m)
SCP = scp id#server:path/relative/to/your/serverhomedir
LAST_PUSH = .last_push
.PHONY : push
push : $(LAST_PUSH)
$(LAST_PUSH) : $(FILES)
$(SCP) $?
touch $(LAST_PUSH)
Run this with make or make push. The key is the variable $?, which is populated with the list of all prerequisites that are newer than the target - in this case, the list of .m files that have been modified more recently than the last push.
How do you copy files to the server? Assuming you have ssh/scp available:
FILES = file1 file2 *.matlab
copy:
scp $(FILES) id#server:path/relative/to/your/serverhomedir
Run with
$ make copy
As a shell script, it could look like this:
#!/bin/sh
set -- file1 file2 *.matlab
scp "$#" id#server:path/relative/to/your/serverhomedir
Don't forget to chmod u+x yourscript.

Calling Makefile of winexe from Makefile of Rsync

I want to merge two different source code and make single executable for that.
I have sourcecode1 as RSYNC and sourcecode2 as WINEXE.
I want to integrate WINEXE code into RSYNC. For that purpose I place WINEXE code in RSYNC code.
I have called the WINEXE makefile located in WINEXE/source4/ in Makefile of RSYNC as
WINEXE = winexe/source4
TARGET = $(WINEXE)
$(TARGET):
#$(MAKE) -C $#;
and called the main function of WINEXE from RSYNC code.
But I got lots of the same error that Header file not found. But when I use "make" command inside WINEXE it works fine.
There are hundreds of header files, so it is not possible to change path of header files and libraries in each file.
please tell me how to integrate these two codes?
problem resolved:
Tried to use follwing command
.PHONY: winexe
winexe:
cd winexe/source4 && ./configure && make
#echo "i am here inside source"
In the outer Makefile, call the Makefile of inner folder.

How can CMake be used to generate Makefiles with personalized commands?

I like to keep my Makefiles flexible and multifunctional. One of the tasks I usually add to make command is tar, for example the following instruction does the job:
tar:
tar -cvf $(PROGNAME).tar $(SRCS) Makefile
My question is: How can CMake be used to generate personalized commands like tar?
I would like to see some code samples.
For the full functionality it would be useful to create project's components and be able to use them as parameters.
(Exempli gratia: archive only header files or some specific library).
Thanks in advance for your answers!
The literal translation of your tar example would be:
ADD_CUSTOM_TARGET(tar
tar -cvf ${CMAKE_CURRENT_BINARY_DIR}/${PROGNAME}.tar ${SRCS} Makefile
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
This adds a new target "tar" that always executes the given command whenever it is requested as a command line target, i.e. whenever you run make tar it will create a new tar file. The WORKING_DIRECTORY argument will ensure that the source files are taken from the source directory, while CMAKE_CURRENT_BINARY_DIR ensures the output goes in the current build directory.
A slightly better iteration would be to replace tar with ${CMAKE_COMMAND} -E tar, as this doesn't depend on the command line tar program being available. So something like this would tar up all the header files when you run make tar:
SET(HEADER_FILES my.h another.h)
SET(PROGNAME myprog)
ADD_CUSTOM_TARGET(tar ${CMAKE_COMMAND} -E tar -czvf
${CMAKE_CURRENT_BINARY_DIR}/${PROGNAME}.tar.gz ${HEADER_FILES}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
An even better iteration would be to use the CPack features to create source or binary tar files, but that's quite a bit more work and may not be what you need anyway.

Resources