If I have a, for instance, dbg executable that I compile with:
make dbg
//outputs: my_exe-dbg
And I make edits to the makefile, I would then like to re-run make dbg. However, the presence of the my_exe-dbg prevents make from doing anything.
I would like to write:
make dbg -f
Which compiles and replaces the executable. If I write:
make dbg -fr
It would compile and replace everything (r would signify "executable"). How would I check for flags and reason about them within the makefile?
Is there a variable or built in mechanism for capturing or defining flags to look for?
Is there a work-around for detecting these dash flags?
You can invoke make (at least GNU make, not sure how portable this is) as
make -B dbg
which disables the timestamp checks and always builds everything. A per-target workaround could instead be
dbg-f: # dependencies only if referred to by $< below
# command to build dbg
.PHONY: dbg-f
This way, you can force the compilation by
make dbg-f
while
make dbg
works as before and checks for dependencies and their timestamps.
Related
I am trying to compile c++ files using make. But, it is not using -std=c++11 flag by default. Whenever I need to compile a program which uses c++11 specific features, I have to explicitly compile it using g++.
So, I want to ask how can I have make automatically use the option -std=c++11 for all my c++ files on my system.
If I need to change some global makefile for g++ , what is the location of the makefile on Linux Mint 18 and what needs to be changed or added?
Or do I need to create a Makefile for myself?
EDIT 1: I am invoking make like make myfile
And there are only .cpp files and their binaries in the directory. I don't have any Makefile in the directory.
EDIT 2: Here, myfile is the name of the c++ file which I want to compile.
When I run make with the -d option, I get the following output (I can not paste all of the output as it is quite long and is exceeding the body size limit so, I am including the screenshots of the output).
Image 1
And this image(2) has some lines from the end.
Image 2
I intentionally made a change in the file "MagicalWord.cpp" so that make finds something to make!
There is no "global makefile" and there is no way to change the default flags for all invocations of make (unless you edit the source code to GNU make and compile it yourself, which is a bad idea in this situation).
In your makefile(s), add the line:
CXXFLAGS += -std=c++11
Assuming you're using the built-in rules for compiling things, or that you're using the standard variables with your own rules, that will do what you need.
If that doesn't work we'll need to see your makefile or at least the rules you use to build your C++ source files (things like the -d output aren't useful here--that would be interesting if files weren't being built, that you thought should be or similar).
Setting a system-wide language for all your C++ projects isn't necessarily a good idea. Instead, define a Makefile that specifies any compiler options you'd like:
CXXFLAGS := -std=c++11 $(CXXFLAGS)
The CXXFLAGS are then passed to your compiler when compiling a C++ program (assuming you're using the default GNU Make rules).
If the Makefile lives in your current working directory, you can now run make target in order to compile a target.cpp file into a target executable.
If the Makefile is in another directory, you must specify the path to it:
make -f path/to/your/Makefile target
If you want to add extra parameters just for one run, you can set an environment variable or a make variable on the command line:
# environment:
CXXFLAGS='-std=c++11' make target
# make variable:
make target CXXFLAGS='-std=c++11'
Any of these will cause the execution of g++ -std=c++11 target.cpp -o target or equivalent.
In theory you can edit your shell profile to export CXXFLAGS='-std=c++11' which will make that environment variable available to all programs you run. In practice, setting compiler options through environment variables tends to cause more problems than it solves.
Of all these solutions, just writing a normal Makefile is by far the easiest approach. That way, all of the build configuration is in one place and completely automated.
How to show the makefile after it's been preprocessed? For example, if we have two makefiles:
# Makefile
include Makefile2
# Makefile2
a:a.c
gcc -o a a.c
Then <preprocessor> Makefile should give:
a:a.c
gcc -o a a.c
It's similar to what a C preprocessor does (gcc -E). Is there such a makefile preprocessor?
You didn't specify for which make tool you are writing makefile. Assuming that it is GNU make, you can try running makefile with -n (--just-print) option See Command-Line Options chapter here. That will show what make is going to execute without execution (however, the commands needed for evaluation of variables will be executed). This is probably the closest to what you want to see.
This causes make to read the makefile and print every command it would
normally execute to update the target but without executing them.
Apart from that there is $(warning ) function to debug makefiles. You can place it almost to any part in makefile and the following will show you the values of all defined variables in that place:
$(warning Variables HERE: .VARIABLES)
I'm new to using makefiles and trying to produce a basic makefile as part of an exercise for university. I have two source code files, chello.c and writeexit.s, which have to be compiled/assembled and then linked to produce chello.
This is the code I have so far for the makefile:
chello: chello.o writeexit.o
ld -N chello.o writeexit.o -o chello
chello.o: chello.c
gcc -c chello.c -o chello.o
writeexit.o: writeexit.s
as writeexit.s -o writeexit.o
The whitespace before ld, gcc and as are all tabs, so I think the whitespacing is fine. When I call 'make makefile', it returns 'make: Nothing to be done for `makefile'.' However, if I change the dependencies of chello, like chello.c, the same message is returned and chello's behaviour is not modified.
From man make:
make executes commands in the makefile to update one or more target
names, where name is typically a program. If no -f option is present,
make will look for the makefiles GNUmakefile, makefile, and Makefile,
in that order.
make makefile will actually execute your "makefile" (because it is listed among the default names in the man page) file, trying to build the "makefile" target (because of the argument you are passing), which already exists
What you need is to build the "chello" binary, so you have to type:
make chello
Or alternatively:
make -f makefile chello
Alternative account here, it seems to work fine if I just call "make" instead of "make makefile". This question can be ignored.
Most Linux apps are compiled with:
make
make install clean
As I understand it, the make command takes names of build targets as arguments. So for example install is usually a target that copies some files to standard locations, and clean is a target that removes temporary files.
But what target will make build if no arguments are specified (e.g. the first command in my example)?
By default, it begins by processing the first target that does not begin with a . aka the default goal; to do that, it may have to process other targets - specifically, ones the first target depends on.
The GNU Make Manual covers all this stuff, and is a surprisingly easy and informative read.
To save others a few seconds, and to save them from having to read the manual, here's the short answer. Add this to the top of your make file:
.DEFAULT_GOAL := mytarget
mytarget will now be the target that is run if "make" is executed and no target is specified.
If you have an older version of make (<= 3.80), this won't work. If this is the case, then you can do what anon mentions, simply add this to the top of your make file:
.PHONY: default
default: mytarget ;
References:
https://www.gnu.org/software/make/manual/html_node/How-Make-Works.html
GNU Make also allows you to specify the default make target using a special variable called .DEFAULT_GOAL. You can even unset this variable in the middle of the Makefile, causing the next target in the file to become the default target.
Ref: The Gnu Make manual - Special Variables
bmake's equivalent of GNU Make's .DEFAULT_GOAL is .MAIN:
$ cat Makefile
.MAIN: foo
all:
#echo all
foo:
#echo foo
$ bmake
foo
See the bmake(1) manual page.
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.