How I could add dir to $PATH in Makefile?
Did you try export
directive of Make itself (assuming that you use GNU Make)?
export PATH := bin:$(PATH)
test all:
x
Also, there is a bug in you example:
test all:
PATH=bin:${PATH}
@echo $(PATH)
x
First, the value being echo
ed is an expansion of PATH
variable performed by Make, not the shell. If it prints the expected value then, I guess, you've set PATH
variable somewhere earlier in your Makefile, or in a shell that invoked Make. To prevent such behavior you should escape dollars:
test all:
PATH=bin:$$PATH
@echo $$PATH
x
Second, in any case this won't work because Make executes each line of the recipe in a separate shell. This can be changed by writing the recipe in a single line:
test all:
export PATH=bin:$$PATH; echo $$PATH; x
Problems setting PATH in Makefile
I can't reproduce your results (using GNU make 3.81 on a GNU/Linux system). It appears that there may be some difference in either the way the Apple system works, or that Apple has made some kind of patch to the GNU make version they ship that is causing this problem.
GNU make has two ways of running recipes: the normal way, where it invokes a shell and passes the recipe to the shell to be run, and the "fast path", where, if make sees that the command is "simple enough" (that is if it contains no shell special characters), it will chop up the command into words and directly execute the command without invoking the shell. The latter is much faster, but since it's being invoked directly it inherits the PATH
setting from GNU make itself not from the shell.
It appears that for some reason the version of GNU make shipped by Apple is not working properly in that it's not setting the environment correctly for commands which are run directly by GNU make, via the "fast path".
I have a very vague recollection of something like this being discussed on the GNU make mailing lists, but after spending some time searching I wasn't able to come up with anything.
You can "fix" this problem by forcing your command to use the slow path, by introducing some shell special characters (globbing, ;
, pipes, etc.). Or you can use a fully-qualified path to the program.
Or, you can go get the source code for GNU make and build it yourself; if this difference is a result of a "fix" by Apple that should make it work better. Or install GNU make from homebrew or ports, which will also get you a newer version with more features, I expect.
how to set the directory where Makefile exists so that I can run make from different directory using `make -C` option?
If you really use make -C
(not make -f
) and your Makefile is not included in another, you can simply use the CURDIR
variable. GNU make sets it to the absolute path of the current directory when it starts, "after it has processed any -C
options". So, in your case it should do exactly what you want.
Else, if you sometimes use make -f
or if you have included Makefiles, you can put this as the first line of any of your Makefiles (or, at least, before any include
statement):
HERE := $(dir $(lastword $(MAKEFILE_LIST)))
and then use $(HERE)
to refer to this Makefile's directory. See the GNU make manual for the details.
Note: I was almost sure this question would be a duplicate. Surprisingly I searched SO for a clear answer and found only old answers that first suggest shell calls before using make built-ins or wrong answers (using firstword
instead of lastword
, for instance).
Specifying path to makefile using make command
All relative paths in the makefile will be relative to your current directory and not the directory of the makefile.
Assuming that you understand that and what you want to do is still going to work then you want the -f
flag to specify the makefile to use. (Which is in the man page, the manual and the --help
output.)
If, instead, what you mean is you want to cd
to somewhere else and run make then perhaps you are looking for (cd /some/path && make)
?
How to prepend directory to all file names stored inside of '$^' variable
One possibility: prepend a dir to all obj and either overwrite OBJS
or replace usage of OBJS
with a new symbol:
OBJS := foo.o bar.o baz.o
SUBDIR_OBJS := $(OBJS:%=subdir/%)
show:
@echo OBJS $(OBJS)
@echo SUBDIR_OBJS $(SUBDIR_OBJS)
For more info about substitutions, see gnu text functions
How can I shift a relative path up one level in make?
If all values of BASE
for which you want to do this begin with ../
, you can try
$(patsubst ../%,%,$(BASE))
If you want to just drop the first component of an arbitrary path (i.e. a/b/c -> b/c), it takes a bit more work:
space := $(empty) $(empty)
shift-list = $(wordlist 2,$(words $1),$1)
shift-path = $(subst $(space),/,$(call shift-list,$(subst /, ,$1)))
and use it as $(call shift-path,$(BASE))
. This breaks if your paths have spaces, but handling those in make
is a nightmare for many other reasons anyway.
Use directory path of target in list of prerequisites in Makefile
I guess Secondary Expansion is probably what you're looking for:
.SECONDEXPANSION:
%.cmp: %.cfg $$(dir %)default.cfg
./compare.pl $^ $@
Also note the absence of slash after $$(dir %)
, dir
function always append one to the resulting value.
Related Topics
Does Linux Schedule a Process or a Thread
Why Is the Page Size of Linux (X86) 4 Kb, How Is That Calculated
Get Ceiling Integer from Number in Linux (Bash)
Randomly Shuffling Lines in Linux/Bash
Replacing Control Character in Sed
Pack Shared Libraries into the Elf
Secure Way to Run Other People Code (Sandbox) on My Server
Sending Udp Packets from the Linux Kernel
How to Get the Source Code for the Linux Utility Tail
Pthread Mutex Lock Unlock by Different Threads
How to Download a File from Server Using Ssh
How to Recall the Argument of the Previous Bash Command
How to Read the Source Code of Shell Commands
Linux Equivalent of the MAC Os X "Open" Command
How to Have the Cp Command Create Any Necessary Folders for Copying a File to a Destination