I have some problems to use a custom shared library, since I get undefined reference errors for some functions from two of many other source files.
If I compile the whole project with main file (release:), everything works just fine. But if I create a shared library (lib:) and use this library with the main file (all:), those compile time errors occur.
Here is a snippet of my makefile
release:
$(CC) -Wall -s -w $(INCLUDES) $(LIBRARY) $(SRC) mainfile.cpp $(OCV) $(BOOST) $(GLOG) $(GFLAGS) -o test.exe
lib:
$(CC) -fPIC $(INCLUDES) $(LIBRARY) -c $(SRC) $(OCV) $(BOOST) $(GLOG) $(GFLAGS)
mv *.o obj/
$(CC) -shared -o libOutput.so obj/*.o
all:
$(CC) -Wall -s -w $(INCLUDES) $(LIBRARY) mainfile.cpp -L/path/to/lib/ -lOutput $(OCV) $(BOOST) $(GLOG) $(GFLAGS) -o project.exe
Since there is no error during compilation using the release-option, I'm assuming that there is a linker specific problem.
I inspected the specific object files using GNU Binary Utilities
nm -C obj/specific.o | grep functionName
with no results. I did the same for the shared library, but this time with the following result,
U functionName(std::vector<int>)
which means that the function is unknown.
Do you have any suggestions, how to fix this issue?
Related
I'm not sure if there is some built-in variable or rule that I don't know about, or if something is wrong with make, or if I'm just crazy.
For one of my projects, I have a makefile as follows:
CC=g++
CFLAGS=-O3 `libpng-config --cflags`
LFLAGS=-lm `libpng-config --ldflags`
OBJS=basic_render.o render.o mandel.o
BINS=basic_render
.PHONY: all clean
all: $(BINS)
clean:
rm -f $(BINS) $(OBJS)
%.o: %.cpp
$(CC) $(CFLAGS) -c -o $# $<
%: $(OBJS)
$(CC) $(LFLAGS) -o $# $(OBJS)
When building, I want to simply be able to run
make clean
make
to build everything in the BINS list.
This works all right at first, but for some reason, the behaviour changes after I edit a source file.
Before editing source file:
$ make clean
rm -f basic_render basic_render.o render.o mandel.o
$ make
g++ -O3 `libpng-config --cflags` -c -o basic_render.o basic_render.cpp
g++ -O3 `libpng-config --cflags` -c -o render.o render.cpp
g++ -O3 `libpng-config --cflags` -c -o mandel.o mandel.cpp
g++ -lm `libpng-config --ldflags` -o basic_render basic_render.o render.o mandel.o
rm mandel.o basic_render.o render.o
I can do this over and over again and it works just fine. After I make changes to basic_render.cpp (literally just changing a couple of constants), it suddenly changes to this:
$ make clean
g++ -O3 `libpng-config --cflags` -c -o basic_render.o basic_render.cpp
g++ -O3 `libpng-config --cflags` -c -o render.o render.cpp
g++ -O3 `libpng-config --cflags` -c -o mandel.o mandel.cpp
g++ -lm `libpng-config --ldflags` -o makefile basic_render.o render.o mandel.o
rm mandel.o basic_render.o render.o
makefile:1: warning: NUL character seen; rest of line ignored
makefile:1: *** missing separator. Stop.
not only did make clean just try to compile the program, it compiled basic_render with the output set in Makefile, overwriting the Makefile itself.
After editing basic_render.cpp, I looked in Makefile, and it hadn't changed, so it's not like my editor is changing the makefile or something.
So, what am I doing wrong here?
Here is an MCVE of your problem:
$ ls -R
.:
bar.c main.c Makefile
$ cat main.c
extern int bar(void);
int main(void)
{
bar();
return 0;
}
$ cat bar.c
int bar(void)
{
return 42;
}
$ cat Makefile
OBJS := main.o bar.o
BINS := prog
.PHONY: all clean
all: $(BINS)
%: $(OBJS)
$(CC) -o $# $(OBJS)
clean:
$(RM) $(OBJS) $(BINS)
Make first time:
$ make
cc -c -o main.o main.c
cc -c -o bar.o bar.c
cc -o prog main.o bar.o
rm bar.o main.o
Pause to notice the undesired consequence of 10.4 Chains of Implicit Rules:
rm bar.o main.o
All of the object files are auto-deleted after the program is linked, defeating the purpose
of Make. The implicit rules to blame for that are our own implicit rule:
%: $(OBJS)
$(CC) -o $# $(OBJS)
plus the built-in implicit rule1:
%.o: %.c
# recipe to execute (built-in):
$(COMPILE.c) $(OUTPUT_OPTION) $<
which together make an implicit rule chain that results in all of the object files
becoming intermediate files.
Moving on, let's update a source file:
$ touch main.c
and make a second time:
$ make
cc -c -o main.o main.c
cc -c -o bar.o bar.c
cc -o Makefile main.o bar.o
rm bar.o main.o
Makefile:1: warning: NUL character seen; rest of line ignored
Makefile:1: *** missing separator. Stop.
There is our Makefile clobbered by the linkage:
cc -o Makefile main.o bar.o
This snafu is explained in the manual 3.5 How Makefiles Are Remade:
Sometimes makefiles can be remade from other files, such as RCS or SCCS files.
If a makefile can be remade from other files, you probably want make to get an
up-to-date version of the makefile to read in.
To this end, after reading in all makefiles, make will consider each as a goal
target and attempt to update it. If a makefile has a rule which says how to update it
(found either in that very makefile or in another one) or if an implicit rule applies to it
(see Using Implicit Rules), it will be updated if necessary.
After all makefiles have been checked, if any have actually been changed,
make starts with a clean slate and reads all the makefiles over again.
(It will also attempt to update each of them over again, but normally this will
not change them again, since they are already up to date.)
(Emphasis mine). Is there an implicit rule that is applicable to Makefile considered
as a target? Yes, it is:
%: $(OBJS)
$(CC) -o $# $(OBJS)
since the target pattern % matches any file whatever. If we restore our clobbered
Makefile and try the same experiment thing again, this time with debugging:
make -d >debug.log 2>&1
the output will show us:
...
Reading makefiles...
Reading makefile 'Makefile'...
Updating makefiles....
Considering target file 'Makefile'.
Looking for an implicit rule for 'Makefile'.
...
...
Found an implicit rule for 'Makefile'.
...
...
Finished prerequisites of target file 'Makefile'.
Prerequisite 'main.o' is newer than target 'Makefile'.
Prerequisite 'bar.o' is newer than target 'Makefile'.
Must remake target 'Makefile'.
cc -o Makefile main.o bar.o
...
We can avoid this upshot, and also the self-defeating auto-deletion of
our object files, by not using a match-anything implicit rule to perform our
linkage. The customary thing is to make a program from its object files by
an explicit rule, e.g.
Makefile (2)
OBJS := main.o bar.o
BIN := prog
.PHONY: all clean
all: $(BIN)
$(BIN): $(OBJS)
$(CC) -o $# $(OBJS)
clean:
$(RM) $(OBJS) $(BIN)
It appears that you cherish the option to have BINS be a list of multiple
programs:
I want to simply be able to run
make clean
make
to build everything in the BINS list.
But consider that with:
BINS := prog1 prog2
and the recipe:
%: $(OBJS)
$(CC) $(LFLAGS) -o $# $(OBJS)
as your way of making everything in the BINS list, you will just make the same program
twice, with two different names. And even if you wanted to do this, the way to do
it would be:
Makefile (3)
OBJS := main.o bar.o
BINS := prog1 prog2
.PHONY: all clean
all: $(BINS)
$(BINS): $(OBJS)
$(CC) -o $# $(OBJS)
clean:
$(RM) $(OBJS) $(BIN)
which runs like:
$ make
cc -c -o main.o main.c
cc -c -o bar.o bar.c
cc -o prog1 main.o bar.o
cc -o prog2 main.o bar.o
[1] You can get GNU Make to show you all its builtin-rules, and all the rest
of its rules for a particular build, with make --print-data-base ...
I would suggest that the % target is somehow matching the makefile file and therefore using it as the target(1).
My advice would be to change that line to:
$(BINS): $(OBJS)
and that should hopefully prevent make from thinking it should create a new makefile when the objects change.
(1) Apart from the explicit rules you provide, make also has quite a lot of implicit rules.
If even one of those rules decides that it depends on makefile (this is often configured since a change to the makefile usually means that a full rebuild should be done, as the rules may well have changed), then the % target may then be used for the makefile.
And, since the objects have changed, the makefile that depends on them will be rebuilt.
I personally have never seen a % target since I believe that means the rule may match any target, including source files which you probably don't want overwritten.
If you're interested in seeing all those implicit rules, make -d should give you quite a bit of information such as the rules used and conditions checked for whether files need to be rebuilt - just be prepared to wade through a lot of output.
I'm trying to create a generic make file so that I can compile my project independently of how many files I add to it and where I decide to put them in the project tree.
In my step by step approach I cam to this makefile which works fine.
CC=g++
OBJECTS=main.o board.o
VPATH=src:\
src/board:\
include/board:\
build:\
bin
boardG : main.o board.o
$(CC) -o bin/boardG build/main.o build/board.o
main.o : main.cpp board.hpp
$(CC) -c -I include $< -o build/$#
board.o : board.cpp board.hpp
$(CC) -c -I include $< -o build/$#
This version will do the job just fine. See output below:
me#01:~/code/projects/boardG$ make
g++ -c -I include src/main.cpp -o build/main.o
g++ -c -I include src/board/board.cpp -o build/board.o
g++ -o bin/boardG build/main.o build/board.o
The problem here is that I will have to create one rule for each .cpp file. Which is precisely what I try to avoid. Hence I tried to adapt the version above using matching patterns like this:
CC=g++
OBJECTS=main.o board.o
VPATH=src:\
src/board:\
include/board:\
build:\
bin
boardG : main.o board.o
$(CC) -o bin/boardG build/main.o build/board.o
%.o : %.cpp %.hpp
$(CC) -c -I include $< -o build/$#
When I run make now I get the follwing output:
me#01:~/code/projects/boardG$ make
g++ -c -o main.o src/main.cpp
src/main.cpp:2:27: fatal error: board/board.hpp: No such file or directory
compilation terminated.
<builtin>: recipe for target 'main.o' failed
make: *** [main.o] Error 1
My project has the follwing structure/files in it.
./bin/
./build/
./include/board/board.hpp
./src/main.cpp
./src/board/board.cpp
./makefile
I'm wondering why make would change the command when using pattern matching? Or, and probably more accurately, what am I doing wrong that makes make fail?
Just avoid using VPATH when it comes to object files. What's happening is that make is actually using the built-in rule for %.o and not using your rule at all.
If you prefix all your objects with the directory, this should work:
CC=g++
OBJDIR = build
OBJECTS = $(OBJDIR)/main.o $(OBJDIR)/board.o
VPATH = src:\
src/board:\
include/board:\
bin/boardG : $(OBJECTS)
$(CC) -o $# $^
$(OBJDIR)/%.o : %.cpp %.hpp
$(CC) -c -I include $< -o $#
Here is a helpful resource, which more or less exactly describes the problem you've run into.
I am having issue with Makefile that I produced. It consists of one .cpp file with main() inside and I want to create executable from it. While putting in terminal make command I get following:
g++ STutorial.o -o MyExecutable
g++: error: STutorial.o: No such file or directory
g++: fatal error: no input files
While putting first make STutorial.o (.o created) and then make get this:
g++ STutorial.o -o MyExecutable
STutorial.o: In function `main':
STutorial.cpp:(.text+0x47a): undefined reference to `alcOpenDevice'
Firstly, why make does not go from the beginning?
Secondly, why this reference is undefined as if I did not include library, I did that in Makefile aswell as in STutorial.cpp file.
Can you please help me out? I was reading up what could I do wrong and see no clue. (I am beginner and maybe mistake is a rookie one, I apologise in advance but cannot understand it alone)
Makefile:
FLAGS += -std=c++11
CCX=g++
FLAGS +=-c -Wall #for compilation, for warning
FLAGS += -lopenal -lSDL
all: MyExecutable
MyExecutable:
$(CXX) STutorial.o -o MyExecutable
STutorial.o: STutorial.cpp
$(CXX) $(FLAGS) STutorial.cpp
Your makefile should be like this:
CCX=g++
FLAGS +=-c -Wall #for compilation, for warning
LINK_FLAGS += -lopenal -lSDL
all: MyExecutable
MyExecutable: Stutorial.o
$(CXX) STutorial.o -o MyExecutable $(LINK_FLAGS)
STutorial.o: STutorial.cpp
$(CXX) $(FLAGS) STutorial.cpp
Explanation:
Your MyExecutable depends on Stutorial.o which inturn depends on Stutorial.cpp
Now -c flag should be used only with .cpp file to create an object file and not with already created .o file.
Therefore you should have two flags: FLAGS for compiling and LINK_FLAGS for linking libraries during making executable file.
Your executable rule is the issue:
MyExecutable:
$(CXX) STutorial.o -o MyExecutable
It has a target (MyExecutable) and it has a recipe ($(CXX) ...), that all looks good. But what are its prerequisites? MyExecutable does have prerequisites - it needs STutorial.o in order to generate the binary! You need to explicitly tell make about this:
MyExecutable: STutorial.o
$(CXX) STutorial.o -o MyExecutable
Otherwise, you are telling make that you want to build all. all depends on MyExecutable. MyExecutable doesn't depend on anything, so the rule for STutorial.o never gets run.
As for the linker error, you're not linking in the library you need, so you should define something like:
LFLAGS += -lopenal -lSDL
MyExecutable: STutorial.o
$(CXX) STutorial.o $(LFLAGS) -o MyExecutable
You have a few problem in your Makefile starting with:
FLAGS +=-c -Wall #for compilation, for warning
FLAGS += -lopenal -lSDL
You are redefining the FLAGS variable here.
So what you should have is a different variable for your compiler and linker flags:
CFLAGS +=-c -Wall #for compilation, for warning
LDFLAGS += -lopenal -lSDL
Now, for the sake of giving a complete answer, and not solving your immediate problem only I'll try to show how to make the Makefile more flexible:
Start with the sources - you should have a variable for them as well; it's useful when adding/removing source files to/from the project:
SOURCES = STutorial.cpp
define a variable for your object files (this will come in handy at link-time):
OBJ = $(SOURCES:.cpp=.o)
Compile all source files into object files:
.cpp.o:
$(C++) $(CFLAGS) -o $# $<
Link your binary file using the compiled object files:
$(MyExecutable): $(OBJ)
$(C++) $(LDFLAGS) $(OBJ) -o $#
Add a clean command for completeness (removes the binary and object files):
clean:
$(RM) $(EXECUTABLE) $(OBJ)
Now, putting it all together:
CCX=g++
CFLAGS +=-c -Wall -std=c++11#for compilation, for warning
LDFLAGS += -lopenal -lSDL
SOURCES = STutorial.cpp
OBJ = $(SOURCES:.cpp=.o)
all: $(MyExecutable)
$(MyExecutable): $(OBJ)
$(CCX) $(LDFLAGS) $(OBJ) -o $#
.cpp.o:
$(CCx) $(CFLAGS) -o $# $<
clean:
$(RM) $(EXECUTABLE) $(OBJ)
This should allow you to flexibly build, rebuild, clean you project.
This is how you should do:
g++ -std=c++11 -Wall -lopenal -lSDL STutorial.cpp -o MyExecutable
I have tried searching around other questions here on SO, but have still been unable to get my newly created C++ and .h linked to my main C file correctly. My implementation of my loader.cpp and loader.h are based off of this SO question.
My loader.cpp has no main function as I just want to use the C++ functions there. My shift.c file is where my int main() is located. Here is the basic structure of my loader.cpp file.
loader.cpp
#include "loader.h"
...
// Class Declaration
...
// Class implementation
I have been trying to compile with the following.
g++ loader.cpp -o obj -lGLU -lGL -lglut
The error I am getting here is...
(.text+0x20): undefined reference `to main'
So my two questions are, how do I get my cpp file to compile properly, and then what do I need to add to my Makefile to link them properly?
Makefile (for reference)
CC = gcc
CXX = g++
EXE = shift gears
# Main target
all: $(EXE)
CFLG=-O3 -Wall
LIBS=-lglut -lGLU -lGL -lm
CLEAN=rm -f $(EXE) *.o *.a
# Dependencies
gears.o: gears.c
shift.o: shift.c CSCIx229.h
fatal.o: fatal.c CSCIx229.h
loadtexbmp.o: loadtexbmp.c CSCIx229.h
print.o: print.c CSCIx229.h
project.o: project.c CSCIx229.h
errcheck.o: errcheck.c CSCIx229.h
object.o: object.c CSCIx229.h
# Create archive
CSCIx229.a:fatal.o loadtexbmp.o print.o project.o errcheck.o object.o
ar -rcs $# $^
# Compile rules
.c.o:
gcc -c $(CFLG) $<
.cpp.o:
g++ -c $(CFLG) $<
# Link
shift:shift.o CSCIx229.a
gcc -O3 -o $# $^ $(LIBS)
gears:gears.o
gcc -O3 -o $# $^ $(LIBS)
# Clean
clean:
$(CLEAN)
If you want g++ to compile an object module without linking it into a complete program then you must give it the -c option:
g++ -c loader.cpp -o loader.o
Note that that compilation command also assigns a conventional name to the generated object file, and that if you're not linking it into an executable then you don't need to specify libraries to link it to. Your Makefile is already set up for this.
If you add loader.o to the dependencies of CSCIx229.a then that should be enough to persuade make to build it from loader.cpp and to include the object file in your library (which will make it available for linking into your executables). You may also need to add some or all of -lGLU -lGL -lglut to your LIBS variable. It might also be appropriate to add loader.o's dependencies to the makefile if they include more than just loader.cpp itself (e.g. if they include CSCIx229.h).
Add the -c option to compile only. When you are ready to link the final application, then include all the object files and the list of libraries.
g++ -c loader.cpp -o loader.o
g++ loader.o (and the rest of your object files) -lGLU -lGL -lglut
Try adding this to your makefile:
shift:shift.o CSCIx229.a loader.o
gcc -O3 -o $# $^ $(LIBS)
I've been building a C++11 library, and the number of header/source files has grown to the point where compiling programs invoking it, entails passing 20+ .cpp files to g++. I've been reading up on shared libraries and it seems to be the best solution.
However, as headers/source change frequently, I'm hoping to create a makefile that would automatically generate all the .so files from the headers and source.
To better demonstrate what I'm trying to do, I'll take one of my sub-libraries, Chrono and show how I would do this manually.
I first create the object files like so,
$ g++ -std=c++11 -fPIC -g -c -Wall ../src/Chrono/cpp/DateTime.cpp
$ g++ -std=c++11 -fPIC -g -c -Wall ../src/Chrono/cpp/Schedule.cpp
$ g++ -std=c++11 -fPIC -g -c -Wall ../src/Chrono/cpp/Duration.cpp
$ g++ -std=c++11 -fPIC -g -c -Wall ../src/Chrono/cpp/DayCount.cpp
So that I now have DateTime.o, Schedule.o, Duration.o, and DayCount.o in the current directory. I then create the .so file,
$ g++ -shared -Wl,-soname,libChrono.so.1 -o libChrono.so.1.0.1 DateTime.o Schedule.o Duration.o DayCount.o -lc
I then go,
$ rm ./*.o && ldconfig -n ./
So that my working directory now contains, libChrono.so.1.0.1 and the symlink libChrono.so.1.
There are quite a few subdirectories I need to do this for, so you can see that this quickly grows inefficient whenever changes to headers/source are made. I would be grateful if anyone can help me design a makefile that accomplishes all this simply by invoking make.
Thanks!
UPDATE:
Based on goldilock's advice and some digging, I managed to bang together:
CXX=g++
CFLAGS=-std=c++11
TARGET=./lib/libChrono.so.1.0.1
CHRONODIR=./src/Chrono
CHRONOSRC=$(wildcard $(CHRONODIR)/cpp/*.cpp)
CHRONOOBJ=$(join $(addsuffix ../obj/, $(dir $(CHRONOSRC))), $(notdir (CHRONOSRC:.cpp=.o)))
all: $(TARGET)
#true
clean:
#-rm -f $(TARGET) $(CHRONOOBJ)
./lib/libChrono.so.1.0.1: $(CHRONOOBJ)
#echo "======================="
#echo "Creating library file $#"
#echo "======================="
#$(CXX) -shared -Wl,-soname,$(join $(basename $#), .1) -o $# $^ -l
#echo "-- $# file created --"
$(CHRONODIR)/cpp/../obj/%.o : $(CHRONOSRC)
#mkdir -p $(dir $#)
#echo "============="
#echo "Compiling $<"
#$(CXX) $(CFLAGS) -fPIC -g -Wall -c $< -o $#
4 .o files are produced in lib/ but I get multiple definition complaints from ld. Before I was compiling the object files separately, but this unwinds CHRONOOBJ on one line. Any ideas?
Fortunately you included the origin of your problem:
I've been building a C++11 library, and the number of header/source files has grown to the point where compiling programs invoking it, entails passing 20+ .cpp files to g++.
Because this reveals a potential XY problem. The straightforward solution to this is to put object files into an archive (aka. a static library) and use that.
GNU make has an implicit rule for creating C++ .o files. It amounts to this:
%.o: %.cpp
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $<
Meaning, if you make DateTime.o in a directory with a makefile that doesn't redefine this, it will make DateTime.o. You may want to add things to $(CXXFLAGS) however, e.g.:
CXXFLAGS += -Wall -Wextra --std=c++11
If you intend to stick with the shared lib route, -fPIC can go there too. That one line could be your entire makefile.
However, you also want to put these together, so you must first declare all the objects and a rule for combining them:
OBJS = DateTime.o Schedule.o Duration.o
libChrono.a: $(OBJS)
ar crvs $# $^
This last line (see man ar) creates the archive (libChrono.a) containing all the objects in $(OBJS). You can then use this with whatever program by placing it in the same directory (or a directory in the library path) and linking -lChrono. Only the necessary parts will be extracted and compiled in. This saves you having to maintain a shared lib in a system directory.
If you still think you need a shared lib, $# and $^ are automatic variables; you can use similar methodology to create a .so, something along the lines of:
SO_FLAGS = -shared
libChrono.so.1.0.1: $(OBJS)
$(CXX) $(SO_FLAGS) -Wl,-soname,libChrono.so.1 -o $# $^ -lc
If that is your first rule, make will take care of everything: building first the objects and then the library. Notice this one has excluded your normal $(CXXFLAGS) to duplicate exactly the compiler line from the question.