Makefile for Debian - function calls in main - c++

so I have this structure:
simpleConnect.cpp (contains main)
Call feature_extract.cpp
feature_extract.cpp (does some things here, returns to simpleConnect)
ThesisHeader.h (has declaration of feature_extract and all the includes etc...)
Now...These files use a library called ARIA (used for mobilerobots) and a set of header files - EIGEN (for matrix manipulations etc)
I used to suggested structure by Aria as follows:
SOURCES=simpleConnect
all: $(SOURCES)
CFLAGS=-fPIC -g -Wall
ARIA_INCLUDE =-I/usr/local/Aria/include
ARIA_LINK=-L/usr/local/Aria/lib -lAria -lpthread -ldl -lrt
%: %.cpp
$(CXX) $(CFLAGS) $(ARIA_INCLUDE) $< -o $# $(ARIA_LINK)
But I'm getting this error at the line where I call the function feature_extract:
undefined reference to 'feature_extract(......)'
collect2: ld reurned 1 exit status
As far as I can understand this is to do with me not telling the compiler that feature_extract is there....because I don't know how...
I tried adding pieces I found online but to no avail, hence I came asking here.
Could anyone be kind enough to modify the makefile so as to include that file to be able to compile?
Thank you for your time,
Patrick

This app needs `feature_extract`.
You're using "SOURCES" for something other than sources.
CFLAGS=-fPIC -g -Wall
ARIA_INCLUDE =-I/usr/local/Aria/include
ARIA_LINK=-L/usr/local/Aria/lib -lAria -lpthread -ldl -lrt
app_name: simpleConnect.cpp feature_extract.cpp
$(CXX) $(CFLAGS) $(ARIA_INCLUDE) $^ -o $# $(ARIA_LINK)
If this works, further refinements are possible.

I managed to solve this problem, thanks to those who helped.
I ended up reading the GNU make manual, which solved my problem.
https://www.gnu.org/software/make/manual/make.pdf
This is the final makefile that ended up working:
CFLAGS=-fPIC -g -Wall
ARIA_INCLUDE =-I/usr/local/Aria/include
ARIA_LINK=-L/usr/local/Aria/lib -lAria -lpthread -ldl -lrt
edit : simpleConnect.o feature_extract.o
$(CXX) $(CFLAGS) $(ARIA_INCLUDE) -o edit simpleConnect.o
feature_extract.o $(ARIA_LINK)
simpleConnect.o : simpleConnect.cpp ThesisHeader.h feature_extract.cpp
$(CXX) $(CFLAGS) $(ARIA_INCLUDE) -c simpleConnect.cpp $(ARIA_LINK)
feature_extract.o : feature_extract.cpp ThesisHeader.h
$(CXX) $(CFLAGS) $(ARIA_INCLUDE) -c feature_extract.cpp $(ARIA_LINK)
clean :
rm edit simpleConnect.o feature_extract.o

Related

SFML library doesn't link with makefile compilation

I have been trying to link the SFML dlls to my windows C++ project, but I can't get it to work. I always end up with:
fatal error: SFML/System.hpp: No such file or directory
I've tried a bunch of things but nothing changes the issue.
Here is my makefile:
PROGRAM = zero_flip
OBJS = src/main.o src/Math.o src/card.o src/game_board.o src/indicator.o src/ui.o
CXX = g++
CXX_FLAGS = -O0 -g -Wall -Wextra -Wno-unused-parameter -Wno-unused-variable
LIB_DIRS = -L./Resources/libs/
LIBS = -lsfml-system -lsfml-graphics -lsfml-window -lsfml-audio
LNK_FLAGS = $(LIB_DIRS) $(LIBS)
DEPS=$(OBJS:.o=.d)
.PHONY: all clean
all: $(PROGRAM)
-include $(DEPS)
%.o: %.cpp
$(CXX) $(CXX_FLAGS) $(LNK_FLAGS) $< -o $#
$(PROGRAM): $(OBJS)
$(CXX) $(CXX_FLAGS) $(LNK_FLAGS) $^ -o $#
clean:
rm -f $(OBJS) $(DEPS) $(PROGRAM) && clear
The "./Resources/libs/" directory contains:
openal32.dll
sfml-audio-2.dll
sfml-audio-d-2.dll
sfml-graphics-2.dll
sfml-graphics-d-2.dll
sfml-system-2.dll
sfml-system-d-2.dll
sfml-window-2.dll
sfml-window-d-2.dll
Can anyone get me unstuck please this is driving me mad.
This is wrong:
%.o: %.cpp
$(CXX) $(CXX_FLAGS) $(LNK_FLAGS) $< -o $#
This rule says it will compile a source file into an object file, but the recipe actually builds a complete executable: it will compile the source file like xxx.cpp then link it into a program named xxx.o. You need to invoke just the compiler here, not the linker, so you should not have $(LNK_FLAGS) and you need to add the -c option to tell the compiler to stop after compiling and not link.
Then you need to add an -I option to the compile line telling the compiler where to find the header files needed during compilation... in this case SFML/System.hpp.

