How to Call Makefile Located in Other Directory

How to call Makefile located in other directory?

GNU make accepts many options, notably -C to change directory before running, and -f for giving the Makefile to follow.

Combine them appropriately.

Consider using remake to ease debugging (notably with -x) of Makefile related issues. With GNU make version 4 or better, also use make --trace...

You could have your own executable shell script (e.g. in your $HOME/bin/ which would be in your $PATH) which uses both cd and make).

You could consider other build automation tools (ninja perhaps)

Read also P.Miller's paper Recursive Make considered harmful

How can i call make file from other directory

Yes, you can do that. Something like the following should do what you want.

$ cat containers/Makefile
%.run: %
$(MAKE) -C $@

That being said as you can see the command to do what you want is trivial enough to make such a makefile not really necessary (and a simple shell script is as useful here as a makefile).

$ cat run.sh
[ -d "$1" ] || { echo 'No such directory.' >&2; exit 1; }
#make -C "$1"
# OR
#cd "$1" && make

If you wanted to be able to build all the sub-directory projects at once then a makefile could help you with that but even that is a simple enough shell one-liner.

$ for mkfile in */Makefile; do make -C "$(dirname "$mkfile"); done
$ for mkfile in */Makefile; do (cd "$(dirname "$mkfile") && make); done

How to run Makefile from any directory?

You can run a Makefile from another location as if it was in the current directory with:

make -f /path/to/your/makefile

You can make an alias or function for it if you want.

How do I write the 'cd' command in a makefile?

It is actually executing the command, changing the directory to some_directory, however, this is performed in a sub-process shell, and affects neither make nor the shell you're working from.

If you're looking to perform more tasks within some_directory, you need to add a semi-colon and append the other commands as well. Note that you cannot use new lines as they are interpreted by make as the end of the rule, so any new lines you use for clarity need to be escaped by a backslash.

For example:

all:
cd some_dir; echo "I'm in some_dir"; \
gcc -Wall -o myTest myTest.c

Note also that the semicolon is necessary between every command even though you add a backslash and a newline. This is due to the fact that the entire string is parsed as a single line by the shell. As noted in the comments, you should use '&&' to join commands, which means they only get executed if the preceding command was successful.

all:
cd some_dir && echo "I'm in some_dir" && \
gcc -Wall -o myTest myTest.c

This is especially crucial when doing destructive work, such as clean-up, as you'll otherwise destroy the wrong stuff, should the cd fail for whatever reason.

A common usage, though, is to call make in the subdirectory, which you might want to look into. There's a command-line option for this, so you don't have to call cd yourself, so your rule would look like this

all:
$(MAKE) -C some_dir all

which will change into some_dir and execute the Makefile in that directory, with the target "all". As a best practice, use $(MAKE) instead of calling make directly, as it'll take care to call the right make instance (if you, for example, use a special make version for your build environment), as well as provide slightly different behavior when running using certain switches, such as -t.

For the record, make always echos the command it executes (unless explicitly suppressed), even if it has no output, which is what you're seeing.

How to call Makefile from another Makefile?

I'm not really too clear what you are asking, but using the -f command line option just specifies a file - it doesn't tell make to change directories. If you want to do the work in another directory, you need to cd to the directory:

clean:
cd gtest-1.4.0 && $(MAKE) clean

Note that each line in Makefile runs in a separate shell, so there is no need to change the directory back.

Makefiles with source files in different directories

The traditional way is to have a Makefile in each of the subdirectories (part1, part2, etc.) allowing you to build them independently. Further, have a Makefile in the root directory of the project which builds everything. The "root" Makefile would look something like the following:

all:
+$(MAKE) -C part1
+$(MAKE) -C part2
+$(MAKE) -C part3

Since each line in a make target is run in its own shell, there is no need to worry about traversing back up the directory tree or to other directories.

I suggest taking a look at the GNU make manual section 5.7; it is very helpful.

Invoke Makefile in different directory without exiting Vim

Just run:

:make -C path_to_dir_with_your_makefile

Where -C:

-C dir, --directory=dir
Change to directory dir before reading the makefiles or doing anything else. If multiple -C options are specified, each is interpreted relative to the previous one: -C / -C etc is
equivalent to -C /etc. This is typically used with recursive invocations of make.

changing the directory and executing the makefile commands

Within one makefile you can change directory inside the rules, but you can't say this set of rules runs in one directory and this one runs in the other. Which does not prevent you running rules on files in a different directory by simply giving their path. The data/Makefile can contain rules for ../aws-cdk/something and even ../aws-cdk/%.out: ../aws-cdk/%.in and that's just fine.

If you do want to actually change directory, you need a separate makefile. I strongly recommend just putting it in the directory where it will run, so aws-cdk/Makefile and then you can just call it from the one in data like $(MAKE) -C ../aws-cdk. You can also put it anywhere else and give make an explicit argument like $(MAKE) -C ../aws-cdk -f aws-cdk.make, but putting it in the directory will be easier to understand when it needs fixing two years down the line and/or by someone who's never seen it.

How can I create a make file to run other make files independently?

I was able to achieve what I needed by using the code in my original question and just renaming them to fit my needs.

name1:
$(MAKE) -C ./subdir1/

name2:
$(MAKE) -C ./subdir2/

Thanks to @MadScientist as well for pointing out that I had figured out how to do what I needed, I was overthinking it for sure.

I did run into an issue in which when I ran the make file with name1 or name2, I was prompted with a message saying that the directory was up to date. Even if I went into the sub folders and deleted any populated files as a result of calling their respective make files, the issue still persisted.

I was able to bypass it by adding the code below to the bottom of my root make file.

.PHONY: name1 name2...

So now when I call make name1 or make name2, the make files in those sub folders work and do what they are supposed to!



Related Topics



Leave a reply



Submit