I need seven binaries maked from the same set of source codes and headers. All of the codes must be compiled with the same CFLAGS. In my problem, there are 7 alternatives for CFLAGS:
CFLAGS=-O0
CFLAGS=-O1
CFLAGS=-O1 -no-vec
CFLAGS=-O2
CFLAGS=-O2 -no-vec
CFLAGS=-O3
CFLAGS=-O3 -no-vec
What is the shortest and most suitable way to compile all source codes using make?
Overriding variable CFLAGS from command line?
I suggest you to use overriding variable CFLAGS from command line.
For this particular case the set of shell commands looks like:
make CFLAGS=-O0; mv binary binary1; make clean;
make CFLAGS=-O1; mv binary binary2; make clean;
make CFLAGS=-O1\ -no-vec; mv binary binary3; make clean;
make CFLAGS=-O2; mv binary binary4; make clean;
make CFLAGS=-O2\ -no-vec; mv binary binary5; make clean;
make CFLAGS=-O3; mv binary binary6; make clean;
make CFLAGS=-O3\ -no-vec; mv binary binary7; make clean;
This will allow you to keep makefile simple as for the case with one CFLAGS value.
But there is one problem with this method. For creating seven binaries, each time after calling make you should move newly created binary. This can be solved by introducing the
TARGET variable for the name of the particular target.
make CFLAGS=-O0 TARGET=binary1; make clean;
make CFLAGS=-O1 TARGET=binary2; make clean;
make CFLAGS=-O1\ -no-vec TARGET=binary3; make clean;
make CFLAGS=-O2 TARGET=binary4; make clean;
make CFLAGS=-O2\ -no-vec TARGET=binary5; make clean;
make CFLAGS=-O3 TARGET=binary6; make clean;
make CFLAGS=-O3\ -no-vec TARGET=binary7; make clean;
Related
The GNU make manual says:
A phony target should not be a prerequisite of a real target file; if it is, its recipe will be run every time make goes to update that file.
What if that's what I want?
For example, what if I have a phony target called lint that lints app/scripts/main.js, and I want it to run every time make goes to update (transpile & minify) dist/scripts/main.js?
I just removed the lint target and put its recipe as the first command of the recipe for the dist/scripts/main.js target.
dist/scripts/main.js : app/scripts/main.js
./node_modules/.bin/eslint $< && \
mkdir -p dist/scripts && \
./node_modules/.bin/babel $< | \
./node_modules/.bin/uglifyjs - --screw-ie8 -o $# -m -c
Updated answer: the current GNU make manual does not specify the cited "rule" from the question but instead explicit says to make use of this in the entry about forced targets, which includes a note:
As you can see, using FORCE this way has the same results as using .PHONY clean.
Using .PHONY is more explicit and more efficient. However, other versions of make do not support .PHONY; thus FORCE appears in many makefiles
I have a following directory structure
src/
kernel/
gui/
In kernel/ directory, I have generated a library named libkernel.a and in gui/ directory I have to use libkernel.a to generate libgui.a.
I added this to the gui/Makefile.am
libgui_a_LIBADD = $(srcdir)/kernel/libkernel.a
But I am getting the following error
*** No rule to make target `kernel/libkernel.a', needed by `libgui.a'. Stop.
So I don't understand how do I link libkernel.a properly.
Edit/Explanation
In gui/ directory I have one somegui.cpp file that uses xclass.h which is in kernel/ directory.
So in order to solve that issue I am asking how should I proceed.
Try to use non-recursive automake to avoid these kind of problems.
https://www.flameeyes.eu/autotools-mythbuster/automake/nonrecursive.html
Sidenode: use $(top_builddir) when referring to compiled objects. Otherwise your code will break when srcdir != builddir
If you really have to do it recursive, than you can add a rule to gui/Makefile.am
$(top_builddir)/kernel/libkernel.a:
cd $(top_builddir)/kernel && $(MAKE)
Note: If you want to use parallel make (-j) you also need to make sure that in src/Makefile.am there is a dependency between the subdirs
.PHONY kernel gui
kernel:
cd kernel && $(MAKE)
gui: kernel
cd gui && $(MAKE)
I know that makefile is used for a project where files are related. But I want to use it in a different way.
Since I always write lots of test files, I need to type a bunch of flags every time I compile them, that's so troublesome. I just want to write a makefile that compiles all source files into executables with their corresponding names - like a.c to a and b.c to b, etc. so that I can get executables by simply typing make instead of the whole gcc ...
Is there any simple way to do it?
Make has a built in implicit rule like this:
% : %.c
$(CC) -o $# $(CFLAGS) $<
$(CFLAGS) would contain all your options.
Then, doing
make foo
Would try to produce foo from foo.c (if it existed).
To be able to compile all of them in one go, add another rule:
all: $(patsubst %.c,%,$(wildcard *.c))
This new rule, called 'all', has the list of your executables as its prerequisite. The wildcard function lists all .c files in the directory, and the patsubst removes the .c from each of them, leaving a list of the executables that would be produced from each .c file.
So doing
make all
causes it to try to compile each .c file into the corresponding executable.
Alright understood. I'm not too sure if you'll understand the syntax. I'll try to explain as much as I can.
you'll make a file called Makefile no extensions.
DIR=$(HOME)/../"Your directory"
all: "Whatever driver you may have"
purify: purify g++ -o "Your file" -Wall -pedantic -g "objective file .o extension"
# Makes clean file
clean:
rm -f *.o "Drivers"
new:
make clean
make
make has built in implicit rules to do that. Just type make a or make b or make a b or whatever you want. Add and export an environment variable called CFLAGS if you want to add any special options.
Imagine the following folder structure:
project
src
code.c
makefile
bin
How can I compile code.c to code.o and directly put it inside bin? I know I could compile it to code.o under src and the do "mv code.o ../bin" but that would yield an error if there were compile errors, right? Even if it works that way, is there a better way to do it?
Thanks.
The process should or should not "yield an error" depending on what you mean. If there are compiler errors, you'll know it.
That said, there are several ways to do it with make. The best in this case are probably:
You could put the Makefile in bin. Make is good at using files there to make files here, but not the other way around.
You could specify the target path in the makefile target:
$(MAIN_DIR)/bin/%.o: %.c
$(COMPILE)...
A little late, but if it can be helpful.
This is how I get the up one level directory path from where the makefile is.
$(subst $(notdir $(CURDIR)),,$(CURDIR))
if your project looks like that:
~/myProject/
src/
Makefile
#all the .c and .cpp
bin/
#where you want to put the binaries.
$(CURDIR) will output ~/myProject/src
$(subst $(notdir $(CURDIR)),,$(CURDIR)) will output ~/myProject
You could try moving, but only when the compilation was successful using &&:
code.o: code.c code.h
g++ -c code.c && mv code.o ../
mv code.o ../ will only be executed if g++ returned 0, which is when the compilation was successful. This may not be suitable solution for you if you have very complicated makefile, but I thought I'd share what I know.
You can still use the move approach and survive compiler errors:
cc -c code.c && mv code.o ../bin
This won't run the "mv" part if the "cc" part fails.
I am new to Automake and I am attempting to compile without linking. My goal is to generate a simple Makefile as shown below using Automake.
CFLAG = -Wall
build: Thread.o
Thread.o: Thread.cc Thread.h
g++ $(CFLAG) -c Thread.cc
clean:
rm -f *.o
My attempt so far has brought me to the following Makefile.ac.
noinst_PROGRAMS = thread
thread_SOURCES = Thread.cc
EXTRA_DIST= Thread.h
How can I simulate my original Makefile?
One way is to do this is to fool Automake by providing link command that does not link:
thread_LINK = true
Other than that, I wouldn't be suprised if Automake did not have such feature.
For your example, you can just ask Automake to build your .o file directly, e.g.:
$ make Thread.o
I believe this is an implicit rule, so you won't see it in the output Makefile.
In general, Automake generates variables containing all the objects required for each executable or library target. It's pretty straightforward to use them in your Makefile, since it just generates their names by appending _OBJECTS to the target name. You could make your own target in Makefile.am like this:
build-thread: $(thread_OBJECTS)
Then you could build just Thread.o (and any other objects needed for thread) like this:
$ make build-thread
Or if you had multiple targets foo, bar, and baz, you could make your compile-only target in Makefile.am like this:
build: $(foo_OBJECTS) $(bar_OBJECTS) $(baz_OBJECTS)
The only pain here is that you'll need to maintain this list yourself based on the targets in your Makefile.am. You can invoke it at the command line like this:
$ make build
Automake is not designed to produce object. It will build either programs or libraries.
It's hard to answer your question without knowing why you'd want to compile a single object file and not something else. Maybe there is a cleaner answer to your "real" problem.
A Makefile.am you could write is
noinst_LIBRARIES = libThread.a
libThread_a_SOURCES = Thread.cc Thread.h # No need to put headers in EXTRA_DIST
The resulting Makefile would build a library libThread.a containing only libThread.o, ans because *.a libraries are just a collection of object files there is no linking involved.
The above Makefile.am also causes the emitted Makefile to contain rules to compile libThread.o, so you can add a build: rule if you like.
If you really want Automake to emit this compile rule, but not build the library, you could go with
EXTRA_LIBRARIES = libThread.a # EXTRA here means "output build rules but don't
# build unless something depends on it".
libThread_a_SOURCES = Thread.cc Thread.h
build: Thread.$(OBJEXT)
Now you are explicitely requiring the file Thread.$(OBJEXT) to be built only when you type make build, as in your original Makefile.
(Automake uses .$(OBJEXT) rather than .o to support extensions like .obj in DOS variants.)
First off, automake is a tool to auto make making Makefiles; make in and of itself is a whole different beast (and I'm pretty sure that what you were looking for was a make solution).
Here's the easiest GNU based Makefile to accomplish what you want:
all: Thread.o
This fills in something (by default) like the following (please change 4-space whitespace to hard tabs):
all: Thread.o
Thread.o: Thread.cc
$(COMPILE.cpp) $(OUTPUT_OPTION) $<
The COMPILE.cpp and OUTPUT_OPTION macros of course expand by default to GNU make specified values and aren't portable; $< is AT&T Make standard syntax though according to pmake(1)'s manpage though.
GNU make has a concept of implicit vs explicit rules, patterns, suffixes, etc that you could use, but that's not portable to all versions of make, and hence that's why all of the Makefile is plainly spelled out in terms of targets and variables as POSIX doesn't describe many of the desired scenarios for how one should write a Makefile.
Run gmake -p for more details and take a look at the texinfo manual for gmake in the topic of implicit, explicit rules, patterns, suffixes, etc.