Makefile won't compile correctly - c++

I can't figure out how to get my Makefile to compile a group of cpp files using the -lpthread. The problem is occurring with g++ *.cpp -c. My functions (Which are in external files), can't find pthread_exit. What is the correct way to do this?
#
#Makefile for producerConsumer
#
RM = rm -f
#SRC = producer.cpp consumer.cpp
#OBJ = $(SRC:.cpp=.o)
TESTNAME = test
TESTSRC = main.cpp
#
retest: re test
test:
g++ *.cpp -c
g++ *.o -o $(TESTNAME) -lpthread
clean:
-$(RM) *.o
-$(RM) *~
-$(RM) \#*
-$(RM) *.core
fclean: clean
-$(RM) $(TESTNAME)
-$(RM) *.o
re: fclean

It looks like you're using Linux, so use -pthread instead of -lpthread, and make sure to add it to both the compilation and linking commands. The -pthread option will make sure pthread support is activated while (pre-)compiling your code, and will ensure that the correct libraries are linked in properly.
Additionally, make sure you've included <pthread.h> in any compilation unit that uses pthread functions, so they all look for the correct symbols.
Here's a sample makefile :
CXX = g++
LD = g++
CXXFLAGS = -Wall -pthread
LDFLAGS = -pthread
SOURCES = main.cpp
OBJECTS = $(SOURCES:.cpp=.o)
BINARY = test
all : $(SOURCES) $(BINARY)
$(BINARY) : $(OBJECTS)
$(LD) $(LDFLAGS) $^ -o $#
.cpp.o :
$(CXX) $(CXXFLAGS) -c $< -o $#
.PHONY : clean
clean :
rm -f *.o $(BINARY)

Related

Shared library with freeglut - undefined symbol

I'm actually experiencing some issues while linking an OpenGL/freeglut shared library (.so) with a C++ project. I'm sure that the problem is in my Makefile since the code I use to load (using the dlopen/dlsym/dlclose functions) works fine with other shared libraries.
I thought it comes from headers inclusions but the OpenGL project I'm trying to work with compiles when I create an executable of it. I've also checked the glut FAQ but the solution now redirect to a dead link So there is my Makefile content, does anyone see where I am wrong ?
TARGET = lib_opengl.so
CC = g++
SRC = GL_Handler.cpp \
GL_Utils.cpp
DEVIL_CFLAGS := $(shell pkg-config --cflags IL)
DEVIL_LIBS := $(shell pkg-config --libs IL)
LIBS += -lGL -lGLU -lglut $(DEVIL_CFLAGS) $(DEVIL_LIBS)
CFLAGS = -W -Werror -Wall -ansi -pedantic -fPIC -shared -L/usr/X11R6/lib/ $(LIBS)
SRCDIR = src
OBJDIR = obj
SOURCES := $(addprefix src/, $(SRC))
OBJECTS := $(SOURCES:$(SRCDIR)/%.cpp=$(OBJDIR)/%.o)
rm = rm -rf
mkdir = mkdir -p
$(TARGET): $(OBJECTS)
#$(CC) $(CFLAGS) -o $# $(OBJECTS)
#echo $(TARGET)" compiled !"
$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.cpp
#$(mkdir) $(OBJDIR)
#$(CC) $(CFLAGS) -c $< -o $#
all : $(TARGET)
clean :
#$(rm) $(OBJDIR)
#echo "Binary files deleted"
fclean : clean
#$(rm) $(TARGET) $(LINK)
#echo "Binary and executable files are deleted"
re : fclean all
.PHONY: all clean fclean re
And there is the result when I'm trying to link it with my shared libraries loader.
./so_loader ./lib/lib_opengl.so
./so_loader: symbol lookup error: ./lib/lib_opengl.so: undefined symbol: glutInit
I hope that my problem is understandable and thanks for reading.
As a start, use variable LDFLAGS for linking instead of CFLAGS which is meant for compilation. Something like this:
LDFLAGS = -L/usr/X11R6/lib
...
$(TARGET): LDFLAGS += -shared -Wl,--no-undefined
$(TARGET): $(OBJECTS)
#$(CC) $(LDFLAGS) -o $# $(OBJECTS) ${LIBS}

how to write makefile that adds libraries after source

I have been supplied with the following makefile:
CXX=g++
CXXFLAGS=-std=c++11 -g -O2
LDFLAGS=-ltbb
EXE=$(basename $(wildcard *.cc))
all: $(EXE)
clean:
rm -fr $(EXE) *.dSYM
I am new to makefiles and In order to get it working in Ubuntu, I need to modify it such that the LDFLAGS comes after the source file in the compile command. How can I do this? My attempt is as follows:
CXX=g++
CXXFLAGS=-std=c++11 -g -O2
LDFLAGS=-ltbb
SRCS=$(wildcard *.cc)
EXES=$(subst .cc,,$(SRCS))
all: $(EXES)
$(CXX) $(CXXFLAGS) $(SRCS) $(LDFLAGS) -o $(EXES)
clean:
rm -fr $(EXE) *.dSYM
Libraries should be added to LDLIBS instead of LDFLAGS. Try this in your original makefile:
LDLIBS=-ltbb
See here for reference.

