Multiple linking c++ files - c++

C++ newbie here my command is g++ main.cpp -o main gives me linking errors like the following
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
if i pass c++ files g++ main.cpp myfile.cpp -o main everything is correct
any ideas how to compile multiple c++ files without passing everything in command line.
Thanks

any ideas how to compile multiple c++ files without passing everything in command line.
To build an application you need all object files, so you have to pass all cpp files to compiler.
But for simple cases when all cpp-files stay at single folder, you can
use command (simple, but slow method):
g++ *.cpp -o main

any ideas how to compile multiple c++ files without passing everything in command line.
First create object files:
g++ -c main.cpp -o main.o
g++ -c myfile.cpp -o myfile.o
Then pass them to the linker:
g++ main.o myfile.o -o main

Though there is a fairly large learning curve for Make, a make file is the preferred solution. On SO, I have also noticed significant use of CMake.
Additional ideas for your Makefile:
The following two rules handle 90% of my simpler unit test executables:
R01 handles files with both .cc and .hh
R02 handles files with only .cc
# pattern rule R01
# when any ARCHIVE changes, trigger a rebuild
% : %.cc %.hh $(LIB_ARCHIVEs)
#echo
#echo R01: $<
rm -f $#
$(CC) $(CC_FLAGS) $< -o $# $(LIB_DIRs) $(LIB_NMs)
# pattern rule R02
# when any ARCHIVE changes, trigger a rebuild
% : %.cc $(LIB_ARCHIVEs)
#echo
#echo R02: $<
rm -f $#
$(CC) $(CC_FLAGS) $< -o $# $(LIB_DIRs) $(LIB_NMs)
Occasionally, I will add specific LIB names and directories ... directly to the LIB_DIRs and LIB_NMs definition in the Makefile. For example, here I have added -lrt and -pthread:
LIB_NMs += -lbag_i686 -lposix_i686 -lrt -pthread
bag_i686 and posix_i686 are libraries I built ... simple C++ class wrappers around the linux and posix functions. Most of my unit tests do not use much of posix stuff, but I get no grief including it.
With C++ std::thread, I seldom use -pthread. However, I occasionally use posix semaphore.
My compile command line access (in emacs on Ubuntu) provides a history, so the occasional change or addition to the command line is only a 'bother' one time. From then on, the newer command is available in history.
The emacs I launch is configured with an 'embedded' pre-defined compile command:
USER_FLAGS='-O0 ' ; export USER_FLAGS ; time make CC='g++ -m64' -j 2 -k
This command shows up the 1st time I launch the compiler from within emacs. Emacs presents it as if the command is already in 'compile-command history'.
I manually shorten this if I'm not rebuilding all, usually I only build a single ut:
USER_FLAGS='-O0 ' ; export USER_FLAGS ; time make CC='g++ -m64'
So, for example, when I am ready to compile dumy431.cc, I invoke:
USER_FLAGS='-O0 ' ; export USER_FLAGS ; time make CC='g++ -m64' dumy431
The next build I launch (from within emacs compile) starts with the previous command, and up/down arrow roll through any other versions of the command.
With this form of the command, I can trivially change from g++ to clang++ by inserting "clan" at the appropriate place:
USER_FLAGS='-O0 ' ; export USER_FLAGS ; time make CC='clang++ -m64'
clang++ often provides additional diagnostics that g++ does not report. To roll back to g++, I can up-arrow in the compiler command panel (or edit the command).
Here is a small example where my unit test code has multiple src files. Often, the non-main files (such as eng_format.*) are code that I plan to capture to one of my libraries for future use:
FMssb.o : FMssb.cc FMssb.hh
#echo
#echo R_FMssb.o: $<
rm -f $#
$(CC) $(CC_FLAGS) -c $< -o $#
FMssb_ut : FMssb_ut.cc eng_format.o FMssb.o $(LIB_ARCHIVEs)
#echo
#echo R_FMssb_ut: $<
rm -f $#
$(CC) $(CC_FLAGS) $< -o $# eng_format.o FMssb.o $(LIB_DIRs) $(LIB_NMs)
eng_format.o : eng_format.cpp eng_format.hpp $(LIB_ARCHIVEs)
#echo
#echo R_EF: $<
rm -f $#
$(CC) $(CC_FLAGS) -c $< -o $# $(LIB_DIRs) $(LIB_NMs)

Related

Including Multiple Classes/ .o files with MinGW Tool in C++

