Compilation order in make rule - makefile

I have a compilation rule as follows,
$(compiled_objs) : $(obj_dir)/%.o: $(src_base)/%.cpp
It creates .o dso objects from specific .cpp files in src_base and works fine.
Question:
My question is that is there a way in gnu Makefiles to sort the order in which %.cpp files are processed. For example, in each src_base, i have a file called xxxLast.cpp and i want to create the object for *Last.cpp after all other .cpp files from $src_dir directory has already been processed.
Use-Case:
My use case is not common but i want to embedd the md5sum of all other .o objects in xxxLast.cpp file for which i can add additional handling in my rule.
I haven't done much work on makefiles. Help will be highly appreciated and thanks in advance.

Somewhere else in your makefile you'll have a target that depends on $(compiled_objs):
all_objects: $(compiled_objs)
Make will build the prerequisites of any target in the order they are listed. So if you want a particular object to be built last, then you just put it at the end of the compiled_objs macro.
Be aware that during parallel builds make will still walk the commands to run in the same order, BUT due to parallelization effects they may actually run in a different order, or at least you can't know that the last one will be started after all the previous ones have completed.
For your situation I really don't recommend just stucking the last object at the end and hoping. You should define this relationship explicitly using make rules, so:
all_objects: xxxLast.o
xxxLast.o: $(compiled_objs-but-not-xxxLast.o)
...generate md5sums for $^...
xxxLast.o $(compiled_objs-but-not-xxxLast.o): $(obj_dir)/%.o: $(src_base)/%.cpp

Related

I'm seeing occasional build failure due to auto generated files (automake). How do I create dependencies between autogenerated files?

I have been trying to debug a makefile.am that occasionally causes a build failure in make. In this file, the sources are auto generated .c files and the headers are auto generated .h files.
..._SOURCES = #buildDirectory#/x.c
#buildDirectory#/y.c
#buildDirectory#/z.c
..._HEADERS = #buildDirectory#/x.h
#buildDirectory#/y.h
#buildDirectory#/z.h
The failure looks like this
<failedproto>.proto: "symbol1" is not defined.
<failedproto>.proto: "symbol2" is not defined.
<failedproto>.proto: "symbol3" is not defined.
...
<failedproto>.proto: warning: Import <failedproto>.proto but not used.
make: *** [<failedproto>.c] Error 1
make: *** Waiting for unfinished jobs....
All of these symbols appear in the a corresponding .h. This leads me to think that the .c is being generated before the .h, and its just a straight race. I have added both ..._SOURCES and _HEADERS to BUILT_SOURCES, but I still see the failure. So my next instinct is to create a dependency for the .c on the .h. How do I do this, since they are both auto generated? Also, any alternative solutions would be welcome too.
Hopefully my formatting is not confusing.
Edit with some more detail:
These files are being auto generated by the protoc-c compiler: https://github.com/protobuf-c/protobuf-c
The protoc-c takes these .proto files and generates .pb-c.c and .pb-c.h files, making me think that these two are not dependent after all. Some in house code is also run, which generates other .proto files, I will call them nameX.proto and nameY.proto, which in turn generate nameX.pb-c.c/nameX.pb-c.h and nameY.pb-c.c/nameY.pb-c.h. A more accurate example of the Makefile.am is like this:
..._SOURCES = #buildDirectory#/name.pb-c.c
#buildDirectory#/nameX.pb-c.c
#buildDirectory#/nameY.pb-c.c
..._HEADERS = #buildDirectory#/name.pb-c.h
#buildDirectory#/nameX.pb-c.h
#buildDirectory#/nameY.pb-c.h
I have been trying to track these dependencies, and I will try and describe what conclusions I have come to. nameX.pb-c.c includes its corresponding header nameX.pb-c.h. That header includes nameY.pb-c.h, making me think that nameX.proto is being compiled into nameX.pb-c.c/nameX.pb-c.h before nameY.proto can be compiled. Since there is an include relationship between nameX.pb-c.h and nameY.pb-c.h, the build fails because nameX.pb-c.h needs nameY.pb-c.h. This leads me to two rules I've been suspicious about from the start. These rules are generalized like this:
$(OUT_DIRECTORY)/%nameX.proto:$(SRC_DIRECTORY)/name.proto $(SRC_DIRECTORY)/nameY.proto
command $(OUT_DIRECTORY) $(FLAGS) $<
$(OUT_DIRECTORY)/%nameX.proto:$(SRC_DIRECTORY)/name.proto
command $(OUT_DIRECTORY) $(FLAGS) $<
Could this be an issue? What is stopping the second rule from being run if it truly needs the first rule?
To make matters worse, many of the .proto files are intermediate files (they are generated then discarded throughout the build) so I cannot look at them to see what they look like.
It's very unusual to use #...# replacements throughout your makefile like this. Normally you would assign the replacement once, to a make variable, then use the variable instead (in addition to being "nicer to read", this allows someone to override this value on the make command line if they want to):
BUILDDIR = #buildDirectory#
..._SOURCES = $(BUILDDIR)/x.c
$(BUILDDIR)/y.c
$(BUILDDIR)/z.c
..._HEADERS = $(BUILDDIR)/x.h
$(BUILDDIR)/y.h
$(BUILDDIR)/z.h
Also, it seems likely to me that there are standard automake variables that might already cover this value; if so it's better to use the standard ones than invent new ones... but obviously there's no way to know that without knowing more about your environment.
Anyway, for your question we need to know more about this autogeneration operation. What do your rules for autogenerating look like now? Is it really the case that the generation of the .c file can't be done until the .h file is generated? That's unusual.
If you list the output file, the input files, and the command needed then it's pretty simple to write a correct rule.

