I created a simple C++ project and made the makefile myself.
The makefile looks like this:
all: project1.exe
clean:
rm main.o project1.exe
project1.exe: main.o
g++ -g -o project1 main.o
main.o:
g++ -c -g main.cpp
Originally I just had a main.cpp file. Everything worked until I created a new class (Token.h) and added it to my project. I put a new include statement at the tope of my main file, but when I try to build the project I get this message in the console:
make all
g++ -c -g main.cpp
g++ -g -o project1 main.o
Undefined symbols for architecture x86_64:
"Token::print()", referenced from:
_main in main.o
"Token::Token()", referenced from:
_main in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [project1.exe] Error 1
Anybody know what I have to do in order for my project to build correctly now that I've added a class to it? Do I need to make a change to the makefile? If so, what?
Add a rule to your makefile:
token.o : token.cpp token.hpp
g++ -g -c token.cpp
Modify some rules in your makefile:
main.o: main.cpp token.hpp
g++ -g -c main.cpp
project.exe : main.o token.o
g++ -o project.exe main.o token.o
In the above fragment, the token.hpp class was added as a dependency to main.o. The token.o file was added as a dependency to project.exe and as a parameter to the linking phase.
Related
I get the following error when trying to compile my simple program with make all:
❯ make all
clang++ --std=c++11 -Wall main.cpp
Undefined symbols for architecture arm64:
"file_reader::read_file()", referenced from:
_main in main-99040e.o
"file_reader::file_reader(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >)", referenced from:
_main in main-99040e.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [main.o] Error 1
I can compile the program manually if I do clang++ --std=clang++11 main.cpp file_reader.cpp (and the executable works correctly), so I don't think it's an architecture error like it suggests. I think it might be a problem with my makefile, which I will include below, so if anyone has any insight that would be really helpful. I looked up several conventions for makefiles and none of them helped. The structure is pretty basic with main.cpp creating an object of type file_reader and then referencing one of its methods, so I use #include "file_reader.h" in my main.cpp.
makefile:
# compiler
CXX = clang++
# compiler flags:
# --std=clang++11 : verion
CXXFLAGS = --std=c++11 -Wall
all: main.out
main.out: main.o file_reader.o
$(CXX) main.o file_reader.o -o main
main.o: main.cpp file_reader.h
$(CXX) $(CXXFLAGS) main.cpp
file_reader.o: file_reader.cpp file_reader.h
$(CXX) $(CXXFLAGS) file_reader.cpp
clean:
rm -rf *.o restaurant
In my cpp project, I have header file with #include <boost/asio.hpp>.
i also got a makefile attached to the project:
CFLAGS:=-c -Wall -Weffc++ -g -std=c++11 -Iinclude
LDFLAGS:=-L/Users/user/Downloads/boost_1_61_0
all: EchoClient
g++ -o bin/echoExample bin/connectionHandler.o bin/echoClient.o $(LDFLAGS)
EchoClient: bin/connectionHandler.o bin/echoClient.o
bin/connectionHandler.o: src/connectionHandler.cpp
g++ $(CFLAGS) -o bin/connectionHandler.o src/connectionHandler.cpp
bin/echoClient.o: src/echoClient.cpp
g++ $(CFLAGS) -o bin/echoClient.o src/echoClient.cpp
.PHONY: clean
clean:
rm -f bin/*
What I need to to in order to make the program compile and run?
Do i need to download boost and put it in some folder?
Do i need to change the value LDFLAGS that inside the makefile to the download boost destination?
This is what i did so far, but it seems wrong because when I run make I get this error:
g++ -o bin/echoExample bin/connectionHandler.o bin/echoClient.o -L/Users/user/Downloads/boost_1_61_0
Undefined symbols for architecture x86_64:
"boost::system::system_category()", referenced from:
boost::asio::error::get_system_category() in connectionHandler.o
boost::system::error_code::error_code() in connectionHandler.o
___cxx_global_var_init.2 in connectionHandler.o
boost::asio::error::get_system_category() in echoClient.o
___cxx_global_var_init.2 in echoClient.o
"boost::system::generic_category()", referenced from:
___cxx_global_var_init in connectionHandler.o
___cxx_global_var_init.1 in connectionHandler.o
___cxx_global_var_init in echoClient.o
___cxx_global_var_init.1 in echoClient.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [all] Error 1
Am i doing it OK?
I'm tring to run it both in mac and in windows
The folder boost_1_61_0 contains folders: boosts, libs, status, more, tools and more
I'm currently trying to use a makefile to automate my build process which I am still new to. When I run the g++ command:
g++ -I includes -L lib -lSDL2_test -lSDL2 -lSDL2main main.o -o main.exe
from the following makefile:
main: main.o
g++ -I includes -L lib -lSDL2_test -lSDL2 -lSDL2main main.o -o main.exe
main.o: main.cpp
g++ -c main.cpp
I get clang: error: linker command failed with exit code 1
However when running the same g++ command from the same directory as the makefile everything compiles correctly and I don't get the error. So how do I fix this?
EDIT:
I've done some testing and found out the problem with the makefile is that the -I includes g++ flag is not enabling the main.o file to find SDL.H, hopefully that helps to narrow down the problem.
#G.M's comment isn't unrelated - it's the correct answer to the problem. The include files are needed during the compile stage (the main.o: main.cpp rule), NOT during the link stage (i.e. the main: main.o rule.)
Move the -I includes flag to the second rule, and try again.
I would like to use tinyxml. I have used it in the past, and it works great. The only problem is I was developing on my Linux box which is a laptop. I have a mac mini and I have that set up as my desktop, so I would like to use it for a big chunk of development.
I have a simple tinyxml example that one of my instructors gave me. With this example came a Makefile like so:
ifeq ("$(shell whoami)", "malloy")
CXX = clang++
else
CXX = g++
endif
# Warnings frequently signal eventual errors:
CXXFLAGS=`sdl-config --cflags` -g -W -Wall -Weffc++ -Wextra -pedantic -O0
ifeq ("$(shell uname)", "Darwin")
LDFLAGS = -framework Foundation -framework GLUT -framework OpenGL -lm
else
ifeq ("$(shell uname)", "Linux")
LDFLAGS = `sdl-config --libs` -lm -lSDL_ttf -lSDL_image -ltinyxml
endif
endif
OBJS = \
main.o
EXEC = run
%.o: %.cpp
$(CXX) $(CXXFLAGS) -c $< -o $#
$(EXEC): $(OBJS)
$(CXX) $(CXXFLAGS) -o $# $(OBJS) $(LDFLAGS)
main.o: main.cpp
clean:
rm -rf $(OBJS)
rm -rf $(EXEC)
And when I try to make this simple project I get all of these Undefined symbol errors.
This is what terminal outputs after I type make:
g++ `sdl-config --cflags` -g -W -Wall -Weffc++ -Wextra -pedantic -O0 -o run main.o - framework Foundation -framework GLUT -framework OpenGL -lm
Undefined symbols for architecture x86_64:
"TiXmlString::nullrep_", referenced from:
TiXmlString::quit() in main.o
"TiXmlDocument::LoadFile(TiXmlEncoding)", referenced from:
_main in main.o
"TiXmlDocument::TiXmlDocument(char const*)", referenced from:
_main in main.o
"TiXmlNode::Clear()", referenced from:
_main in main.o
"TiXmlNode::~TiXmlNode()", referenced from:
TiXmlDocument::~TiXmlDocument() in main.o
"TiXmlElement::Attribute(char const*) const", referenced from:
_main in main.o
"TiXmlNode::FirstChildElement() const", referenced from:
TiXmlNode::FirstChildElement() in main.o
"TiXmlNode::NextSiblingElement() const", referenced from:
TiXmlNode::NextSiblingElement() in main.o
"vtable for TiXmlDocument", referenced from:
TiXmlDocument::~TiXmlDocument() in main.o
NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [run] Error 1
I know it is a linker error that is about it. I used Homebrew to install tinyxml. It was actually giving me problems so after I got the tar-ball for tinyxml I extracted it and put the folder in /usr/local/include. g++ doesn't complain about finding the files. Just stuff with the v-table.
Any help is greatly appreciated! Thanks in advance!!!
You should modify the makefile and instruct the linker to use tinyxml (-ltinyxml) in the "Darwin" case. AFAIK, tinyxml is not bundled with OSX so you may need to find or build that. Instead, you can use expat (simpler-easier) or libxml2 (faster-detailed), which already come with OSX (you can also use (c++) wrappers, google them...)
Consider the following g++ invocation (Apple GCC 4.2.1, running on OSX 10.6.5) which works just fine:
g++ -c util/warthog_cfg.cpp -o util/obj/warthog_cfg.o -DOS_MAC -O0 -Wall -Wno-sign-compare -ansi -fmessage-length=0 -m32
g++ main.cpp -o main -I./util util/obj/warthog_cfg.o -m32
Observe that I passed warthog_cfg.o (a required object file) as an argument in the second line. Now I want to put warthog_cfg.o into a library file and link against that. I run the following:
g++ -c util/warthog_cfg.cpp -o util/obj/warthog_cfg.o -DOS_MAC -O0 -Wall -Wno-sign-compare -ansi -fmessage-length=0 -m32
ar -crs lib/libutil.a util/obj/warthog_cfg.o
g++ main.cpp -o ./bin/main -DOS_MAC -O0 -Wall -Wno-sign-compare -ansi -fmessage-length=0 -m32 -L./lib -framework CoreServices -I./TransitC -I./cpd2012/ -I./util -lutil -lutil
Undefined symbols:
"warthog::util::warthog_cfg::print(std::basic_ostream<char, std::char_traits<char> >&)", referenced from:
_main in ccI5ycWY.o
"warthog::util::warthog_cfg::warthog_cfg()", referenced from:
_main in ccI5ycWY.o
"warthog::util::warthog_cfg::parse_args(int, char**)", referenced from:
_main in ccI5ycWY.o
"warthog::util::warthog_cfg::~warthog_cfg()", referenced from:
_main in ccI5ycWY.o
_main in ccI5ycWY.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
make: *** [main] Error 1
The calls appear identical. I thought perhaps the problem is with ar not adding the .o file to the archive. However, otool seems to indicate otherwise. File sizes seem about right too.
otool -I lib/libutil.a
Archive : lib/libutil.a
lib/libutil.a(warthog_cfg.o):
-rw-r--r-- 1 foo staff 5908 10 Sep 18:39 warthog_cfg.o
-rw-r--r-- 1 foo staff 6800 10 Sep 18:35 lib/libutil.a
What's going on here?
I'm not actually seeing you linking the library to the main program.
I don't generally use -L for this (this sets a search path, but I know where the library is). Just add your lib/libutil.a on the linker invocation just like you would another object file. If you want to keep the "search my lib" scheme, add -lutil and hope there's no other util library getting in the way.