I'm using a .phony target to create a configuration file before running most targets in my Makefile. However there is one target, the init: target, that should not run the .phony (because it is initializing the directory and the needed file does not exist.)
Is there a way to disable the .phony target for this one target but have it work for any other target in the makefile?
Related
Could someone please tell me if there is a way to enforce sequential execution of specific Makefile targets. For example, I have a Makefile that builds Libraries and Executables. Now, Executables depend on Libraries, so they must be built after the Libraries are built and staged. This is what I currently have in a single Makefile:
.PHONY: all
all: all_lib all_bin
.PHONY: all_lib
all_lib: $(dep_lib)
.PHONY: all_bin
all_bin: $(dep_bin)
I have two targets all_lib and all_bin, one builds all libraries and the other builds all binary executables. When I pass -j to make to run parallel jobs, I get build failures, because all targets run in parallel and binaries can't find shared library objects and staged header files.
I tried changing it to this to try and force some dependency order:
.PHONY: all
all: all_bin
.PHONY: all_lib
all_lib: $(dep_lib)
.PHONY: all_bin
all_bin: all_lib $(dep_bin)
But for some reason all targets still run in parallel I still get the same build failures. Any ideas?
Make is entirely built around the concept of dependencies. You are simply not using it that way.
If an executable depends on a library, then you should list that library in the prerequisites list of the executable. I can't give you a relevant example because you don't provide any details about the contents of dep_lib or dep_bin above, but for example:
exe1 : exe1.o liblib1.a liblib2.a
etc. Now, exe1 won't attempt to be linked until after the liblib1.a and liblib2.a targets have been created.
I installed OMNET++ 5.1 on my Ubuntu 16 OS and imported my project into the Eclipse IDE. But I can not compile my project as before. Make is giving me error:
make1: *** No rule to make target 'msgheaders'. Stop.
I have a folder called loggingWindow that has its own custom makefile and is excluded from the source.
But I noticed that the generated makefile is not correct:
The makefile is calling msgheaders and smheaders targets in the logginWindow folder. The loggingWindow is a completely separate application with its own makefile and has no idea about mshheader!
Also make clean does not work!
The clean window stuck without any progress:
As a temporary workaround, I have added phony targets (msgheaders, smheaders) in order to compile my project.
As a workaround you can add these targets to your own Makefile in logginWindow, for example:
msgheaders:
echo Do nothing
smheaders:
make all
# content from your existing Makefile
all:
...
I am studying a Makefile obtained from a compiler course project. Only a part of it is pasted here.
# Retain intermediate bitcode files
.PRECIOUS: %.bc
# The default target builds the plugin
plugin:
make -C lib/p1
# create .bc from source
%.bc: %.c
clang -emit-llvm -O0 -c $*.c -o $*.bc
# run printCode on a .bc file
%.printCode: %.bc plugin
opt -load Debug/lib/P1.so -printCode $*.bc
As you see, the target 'plugin' has no dependencies, which, if I understand correctly, should mean that its recipe never runs (unless it is declaared as a phony target, which is not the case here)
However, when I type 'make printCode', (printCode is the last target in the list) the plugin target does execute. How is this made possible? Is there some implicit rule stating that the first target of a Makefile is regarded as a phony target, such as 'all'?
You've got things a little backward.
A rule like the plugin rule can run. You can run it by executing 'make plugin', or 'make' if it's the default target (which it is in this case by virtue of being the first), or if it is a prerequisite of another target that must be built.
I'm not sure exactly what happens when you 'make printCode', since you are showing us only part of the makefile and there is no rule that fits, but judging by this rule:
%.printCode: %.bc plugin
opt -load Debug/lib/P1.so -printCode $*.bc
I'd guess that the printCode rule depends on either plugin or something like foo.printCode that depends on plugin. So Make sees that plugin is a prerequisite, sees that no such file exists, and determines therefore that plugin must be built. It then looks for a rule to build plugin, finds it and runs it.
I just discovered this line in a makefile:
%: Makefile
To me, that says "to make any target, you need this makefile", which strikes me as somewhat obvious.
Is there any situation in which this is not a no-op?
As Etan commented, this will cause every target to be rebuilt whenever the Makefile changes. This is necessary so that anytime you make a change in the build configuration parameters the target will be rebuilt. Otherwise make won't know to rebuild with the new configuration.
I have several directories representing subparts of a project, each with its own Makefile.
I want to create a master Makefile with targets for each of those subparts, each target satisfying the following:
depend on a certain target from that subproject's Makefile.
This is the tricky part.
copy some resulting library/executable build by the subproject into a central directory (kind of like "make install"-ing it).
This I can already achieve using simple commands.
I could only find information about the include directive of GNU make, but that doesn't help me much as it seems not to encapsulate the rules (and execution) of the included makefile in its own directory, but instead just #includes them C-style (rather that thinking of them as packages with separate scopes).
INSTALLDIR := build
SRCDIR := src
TARGETS := projA projB
.PHONY: $(TARGETS)
TARGETS_PATH := $(addprefix $(SRCDIR)/, $(TARGETS))
MAKEFILES := $(addsuffix /osx.mak, $(TARGETS_PATH))
# include them somehow?
For such a setup as defined above, I now want each of $(TARGETS) to depend on the release target of its corresponding Makefile (something like projA: $(SRCDIR)/projA/osx.mak # release for projA, in my own language meaning that target projA depends on the successful execution of the release target in that specific Makefile).
Is there any way to achieve this?
You can suggest other tools apart from GNU make, but the subproject makefiles are already written as makefiles.
Have a look at recursive make.
You could do something like,
SRCDIR := src
TARGETS := projA projB
.PHONY: $(TARGETS)
$(TARGETS):
cd $(SRCDIR)/$#; $(MAKE) release