Makefile - does using .PHONY for running commands was intended when creating make?

I know we can set up commands such as all, clean, install etc in makefile and use .PHONY to tell make they're not associated with files.
But I was wondering - when creating make and makefile - was this kind of use (to run such commands) combined with .PHONY designed for that purpose? Or maybe .PHONY was added later to easily extend make to support those kind of commands?
I also read this but there wasn't anything else there except the regular known usage.
Thanks!
I do not know the history of GNU make.
The use of .PHONY is exactly what you suspect: have targets (which can thus be goals, or commands, if you wish) that are not files, and that work even if, by accident, a file with the same name exists. It is one single and clearly defined purpose.
In certain cases you want to force a target file to be re-built even if it is up-to-date, and you can declare it a prerequisite of .PHONY for this purpose, but it is frequently the sign that your makefile is not what it should be.
Another frequent situation is the grouping of several targets (real or phony) as prerequisites of one single other phony target.
But in both cases, we can say that the resulting phony target is a kind of command. In the first case it is a command that forces the build of a file. In the second it is a kind of alias for a series of actions.

Multiple instances of the same target for make

I am working on a Makefile written by someone else in my lab and I see the following:
include /path/to/Makefile.inc
TARGET_A: pre_req_1 pre_req_2
cmd_1;
cmd_2;
...
When I look at /path/to/Makefile.inc I see that it also includes a target TARGET_A
with other pre-requisites and recipes.
Is this a normal practice? (and would it work?) Would make treat the two rules separately? Can we safely make any assumptions about which one is considered first?
It is a dangerous practice since it is confusing to know which one is applied.
The "include" will act has if the included file content was in the Makefile, and the targets will be overrided while reading the Makefile. So, the last target will be honored, and the first one (in the included file) will be ignored.

makefile not detecting new save file

Strange thing happening:
The idea of the makefile is to be able to compile several files at the same time. If you edit one of those files, when you type make, the only file that should compile is the one that was edited.
Now, for some reason, my makefile has decided to stop recognizing when the file has changed. So I have to: make clean and the make again to be able to compile, which is ridiculous since each time I have to compile takes about 1 minute.
Any ideas why this is happening?
I didn't add anything to my makefile; it just started doing that out of nowhere.
Something changed; programs don't stop working unless something changed. The difficulty is going to be working out what changed. You can always just type:
rm file-that-changed.o
make
to rebuild just the one file that changed, but that's a nuisance.
Is there a multi-step compilation and you have an intermediate file lying around that is confusing make?
I just had a mix up in a multi-step compilation.
If you have a non-standard file suffix that you compile into C code, and then from C into object code (or any other similar multi-step compilation), then the key to getting reliable recompilation with make is to organize the suffix list so that your extensions come at the start. Unfortunately, there isn't a standard easy way to know what the built-in suffix list is, so you end up having to do something like this:
SUFFIXES = .y .l .c .o # Yacc, Lex, C, Object files
EXTRA_SUFFIX = .xc # Extreme C, or Extended C, or ...
.SUFFIXES: # Eliminate all built-in suffixes
.SUFFIXES: ${EXTRA_SUFFIX} ${SUFFIXES}
The second .SUFFIXES line puts your extension at the front of the list. Now you can write your rules to compile your .xc file into a .c or .o file, and then when you modify the .xc file, even if there's an intermediate .c file left around, the fact that the .xc is newer than the .c or .o file will ensure that the recompilation is done.
Once upon a long time ago, the Sun version of make provided a macro called SUFFIXES which contained the default suffixes in the correct order. Sadly, that was not adopted and standardized, so you have to build the suffix list yourself. But the choice of macro name wasn't entirely accidental.

Building hierarchical Makefile with GNU Make

I have a project divided in modules, each hosted in a directory, say:
root
|_module_A
|_module.cpp
|_Makefile
|_module_B
|_Makefile
|_main.c
|_Makefile
main.c depends on targets defined in Makefiles related to module_A and module_B.
I want to write my root/Makefile with respect to targets defined in Makefiles of both modules.
Now, I know that I could use the include directive, but the problem here is that targets and filenames in module_A and module_B aren't prepended with their directory, so I get something like this:
make: *** No rule to make target `module.o', needed by `main.c'. Stop.
There is a good way to solve this?
Thanks.
There are a couple of ways to do this, none of them perfect. The basic problem is that Make is good at using things there to make things here, but not the other way around.
You haven't said what the targets in module_B are; I'll be pessimistic and suppose that module_A and module_B both have targets called module (different source files, different recipes), so you really can't use include.
The biggest choice you have to make is whether to use recursive Make:
If you don't, then root/Makefile must know how to build module_A/module and module_B/module, so you'll simply have to put those rules in. Then you must either leave the redundant rules in the subdir makefiles (and run the risk that they'll drift out of agreement with the master makefile), or eliminate them, or have them call the master makefile recursively (which you wouldn't have to do very often, but it sure would look silly).
If you do, then root/Makefile will look something like this:
main: main.o module_A/module.o Module_B/module.o
...
main.o: main.c
...
%/module.o:
$(MAKE) -C $(#D) $(#F)
This will work well enough, but it will know nothing about dependencies within the subdirectories, so it will sometimes fail to rebuild an object that is out of date. You can make clean (recursively) beforehand every time, just to be on the safe side, crude but effective. Or force the %/module.o rule, which is less wasteful but a little more complicated. Or duplicate the dependency information in root/Makefile, which is tedious and untidy.
It's just a question of your priorities.
Can't you write the makefile in a non-recursive way?
Recursive Make Considered Harmful

Resources