compilation with Makefile fail but success in command line

I was using a Makefile to compile my project and compiled successfully, but when I added a new lib (libbcm2835.a) to linker (-lbcm2835) it fails, otherwise when using the following commands it compile and link with no error :
gcc -c ihome_*.c
gcc -o iHome_Start ihome*.o -lbcm2835 -lpthread
Makefile :
# project name (generate executable with this name)
TARGET = iHome_Start
CC = gcc
# compiling flags here
CFLAGS = -std=c99 -Wall -I.
LINKER = gcc -o
# linking flags here
LFLAGS = -lpthread -lbcm2835
# change these to set the proper directories where each files shoould be
SRCDIR = .
OBJDIR = .
BINDIR = .
SOURCES := $(wildcard $(SRCDIR)/*.c)
INCLUDES := $(wildcard $(SRCDIR)/*.h)
OBJECTS := $(SOURCES:$(SRCDIR)/%.c=$(OBJDIR)/%.o)
rm = rm -f
$(BINDIR)/$(TARGET): $(OBJECTS)
#$(LINKER) $# $(LFLAGS) $(OBJECTS)
#echo "Linking complete!"
$(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.c
#$(CC) $(CFLAGS) -c $< -o $#
#echo "Compiled "$<" successfully!"
.PHONEY: clean
clean:
#$(rm) $(OBJECTS)
#echo "Cleanup complete!"
.PHONEY: remove
remove: clean
#$(rm) $(BINDIR)/$(TARGET)
#echo "Executable removed!"
The problem is in
#$(LINKER) $# $(LFLAGS) $(OBJECTS)
The linker processes the arguments in an order they appear. By the time it sees the libraries, it hadn't yet seen no object files, hence there are no unresolved symbols, hence it pulls nothing from the libraries. Swap $(OBJECTS) and $(LFLAGS):
#$(LINKER) $# $(OBJECTS) $(LFLAGS)
I would also recommend to rename LFLAGS to LIBRARIES.

c++ makefile with multiple program, autodetection of source files

I recently lost 5 hours to figure out how I could write the makefile I need. I'm not an informaticien or programmer so I'd like some comments on what I managed to do. I already looked a lot on different sites but still...
I need a makefile that creates different executables: prog1, prog2...
To create the .o files, as I have many files with many dependencies, I don't want to specify them all. So I want/need to use automatic variables with a pattern rule. To speed up the compilation I also take care to only recompile the modified files. I achieved this by using the -MD flag that creates a .d file saved in the $(BUILD) directory.
What I still can't do is to detect automatically which .o files prog1 needs. So for now I have to specify them automatically... If you know how to do that automatically...
I also would like to save the .o files in the $(BUILD) directory, but I can't make it work.
Any advice are welcome !
Thx
CXX = g++
ERRORS = -Wall -Wextra -pedantic
LAPACK = -llapack -lblas
OPTION = -O3 -fopenmp
CXXFLAGS = $(LAPACK) $(ERRORS) $(OPTION)
LDFLAGS = $(LAPACK) $(ERRORS) $(OPTION)
BUILD=build
SRCS=(wildcard *.cpp)
all:prog1 prog2 ...
prog1:prog1.o dep_only_for_prog_1.o dep_for_all_progs.o dep_for_some_progs.o
$(CXX) -o $# $^ $(LDFLAGS) $(NOASSERT)
prog2:prog2.o dep_only_for_prog_2.o dep_for_all_progs.o dep_for_some_progs.o
$(CXX) -o $# $^ $(LDFLAGS) $(NOASSERT)
...
%.o:%.cpp
$(CXX) -MD -c $(CXXFLAGS) $(NOASSERT) $< -o $#
mv $(<:.cpp=.d) $(BUILD)
-include $(addprefix $(BUILD)/$(SRCS:.cpp=.d))
clean:
rm -f *.o $(BUILD)/*
You just can't get make to infer somehow which files belong to which programs, but you CAN make your makefile simpler to read and update. Also you have a few bad things here, such as adding $(LAPACK) (which contains linker flags) to $(CXXFLAGS) (which are passed to the compiler).
Try:
PROGRAMS = prog1 prog2
prog1_SOURCES = prog1.cpp dep_only_for_prog_1.cpp \
dep_for_all_progs.cpp dep_for_some_progs.cpp
prog2_SOURCES = prog2.cpp dep_only_for_prog_2.cpp \
dep_for_all_progs.cpp dep_for_some_progs.cpp
#----- Don't need to change below here
CXX = g++
ERRORS = -Wall -Wextra -pedantic
LAPACK = -llapack -lblas
OPTION = -O3 -fopenmp
CXXFLAGS = $(ERRORS) $(OPTION)
LDFLAGS = $(LAPACK) $(ERRORS) $(OPTION)
BUILD=build
SRCS := $(wildcard *.cpp)
all: $(PROGRAMS)
.SECONDEXPANSION:
$(PROGRAMS): $$($$#_SOURCES:%.cpp=%.o)
$(CXX) -o $# $^ $(LDFLAGS) $(NOASSERT)
%.o : %.cpp
$(CXX) -MD -c $(CXXFLAGS) $(NOASSERT) $< -o $#
mv $(<:.cpp=.d) $(BUILD)
-include $(addprefix $(BUILD)/$(SRCS:.cpp=.d))
clean:
rm -f *.o $(BUILD)/*
Or you can use eval if you want.

Makefile - wildcard, how to do that properly?

FLAGS:= -Wall -Wvla -g -lm
OBJECT := Nominated.h UniversityNominated.h AliceGraduate.h BobGraduate.h CollegeNominated.h ColinGraduate.h DannyGraduate.h NominatedList.h Parser.h Parser.cpp
all: Hire
Nominated.o: Nominated.h Nominated.cpp
g++ -c $(FLAGS) Nominated.cpp -o Nominated.o
NominatedList.o: Nominated.h NominatedList.h NominatedList.cpp
g++ -c $(FLAGS) NominatedList.cpp -o NominatedList.o
UniversityNominated.o: Nominated.h UniversityNominated.h UniversityNominated.cpp
g++ -c $(FLAGS) UniversityNominated.cpp -o UniversityNominated.o
AliceGraduate.o: Nominated.h UniversityNominated.h AliceGraduate.h AliceGraduate.cpp
g++ -c $(FLAGS) AliceGraduate.cpp -o AliceGraduate.o
BobGraduate.o: Nominated.h UniversityNominated.h BobGraduate.h BobGraduate.cpp
g++ -c $(FLAGS) BobGraduate.cpp -o BobGraduate.o
CollegeNominated.o: Nominated.h CollegeNominated.h CollegeNominated.cpp
g++ -c $(FLAGS) CollegeNominated.cpp -o CollegeNominated.o
ColinGraduate.o: Nominated.h CollegeNominated.h ColinGraduate.h ColinGraduate.cpp
g++ -c $(FLAGS) ColinGraduate.cpp -o ColinGraduate.o
DannyGraduate.o: Nominated.h CollegeNominated.h DannyGraduate.h DannyGraduate.cpp
g++ -c $(FLAGS) DannyGraduate.cpp -o DannyGraduate.o
Parser.o: $(OBJECT)
g++ -c $(FLAGS) Parser.cpp -o Parser.o
Parser: Nominated.o UniversityNominated.o AliceGraduate.o BobGraduate.o CollegeNominated.o ColinGraduate.o DannyGraduate.o NominatedList.o Parser.o
ar rcu libParser.a Nominated.o UniversityNominated.o AliceGraduate.o BobGraduate.o CollegeNominated.o ColinGraduate.o DannyGraduate.o NominatedList.o Parser.o
ranlib libParser.a
Hire: Hire.cpp Parser
g++ Hire.cpp libParser.a -o Hire
clean:
rm -f Hire *.a *.o *~
.PHONY: clean all
so this is my Makefile.
How can I make less ugly ?
I am always read about that but I can not get the idea
How ?
I mean I understand I need to use the wildcard tool but as you I probably used it wrong
Here's an example of how to use wildcard and pattern substitution:
SOURCES := $(wildcard *.cpp)
OBJECTS := $(patsubst %.cpp,%.o,$(SOURCES))
CXX := g++ -Wall -Wvla -g
.cpp.o:
${CXX} -c $<
This will build all the .cpp files into their object files.
There's many things you can do, but one of the best is a pattern rule for specific types. All of your objects seem to be built the same way.
%.o: %.cpp
${CXX} -c $(FLAGS) -o $# $<
You'll notice that this doesn't include any header files as dependencies. Manually maintaining the header dependencies in a Makefile is a bad idea because it's bound to get out of date as you modify your program. Sometimes your compiler can generate make-friendly dependencies for you automatically. Assuming you have a list of objects such as this:
OBJS := $(SOURCES:%.c=%.o)
You can include this at the very end of your Makefile (with no blank line afterward)
-include $(OBJS:.o=.d)
Then add, -MMD to your compiler flags. This will cause GCC to generate .d files that contain the header dependencies for each of your objects as a Make rule, and the above include line will include those rules and use them to resolve the dependencies of your objects. This will mean that any header change will cause all files that include it (directly or indirectly) to be rebuilt.
Try this:
FLAGS = -Wall -Wextra
SRC = $(wildcard *.cpp)
OBJ = $(patsubst %.cpp,%.o,$(SRC))
DEP = $(patsubst %.cpp,%.d,$(SRC))
PARSER = $(filter-out Hire.o,$(OBJ))
all: $(DEP) build
build:
make Hire
%.d:
g++ -MM $*.cpp > $*.d
%.o: %.cpp
g++ $(FLAGS) -c $*.cpp
libParser.a: $(PARSER)
ar rcu libParser.a $(PARSER)
ranlib libParser.a
Hire: Hire.cpp libParser.a
g++ Hire.cpp libParser.a -o Hire
clean:
rm -f Hire *.a *.o *.d *~
.PHONY: clean all
#
# This line includes all the dependencies.
# There is one for each file.
# Check the *.d files after you run make
-include $(DEP)