I am relatively new to C++, but I have used log4j (and it's Python clone logging). Therefore I want to use log4cxx for logging in my new C++ project.
I installed log4cxx with
brew install log4cxx
Now I need to include it in my source files. I tried, e.g.
#include "log4cxx/logger.h"
namespace EnsembleClustering {
METISGraphParser::METISGraphParser() {
// logging
log4cxx::LoggerPtr logger(log4cxx::Logger::getLogger("METISGraphParser"));
logger->setLevel(log4cxx::Level::getInfo());
this->logger = logger;
}
}
which does not seem to include enough, since this gives me the linker error
13:06:29 **** Incremental Build of configuration Debug for project EnsembleClustering ****
make all
Building file: ../src/METISGraphParser.cpp
Invoking: GCC C++ Compiler
g++ -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/METISGraphParser.d" -MT"src/METISGraphParser.d" -o "src/METISGraphParser.o" "../src/METISGraphParser.cpp"
../src/METISGraphParser.cpp: In member function 'virtual void EnsembleClustering::METISGraphParser::connectNode(EnsembleClustering::id, std::vector<unsigned int, std::allocator<unsigned int> >)':
../src/METISGraphParser.cpp:128: warning: unused variable 'deg'
../src/METISGraphParser.cpp: In member function 'virtual EnsembleClustering::Graph EnsembleClustering::METISGraphParser::parse(std::string)':
../src/METISGraphParser.cpp:112: warning: control reaches end of non-void function
Finished building: ../src/METISGraphParser.cpp
Building target: EnsembleClustering
Invoking: MacOS X C++ Linker
g++ -o "EnsembleClustering" ./src/EdgeScoring.o ./src/EdgeTripleGraphData.o ./src/EnsembleClustering.o ./src/EnsembleClusteringAlgo.o ./src/Graph.o ./src/METISGraphParser.o ./src/Matching.o ./src/Modularity.o
Undefined symbols for architecture x86_64:
"log4cxx::spi::LocationInfo::LocationInfo(char const*, char const*, int)", referenced from:
EnsembleClustering::METISGraphParser::initGraph(int, int)in METISGraphParser.o
"log4cxx::Level::getInfo()", referenced from:
EnsembleClustering::METISGraphParser::METISGraphParser()in METISGraphParser.o
EnsembleClustering::METISGraphParser::METISGraphParser()in METISGraphParser.o
"log4cxx::Level::getDebug()", referenced from:
EnsembleClustering::METISGraphParser::initGraph(int, int)in METISGraphParser.o
"log4cxx::Logger::getLogger(char const*)", referenced from:
EnsembleClustering::METISGraphParser::METISGraphParser()in METISGraphParser.o
EnsembleClustering::METISGraphParser::METISGraphParser()in METISGraphParser.o
"log4cxx::helpers::MessageBuffer::str(std::basic_ostream<char, std::char_traits<char> >&)", referenced from:
EnsembleClustering::METISGraphParser::initGraph(int, int)in METISGraphParser.o
"log4cxx::helpers::MessageBuffer::MessageBuffer()", referenced from:
EnsembleClustering::METISGraphParser::initGraph(int, int)in METISGraphParser.o
"log4cxx::helpers::MessageBuffer::~MessageBuffer()", referenced from:
EnsembleClustering::METISGraphParser::initGraph(int, int)in METISGraphParser.o
"log4cxx::helpers::MessageBuffer::operator<<(char const*)", referenced from:
EnsembleClustering::METISGraphParser::initGraph(int, int)in METISGraphParser.o
"log4cxx::helpers::ObjectPtrBase::exchange(void**, void*)", referenced from:
log4cxx::helpers::ObjectPtrT<log4cxx::Logger>::exchange(log4cxx::Logger const*)in METISGraphParser.o
"log4cxx::helpers::ObjectPtrBase::ObjectPtrBase()", referenced from:
log4cxx::helpers::ObjectPtrT<log4cxx::Logger>::ObjectPtrT()in METISGraphParser.o
"log4cxx::helpers::ObjectPtrBase::~ObjectPtrBase()", referenced from:
log4cxx::helpers::ObjectPtrT<log4cxx::Level>::~ObjectPtrT()in METISGraphParser.o
log4cxx::helpers::ObjectPtrT<log4cxx::Level>::~ObjectPtrT()in METISGraphParser.o
log4cxx::helpers::ObjectPtrT<log4cxx::Logger>::~ObjectPtrT()in METISGraphParser.o
log4cxx::helpers::ObjectPtrT<log4cxx::Logger>::~ObjectPtrT()in METISGraphParser.o
"log4cxx::helpers::CharMessageBuffer::operator<<(int)", referenced from:
EnsembleClustering::METISGraphParser::initGraph(int, int)in METISGraphParser.o
"log4cxx::Logger::isDebugEnabled() const", referenced from:
EnsembleClustering::METISGraphParser::initGraph(int, int)in METISGraphParser.o
"log4cxx::Logger::forcedLog(log4cxx::helpers::ObjectPtrT<log4cxx::Level> const&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, log4cxx::spi::LocationInfo const&) const", referenced from:
EnsembleClustering::METISGraphParser::initGraph(int, int)in METISGraphParser.o
"typeinfo for log4cxx::helpers::ObjectPtrBase", referenced from:
typeinfo for log4cxx::helpers::ObjectPtrT<log4cxx::Level>in METISGraphParser.o
typeinfo for log4cxx::helpers::ObjectPtrT<log4cxx::Logger>in METISGraphParser.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
make: *** [EnsembleClustering] Error 1
What do I need to include to get me started with log4cxx? Or do I need to explicitly link to log4cxx by modifying my Eclipse build settings? The Introduction to log4cxx isn't particularly helpful in this respect.
Here's how I managed to link log4cxx properly. Homebrew gives you a hint where it has installed the library:
cls ~/ $ brew info log4cxx
log4cxx: stable 0.10.0
http://logging.apache.org/log4cxx/index.html
Depends on: automake, libtool
/usr/local/Cellar/log4cxx/0.10.0 (182 files, 7,3M) *
https://github.com/mxcl/homebrew/commits/master/Library/Formula/log4cxx.rb
As user Component 10 has said, I need to add -L<dir>and -l<lib>to the linker line, where <dir> is /usr/local/Cellar/log4cxx/0.10.0/lib/and <lib> is the library name (not filename) log4cxx.
In Eclipse, I needed to edit the following settings:
To make this slightly simpler you can do
brew link log4cxx
It'll create the symlinks to the libraries in /usr/local/lib and /usr/local/include which are usually in the default linker/include search paths.
You'll still need to specify -llog4cxx.
Related
This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 3 years ago.
I'm not sure if I have a problem w/ requiring additional arguments to cmake, or a problem with my own Makefiles. I am trying to build and install googletest for use in one of my projects. I am running on macOS mojave, with cmake installed via Homebrew. To install googletest, I have done the following:
git clone https://github.com/google/googletest
cd googletest
mkdir build
cd build
cmake ..
make
make install
I compile my source and test files. Here is an example command that gets generated by the Makefile for compiling a file named Point2d.cpp:
clang++ -arch x86_64 -c -std=c++11 -stdlib=libc++ -O2 -I /usr/local/include -c -o ../build/core/Point2d.o core/Point2d.cpp
I then try to link all my object files. Here is the command generated by the makefile (where main.o is the object file containing the main function for running the tests):
clang++ -arch x86_64 ../build/core/Point2d.o ../build/PointTest.o ../build/main.o -o ../bin/test -L /usr/local/lib
Resulting link error:
Undefined symbols for architecture x86_64:
"testing::InitGoogleTest(int*, char**)", referenced from:
_main in main.o
"testing::Test::SetUp()", referenced from:
vtable for Point2dTests_Constructors_Test in PointTest.o
"testing::Test::TearDown()", referenced from:
vtable for Point2dTests_Constructors_Test in PointTest.o
"testing::Test::Test()", referenced from:
testing::internal::TestFactoryImpl<Point2dTests_Constructors_Test>::CreateTest() in PointTest.o
"testing::Test::~Test()", referenced from:
Point2dTests_Constructors_Test::~Point2dTests_Constructors_Test() in PointTest.o
Point2dTests_Constructors_Test::~Point2dTests_Constructors_Test() in PointTest.o
"testing::Message::Message()", referenced from:
Point2dTests_Constructors_Test::TestBody() in PointTest.o
"testing::UnitTest::GetInstance()", referenced from:
_main in main.o
"testing::UnitTest::Run()", referenced from:
_main in main.o
"testing::internal::AssertHelper::AssertHelper(testing::TestPartResult::Type, char const*, int, char const*)", referenced from:
Point2dTests_Constructors_Test::TestBody() in PointTest.o
"testing::internal::AssertHelper::~AssertHelper()", referenced from:
Point2dTests_Constructors_Test::TestBody() in PointTest.o
"testing::internal::GetTestTypeId()", referenced from:
__GLOBAL__sub_I_PointTest.cpp in PointTest.o
"testing::internal::MakeAndRegisterTestInfo(char const*, char const*, char const*, char const*, testing::internal::CodeLocation, void const*, void (*)(), void (*)(), testing::internal::TestFactoryBase*)", referenced from:
__GLOBAL__sub_I_PointTest.cpp in PointTest.o
"testing::internal::GetBoolAssertionFailureMessage(testing::AssertionResult const&, char const*, char const*, char const*)", referenced from:
Point2dTests_Constructors_Test::TestBody() in PointTest.o
"testing::internal::IsTrue(bool)", referenced from:
testing::internal::SuiteApiResolver<testing::Test>::GetSetUpCaseOrSuite(char const*, int) in PointTest.o
testing::internal::SuiteApiResolver<testing::Test>::GetTearDownCaseOrSuite(char const*, int) in PointTest.o
"testing::internal::GTestLog::GTestLog(testing::internal::GTestLogSeverity, char const*, int)", referenced from:
testing::internal::SuiteApiResolver<testing::Test>::GetSetUpCaseOrSuite(char const*, int) in PointTest.o
testing::internal::SuiteApiResolver<testing::Test>::GetTearDownCaseOrSuite(char const*, int) in PointTest.o
"testing::internal::GTestLog::~GTestLog()", referenced from:
testing::internal::SuiteApiResolver<testing::Test>::GetSetUpCaseOrSuite(char const*, int) in PointTest.o
testing::internal::SuiteApiResolver<testing::Test>::GetTearDownCaseOrSuite(char const*, int) in PointTest.o
"testing::internal::AssertHelper::operator=(testing::Message const&) const", referenced from:
Point2dTests_Constructors_Test::TestBody() in PointTest.o
"typeinfo for testing::Test", referenced from:
typeinfo for Point2dTests_Constructors_Test in PointTest.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[1]: *** [../bin/test] Error 1
make: *** [test] Error 2
Solved. Please see the comments of the question, posted by #AlexDenisov
I have read a few related answers and some articles online as well as the official Google Test documentation, but since I lack experience in this area I am very insecure about a few things and seek guidance.
I am starting a brand new pet project in c++ and I want to write proper tests as I code along, ran into Google Test and decided to give it a try.
Currently this is my folder structure:
/
/bin
/main.cpp
/lib
/lib/db
/lib/external/googletest
My idea is to have the tests and class files in their own folders, for example:
/lib/db/db.h
/lib/db/db.cpp
/lib/db/db.test
Question #1
Is there a naming convention or expectation for the file containing the tests? (/lib/db/db.test in that example above)
Question #2
I ran the following commands
cd lib/external/googletest/googletest
cmake .
make
make install
cp lib*.a /usr/local/lib
cp -r include/gtest/ /usr/local/include/
And seeing how it ended up creating a series of .h files in /usr/local/include/gtest, I expected to be able to #include <gtest/gtest.h> and be able to run tests, I added this to my main.cpp:
TEST(Param1, Param2) {
EXPECT_EQ(1, 1);
}
and when building the following error showed up:
Undefined symbols for architecture x86_64:
"testing::AssertionSuccess()", referenced from:
testing::AssertionResult testing::internal::CmpHelperEQ<int, int>(char const*, char const*, int const&, int const&) in main-230b96.o
"testing::Test::SetUp()", referenced from:
vtable for Param1_Param2_Test in main-230b96.o
"testing::Test::TearDown()", referenced from:
vtable for Param1_Param2_Test in main-230b96.o
"testing::Test::Test()", referenced from:
Param1_Param2_Test::Param1_Param2_Test() in main-230b96.o
"testing::Test::~Test()", referenced from:
Param1_Param2_Test::~Param1_Param2_Test() in main-230b96.o
"testing::Message::Message()", referenced from:
Param1_Param2_Test::TestBody() in main-230b96.o
"testing::internal::AssertHelper::AssertHelper(testing::TestPartResult::Type, char const*, int, char const*)", referenced from:
Param1_Param2_Test::TestBody() in main-230b96.o
"testing::internal::AssertHelper::~AssertHelper()", referenced from:
Param1_Param2_Test::TestBody() in main-230b96.o
"testing::internal::GetTestTypeId()", referenced from:
___cxx_global_var_init in main-230b96.o
"testing::internal::MakeAndRegisterTestInfo(char const*, char const*, char const*, char const*, testing::internal::CodeLocation, void const*, void (*)(), void (*)(), testing::internal::TestFactoryBase*)", referenced from:
___cxx_global_var_init in main-230b96.o
"testing::internal::IsTrue(bool)", referenced from:
testing::internal::scoped_ptr<std::__1::basic_stringstream<char, std::__1::char_traits<char>, std::__1::allocator<char> > >::reset(std::__1::basic_stringstream<char, std::__1::char_traits<char>, std::__1::allocator<char> >*) in main-230b96.o
testing::internal::scoped_ptr<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >::reset(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*) in main-230b96.o
"testing::internal::EqFailure(char const*, char const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool)", referenced from:
testing::AssertionResult testing::internal::CmpHelperEQFailure<int, int>(char const*, char const*, int const&, int const&) in main-230b96.o
"testing::internal::AssertHelper::operator=(testing::Message const&) const", referenced from:
Param1_Param2_Test::TestBody() in main-230b96.o
"typeinfo for testing::Test", referenced from:
typeinfo for Param1_Param2_Test in main-230b96.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
Solution
Thanks to trojanfoe I fixed my makefile to look like this:
CC=g++
target_folder=bin
all:
$(CC) *.cpp -o $(target_folder)/prod
./bin/prod
test:
$(CC) *.cpp -o $(target_folder)/test lib/external/googletest/googletest/libgtest.a lib/external/googletest/googletest/libgtest_main.a
./bin/test
clean:
rm -f $(target_folder)/* *.o
And now it works just fine, please keep in mind that this is a skeleton project and I need to structure the test files and entry point, so at this point its just compiling a basic test.
You have forgotten to link-in the google test library with your executable.
I am testing out eclipse C++ for Mac. I have three specific questions.
This is the classic iostream problem for Mac. It does not know where to find it. So in the project properties I add the path where iostream is located (Preferences->C/C++ General->Paths and Symbols->includes). Now iostream works. But I am trying to find a way where I don't have to do this for every new project. Is there a specific setting I can select to include this directory automatically for each new project?
Is xCode necessary for eclipse to work? If yes, how can I get eclipse to work without it? xCode takes up 6 GBs.
I'm getting an error on a test project (see below) that I'm not sure how to fix. Something about "linker command failed". I seem to be able to compile regular C programs fine though. Note this project works fine in Visual Studio.
23:37:30 **** Incremental Build of configuration Debug for project pointClass ****
make all
Building target: pointClass
Invoking: MacOS X C++ Linker
g++ -o "pointClass" ./point.o ./test.o
Undefined symbols for architecture x86_64:
"std::istream::operator>>(double&)", referenced from:
_main in test.o
"std::ostream::operator<<(std::ostream& ()(std::ostream&))", referenced from:
_main in test.o
Point::Point(double, double) in test.o
Point::Point(Point const&) in test.o
"std::ostream::operator<<(double)", referenced from:
_main in test.o
Point::Point(double, double) in test.o
"std::basic_string, std::allocator >::~basic_string()", referenced from:
_main in test.o
"std::ios_base::Init::Init()", referenced from:
___cxx_global_var_init in test.o
"std::ios_base::Init::~Init()", referenced from:
___cxx_global_var_init in test.o
"std::cin", referenced from:
_main in test.o
"std::cout", referenced from:
_main in test.o
Point::Point(double, double) in test.o
Point::Point(Point const&) in test.o
"std::basic_ostream >& std::endl >(std::basic_ostream >&)", referenced from:
_main in test.o
Point::Point(double, double) in test.o
Point::Point(Point const&) in test.o
"std::basic_ostream >& std::operator<< >(std::basic_ostream >&, char const)", referenced from:
_main in test.o
Point::Point(double, double) in test.o
Point::Point(Point const&) in test.o
"std::basic_ostream >& std::operator<<, std::allocator >(std::basic_ostream >&, std::basic_string, std::allocator > const&)", referenced from:
_main in test.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: *** [pointClass] Error 1
I am trying to run an opencv project by xcode6.
This tutorial is cool and works for me, first, without xcode: The application runs perfectly after make'ing.
Now, I want to use Xcode 6 as development environment.
But I get an Apple Mach-O Linker error.
Build Settings are:
Header Search Paths : /usr/local/include (non-recursive)
Library Search Paths: /urs/local/lib (non-recursive)
Build Phases > Link Binary With Libraries:
Libc++.dylib
This is the error:
Ld /Users/XXX/Library/Developer/Xcode/DerivedData/HelloWorld-ejnkjggujedpyibjbhvocitoxxaj/Build/Products/Debug/HelloWorld normal x86_64
cd /Users/XXX/Desktop/make/CLTproject/HelloWorld/HelloWorld
export MACOSX_DEPLOYMENT_TARGET=10.10
/Applications/Xcode-Beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++ -arch x86_64 -isysroot /Applications/Xcode-Beta.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk -L/Users/XXX/Library/Developer/Xcode/DerivedData/HelloWorld-ejnkjggujedpyibjbhvocitoxxaj/Build/Products/Debug -L/usr/local/lib -F/Users/XXX/Library/Developer/Xcode/DerivedData/HelloWorld-ejnkjggujedpyibjbhvocitoxxaj/Build/Products/Debug -filelist /Users/XXX/Library/Developer/Xcode/DerivedData/HelloWorld-ejnkjggujedpyibjbhvocitoxxaj/Build/Intermediates/HelloWorld.build/Debug/HelloWorld.build/Objects-normal/x86_64/HelloWorld.LinkFileList -mmacosx-version-min=10.10 -stdlib=libc++ -lc++ -Xlinker -dependency_info -Xlinker /Users/XXX/Library/Developer/Xcode/DerivedData/HelloWorld-ejnkjggujedpyibjbhvocitoxxaj/Build/Intermediates/HelloWorld.build/Debug/HelloWorld.build/Objects-normal/x86_64/HelloWorld_dependency_info.dat -o /Users/XXX/Library/Developer/Xcode/DerivedData/HelloWorld-ejnkjggujedpyibjbhvocitoxxaj/Build/Products/Debug/HelloWorld
Undefined symbols for architecture x86_64:
"cv::namedWindow(cv::String const&, int)", referenced from:
_main in main.o
"cv::GaussianBlur(cv::_InputArray const&, cv::_OutputArray const&, cv::Size_<int>, double, double, int)", referenced from:
_main in main.o
"cv::Mat::deallocate()", referenced from:
cv::Mat::release() in main.o
"cv::Mat::copySize(cv::Mat const&)", referenced from:
cv::Mat::operator=(cv::Mat const&) in main.o
"cv::String::deallocate()", referenced from:
cv::String::~String() in main.o
"cv::String::allocate(unsigned long)", referenced from:
cv::String::String(char const*) in main.o
"cv::imread(cv::String const&, int)", referenced from:
_main in main.o
"cv::imshow(cv::String const&, cv::_InputArray const&)", referenced from:
_main in main.o
"cv::waitKey(int)", referenced from:
_main in main.o
"cv::fastFree(void*)", referenced from:
cv::Mat::~Mat() in main.o
"cv::Mat::copyTo(cv::_OutputArray const&) const", referenced from:
cv::Mat::clone() const in main.o
"vtable for cv::_InputArray", referenced from:
cv::_InputArray::_InputArray() in main.o
cv::_InputArray::_InputArray(cv::Mat const&) in main.o
NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
"vtable for cv::_OutputArray", referenced from:
cv::_OutputArray::_OutputArray(cv::Mat&) 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)
Any Idea?
Thanks,
isicom
Just to give some light to everybody in the same problem. I added all libraries and worked fine for me. I stayed in the libc++ with no building errors.
I'm trying to use Poco C++ library to do the simple http requests in C++ on Mac OS X 10.8.2. I installed Poco, copy-pasted the http_request.cc code from this tutorial, ran it with 'g++ -o http_get http_get.cc -lPocoNet', but got:
Undefined symbols for architecture x86_64:
"Poco::StreamCopier::copyStream(std::basic_istream<char, std::char_traits<char> >&, std::basic_ostream<char, std::char_traits<char> >&, unsigned long)", referenced from:
_main in ccKuZb1g.o
"Poco::URI::URI(char const*)", referenced from:
_main in ccKuZb1g.o
"Poco::URI::~URI()", referenced from:
_main in ccKuZb1g.o
"Poco::URI::getPathAndQuery() const", referenced from:
_main in ccKuZb1g.o
"Poco::URI::getPort() const", referenced from:
_main in ccKuZb1g.o
"Poco::Exception::displayText() const", referenced from:
_main in ccKuZb1g.o
"typeinfo for Poco::Exception", referenced from:
GCC_except_table1 in ccKuZb1g.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
Have been struggling with this for couple of hours. Any idea how to fix this? Thanks in advance!
the Poco::URI, Poco::StreamCopier classes are in the PocoFoundation library, so you will need to link to that library also.
g++ -o http_get http_get.cc -lPocoNet -lPocoFoundation
You don't appear to have specified the include path for the library and the library to use when compiling your source.
You need to provide the -I and the -L directive to g++ to specify the include path for the library and the library itself respsectively.