I want to compile 2 classes into .o file and include them in Test.exe file created from avl.cpp main file.
I use the MinGW tool while doing this, but Nothing happens when I type the command mingw32-make into CMD. When I did this with only 1 class, there was no problem.
The content of the makefile file is as follows:
all: compile execute
compile:
g++ -I ./include/ -o ./lib/AVLClass.o -c ./src/AVLClass.cpp
g++ -I ./include/ -o ./lib/PersonsClass.o -c ./src/PersonsClass.cpp
g++ -I ./include/ -o ./bin/Test ./lib/PersonsClass.o ./lib/AVLClass.o ./src/avl.cpp
execute:
./bin/Test
Makefile uses dependancies to determine what gets built in which order.
So the line execute: should really be execute: compile to tell make to do the execute step after the compile step completed.
But you should really split compilation an linking into steps to use the dependancy resolving qualities of make.
Here's how I would do it:
BINEXT=.exe
CXX=g++
MKDIR=mkdir -p
RM=rm -f
all: bin/Test$(BINEXT) test
lib/%.o: src/%.cpp
$(MKDIR) lib
$(CXX) -c -o $# $^
bin/Test$(BINEXT): lib/AVLClass.o lib/PersonsClass.o lib/avl.o
$(MKDIR) bin
$(CXX) -o $# $^
test: bin/Test$(BINEXT)
bin/Test$(BINEXT)
clean:
$(RM) lib/*.o bin/Test$(BINEXT)
Note that the indents must be tabs, not spaces.
Actually I wouldn't add test to the all target. It's better to leave it up to the user if they want to run make test.

How to use Makefile variables as files to include in g++ command?

Here's my problem : I have a makefile file containing the info to compile everything in my project to make my life easier, but it is giving me some headaches recently.
It can compile multiple files, such as this :
objects/io.o: sources/io.cpp
#g++ -c $< -o $# -std=c++11
objects/map.o: sources/map.cpp
#g++ -c $< -o $# -std=c++11
At the top of the makefile, I have variables declared as such :
IO="objects/io.o"
MAP="objects/map.o"
[... other object files ...]
ALL="$(IO) $(MAP) [...]"
When I want to compile my main file, I use this command :
main.exe: tests/main.cpp
#g++ $< $(ALL) -o $# -std=c++11
When I compile this problem manually (inputting everything in one line of command, instead of making make main.exe) it compiles without problems.
However, when I use the make command for the project, the following error pops up :
clang: error: no such file or directory: 'objects/io.o objects/map.o [...]'
make: *** [main.exe] Error 1
Can I not use variables this way ? I'm extremely confused. I know for a fact those files are compiled, it just seems the make utility doesn't understand file paths.
I think the problem is that you have quoted your variables. Try unquoting them and they won't expand a single parameter:
ALL = $(obj1) $(obj2) ...
Also, for those objects which use the same compilation process I generally define a single rule:
obj/%.o: %.cc
$(GCC) -o $# -c $< $(FLAGS)
Obviously that would require defining the extra variables GCC and FLAGS

Using makefile arguments without foo=

I have a makefile I use to compile a single file. When I need to pass an argument, I use target=targetFile.
The script takes the argument, looks for the file (within the same directory) that has the same value as the argument and compiles it.
I use this for compiling problems from uhunt and uva, which use a single c++ file. So I dont' need multiple makefiles for multiple source files. Single makefile for multiple source files is the reason I made the makefile.
Here's the code I have so far
OBJS = $(target).o
CC = g++
CFLAGS = -Wall -g -std=c++11
INCLUDE = -I./$(target)
#default command to run
all : Main-$(target) clean run
#compile and build
Main-$(target) : $(OBJS)
$(CC) $(CFLAGS) $^ -o $#
%.o : %.cpp
$(CC) -c $(CFLAGS) $<
#remove object and any other garbage files.
clean:
rm -rf -d $(target).o *~ *% *# .#*
#remove the compiled file
clean-all:
$(clean) rm Main-$(target)
#run the compiled file
run:
./Main-$(target)
The command I use to compile is,
make target=sourceFile
Also I don't include the file extension, I have all my source file extensions to be cpp
What I want in the end is:
make sourceFile
Just a side note, for using the command clean and clean-all, I use
make target=sourceFile clean
make target=sourceFile clean-all
I'd prefer if I can use:
make sourceFile clean
make sourceFile clean-all
You may use common Makefile variable MAKECMDGOALS that contains all targets passed to make.
Please try this variant
CC = g++
CFLAGS = -Wall -g
MAKECMDGOALS := $(filter-out clean, $(MAKECMDGOALS))
.PHONY: $(MAKECMDGOALS)
$(MAKECMDGOALS):
$(CC) $(CFLAGS) $#.c -o Main-$#
clean:
rm -f *.o
Here the lines
$(MAKECMDGOALS):
$(CC) $(CFLAGS) $#.c -o Main-$#
will generate separate build targets for each word in MAKECMDGOALS.
Note, we need this Makefile to know that 'clean' is a target for removing stuff, but not to attempt build Main-clean. This why we remove clean from MAKECMDGOALS using filter-out function.
So if we run make a b clean, the build system will generate automatically targets for building Main-a and Main-b and then use already written clean target
Disclaimer -- this is a non-standard use of Make, and will therefore open up all kinds of corner cases, so I don't recommend it. This is better suited for a shell script calling make. That being said... it is an interesting question.
You can't do make xxx clean, and not have it try to build xxx (unless you do some really nasty cludge using recursive make, but I won't go there). You could do something like make clean-xxx though, as follows:
%:Main-%
Main-%:%.cpp
$(CC) $(CFLAGS) $< -o Main-$#
clean-%:
rm Main-$*
Notice that %-clean has a shorter stem, and therefor takes precedence over the % if the make target starts with clean-.

Makefile to build shared library

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.

beginner GNU Makefile Error

This is my first, attempt at a, Makefile after necessity from a previous post.
Anyway here's the code
SortLab.exe : SelectionSort.o Main.o
g++ -o $# $^
SelectionSort.o : SelectionSort.cpp SelectionSort.h
Main.o : Main.cpp
#-------------------------------------------------------------
run: SortLab.exe
./SortLab.exe
clean:
rm -f *.o
rm -f *.exe
build: clean SortLab.exe
%.o: %.cpp
g++ -c $<
I intend to have SelectionSort.cpp & SelectionSort.h form an object file, and Main.cpp to form its own object file. Then finally create an executable. Main.cpp depends on SelectionSort.cpp, where do I go wrong?
Also where can I find what the different GNU commands mean, -o -c and such
You shouldn't need to define the %.o: %.cpp rule yourself, Make knows how to compile C++.
Indent with tabs, not spaces; Make is sensitive to the difference.
Every object file should depend on the headers included in the source files it depends on. You probably need Main.o : Main.cpp SelectionSort.h.
build shouldn't depend on clean, it defeats one of Make's main features (selectively recompilation when files have changed).
If you make build the first target, you can run Make without a target to get a full compile. It's customary to call the main target all.