I am finding problem when I try to include a C source file in my Makefile. This C source file contains a function which is called by the C++ code (list.cpp) through external C linkage option. I would like to know which is the right place in the Makefile to include this C source code whose function is invoked inside C++ code. If I try adding this C file in the Makefile's SOURCES variable in order to built it, then the C++ code fails to correctly resolve the function call of C and I am getting linker error: undefined reference
Following is my Makefile content:
CFLAGS =-c -g -Wall -std=c++11
SOURCES = list.cpp
OBJECTS = $(SOURCES:.cpp=.o)
EXEC = a.out
all: $(SOURCES) $(EXEC)
$(EXEC): $(OBJECTS)
#$(CXX) $(OBJECTS) -o $# && $(EXEC)
.cpp.o:
#$(CXX) $(CFLAGS) $< -o $#
Let's assume the C source file that you need in the build is bar.c,
and that it has an associated header file bar.h that you are
#include-ing in list.cpp, and that you have correctly coded the extern C
boilerplate in bar.h.
Then the following makefile will do what you need:
Makefile
CXX_SOURCES := list.cpp
C_SOURCES := bar.c
OBJECTS = $(C_SOURCES:.c=.o) $(CXX_SOURCES:.cpp=.o)
CXXFLAGS := -g -Wall -std=c++11
CFLAGS := -g -Wall
CPPFLAGS :=
LDFLAGS :=
LDLIBS :=
EXEC := a.out
.PHONY: all clean test
all: $(EXEC)
test: $(EXEC)
./$<
$(EXEC): $(OBJECTS)
$(CXX) $(LDFLAGS) $^ -o $# $(LDLIBS)
list.o: bar.h
clean:
rm -f $(EXEC) *.o
There are a lot of learning-points here:
1. Use immediate evaluation (:=) rather than recursive evaluation (=) of
make variables unless you particularly want recursive evaluation. See
6.2 The Two Flavors of Variables
2. If a target is merely a name for a task and not the name of a file that
the task will create, then it's a phony target
and you should tell make that it is a phony target, like:
.PHONY: all clean test
3. It is not normal for the make-recipe that builds a program to run the program as
well, like your:
#$(CXX) $(OBJECTS) -o $# && $(EXEC)
You don't always want to run a program just because you've built it, and
if the program is a long-running or interactive one then this approach
will make it impractial to build the program at all.
Probably, you want to run the program to test that it has been built correctly.
But building is one task, testing is another (that may take much longer and
involve additional resources); so you should provide a separate phony target
for testing. I've called it test in this makefile: often it is called check.
To build the program without testing it, just run make. To test it,
run make test - and this will also (re)build the program if it needs to be (re)built.
4. You don't need to write a rule to make name.o from a name.cpp, or
a rule to make name.o from a name.c. GNU make has builtin rules for doing
this correctly, as long as you have correctly set the make-variables that
make uses in those builtin rules:
CC: The command that invokes C compilation or linkage, e.g. gcc
CXX: The command that invokes C++ compilation or linkage, e.g. g++
CFLAGS: Options for C compilation
CXXFLAGS: Options for C++ compilation
CPPFLAGS: Options for the C/C++ preprocessor
5. Two more important make-variables that have conventional meanings are:
LDFLAGS: Options for linkage, excluding library (-l) options
LDLIBS: Library options (-l) for linkage.
In the simple makefile above, CPPFLAGS, LDFLAGS and LDLIBS are not
needed and could be ommitted. Instead, I've assigned them empty values
just to illustrate their use.
6. A makefile should have a phony target clean that deletes any files
that the makefile might have created, so that make clean gets you
ready to build anything or everything from scratch.
7.. If name.o is compiled from name.c or name.cpp, then of
course name.o depends on name.c|name.cpp, but it also depends
on every header file that is included by name.c|name.cpp, and the
makefile needs to express all those dependencies to work reliably. So
in this case you need (at least) the rule:
list.o: bar.h
so that if you change bar.h then make will see that foo.o is out of
date and will carry out its recipe for re-making foo.o. When you
start building complex programs it will become impractical for you
to figure out all these header-file dependencies yourself: then you'll need
to find out about auto dependency generation.
Here is the GNU Make manual
Related
I should start by saying I'm a bit of a newbie when it comes to gcc and makefiles.
On an Ubuntu machine that I've recently started using, I find that when running gcc, the order in which I put the source files and the libraries/headers makes a difference. On another machine I could do:
gcc -I../include -L../lib myProgram.c -o myProgram
But on the new machine, this will not link the libraries, and I must do:
gcc myProgram.c -o myProgram -I../include -L../lib
Now, I have the following makefile:
SHELL = /bin/sh
CC = gcc -O3
CFLAGS = -I../include
LDFLAGS = -L../lib
PROGS = myProgram
all: $(PROGS)
$(all): $(PROGS).o
$(CC) -o $# $#.o $(LIBS) $(CFLAGS) $(LDFLAGS)
rm -f $#.o
clean:
rm -f *.o $(PROGS)
But when I do "make", the actual gcc command that it runs has the libraries and source files in the wrong order. My question is: what do I need to do in the makefile to force the "-L../libs" option to come after the source files, so that the libraries will link properly?
I've also tried including the "-Wl,--no-as-needed" option, as I thought that an --as-needed flag might be the reason that the order matters in the first place, but this didn't appear to change anything (i.e. it still fails to link the libraries unless "-L../libs" comes after the source files).
The problem was that you thought you were using that rule, but you weren't. You never defined a variable named all, so the target of the second rule actually expanded to nothing. When you commanded Make to build myProgram, Make found no suitable rule in this makefile. Make has a toolbox of implicit rules it can fall back on in such cases; it wanted to build myProgram, it saw a file named myProgram.c, and one of its rules looks something like this:
%: %.c
$(CC) $(LDFLAGS) $^ -o $#
There you have it, linker flags before sources.
You can write your own pattern rule which Make will use instead:
%: %.o
$(CC) -o $# $^ $(LIBS) $(CFLAGS) $(LDFLAGS)
(Note that this builds myProgram from myProgram.o, and lets Make figure out how to build myProgram.o.)
If your executable is to be built from several object files, add a rule like this:
myProgram: other.o yetAnother.o
If you like you can have one more rule (the first) to tell Make what you want built:
all: myProgram myOtherProgram friendsProgram
(A final note: we've all had tight work deadlines. Asking for help once can be faster than learning the tools, but learning the tools is faster than asking for help N times. Determining the value of N is up to you.)
I'm trying to set up a Makefile to handle two different targets from one set of sources, and I'm a little out of my element. The vast majority of it works fine, but my dependency structure is hosed and thus I'm forced to do a full recompile each time. A pared down sample is as follows:
first: OBJDIR = obj
second: OBJDIR = obj-2
SRCS = $(wildcard src/*.cc)
OBJECTS = $(patsubst %.cc,$(OBJDIR)/%.o,$(SRCS))
first: CFLAGS = -g -Wall -Wextra -std=c++11 -MMD
second: CFLAGS = -g -Wall -Wextra -std=c++11 -MMD -DCOMPILE_FLAG
$(OBJDIR)/%.o: %.cc
#mkdir -p $(OBJDIR)/src
clang++ -c $(CFLAGS) -o $(OBJDIR)$# $<
#DEPENDENCIES AREN'T WORKING PROPERLY
-include $(OBJECTS:.o=.d)
first: $(OBJECTS)
clang++ -o gen/first $(OBJECTS)
second: $(OBJECTS)
clang++ -o gen/second $(OBJECTS)
If I #echo $(OBJECTS:.o=.d) under my first: executable generation (or as it's used in the compilation step), it properly expands to /obj/src/filename.d. However, when it's in the include line, it shows up simply as /src/filename.d. Obviously the .d files don't exist in that location, so it doesn't find them and does a full recompile.
Makefiles are not something I'm heavily experienced with, so if there are better ways to do anything up above, I'm all ears. The key point, though, is being able to have two sets of object files and two sets of dependencies from the same sources.
--
To clarify on the eventual goals, what I have is a set of source files that are used to build two separate executables, with the differences handled via #ifdefs.
What I want to get out of the makefile structure is a single makefile with two targets. Each target generates its own .o/.d files, so that when a change is made to the source, I can run make first and make second to generate the two new executables without having to recompile everything from scratch. I've handled this previously by having two separate makefiles, but that just seems wrong.
You've missed a critical sentence in the GNU make manual related to target-specific variables:
As with automatic variables, these values are only available within the context of a target's recipe
This means that you can't use target-specific variables in either the target or prerequisite lists: any variables used there will ALWAYS have the global value and never the target-specific value. Similarly, include lines are parsed as the makefile is read in: there's no target context at all here either so the global value is used.
Further, any time you see ANY rule in a makefile that is creating a file which is not exactly $# but is instead some modification of it, that's a red flag and you know you have a problem: -o $(OBJDIR)$# is wrong.
In general, there's a lot wrong with this makefile and it's not entirely clear exactly what you're trying to do here. Maybe if you stepped back and described the goal you want to achieve we can give you some pointers.
I believe the answer is simply to rethink the way I was doing it. I've rewritten the makefile to be as follows (trimming out anything unrelated), after reading a lot of Makefile documentation and taking into consideration some comments from MadScientist:
CC = clang++
SRCS = $(wildcard src/*.cc)
OBJECTS = $(patsubst %.cc,$(OBJDIR)/%.o,$(SRCS))
CFLAGS = -g -Wall -Wextra -std=c++11 -MMD
.PHONY: all clean run
all: $(EXECUTABLE)
-include $(OBJECTS:.o=.d)
$(EXECUTABLE): $(OBJECTS)
#mkdir -p gen
$(CC) -o gen/$(EXECUTABLE) $(OBJECTS)
$(OBJDIR)/%.o: %.cc
#mkdir -p $(#D)
$(CC) -c $(CFLAGS) $(CMDFLAGS) -o $# $<
clean:
rm -rf obj obj-2 gen
run:
cd gen && ./$(EXECUTABLE)
From there, I made a couple aliases in my .bash_profile:
alias mfirst="make OBJDIR=obj EXECUTABLE=first"
alias msecond="make OBJDIR=obj-2 CMDFLAGS=-DCOMPILE_FLAG EXECUTABLE=second"
Because the variables are now set outside of any target specification, everything plays nicely. It keeps the object files and the dependencies separate, and the aliases still allow quick usage (including mfirst run, for example).
Feel free to point out any flaws here, but I'm fairly happy with the result.
I am using make which calls g++ always re-compiles the code, even when I do not change the source code. That happens for all my projects, even for simple ones such as:
[code]
all: main.cpp
g++ -std=c++11 -c main.cpp
[/code]
I believe it should compare the date/time on source and object code. Could some help me with this, I am running using GNU toolchain on Ubuntu 12.04
THX
Edit: sorry guys, I do use Makefile, I edited my question accordingly.
Simplest Makefile
It was already pointed out that your Makefile is probably wrong. The 'all' target is indeed always built (although it may result in a no-op if it has no commands and all dependencies are already satisfied). All you need in your makefile is this:
all: main
Object files
If you expect to have more source file in your build, you should consider creating intermediate object files:
all: main
main: main.o
Tweak the build
Make will automatically find the main.ccp file and turn it into main which is required per the directive above. You can use special make variables to further tweak the compilation, e.g. for debug information inclusion and for warning configuration:
CXXFLAGS = -g -Wall -Werror
all: main
main: main.o
Nitpicking
If you insist on building up the compile rule yourself, you can do it like this:
%.o: %.hpp
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $# -c $<
CXX: C++ compiler
CPPFLAGS: C preprocessor flags
CXXFLAGS: C++ compiler flags
$#: Target
$<: First dependency
If you don't want to use the standard variables nor pattern matching, you can build up the whole makefile explicitly:
all: main
main: main.o
gcc -o $# $^
main.o: main.c
gcc -g -Wall -Werror -o $# -c $<
$^: Use that one if you want to include all dependencies, for example if you have multiple *.o files to build one binary.
Note: It is a bad idea to write the file names directly into the command as you might forget to update them later.
all: main.cpp
g++ -std=c++11 -c main.cpp
This seems wrong. Why does the rule for all has main.cpp as its target? Shouldn't it be something.exe or something.o? Say
all: main.exe
main.exe: main.cpp
g++ -std=c++11 main.cpp -o main.exe
clean:
del main.exe
Targets are output files and cpp files are source code which should be input to the make system.
g++ would have to "recompile" in general (what happens if you change the header but not main.cpp?)
If you are concerned about long build times, you should use something like Make (which is designed specifically to avoid recompiling when the source hasn't changed)
The compiler will always compile the code. If you want to do conditional compilation (based on file times etc) you will need to use a make system such as Make, CMake, Ant, etc. For the simplest you can set up a small "Makefile" in the directory and use the command "make" to build.
Simple Makefile for compiling "myapp.exe" from "main.cpp", "file1.cpp" and "file2.cpp"
myapp.exe: main.o file1.o file2.o
g++ -o myapp.exe main.o file1.o file2.o
(make knows to use .cpp files to build .o files)
But if you also have header files, then you will need to build dependency chains, for which you may want to look into something more sophisticated like automake, cmake, ant, etc.
---- EDIT ----
Based on your updated post, the problem is that you aren't specifying a target, so Make has to assume it needs to recompile. See my example in the above answer.
I am new to make files and I put this together with a bit of trial & error. This code is used to compile my c++ program.
My main.cpp file in the same folder as the makefile. I have a lib/ folder that contains the headers main depends on.
The following makefile results in a correct and complete compilation of my code. But I was expecting that I would find *.o objects left behind. (Note that I've tried to make both with and without the "clean" rule, and I get the same results both times.)
#
# Makefile
#
CXX = g++
CCFLAGS = -O3 -I/sw/include -L/sw/lib
## /sw/include and /sw/lib contain dependencies for files in my lib/
LDFLAGS = -lpng
OPTS = $(CCFLAGS) $(LDFLAGS)
SOURCES = $(wildcard lib/*.cpp) main.cpp
OBJECTS = $(SOURCES: .cpp = .o)
TARGET = spirals
$(TARGET): $(OBJECTS)
$(CXX) $(OPTS) $^ -o $#
.PHONY: depend
depend:
g++ -MM $(SOURCES) > depend
## generate dependencies list
include depend
.PHONY: clean
clean:
rm -f *.o lib/*.o $(TARGET)
Also, in case it matters, I'm on MacOSX and my program is designed in xcode. (I know that xcode has its own build flow, but I'm designing a command-line program for a linux system and I'd like to test compilation & linking in a bash environment instead of only going through xcode.)
Questions:
Am I correct to expect makefiles to produce *.o files that stick around once the main target has been created?
If so, why doesn't my makefile do this?
If you observe what command your $(TARGET) rule causes to be run:
g++ -O3 -I/sw/include -L/sw/lib -lpng lib/bar.cpp lib/foo.cpp main.cpp -o spirals
you'll see that $(OBJECTS) in fact contains *.cpp files, and there are no *.o files sticking around because you haven't asked for any.
The problem is here:
OBJECTS = $(SOURCES:.cpp=.o)
In your GNU makefile as written, this substitution reference is written with excess spaces, so never matches anything and $(OBJECTS) ends up the same as $(SOURCES). Rewrite it as above and it'll do what you expect.
(Other notes: -lpng needs to go at the end of the link command to work in general, so you should introduce another make variable (traditionally called $(LDLIBS)) so as to arrange that. Especially as someone new to makefiles, you would do better to spell out your dependencies explicitly rather than playing games with $(wildcard) and a computed $(OBJECTS). -I options are needed during compilation while -L options are used during linking, so it would be good to arrange separate $(CXXFLAGS)/$(LDFLAGS) variables used in separate rules so they are only added when required.)
i need to build the same source tree twice,
1 - with normal cflags to build the project binary
2 - with cflags plus -fPIC to build a static library that would be some sort of SDK to develop project dynamic modules.
Using only one Makefile, what is the best approach to accomplish this?
It would be nice to do some sort of :
all: $(OBJECTS)
lib_rule: $(OBJECTS)
CFLAGS += -fPIC
.cpp.o:
$(CC) -c $< -o $# $(CFLAGS)
But obviously it can't be done.
Thanks
One thing I've used in the past is a different extension:
.cpp.o:
$(CC) -c $< -o $# $(CFLAGS)
.cpp.lo:
$(CC) -c $< -o $# $(CFLAGS) $(EXTRA_CFLAGS)
You then build your static library from the .lo files and you binary from the .o files:
prog: a.o b.o
libsdk.a: a.lo b.lo
Assuming you are using GNU Make, you can use some built in functions to only have to maintain the list of objects one time:
OBJS = a.o b.o
LOBJS = $(patsubst %.o, %.lo, $(OBJS))
GNU make offers also "Target-specific Variable Values". Consider the following Makefile:
# Makefile
CFLAGS := My Cflags
all: $(OBJECTS)
#echo "$# CFLAGS is: " $(CFLAGS)
lib_rule: CFLAGS += extended by -fPIC
lib_rule: $(OBJECTS)
#echo "$# CFLAGS is: " $(CFLAGS)
# Makefile - end.
$ make all
all CFLAGS is: My Cflags
$ make lib_rule
lib_rule CFLAGS is: My Cflags extended by -fPIC
$
(Please note: if you copy and paste the example, remember to re-add the tabstops in front of the command lines. I always get caught by that.)
Instead of placing the compiled .o files in the same directory as the source, I create them in labeled sub-directories. In your case, you can have the static library files created as source_dir/lib/*.o and your normal files as source_dir/bin/*.o. In your different build targets after you set up your unique CFLAGS, simply generate a DIR_NAME value holding the name of the appropriate sub-folder. You can use this variable when you create the paths for the compiler to use when building and when linking.
In a different make tool such as CMake, you can express something like that much more easily.
For instance, you could well do
set(sources ABC.cpp DEF.cpp XYZ.cpp)
ADD_LIBRARY(mylib STATIC ${sources})
add_executable(myExecutable ${sources} main.cpp)
Or, you could repeatedly build the same directory with different flags by including it several times from the directory's logical parent, i.e.
set(MyTweakFlag 2)
add_subdirectory("libDir" "libDir2")
set(MyTweakFlag 3)
add_subdirectory("libDir" "libDir3")
...and then use if() or whatnot in the child directory to set the right flags.
Particularly if you have many such configurations, using make becomes quite fragile; make won't correctly find the transitive closure of recursive make dependancies (and certainly won't correctly find the dependancy on the makefile itself - if you change flags, say) so if you're going to do complicated makefile magic: do it with a better tool!
(CMake simply happens to be what I replaced make with, but there are various other replacements possible, of course)