makefile : How to link object files - c++

I have makefile and I need to link two objects into "main" object
They are -> oglinet.o and libshape.o
their path in system -> home/pi/openvg/
Problem :I need to write full path and objects name(home/pi/openvg/libshapes.o) is possible to "make" them as Makefile variable for example home/pi/openvg/libshape.o into $(OBJ1) in makefile rule ?
Tried to make them as variable for example Obj1= /home/pi/openvg/oglinit.o
if I compile that the compilator freeks out.
Working Makefile
#NOT IDEAL MAKEFILE BUT WORKING!!!!!
INCLUDEFLAGS = -I/opt/vc/include -I/opt/vc/include/interface/vmcs_host/linux -I/opt/vc/include/interface/vcos/pthreads -I/home/pi/openvg
LIBFLAGS = -L/opt/vc/lib -lbrcmEGL -lbrcmGLESv2 -lbcm_host -lpthread -ljpeg
main:main.cpp
g++ -Wall $(INCLUDEFLAGS) -o main main.cpp $(LIBFLAGS) home/pi/openvg/libshapes.o /home/pi/openvg/oglinit.o
Expectations:
what libshape.o and oglinit.o objects and thei path in system are "stored" in some kind of variable/variables
and if I need I can easily make changes in makefile /
After help of Chriss Dodd (not ideal?) makefile looks like this
INCLUDEFLAGS = -I/opt/vc/include -I/opt/vc/include/interface/vmcs_host/linux -I/opt/vc/include/interface/vcos/pthreads -I/home/pi/openvg
LIBFLAGS = -L/opt/vc/lib -lbrcmEGL -lbrcmGLESv2 -lbcm_host -lpthread -ljpeg
OPENVG=/home/pi/openvg
App: main.cpp $(OPENVG)/libshapes.o $(OPENVG)/oglinit.o
g++ -Wall -o $# $^ $(LIBFLAGS) $(INCLUDEFLAGS)

You usually want to make all the object files you're linking dependencies of the target. Then you can just use $^. You also usually want all the libraries after all the object files on the linker command line. With both of those you end up with something like:
OPENVG=/home/pi/openvg
main: main.o $(OPENVG)/libshape.o $(OPENVG)/objinit.o
g++ -Wall -o $# $^ $(LIBFLAGS)

Related

Makefile missing include path Although the path exists and defined