How to change MakeFile to use locally installed libraries instead of source relative path?

I'm trying to get started with the mosquitto MQTT library (c++, raspberry pi). I think I have successfully installed all of the packages I need, and was able to build and execute the included "temperature_conversion" sample without errors. I do receive a bunch of warnings about deprecated functions, but I'm ignoring those as not part of the immediate problem.
Though not a complete newbie, I'm not well experienced with linux development tools and building/linking/MakeFiles. In trying to create my own stand-alone test based on the sample found here:
https://github.com/eclipse/mosquitto/tree/master/examples/temperature_conversion
Output when running 'make' (on my modified version): [edited to include change based on JDAllen's comment]
pi#raspberrypi:~/Documents/c/offgrid $ make
g++ main.o mqtt_manager.o -o offgrid -L/usr/local/lib/libmosquittopp.so.1 /usr/local/lib/libmosquitto.so.1
main.o: In function `main':
/home/pi/Documents/c/offgrid/main.cpp:8: undefined reference to `mosqpp::lib_init()'
/home/pi/Documents/c/offgrid/main.cpp:11: undefined reference to `mosqpp::mosquittopp::loop_forever(int, int)'
.
.
(Similar 'undefined reference' messages omitted for clarity)
.
.
collect2: error: ld returned 1 exit status
Makefile:11: recipe for target 'offgrid' failed
make: *** [offgrid] Error 1
My modified MakeFile: [edited to include change based on JDAllen's comment]
CFLAGS=-Wall -ggdb -I/usr/local/include
LDFLAGS=-L/usr/local/lib/libmosquittopp.so.1 /usr/local/lib/libmosquitto.so.1
.PHONY: all clean
all : offgrid
offgrid : main.o mqtt_manager.o
${CXX} $^ -o $# ${LDFLAGS}
main.o : main.cpp
${CXX} -c $^ -o $# ${CFLAGS}
mqtt_manager.o : mqtt_manager.cpp
${CXX} -c $^ -o $# ${CFLAGS}
clean :
-rm -f *.o offgrid
UNMODIFIED sample application's MakeFile:
CFLAGS=-Wall -ggdb -I../../lib -I../../lib/cpp
LDFLAGS=-L../../lib ../../lib/cpp/libmosquittopp.so.1 ../../lib/libmosquitto.so.1
.PHONY: all clean
all : mqtt_temperature_conversion
mqtt_temperature_conversion : main.o temperature_conversion.o
${CXX} $^ -o $# ${LDFLAGS}
main.o : main.cpp
${CXX} -c $^ -o $# ${CFLAGS}
temperature_conversion.o : temperature_conversion.cpp
${CXX} -c $^ -o $# ${CFLAGS}
clean :
-rm -f *.o mqtt_temperature_conversion
I have verified that /usr/local/include contains mosquittopp.h, and that /usr/local/lib contains libmosquittopp.so.1
Could someone please enlighten me on what I'm missing here? I'm pretty sure I could make it work by copying the /lib directory structure from the example, but I would like to use the ?installed? versions in /usr because that seems like the way one should go about such things.
[EDIT1: I have now verified that copying /lib from the example directory into my own and replacing the first two lines in the Makefile with paths relative to those directories does, indeed, allow my modified code to build without the aforementioned errors. I still want to be able to use the files in /usr/local/lib though - why doesn't this work? What further steps can I take to see where things are going wrong?]
If requested, I can update this with my modified code but unless I've done something stupid, it's a structurally equivalent pared down version of the original example linked above.
Well, I don't completely understand what's going on in the back-end, but I was able to figure out what works based another discussion with the same/similar problem here:
https://www.raspberrypi.org/forums/viewtopic.php?t=254740
In case the above link doesn't work, the following is an excerpt from that discussion:
If you are building some C code as a client you will need "-lmosquitto" at the end of the gcc command.
That says "use the library libmosquitto" which will resolve all those missing symbols.
Note that is a lower case "-l", the upper case "-L" indicates a library search path.
Use "-lmosquittopp" if you are building C++.
You will need to have installed the mosquitto client development library packages: libmosquitto-dev for C and/or libmosquittopp-dev for C++.
After a small amount of trial & error, I ended up with the following Makefile that appears to work just fine:
LDFLAGS=-lmosquittopp
.PHONY: all clean
all : offgrid
offgrid : main.o mqtt_manager.o
${CXX} $^ -o $# ${LDFLAGS}
main.o : main.cpp
${CXX} -c $^ -o $# ${CFLAGS}
mqtt_manager.o : mqtt_manager.cpp
${CXX} -c $^ -o $# ${CFLAGS}
clean :
-rm -f *.o offgrid

makefile linking does not work (although no error message)

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

How to link multiple .so files in a C++ Makefile

My Makefile looks as follows:
CXX = g++
CXXFLAGS = -g
INCLUDES = -Iinclude/
OBJS = a1.o \
b1.o
LIBPATH= /usr/lib/<arch>
test-app:$(OBJS)
$(CXX) -o $# $(OBJS)
%.o : %.cpp
$(CXX) $(INCLUDES) -c $(CXXFLAGS) $< -o $#
I want to link two files lib1.so and lib2.so present in LIBPATH? Can anyone please help me with the syntax?
The syntax is
test-app:$(OBJS)
$(CXX) -o $# $(OBJS) -Lpath_to_your_lib -lyour_libname
Also you should use pkg-config to find those variables value.
Try this one:
LIBRARIES= -llib1 -llib2
...
test-app:$(OBJS)
$(CXX) -o $# -L$(LIBPATH) $(LIBRARIES) $(OBJS)
Consider that the arguments order are most of times important since the gcc compiler/linker process the files just one time in the given order and if the order was wrong errors like "Symbol not find" and "undefined reference" will be produced.
Though, I strongly recommend CMake since it's syntax is so easier, more dynamic and It supports many build platforms (IDEs, Compilers, Makefiles, etc.)
Update:
This configuration is likely more effective than the above:
SHARED_LIBRARIES= -L/path/to/shared_libs -llib1 -llib2
STATIC_LIBRARIES= -L/path/to/static_libs -llib1 -llib2 -L/another/path/to/static_libs -llib3
...
test-app:$(OBJS)
$(CXX) -o $# $(STATIC_LIBRARIES) $(SHARED_LIBRARIES) $(OBJS)

g++ consolidation: ld: fatal: file main.o: unknown file type

I'm scanning the web and all my project files for solution but still can't find the answer why my linker won't finish the job. Everything smoothly compiles into .o files, but the last make command fails. And here is the Makefile content:
CXX = g++
CXXFLAGS = -Wall -pedantic -c
OBJS = main.o operacje.o porownaj.o
dzialania: $(OBJS)
$(CXX) $^ -o $#
main.o: main.cpp operacje.h porownaj.h
$(CXX) $(CXXFLAGS) $^ -o $#
operacje.o: operacje.cpp operacje.h porownaj.h
$(CXX) $(CXXFLAGS) $^ -o $#
porownaj.o: porownaj.cpp operacje.h porownaj.h
$(CXX) $(CXXFLAGS) $^ -o $#
clean:
rm -f *o
and again, here is the mistake that pops out:
g++ main.o operacje.o porownaj.o -o dzialania
ld: fatal: file main.o: unknown file type
ld: fatal: file processing errors. No output written to dzialania
*** Error code 1
make: Fatal error: Command failed for target `dzialania'
I'm sure it's some kind of a basic mistake but after staring at the file for a few hours I won't notice it anyway. Maybe some of you folks with notice the bug with a fresh eye.
btw. it's my first post after long-term passive lurking, I hope I did everything right. Thanks in advance!
#edit1 OK, I did all the suggested corrections
#edit2 Seems like the problem is caused by improper module division of my program. I'll rearrange it's structure and let you know if it works then. Thanks for all the support!
#edit3 OK, I changed the structure of my program and everything runs smooth, Thanks again!
Try using $< instead of $^ in your rules to compile main.o, operacje.o, and porownaj.o:
main.o: main.cpp operacje.h porownaj.h
$(CXX) $(CXXFLAGS) $< -o $#
operacje.o: operacje.cpp operacje.h porownaj.h
$(CXX) $(CXXFLAGS) $< -o $#
porownaj.o: porownaj.cpp operacje.h porownaj.h
$(CXX) $(CXXFLAGS) $< -o $#
That will cause make to compile only the corresponding .cpp file. When you use $^ the header files are passed to the g++ command which tells the compiler to create precompiled headers for them - that's what's ending up in main.o instead of the object file for main.cpp.
GNU make variable definitions like CC = g++, or CFLAGS = -Wall -pedantic etc.. should each be on its own line:
CC = g++
CFLAGS = -Wall -pedantic
OBJS = main.o operacje.o porownaj.o
BTW, you probably mean
CXX = g++
CXXFLAGS = -Wall -pedantic
You certainly don't want -c explicitly in your CFLAGS or CXXFLAGS; you really should remove it.
Also, recipes should be after its rule, so you want
dzialania: $(OBJS)
$(LINK.cc) $^ -o $#
operacje.o: operacje.cpp operacje.h porownaj.h
$(CXX) $(CXXFLAGS) -c $< -o $#
The several spaces are actually a single tab character.
Run make -p to understand the rules known by make; see also this answer and that one.
Take time to read GNU make documentation.