问题
Below is the folder structure for my code. This is a very small example to understand the concept of multiple makefiles based on which I have to create makefile for bigger code structure.
work
├── code
| |
| └── main.h and test.h files here
│ └── main.c and test.c files here
| └── subdir.mk
|
├── _Build/
│ └── Makefile here
I am keeping both Makefile and subdir.mk files to be very basic and simple to grasp the concept.
Below is the code for subdir.mk
#subdir.mk
#============================================
test.o : test.c test.h
@echo Building test.c ...
gcc -Werror -Wall -c test.c -o test.o
main.o : main.c main.h test.h
@echo Building main.c ...
gcc -Werror -Wall -c main.c -o main.o
#============================================
Below is the code for main file ... Makefile
#Makefile
#============================================
include ../code/subdir.mk
main : ../code/main.o ..code/test.o
@echo Building ...
make subdir.mk # <--- What is the correct way to perform this code
@echo Linking files ...
gcc -Llib ../code/main.o ../code/test.o -lm -o main
clean:
rm -rv ../code/*.o
#============================================
The error I am getting is
make: *** No rule to make target 'test.c', needed by 'test.o'. Stop.
In subdir.mk I am trying to generate object files. In Makefile I am trying to link the object files generated in subdir.mk
The way I am trying to execute is correct way or some different steps are followed when we have multiple subdir.mk and main Makefile.
Share your valuable comments please.
回答1:
You cannot both include the subdir.mk
file and also invoke it recursively.
You need to decide whether you want to use non-recursive make (which means you'd use include) or recursive make (which means you'd run a sub-make command).
If you want to use non-recursive make then your subdir.mk
makefile needs to be prepared to be run when the current working directory is different than the directory that the subdir.mk file appears in.
If you want to use recursive make then you need a separate rule to build the objects, and you should not include subdirs.mk
. Something like this:
main : ../code/main.o ..code/test.o
@echo Linking files ...
gcc -Llib ../code/main.o ../code/test.o -lm -o main
../code/main.o ..code/test.o : subdir ;
subdir:
@echo Building ...
cd ../code && $(MAKE) -f subdir.mk
.PHONY: subdir
Be sure to include the semicolon after the subdir
in the .o
rule.
When invoking sub-makes you should always use the $(MAKE)
variable, never use the literal string make
.
You will probably be better off having your subdir.mk
build a single library out of the objects rather than having to repeat all the object files in multiple places. Then replace the list of object files in this makefile with the library.
Contrary to Andreas's assertion, this will not always rebuild main
. It will only be rebuilt when one of the object files was changed.
回答2:
subdir.mk
has to use paths relative to the main makefile. E.g.
../code/test.o : ../code/test.c ../code/test.h
...
回答3:
What you need is a recipe for creating the object files. In Makefile you'll need to remove include ../code/subdir.mk
and add something like this:
.PHONY: ../code/main.o ..code/test.o
../code/main.o ..code/test.o:
$(MAKE) -C ../code/ -f subdir.mk $(@F)
When you build target main
, make sees you need the object files. Then make find the above recipe for creating the object files and so runs it.
Having them .PHONY
is because the top Makefile can´t tell whether or not they´re up to date. Without it the object files would never be rebuilt. This has the unfortunate consequence that main
will always be rebuilt, even if subdir.mk
determines the object files were indeed up to date. The solution is either to have it all in a single make (can still split into files and include), or change to a build tool that can get it right.
来源:https://stackoverflow.com/questions/63941725/calling-subdir-mk-from-makefile-with-multiple-code-directories