I'm using a tool chain where I do not know the names of all of the intermediate files.
E.g. I know that I start out with a foo.s, and go through several steps to get a foo.XXXX.sym and a foo.XXXX.hex, buried way down deep. And then running other tools on foo.XXXX.hex and foo.XXXX.sym, I eventually end up with something like final.results.
But, the trouble is that I don't know what the XXXX is. It is derived from some other parameters, but may be significantly transformed away from them.
Now, after running the tool/steps that generate foo.XXXX.{sym,hex}, I now typically scan the overall result directory looking for foo.*.{sym,hex}. I.e. I have code that can recognize the intermediate outputs, I just don't know exactly what the names will be.
I typically use make or scons - actually, I prefer scons, but my team highly prefers make. I'm open to other build tools.
What I want to do is be able to say (1) "make final.results", or "scons final.results", (2) and have it scan over the partial tree; (3) figure out that, while it does not know the full path, it definitely knows that it has to run the first step, (4) after that first step, look for and find the foo.XXX.* files; (5) and plug those into the dependency tree.
I.e. I want to finish building the dependency tree after the build has already started.
A friend got frustrated enough with scons' limitations in this area that he wrote his own build tool. Unfortunately it is proprietary.
I guess that I can create a first build graph, say in make with many .PHONY targets, and then after I get through the first step, generate a new makefile with the new names, and have the first make invoke the newly generated second makefile. Seems clumsy. Is there any more elegant way?
GNU make has an "auto-rexec" feature that you might be able to make use of. See How Makefiles Are Remade
After make finishes reading all the makefiles (both the ones found automatically and/or on the command line, as well as all included makefiles), it will try to rebuild all its makefiles (using the rules it knows about). If any of those makefiles are automatically rebuilt, then make will re-exec itself so it can re-read the newest versions of the makefiles/included files, and starts over (including re-trying to build all the makefiles).
It seems to me that you should be able to do something with this. You can write in your main makefile and "-include foo.sym.mk" for example, and then have a rule that builds "foo.sym.mk" by invoking the tool on foo.s, then running your "recognized the next step" code and generate a "foo.sym.mk" file which defines a rule for the intermediate output that got created. Something like (due to lack of specificity in your question I can't give true examples you understand):
SRCS = foo.s bar.s baz.s
-include $(patsubst %.s,%.sym.mk,$(SRCS))
%.sym.mk: %.s
<compile> '$<'
<recognize output and generate makefile> > '$#'
Now when make runs it will see that foo.sym.mk is out of date (if it is) using normal algorithms and it will rebuild foo.sym.mk, which as a "side effect" causes the foo.s file to be compiled.
And of course, the "foo.sym.mk" file can include ANOTHER file, which can recognize the next step, if necessary.
I'm not saying this will be trivial but it seems do-able based on your description.
Make constructs the graph before running any rule, so there won't be a perfect answer. Here are some reasonably clean solutions.
1) use PHONY intermediates and wildcards in the commands. (You can't use Make wildcards because make expands them before running rules.)
final.results: middle
# build $# using $(shell ls foo.*.sym) and $(shell ls foo.*.hex)
.PHONY: middle
middle: foo.s
# build foo.XXXX.sym and foo.XXXX.hex from $<
2) Use recursive Make (which is not as bad as people say, and sometimes very useful.)
SYM = $(wildcard foo.*.sym)
HEX = $(wildcard foo.*.hex)
# Note that this is is the one you should "Make".
# I've put it first so it'll be the default.
.PHONY: first-step
first-step: foo.s
# build foo.XXXX.sym and foo.XXXX.hex from $<
#$(MAKE) -s final.results
final.results:
# build $# using $(SYM) and $(HEX)
3) Similar to 2, but have a rule for the makefile which will cause Make to run a second time.
SYM = $(wildcard foo.*.sym)
HEX = $(wildcard foo.*.hex)
final.results:
# build $# using $(SYM) and $(HEX)
Makefile: foo.s
# build foo.XXXX.sym and foo.XXXX.hex from $<
#touch $#
Related
I remember doing this in my advanced C++ class, but it's been a couple years and I forgot.
I want to make a sort of simple re-usable makefile where I just type "make programName" and it compiles programName.cpp into programName.exe.
I've looked for this for a couple hours, but haven't found what I need. I know this will get marked as duplicate, but at least point me to what I need.
Make has a built-in variable called $(MAKECMDGOALS), which contains all targets specified as command line parameters.
You can use it to generate recipes, like so:
# Stop if 0 or 2+ targets were specified.
$(if $(filter-out 1,$(words $(MAKECMDGOALS))),$(error Expected one target))
name := $(MAKECMDGOALS)
$(name).exe: $(name).cpp
g++ $^ -o $#
Adding a way to customize compiler executable and flags is left as an exercise to the reader. As well as conditionally removing .exe from the target name when building on Linux.
Why do you want your output to be suffixed with .exe? That's a Windows convention that is not followed on POSIX systems like Linux.
If you don't want that you don't even need a makefile at all. You can type make programName with no makefile and if you have a file programName.c, it will be built into an executable programName via make's built-in rules.
using c++
I compile my code on an automated schedule and need to use the time at which the code was compiled in the code itself. Currently I'm just using the __DATE__, __TIME__ macros to get the compile- time date and time. However, this causes the binaries to change even if no changes have been made to the source (macros will inflate at compile time) which is not good (i don't want the setup to think that the binary changed if there have been no changes to the source).
Is it possible to get the compile-time without using any means that would cause the source to change?
Thanks
The standard __DATE__ and __TIME__ macros do what you observe, return a time dependent string.
It depends upon the system (and perhaps the compiler) and notably the build system (like GNU make for example).
A possible idea could be to link in a seperate timestamp file, something like (in make syntax)
timestamp.c:
date +'const char timestamp[]="%c";' > $#
program: $(OBJECTS) timestamp.c
$(LINKER.cc) $^ -o $# $(LIBES)
rm -f timestamp.c
The timestamp.owould then be regenerated and your programwould be relinked at every make (so the generated program will indeed change, but most of the code -thru $(OBJECTS) make variable- will stay unchanged).
Alternatively, you could e.g. log inside some database or textual log file the time of linking, e.g.
program: $(OBJECTS)
$(LINKER.cc) $^ -o $# $(LIBES)
date +'$# built at %c' >> /var/log/build.log
(you might use logger instead of date to get that logged in the syslog)
Then the generated program won't change, but you'll have logged somewhere a build timestamp. BTW you could log also some checksum (e.g. $(shell md5sum program) in make syntax) of your binary program.
If you use the compile-time IN YOUR binaries, then you will have the binary change.
There are several solutions, but I think the main point is that if you rebuild the binaries on a regular basis, it should really only be done if there are actually some changes (either to the build system or to the source code). So make it part of your build system to check if there are changes, and don't build anything if there isn't any changes. A simple way to do this is to check what the "latest version" in the version control system for the source code is. If the latest version is the same as the one used in the previous build, then nothing needs to be built. This will save you generating builds that are identical (apart from build time-stamp), and will resolve the issue of storgin __DATE__ and __TIME__ in the binary.
It's not clear to me what you want. If it's the last modified
time of the file, getting it will depend on your system and
build system: something like -D $(shell ls -l
--time-style=long-iso $< | awk '{ print $7, $8 }') could be used
in the compiler invocation with GNU make under Linux, for
example. But of course, it means that if an include file was
changed, but not the source, the time and date wouldn't reflect
it.
I need to write a pre-build makefile which is called separately from the main build file. This make file should make a walk in a directory where it is called. There is a list of directories in another make file called 'sources.mk' with a variable which describe the directory:
SUBDIRS := \
. \
directory1 \
directory2 \
Now, I need to run a loop through this list and in this loop I need to call an utility which will process all file with a 'h' extension. I wrote this:
include Default/sources.mk
find_files:
for prefix in $(SUBDIRS); do \
for file in *.h; do \
C:/QtSDK/Desktop/Qt/4.7.4/mingw/bin/moc.exe $$prefix/$$file; \
done \
done
Run command: make -f premake.mk
I don't describe the errors, there are a lot of them, I was trying different makefiles, but I am a newbie at it and these attempts failed. Please, review my code and/or suggest other methods.
Your problem is probably just this one simple thing: You're looking for file in *.h in the current directory, not in the subdirectory. Try this instead:
for prefix in $(SUBDIRS); do \
for file in $$prefix/*.h; do \
C:/QtSDK/Desktop/Qt/4.7.4/mingw/bin/moc.exe $$file; \
done \
done
With that said, a much better way of doing this is to use make to handle the processing of all of the files (and deciding whether or not all of them need to be reprocessed!), rather than using an explicit loop in the rule. You'd start with a list of header files, as Eldar Abusalimov's answer suggests:
moc_headers := $(wildcard $(SUBDIRS:%=%/*.h))
The inner piece of that manipulates the SUBDIRS list into a form directory1/*.h, directory2/*.h, and so on, and then the wildcard function expands all the *.h patterns.
Then, you generate the list of output files from them:
moc_mocfiles := $(patsubst %.h, %_moc.cpp, $(moc_headers))
This takes that expanded list of header files directory1/header1.h, directory1/header2.h, and so on, and substitutes the %.h pattern with %_moc.cpp. (Note that, because these names all have the directory name as part of the name, you can't easily use the more common moc_%.h name pattern, because you'd get moc_directory1/header1.cpp, not the desired directory1/moc_header1.cpp. There are ways to get around that, but it's easier to avoid the problem.) In any case, this gives you a list of output files: directory1/header1_moc.cpp, directory1/header2_moc.cpp, and so on.
Now that you have a list of output files, Make knows how to iterate over those pretty easily. You just declare that list as a prerequisite of some other target that you're making, for instance:
find_files: $(moc_mocfiles)
And, finally, you give make a generic rule for making a *_moc.cpp file from a *.h file:
%_moc.cpp: %.h
C:/QtSDK/Desktop/Qt/4.7.4/mingw/bin/moc.exe $< -o $#
There, the first line indicates "this is how you make a file that fits the %_moc.cpp pattern, if you have a file fitting the %.h pattern to make it from". In the second line, the $< becomes the input file (the %.h file), and the $# becomes the output file. Here, you're explicitly telling moc.exe with the -o option to spit out a file with the %_moc.cpp name rather than whatever it uses by default.
So, putting all this together, when you make the find_files target, make will realize that it needs to make all those %_moc.cpp files in the moc_mocfiles list, and for each one it will see that it has a possible rule that fits, it will see that the rule applies because the corresponding %.h file exists, and it will apply the rule.
This also has the advantage that, if the %_moc.cpp file already exists and is newer than the %.h file, indicating that it's already up-to-date, it won't bother regenerating it next time you run make. It will only regenerate the files corresponding to the %.h files you've edited.
(Oh, and one last thing: When cutting-and-pasting all these things from this answer, make sure you get your tabs in the right places!)
Just use native wildcard function of GNU Make:
HEADERS := $(wildcard $(SUBDIRS:%=%/*.h))
I'm new to compiling C/C++ with the aid of make. I downloaded an open source project and noticed that there is in the make file CXXSources and CXXObjects. I think I understand roughly what the make file is doing with them but...
I don't have any of the source files listed under CXXSources. Are these like dependences I'm supposed to know how to find? Is there any custom as to what CXXSource is versus just Source?
Added link to project: http://www.fim.uni-passau.de/en/fim/faculty/chairs/theoretische-informatik/projects.html
More specifically, the GML parser, eg. http://www.fim.uni-passau.de/fileadmin/files/lehrstuhl/brandenburg/projekte/gml/gml-parser.tar.gz
It seems to be getting stuck on the line:
gml_to_graph : $(CXXOBJECTS) gml_scanner.o gml_parser.o
$(CXX) -o gml_to_graph_demo $(CXXOBJECTS) gml_parser.o gml_scanner.o -L$(LEDADIR)/lib -lG -lL -lm
The $CXXObjects is defined by
CXXSOURCES = gml_to_graph.cc gml_to_graph_demo.cc
CXXOBJECTS = $(CXXSOURCES:.cc=.o)
So I need gml_to_graph.cc, it seems. Or maybe I'm wrong?
Usually, the variables are set before the point where you see them. This could be
(a) via the environment
(b) before including the quoted makefile
(c) in the quoted makefile, but preceding the location quoted
To see (verbosely) what GNU make takes into account, do:
make -Bn
(it will show everything that _would get executed)
Even more verbose:
make -p all
It will show you all the internal variable expansions.
If you post a link or more information, we will be able to come up with less generic (and hence possibly less confusing) answers
I have several hundred files in a non-flat directory structure. My Makefile lists each sourcefile, which, given the size of the project and the fact that there are multiple developers on the project, can create annoyances when we forget to put a new one in or take out the old ones. I'd like to generalize my Makefile so that make can simply build all .cpp and .h files without me having to specify all the filenames, given some generic rules for different types of files.
My question: given a large number of files in a directory with lots of subfolders, how do I tell make to build them all without having to specify each and every subfolder as part of the path? And how do I make it so that I can do this with only one Makefile in the root directory?
EDIT: this almost answers my question, but it requires that you specify all filenames :\
I'm sure a pure-gmake solution is possible, but using an external command to modify the makefile, or generate an external one (which you include in your makefile) is probably much simpler.
Something along the lines of:
all: myprog
find_sources:
zsh -c 'for x in **/*.cpp; echo "myprog: ${x/.cpp/.o}" >> deps.mk'
include deps.mk
and run
make find_sources && make
note: the exact zsh line probably needs some escaping to work in a make file, e.g. $$ instead of $. It can also be replaced with bash + find.
One way that would be platform independent (I mean independent from shell being in Windows or Linux) is this:
DIRS = relative/path1\
relative/path2
dd = absolute/path/to/subdirectories
all:
#$(foreach dir, $(DIRS), $(MAKE) -C $(dd)$(dir) build -f ../../Makefile ;)
build:
... build here
note that spaces and also the semicolon are important here, also it is important to specify the absolute paths, and also specify the path to the appropriate Makefile at the end (in this case I am using only one Makefile on grandparent folder)
But there is a better approach too which involves PHONY targets, it better shows the progress and errors and stops the build if one folder has problem instead of proceeding to other targets:
.PHONY: subdirs $(DIRS)
subdirs: $(DIRS)
$(DIRS):
$(MAKE) -C $# build -f ../../Makefile
all : prepare subdirs
...
build :
... build here
Again I am using only one Makefile here that is supposed to be applicable to all sub-projects. For each sub-project in the grandchild folder the target "build" is created usinf one Makefile in the root.
I would start by using a combination of the wildcard function:
http://www.gnu.org/software/make/manual/make.html#Wildcard-Function
VPATH/vpath
http://www.gnu.org/software/make/manual/make.html#Selective-Search
and the file functions
http://www.gnu.org/software/make/manual/make.html#File-Name-Functions
For exclusion (ie: backups, as Jonathan Leffler mentioned), use a seperate folder not in the vpath for backups, and use good implicit rules.
You will still need to define which folders to do to, but not each file in them.
I'm of two minds on this one. On one hand, if your Make system compiles and links everything it finds, you'll find out in a hurry if someone has left conflicting junk in the source directories. On the other hand, non-conflicting junk will proliferate and you'll have no easy way of distinguishing it from the live code...
I think it depends on a lot of things specific to your shop, such as source source control system and whether you plan to ever have another project with an overlapping code base. That said, if you really want to compile every source file below a given directory and then link them all, I'd suggest simple recursion: to make objects, compile all source files here, add the resultant objects (with full paths) to a list in the top source directory, recurse into all directories here. To link, use the list.