I am working on a project that requires me to use a variety of classes.
For some reason, whenever I try compiling, I get an error that says:
Undefined symbols for architecture x86_64:
I originally was working on a class we can call User that had a declaration like this in user.h:
#ifndef USER_H
#define USER_H
...other include statements
class User
{
public:
User();
public and private members and functions
};
#endif
Definitions of the methods was housed in a separate file in the same directory, user.cpp.
Whenever I would try to compile, I would get an error saying there were undefined symbols for the constructor and destructor. I had both of these defined in the .cpp file, but I couldn't get the error to go away.
I include the User class in main with the following:
#include "user.h"
I managed to fix this by pasting all code from the user.cpp file into user.h, but now I am having issues with other classes whose code I am not allowed to modify.
Right now, I have a class called GMLReader in gmlreader.h with a method I am calling statically. However, even though I am importing it for my main, I am getting the following error code whenever I try to call it:
Undefined symbols for architecture x86_64:
"GMLReader::read(char const*, std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&, std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&)", referenced from:
_main in cchnzOEh.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
I am using the following to compile with sn.cpp housing my main:
g++ -g -Wall -o sn sn.cpp
Is there any reason an error like this would have occurred and how can I go about fixing it?
You need to compile and link user.cpp as well:
g++ -g -Wall -c user.cpp -o user.o
g++ -g -Wall -o sn sn.cpp user.o
Related
Setup:
test.cpp
#include <set>
#include <string>
void common_config_file_iterator(const std::set<std::string>& allowed_options) {}
include.cpp
#include <set>
#include <string>
void common_config_file_iterator(const std::set<std::string>&) noexcept;
int main() {
std::set<std::string> set;
common_config_file_iterator(set);
return 0;
}
test.sh
clang++-7 test.cpp -c -O3 -fno-rtti -fno-exceptions -o test.o
g++-8 test.o include.cpp -O3 -fno-rtti -fno-exceptions -o test
Output:
Undefined symbols for architecture x86_64:
"common_config_file_iterator(std::set<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&)", referenced from:
_main in ccWoGgrX.o
ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status
So I did nm -g test.o:
0000000000000000 T __Z27common_config_file_iteratorRKNSt3__13setINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEENS_4lessIS6_EENS4_IS6_EEEE
According to demangler.com, it means:
common_config_file_iterator(std::__1::set<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&)
Libc++ says:
[Features and Goals:] ABI compatibility with gcc's libstdc++ for some low-level features such as exception objects, rtti and memory allocation.
So, is the problem std::allocator<char>?
Note that I use the macOS assembler.
Curiosity caused by this issue and boost/program-options.
So, is the problem std::allocator<char>?
What? No. It's everything in your example.
The doc you quoted clearly says the goal is compatibility for "low-level features such as exception objects, rtti and memory allocation".
std::set and std::string are not "low-level features such as exception objects, rtti and memory allocation". They are very definitely not compatible between libc++ and libstdc++, which are completely different libraries with completely different implementations.
The compatible pieces are things like std::type_info and std::exception (and the derived exception types in <stdexcept>) because those are part of the basic language runtime. Anything above that, such as containers, strings, algorithms, I/O, locales etc. is not compatible.
I am trying to compile a program using cmake, and am seeing the following linker error:
/home/quant/bin/boost_1_61_0/stage/lib/libboost_log_setup.so:
undefined reference to
boost::filesystem::path_traits::convert(wchar_t const*, wchar_t
const*, std::__cxx11::basic_string<char, std::char_traits<char>,
std::allocator<char> >&, std::codecvt<wchar_t, char, __mbstate_t>
const&)' /home/quant/bin/boost_1_61_0/stage/lib/libboost_log.so:
undefined reference to
boost::filesystem::path_traits::dispatch(boost::filesystem::directory_entry
const&, std::__cxx11::basic_string,
std::allocator >&)'
The linker command that ninja generated looks like this:
g++ -pthread -DBOOST_ALL_DYN_LINK
utility/test/CMakeFiles/utilityTest.dir/loadCSVTests.cpp.o
utility/test/CMakeFiles/utilityTest.dir/main.cpp.o
utility/test/CMakeFiles/utilityTest.dir/randomDeviceTests.cpp.o -o
utility/test/utilityTest -rdynamic
/home/quant/bin/boost_1_61_0/stage/lib/libboost_thread.so
/home/quant/bin/boost_1_61_0/stage/lib/libboost_program_options.so
/home/quant/bin/boost_1_61_0/stage/lib/libboost_serialization.so
/home/quant/bin/boost_1_61_0/stage/lib/libboost_unit_test_framework.so
/home/quant/bin/boost_1_61_0/stage/lib/libboost_system.so
/home/quant/bin/boost_1_61_0/stage/lib/libboost_log.so
/home/quant/bin/boost_1_61_0/stage/lib/libboost_log_setup.so
/home/quant/bin/boost_1_61_0/stage/lib/libboost_filesystem.so
utility/lib/libutilityLib.a utility/testLib/libutilityTestLib.a
utility/lib/libutilityLib.a
/home/quant/bin/boost_1_61_0/stage/lib/libboost_thread.so
/home/quant/bin/boost_1_61_0/stage/lib/libboost_program_options.so
/home/quant/bin/boost_1_61_0/stage/lib/libboost_serialization.so
/home/quant/bin/boost_1_61_0/stage/lib/libboost_unit_test_framework.so
/home/quant/bin/boost_1_61_0/stage/lib/libboost_system.so
/home/quant/bin/boost_1_61_0/stage/lib/libboost_log.so
/home/quant/bin/boost_1_61_0/stage/lib/libboost_log_setup.so
/home/quant/bin/boost_1_61_0/stage/lib/libboost_filesystem.so
-Wl,-rpath,/home/quant/bin/boost_1_61_0/stage/lib
As you can see, I am linking against boost_filesystem and boost_system, so it's not the same problem as referenced on this SO post (and the many others like it).
I am using boost 1.61, which I compiled with gcc 5.3 (the same compiler as the one I'm compiling my program with).
What am I doing wrong?
I had a similar issue, this could be because of a new ABI which is introduced from gcc 5.1.
https://github.com/openframeworks/openFrameworks/issues/4203
I fixed mine by adding "add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0)" to CMakeLists.txt
The following library files exist:
cls /usr/local/Cellar/boost/1.51.0/lib $ ls libboost_program*
libboost_program_options-mt.a libboost_program_options-mt.dylib
I include the following header with #include <boost/program_options.hpp>:
cls /usr/local/Cellar/boost/1.51.0/include $ ls boost/program_options.hpp
boost/program_options.hpp
I try to link the libraries with
-lboost_program_options-mt
-L/usr/local/Cellar/boost/1.51.0/lib
(I assume that the name of the library is derived from the file name minus the "lib" and the file ending. If I try the name boost_program_options (without -mt), I get ld: library not found for -lboost_program_options)
This is my main function using the library:
#include <boost/program_options.hpp>
#include <iostream
int main(int argc, char **argv) {
namespace opts = boost::program_options;
opts::options_description desc("EnsembleClustering options");
desc.add_options()
("hello", "produce greeting");
opts::variables_map vmap;
opts::store(opts::parse_command_line(argc, argv, desc), vmap);
opts::notify(vmap);
if (vmap.count("hello")) {
std::cout << "Hello World" << std::endl;
}
}
Why does this setup give me a symbol(s) not found error?
make all
Building target: EnsembleClustering-DPar
Invoking: MacOS X C++ Linker
/usr/local/bin/g++-4.7 -L"/Users/cls/workspace/STINGER/OpenMP Debug" -L"/Users/cls/workspace/gtest/lib" -L/usr/local/Cellar/log4cxx/0.10.0/lib -L/usr/local/Cellar/boost/1.51.0/lib -fopenmp -std=c++11 -o "EnsembleClustering-DPar" ./src/scoring/EdgeScoring.o ./src/scoring/ModularityScoring.o ./src/overlap/test/OverlapGTest.o ./src/overlap/Overlapper.o ./src/overlap/RegionGrowingOverlapper.o ./src/matching/Matcher.o ./src/matching/Matching.o ./src/matching/ParallelMatcher.o ./src/io/test/InputGTest.o ./src/io/CSVWriter.o ./src/io/GraphFromAdjacencies.o ./src/io/GraphIO.o ./src/io/GraphReader.o ./src/io/METISGraphReader.o ./src/io/METISParser.o ./src/io/METISToGraph.o ./src/graph/test/GraphGTest.o ./src/graph/test/STINGERGTest.o ./src/graph/Graph.o ./src/graph/GraphGenerator.o ./src/ensemble/test/EnsembleGTest.o ./src/ensemble/EnsembleClusterer.o ./src/coarsening/test/CoarseningGTest.o ./src/coarsening/ClusterContracter.o ./src/coarsening/ClusteringProjector.o ./src/coarsening/Contracter.o ./src/coarsening/GraphContraction.o ./src/coarsening/MatchingContracter.o ./src/clustering/test/ClusteringGTest.o ./src/clustering/base/Clustering.o ./src/clustering/base/ClusteringGenerator.o ./src/clustering/base/Modularity.o ./src/clustering/base/QualityMeasure.o ./src/clustering/algo/test/ClusteringAlgoGTest.o ./src/clustering/algo/Clusterer.o ./src/clustering/algo/LabelPropagation.o ./src/clustering/algo/ParallelAgglomerativeClusterer.o ./src/aux/test/AuxGTest.o ./src/aux/Noise.o ./src/aux/RandomInteger.o ./src/aux/RandomProbability.o ./src/aux/Timer.o ./src/EnsembleClustering.o -lSTINGER -lgtest -llog4cxx -lboost_program_options-mt
Undefined symbols for architecture x86_64:
"boost::program_options::detail::cmdline::cmdline(std::__debug::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&)", referenced from:
boost::program_options::basic_command_line_parser<char>::basic_command_line_parser(int, char const* const*) in EnsembleClustering.o
ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status
make: *** [EnsembleClustering-DPar] Error 1
EDIT: Checking the library files with lipo gives
cls /usr/local/Cellar/boost/1.51.0/lib $ lipo -detailed_info libboost_program_options-mt.a libboost_program_options-mt.dylib
input file libboost_program_options-mt.a is not a fat file
input file libboost_program_options-mt.dylib is not a fat file
Non-fat file: libboost_program_options-mt.a is architecture: x86_64
Non-fat file: libboost_program_options-mt.dylib is architecture: x86_64
I'd like to link the static library.
Read the error message
Undefined symbols for architecture x86_64:
"boost::program_options::detail::cmdline::cmdline(std::__debug::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&)", referenced from:
boost::program_options::basic_command_line_parser<char>::basic_command_line_parser(int, char const* const*) in EnsembleClustering.o
It very clearly says, missing symbol std::__debug::vector, note that the std::__debug namespace is key here. I suspect you've built your source code using iterator debugging with -D_GLIBCXX_DEBUG but are attempting to link against a library that hasn't, such as boost program options. You didn't show us how you built your translation units, so here is a sscce:
$ g++-4.8 -std=c++11 -O2 -pthread main.cpp -D_GLIBCXX_DEBUG -lboost_program_options && ./a.out
/tmp/cca1jwUx.o: In function `boost::program_options::basic_command_line_parser<char>::basic_command_line_parser(int, char const* const*)':
main.cpp:(.text._ZN5boost15program_options25basic_command_line_parserIcEC2EiPKPKc[_ZN5boost15program_options25basic_command_line_parserIcEC5EiPKPKc]+0x319): undefined reference to `boost::program_options::detail::cmdline::cmdline(std::__debug::vector<std::string, std::allocator<std::string> > const&)'
collect2: error: ld returned 1 exit status
There are a few ways to solve this
remove the -DGLIBCXX_DEBUG flag from translation units including the program options headers.
consult your boost package maintainer to see if they offer a version built with -D_GLIBCXX_DEBUG. Some variants on Linux do, you might ask around the MacPorts or brew users mailing lists.
Since you're specifying the location for includes, libraries and providing the appropriate .dylib, the only problem I can think of is that the library that you're linking to doesn't have an x86_64 arch in it.
Try checking the library with either file or lipo. If it doesn't show x86_64, then that's the problem.
I am trying to use a template class and when I compile it in one file in LWS it works:
(Link is dead)
~http://liveworkspace.org/code/a9c412a7e683439dfa35a9363749369d~
But when I try to compile it made-up of 3 files,
stack.h lines 4 to 21
stack.cpp lines 24 to 48
main.cpp lines 49 to end
When I try to compile those 3 files I get
Undefined symbols for architecture x86_64:
"Stack2<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >::push(Node**, std::basic_string<char, std::char_traits<char>, std::allocator<char> >)", referenced from:
_main in ccCoizCT.o
"Stack2<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >::top(Node*&)", referenced from:
_main in ccCoizCT.o
"Stack2<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >::pop(Node*&)", referenced from:
_main in ccCoizCT.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
Yes I have included stack.h in a stack.cpp and main.cpp files
Sounds like you need to place the template definitions of stack back in the header file. Templates form a plan for code generation, so if the compiler can't see the entire template definition and only sees the declaration, code for that specific instantiations of the template will not be generated. It will simply trust the declaration and expect that at link time there exists an objects file with the instantiations of those templates. The solution to this is 1) keep the template definitions in the header file or 2) pre-generate the required definitions so the linker can find them at link time.
See here:
Template issue causes linker error (C++)
Getting this error while compiling C++ code:
undefined reference to `__stack_chk_fail'
Options already tried:
added -fno-stack-protector while compiling - did not work, error persists
added a dummy implementation of void __stack_chk_fail(void) in my code. Still getting the same error.
Detailed Error:
/u/ac/alanger/gurobi/gurobi400/linux64/lib/libgurobi_c++.a(Env.o)(.text+0x1034): In function `GRBEnv::getPar/u/ac/alanger/gurobi/gurobi400/linux64/lib/libgurobi_c++.a(Env.o)(.text+0x1034): In function `GRBEnv::getParamInfo(GRB_StringParam, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&)':
: undefined reference to `__stack_chk_fail'
amInfo(GRB_StringParam, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&)':
: **undefined reference to `__stack_chk_fail'**
Earlier, I was getting 10's of such errors. Found out that there was a version mismatch between the gcc of the pre-compiled libraries I am using and the gcc version I was using to compile the code. Updated gcc and now I am getting only 2 of these errors.
Any help, please?
libgurobi_c++.a was compiled with -fno-stack-protector (obviously).
A few things come to mind:
add -fstack-protector when linking. This will make sure that libssp gets linked.
Manually link -lssp
Make your dummy version of __stack_chk_fail(void) in it's own object file and and add this .o file to your linker command AFTER libgurobi_c++.a. GCC/G++ resolves symbols from left to right during linking so despite your code having the function defined, a copy of an object containing the __stack_chk_fail symbol needs to be on the linker line to the right of libgurobi_c++.a.
In gentoo I had the same problem and i resolved creating 2 files. The first contain the option to be parsed by emerge and passed to gcc:
/etc/portage/env/nostackprotector.conf
CFLAGS="-fno-stack-protector -O2"
And the second tells which package should use this settings:
/etc/portage/package.env/nostackprotector
x11-libs/vte nostackprotector.conf
sys-libs/glibc nostackprotector.conf
www-client/chromium nostackprotector.conf
app-admin/sudo nostackprotector.conf
Just had the same issue: c++ code with an implementation of void __stack_chk_fail(void) showing several undefined reference to __stack_chk_fail errors when compiling.
My solution was to define __stack_chk_fail(void) as extern "C":
extern "C" {
__stack_chk_fail(void)
{
...
}
}
This suppressed the compilation error :)
Hope it helps!
https://wiki.ubuntu.com/ToolChain/CompilerFlags
says:
"Usually this is a result of calling ld instead of gcc during a build to perform linking"
This is what I encountered when modified the Makefile of libjpeg manually. Use gcc instead of ld solved the problem.