I have a Makefile.am that will create an Makefile lauching makes in subdirectories which contain external code, so its content is just
SUBDIRS=foo1 foo2 foo3
In foo1, there is already a Makefile (which compiles fortran and C code) so I do not want to write a file Makefile.am in this directory, but I would like to execute
make USE_THREAD=0
in the directory foo1 during the build.
Any idea how to tell automake to pass USE_THREAD=0 to the make command in foo1?
You should not use SUBDIRS for non-automake subdirectories. Instead, create your own rule:
foo1-build:
-$(MAKE) USE_THREAD=0 whatever-target
you will also need to wire in the right -local targets for clean and uninstall of course.
Related
Imagine we have an existing (untouchable) Makefile with target "foo", and another included Makefile which I can modify. I would like to add a new target called "runafter" which shall be executed after "foo" was run. So the user keeps calling "foo" and some additional code shall be run afterwards.
The usual way to achieve this would be to rename the original ones and do something like:
foo_old:
...
foo: foo_old
# run some code or call another target explicitly
$(MAKE) runafter
But that only works if you can rename foo. If not, how could I extend the behavior of the existing target? Everything I tried to do with foo: ... apparently causes overriding of the old foo target (with warning). But I just want to run some code afterwards!
I do not see how to do this from the included makefile but if you use GNU make then you can add a makefile named makefile instead of Makefile:
$ cat makefile
foo:
$(MAKE) -f Makefile $#
$(MAKE) runafter
runafter:
...
From the GNU make man page:
If no -f option is present, make will look for the makefiles GNUmakefile, makefile, and Makefile, in that order.
So you can also name it GNUmakefile if you wish. With one or the other running make foo should do what you want.
I'm working with autotools for the first time, for a tool that's written in perl (SQLTeX), so only installation is required, no compilation.
The toplevel contains a simple Makefile.am:
AUTOMAKE_OPTIONS = foreign
SUBDIRS = src man doc
EXTRA_DIST = README.md
.PHONY: all-am
all-am:
#echo "Done!"
If I create Makefile.am files in the sub-directories too, nothing seems to happen there so I just stick to Makefile. A snippet from src/Makefile (EDIT: this file is now renamed to Makefile.am):
SQLTeX: SQLTeX.pl
cat $^ | sed -e 's#{PERLDIR}#$(PL)#;s#{SYSCONFDIR}#$(sysconfdir)#' > $#
#chmod +x $#
The symbol PL is set as expect (defined in the same makefile), but sysconfdir is empty, although it is defined in the top-level Makefile generated by ./configure.
What am I doing wrong?
Thanks in advance!
What am I doing wrong?
Although the Autotools support, with some caveats, recursing into directories where you provide pre-built makefiles, you cannot expect those pre-built makefiles to be able to rely on autotools-provided variables such as the standard directory variables bindir and sysconfdir. Thus, although it is allowed to rely on hand-written makefiles in subdirectories, this is probably a false trail for you.
I recommend going back to this:
If I create Makefile.am files in the sub-directories too, nothing seems to happen there
and working out what's wrong. The Autotools definitely support generating recursive build systems, and one Makefile.am per directory is part of the usual approach to that. If it didn't work for you then my first guess would be that you forgot to list the extra makefiles in your AC_CONFIG_FILES list.
As an alternative, just because you have multiple directories does not mean that you need to use recursive make. It is quite possible to build such a project with the support of a single makefile, and the Autotools can help with such a makefile.
Here is Makefile as following, I want to ask what step1 and 2 will do seperately? thanks
DIRS = modules utils library
BUILDDIRS = $(DIRS:%=build-%) step1
all: $(BUILDDIRS)
$(BUILDDIRS):
$(MAKE) -C $(#:build-%=%) step2
This looks like a dispatching Makefile. Its job is to expose the build targets build-modules, build-utils and build-library. If it is not given any target, it builds the all target which depends on all of these. We can also think about, for instance, make build-utils being directly invoked.
Each build-<whatever> corresponds to a <whatever> dir without the build- prefix.
For instance to update the target build-utils, the action is to recursively invoke make with -C utils step2 as the arguments: change to the utils directory and look for a Makefile there, invoking its step2 target.
This Makefile has a flaw: the targets all and the build-<dir> targets are all phony, but there is no .PHONY: declaration for them. This means that make will probe the filesystem, looking for files named all, and build-modules, etc. If you create files with these names, such as by touch build-modules or touch all, the Makefile will then malfunction.
How would one test for the existence of files with a certain extension (.cpp in this case) in a directory at a specified location which is several directories down from the location of the makefile? I would like to print(echo) a message out if they are found
Your question is ambiguous. You mean, inside a make recipe you want to perform this test? If so then just write the appropriate shell scripting to check for the existence of said files.
If you mean outside of any recipe, in the makefile itself, if you're using GNU make you can use the $(wildcard ...) function:
ifneq (,$(wildcard some/sub/directory/*.cpp))
$(info found some cpp files!)
endif
I have a project that I am working to release that actually contains 3 subprojects, all of which need to be compiled in one go. My makefile looks roughly like this:
all: a b c
a:
#cd a && make
b:
#cd b && make
c:
#cd c && make
Projects A and B both compile fine but for the 3rd project, it tells me there is nothing to be done although switching to the C directory and running make does in fact compile code.
To be a little more specific: Project C in the example above is actually Mozilla's SpiderMonkey. Whereas A and B are code/makefiles that I have written, C is just a raw copy of SpiderMonkey from the Mozilla website. The actually compile command for it is:
make JS_DIST=/usr JS_THREADSAFE=1 JS_HAS_FILE_OBJECT=1
In my master Makefile, I have:
spidermonkey:
#cd spidermonkey/src && $(MAKE) JS_DIST=/usr JS_THREADSAFE=1 JS_HAS_FILE_OBJECT=1
Running "make spidermonkey" outputs "make: Nothing to be done for `spidermonkey'." How do I get make to run the command?
EDIT:
I've tried adding the following lines to my makefile:
.PHONY: spidermonkey
As well as renaming the spidermonkey rule to sm, but still no change.
EDIT:
My bad! I had spaces when I should have had a tab. doh!
You probably have a file or directory at the toplevel called "spidermonkey". Make thinks this is what its supposed to create, and since it is already there, make stops.
One of the most important rules to follow when writing makefiles is each target should create one file with the same name as the target. In other words, if you have
a:
<some command>
That command should produce a single file called "a".
Rules which do not produce files but are only there as placeholders are called phony targets, and they should be declared like this:
.PHONY: a
Make will then always assume that a has to be remade.
Also, as a general rule do not use "make" to invoke make recursively, use $(MAKE) instead.
EDIT: changed "pseudo" to "phony"
Make only checks for the existance of a file (or directory) named the same as the rule target, and if there is (and it is newer than the dependencies) then from make's point of view there is nothing more to do.
So your problem is that you have a spidermonkey rule (with no dependencies) as well as a directory called spidermonkey, and then make thinks "the target is already made, nothing for me to do". To get make to do what you want, rename the spidermonkey rule (or the directory).
Speaking of recursive make by the way, this is not neccessarily a good idea,
see Recursive Make Considered Harmful.