i have make file which i try to make them generic
but it keeps to compline it missing include directory
this is the makefile :
CXX=g++
CPPFAGS= -Wall -O0 -g -std=c++14
INCLUDES = -I/home/vagrant/libuv/include -Isrc
LIBS_DIRS = -L/home/vagrant/libuv/build
LDFLAGS= -lssl -lcrypto
LIB_STATIC = -Wl,--no-as-needed -Bstatic -luv_a -ldl -lpthread
SOURCE = $(wildcard echo.cpp) \
$(wildcard src/*.cpp)
OBJ = $(SOURCE:.cpp=.o)
DEP = $(OBJ:.o=.d)
TARGET = myproj
$(TARGET) : $(OBJ)
$(CXX) $(CPPFLAGS) $(INCLUDES) -o $# $^ $(LIBS_DIRS) $(LDFLAGS) $(LIB_STATIC)
all: $(TARGET)
clean:
rm -f $(OBJ) $(TARGET)
cleandep:
rm -f $(DEP)
.PHONY:all clean cleandep
when i make : make -n :
make -n
g++ -c -o echo.o echo.cpp
g++ -c -o src/base64.o src/base64.cpp
g++ -c -o src/Server.o src/Server.cpp
g++ -c -o src/sha1.o src/sha1.cpp
g++ -c -o src/Client.o src/Client.cpp
g++ -I/home/vagrant/libuv/include -Isrc -o myproj echo.o src/base64.o src/Server.o src/sha1.o src/Client.o -L/home/vagrant/libuv/build -lssl -lcrypto -Wl,--no-as-needed -Bstatic -luv_a -ldl -lpthread
when i invoke make , im getting this error:
make
g++ -c -o echo.o echo.cpp
In file included from src/Server.h:9:0,
from echo.cpp:1:
src/Client.h:6:10: fatal error: uv.h: No such file or directory
#include <uv.h>
^~~~~~
compilation terminated.
make: *** [echo.o] Error 1
but the uv do exist in : /home/vagrant/libuv/include
You have no rule to build your object files: you've only defined a rule to link your object files into a final executable. As mentioned in the comments, adding $(INCLUDES) into that recipe is useless because header file directories are only used during compiling (creating object files) not linking (converting object files and libraries into executables).
Because you haven't defined your own rule to build object files, you're using make's built-in rule. But make's built-in rule doesn't know anything about a variable named INCLUDES, so that variable is not used during compilation. You can easily see this by looking at the compiler commands generated by make.
You need to either (a) create your own rule for compiling object files that uses your personal make variables, or (b) use the normal built-in variables that make expects to be used with its built-in rules.
For (b), as described in the manual, you should take your current CPPFAGS [sic] variable and rename it to CXXFLAGS, take your current INCLUDES variable and rename it CPPFLAGS, take your current LIBS_DIRS variable and rename it LDFLAGS, and take your current LDFLAGS variable and rename it to LDLIBS.
Also just to note, you have DEPS etc. but there is nothing in your makefile that does anything with them or to create them so they're useless.

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

Trouble compiling/linking C and C++ files

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)

C++ - Makefile Good Practice

I have a Makefile that works for how I'm using it, but will anyone tell me if what I'm doing is good practice? Or if there is a better, cleaner or more efficient way to achieve the goal I am reaching?
Here is my Makefile Code.
# Object files to either reference or create
OBJECTS = Proj2.o Blackjack.o Deck.o Card.o Hand.o Player.o
# The executable file that will be created
EXEC = Proj2.out
# The c++ flags to use for compilation
CXXFLAGS = -Wall
# The c++ compiler to use for compilation
CXX = g++
# This section is called on 'make'
# Will call compile, and then call clean
all: compile clean
# Perform action on all object files (May or may not exist)
# The makefile will implicitly compile all .o files needed
# Will also compile them into the EXEC file listed
compile: $(OBJECTS)
$(CXX) $(CXXFLAGS) -o $(EXEC) $(OBJECTS)
# This section is called after compilation is completed
# This will clean all existing .o files listed in the directory
clean:
rm -f *.o
Here is the terminal output when I call make.
g++ -Wall -c -o Proj2.o Proj2.cpp
g++ -Wall -c -o Blackjack.o Blackjack.cpp
g++ -Wall -c -o Deck.o Deck.cpp
g++ -Wall -c -o Card.o Card.cpp
g++ -Wall -c -o Hand.o Hand.cpp
g++ -Wall -c -o Player.o Player.cpp
g++ -Wall -o Proj2.out Proj2.o Blackjack.o Deck.o Card.o Hand.o Player.o
rm -f *.o
Is it good practice to use a Makefile like this? Specifically, am I doing the cleaning part of my Makefile correctly?
You should not make all depend on clean at all. By doing this you are ensuring that every time you run make, you have to recompile everything. If you want to do that then using make is itself useless: just write a shell script that compiles and links your code.
The clean target should be a separate target and if you want to clean your workspace you run make clean explicitly.
The other problem with your makefile is that the link rule lists compile as the target, but it builds $(EXE). It's almost never a good idea to have a rule create a file which is not exactly the target you told make it would build. To ensure this, always use $# as the target to generate. Rewrite it like this:
compile: $(EXE)
$(EXE): $(OBJECTS)
$(CXX) $(CXXFLAGS) -o $# $^

Simple makefile for compiling a shared object library file

I need a very simple makefile to compile a shared object library file (*.so). I also need to know how to pass optimization parameters like -O2 and -O3. I tried to search for simple examples using google, but all examples are twisted.
I don't need to create any version like *.so.1.0 but only a simple *.so file. My project would have multiple files, so I need an example which compiles multiple files.
The simplest makefile that I can think of that does what you want:
CXXFLAGS += -fPIC
CXXFLAGS += -O3
x.so: x.o y.o
g++ -shared $^ -o $#
In the alternative, you may want to use more of make's built-in rules and variables:
CXXFLAGS += -fPIC
CXXFLAGS += -O3
x.so: x.o y.o
$(LINK.cc) -shared $^ $(LOADLIBES) $(LDLIBS) -o $#