How I Could Add Dir to $Path in Makefile

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 echoed 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



Leave a reply



Submit