Makefiles and subdirectories
Hi all, I have questions about how to make good use of makefile.
I've used the very basics of a Makefile before such as this: Code:
SHELL=/bin/bash If I want to organize the files into subdirectories like this ~\MyProj\ ~\MyProj\src\ <- contains the *.cc *.c *.h and Makefile ~\MyProj\bin\ <- contains the output exe's. How should the above Makefile be changed? Also, any suggestions about where to store the intermediate *.o files? Thank you. |
How about:
Code:
TOPDIR := ~\MyProj |
How about this for a makefile:
Code:
INTERMEDIATE_DIR=../intermediates For dependencies based on include files, see : Advanced Auto-Dependency Generation |
Well I know I already answered, but I think I got something a bit more robust: (happy for some comments on what I could improve)
Code:
TOPDIR := ~/MyProj/ |
Nice!
A couple of comments: If you use a "~" to define TOPDIR, then the shell translates that to a path when you do the find resulting in SOURCES containing full pathnames that don't contain the "~". Then the patsubst command does not match SRCDIR because it *does* contain a "~". This problem goes away if you define TOPDIR as $(HOME)/MyProj/ instead of ~/Myproj/ I like to explicitly list all the sources that should be combined into an executable rather than using find or some other shell command to get them. This way you don't have to worry about some temporary copy of a source file getting pulled into your executable. You also don't pay the price of invoking a shell *every* time you run make, even if you don't even need the list of sources. That's just a personal preference though. Here's a slightly modified version of your makefile that addresses these two points: Code:
TOPDIR := $(HOME)/MyProj/ |
Thanks for replying.
I see that the approach is to resolve the files into their fullpath and name using variables and macros. e.g. originally Code:
a.exe: a.o c.o common.o Code:
SRCDIR := ./ What I am looking for, is if there are techniques that can tell MAKE the *.o are located in $(OBJDR), and *.cc *.h are in $(SRCDIR), and *.exe in $(BINDIR), and the like? |
Ok Jerry ... (I hope you appreciate this as it took me a lot more hours than it probably should have (mainly cause I am doing this for the first time inages ;)))
Anyhoo, here we go: 1. Under the 'src' directory, place all your files in the respective directories named after the executable (ie. src/a, src/b, etc) 2. In each of these place their own Makefile (good part here is that these are all identical files, so make 1 copy/paste) This file looks like: Code:
TOPDIR := $(HOME) Code:
ALLSOURCES := $(wildcard src/*) |
Thank you for spending time helping. But it doesn't work yet. Where do you put the common sources?
The tree is like like now Code:
. The TOPDIR in makefile has been modified to TOPDIR := /home/jerry/dev/ At the $TOPDIR, 'make' gives the following error: Code:
$ make but I think I understand what you are doing. I don't know if I make any sense to you... Basically, organise the unique source files in a subdirectories and the common source files in the upper level directories. Have the make program traverse to the bottom level subdir so that the dependencies are built in the way. I will be back with a solution! |
Jerry, is your intention to build three different executables, one for directory a, one for b, and one for src? Or do you want to build just one executable that combines code from all three directories?
Never mind. You answered that in your post #6 on this thread. |
Hey Jerry
I see where you are coming from, and again I am still wrapping my own head around some of this stuff, but, based on the new criteria of "common" files, if they are not creating an executable (ie common.exe) then I would place them at the top level (ie that is in the TOPDIR) the put COMMON := <you know the rest> in the top Makefile and export prior to call to compile the rest, this will then get past to all subsequent calls to make and you can simply combine with SOURCES. Hmmm ... thinking as I am typing, the other alternative is to place them in SRC directory and have the ALLSOURCES script look only for items without a suffix, but then in the Makefiles in the sources directories do an include of all files under dir name (ie src/a) as well as under SRC. btw. the site that has helped me enormously is the following: http://www.gnu.org/software/make/manual/make.html and this part should help with some of the above I have explained: http://www.gnu.org/software/make/man...Name-Functions |
I think the issue is at the rule definition:
target : dependencies Although dependencies can be searched through VPATH or vpath, one must clearly spell out where to find and put target. Thus, Code:
VPATH := $(SRCDIR):$(OBJDIR) #bad example anyway Code:
resolve %.exe,$(BINDIR) # my humble wish only |
Hi Jerry,
I don't know if this is still of interest or not. That said, here are makefiles that should do most of what you have in mind. Include file dependencies are not provided but that can be retrofitted. At the top level : makefile.include Code:
OBJDIR := $(TOPDIR)/obj Code:
TOPDIR := $(HOME)/MyProj Code:
TOPDIR := $(HOME)/MyProj Note that in "src/a/makefile" the common.cc file is absolute path and in "src/b/makefile" the same file is specified via relative path. Either one works. There's room for a lot of polishing here - I kept it minimal for ease of understanding. In particular, if you want to do something with include file dependencies this is a good reference: Advanced Auto-Dependency Generation |
All times are GMT -5. The time now is 02:39 AM. |