Reputation: 740
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
Upvotes: 1
Views: 1587
Reputation: 5566
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)
Upvotes: 1
Reputation: 121
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
Upvotes: 1
Reputation: 466
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
Upvotes: 1