I have a C++ project based on CMake. The starting point of the project was created using cmake-init.
I am trying to add gRPC to the project. However, when using coverage flags, a linker error occurs:
build] /usr/bin/ld: CMakeFiles/demo_lib.dir/source/lib.cpp.o: warning: relocation against `_ZTVN4grpc12experimental38FileWatcherAuthorizationPolicyProviderE' in read-only section `.text._ZN4grpc12experimental38FileWatcherAuthorizationPolicyProviderC2EP34grpc_authorization_policy_provider[_ZN4grpc12experimental38FileWatcherAuthorizationPolicyProviderC5EP34grpc_authorization_policy_provider]'
[build] /usr/bin/ld: /usr/bin/ld: ../CMakeFiles/demo_lib.dir/source/lib.cpp.o: warning: relocation against `_ZTVN4grpc12experimental38FileWatcherAuthorizationPolicyProviderE' in read-only section `.text._ZN4grpc12experimental38FileWatcherAuthorizationPolicyProviderC2EP34grpc_authorization_policy_provider[_ZN4grpc12experimental38FileWatcherAuthorizationPolicyProviderC5EP34grpc_authorization_policy_provider]'
[build] /usr/bin/ld: ../CMakeFiles/demo_lib.dir/source/lib.cpp.o: in function `grpc::experimental::StaticDataAuthorizationPolicyProvider::StaticDataAuthorizationPolicyProvider(grpc_authorization_policy_provider*)':
[build] /home/toto/development/cmake-init-tuto/demo/build/coverage/vcpkg_installed/x64-linux/include/grpcpp/security/authorization_policy_provider.h:48: undefined reference to `vtable for grpc::experimental::StaticDataAuthorizationPolicyProvider'
[build] /usr/bin/ld: ../CMakeFiles/demo_lib.dir/source/lib.cpp.o: in function `grpc::experimental::FileWatcherAuthorizationPolicyProvider::FileWatcherAuthorizationPolicyProvider(grpc_authorization_policy_provider*)':
[build] /home/toto/development/cmake-init-tuto/demo/build/coverage/vcpkg_installed/x64-linux/include/grpcpp/security/authorization_policy_provider.h:73: undefined reference to `vtable for grpc::experimental::FileWatcherAuthorizationPolicyProvider'
[build] CMakeFiles/demo_lib.dir/source/lib.cpp.o: in function `grpc::experimental::StaticDataAuthorizationPolicyProvider::StaticDataAuthorizationPolicyProvider(grpc_authorization_policy_provider*)':
[build] /home/toto/development/cmake-init-tuto/demo/build/coverage/vcpkg_installed/x64-linux/include/grpcpp/security/authorization_policy_provider.h:48: undefined reference to `vtable for grpc::experimental::StaticDataAuthorizationPolicyProvider'
[build] /usr/bin/ld: CMakeFiles/demo_lib.dir/source/lib.cpp.o: in function `grpc::experimental::FileWatcherAuthorizationPolicyProvider::FileWatcherAuthorizationPolicyProvider(grpc_authorization_policy_provider*)':
[build] /home/toto/development/cmake-init-tuto/demo/build/coverage/vcpkg_installed/x64-linux/include/grpcpp/security/authorization_policy_provider.h:73: undefined reference to `vtable for grpc::experimental::FileWatcherAuthorizationPolicyProvider'
The thing that differs from similar questions here is that without the coverage flags, this does not happen + I do not use AuthorizationPolicy in any way. The code I am using right now is essentially what you can find in https://github.com/faaxm/exmpl-cmake-grpc
Here is the relevant flags from the CMakePresets.json:
{
"name": "flags-unix",
"hidden": true,
"cacheVariables": {
"CMAKE_CXX_FLAGS": "-Wall -Wextra -Wpedantic -Wconversion -Wsign-conversion -Wcast-qual -Wformat=2 -Wundef -Werror=float-equal -Wshadow -Wcast-align -Wunused -Wnull-dereference -Wdouble-promotion -Wimplicit-fallthrough -Wextra-semi -Woverloaded-virtual -Wnon-virtual-dtor -Wold-style-cast -Wl,--whole-archive -Wl,--allow-multiple-definition"
}
},
{
"name": "coverage-unix",
"binaryDir": "${sourceDir}/build/coverage",
"inherits": "ci-unix",
"hidden": true,
"cacheVariables": {
"ENABLE_COVERAGE": "ON",
"CMAKE_BUILD_TYPE": "Coverage",
"CMAKE_CXX_FLAGS_COVERAGE": "-Og -g --coverage -fkeep-inline-functions -fkeep-static-functions",
"CMAKE_EXE_LINKER_FLAGS_COVERAGE": "--coverage",
"CMAKE_SHARED_LINKER_FLAGS_COVERAGE": "--coverage",
"CMAKE_MAP_IMPORTED_CONFIG_COVERAGE": "Coverage;RelWithDebInfo;Release;Debug;"
}
},
Edit:
The header that is referenced is here: https://grpc.github.io/grpc/cpp/authorization__policy__provider_8h_source.html (it's only 80 lines). it does not seem to me that any pure-virtual method are not defined. Am I wrong?
This is what the source file look like: https://github.com/faaxm/exmpl-cmake-grpc/blob/master/server/src/main.cpp except that in my case, it's a void launch_server() function instead of int main(), and the actual int main() calls launch_server().
One (maybe) hint that I have is that the ServerBuilder class ('grpcpp/server_builder.h') has:
class ServerBuilder {
public:
ServerBuilder();
virtual ~ServerBuilder();
// (...)
/// NOTE: class experimental_type is not part of the public API of this class.
/// TODO(yashykt): Integrate into public API when this is no longer
/// experimental.
class experimental_type {
public:
// (...)
/// Sets server authorization policy provider in
/// GRPC_ARG_AUTHORIZATION_POLICY_PROVIDER channel argument.
void SetAuthorizationPolicyProvider(
std::shared_ptr<experimental::AuthorizationPolicyProviderInterface>
provider);
private:
ServerBuilder* builder_;
};
//(...)
private:
std::shared_ptr<experimental::AuthorizationPolicyProviderInterface>
authorization_provider_;
This is the only way that the AuthorizationPolicyProvider somehow gets into my code, through the gRPC ServerBuilder class. What should I do then?
IIRC this is related to something called Position Independent Code. You essentially have a static library that you wish to link in a shared library (this is most likely caused by the --coverage flag), you can't do that without position independent code. What you need to do is recompile the static libraries by passing -fPIC.
Then you can recompile your project and it should work.
EDIT: Here is a link to a stackoverflow question with an explanation on how to figure out if the library was compiled with -fPIC.
Related
I have the problem, that linking to stdc++fs (std::exeperimental::filesystem) is not going to work.
Essentially I have the following to invocations for my target:
target_link_libraries(${TARGETNAME} PRIVATE "c++fs" "c++experimental")
target_link_libraries(${TARGETNAME} PRIVATE MyCoreDeps)
which results in
/usr/local/opt/llvm-7.0/bin/clang++ -g -L/usr/local/opt/llvm-7.0/lib
-Wl,-rpath,/usr/local/opt/llvm-7.0/lib
-fsanitize=address
CMakeFiles/ExecutionGraphTest-ExecutionTree.dir/src/main_ExecutionTree.cpp.o
CMakeFiles/ExecutionGraphTest-ExecutionTree.dir/src/TestFunctions.cpp.o
-o ExecutionGraphTest-ExecutionTree
-Wl,-rpath,...some..paths...
../lib/libExecutionGraph-CoreForTests-dbg.so.1.0.3
../lib/libgtestd.a
../lib/libgmock_maind.a
-lc++fs -lc++experimental
../../buildExternal/install/fmt/lib/libfmt.a
../../buildExternal/install/rttr/lib/librttr_core.so.0.9.7
../../buildExternal/install/flatbuffers/lib/libflatbuffers.a
../../buildExternal/install/crossguid/lib/libcrossguid.a /usr/lib/x86_64-linux-gnu/libuuid.so
../lib/libgmockd.a
../lib/libgtestd.a
-pthread
Which fails because -lc++fs is in the middle of the link command, instead of at the end because its a static library? how can I circumvent this and why is cmake not capable of doing this right, meaning serving the linker with the correct dependencies, what I am doing wrong here?
Output:
/usr/bin/ld: ../lib/libExecutionGraph-CoreForTests-dbg.so.1.0.3: undefined reference to `std::experimental::filesystem::v1::__cxx11::path::_M_split_cmpts()'
/usr/bin/ld: ../lib/libExecutionGraph-CoreForTests-dbg.so.1.0.3: undefined reference to `std::experimental::filesystem::v1::__cxx11::path::compare(std::experimental::filesystem::v1::__cxx11::path const&) const'
Sadly, there was no error message that -lc++fs was not used. The correct naming is important: stdc++fs
target_link_libraries(${TARGETNAME} PRIVATE "stdc++fs" "c++experimental")
I am creating a simple game on linux in C++ and using FMOD for the sound. I recently downloaded the latest FMOD API however when I try to use it I get an undefined reference error. From what I can see with other related questions it usually has to do with where the -lfmod tag is when compiling, however no matter where I put that tag I still encounter problems.
I followed the Debian instructions for downloading the FMOD api and library.
https://wiki.debian.org/FMOD
However when the -I/usr/local/include -L/usr/local/lib didn't work I moved all the library and header files to local folders and adjusted accordingly.
I am using Debian on x86_64 architecture, if that helps.
I also followed these instructions here
https://www.fmod.com/docs/api/content/generated/platform_linux/basics.html
And using ldconfig I was able to verify that I do have libasound.so.2 downloaded in /usr/lib/x86_64-linux-gnu/
I am aware of this answer
C++:Undefined reference to 'FMOD:: X'
but because I am compiling using G++ and the FMOD linux libraries were compiled using GCC I don't think there should be a problem.
Here is the error I get when compiling.
g++ -c audioEngine.cpp
g++ driver.o game.o uiInteract.o uiDraw.o audioEngine.o point.o velocity.o flyingObject.o ship.o bullet.o rocks.o pause.o keyBind.o asteroid.o -I/usr/local/include -L/usr/local/lib -lfmod -lglut -lGLU -lGL
audioEngine.o: In function `Implementation::Implementation()':
audioEngine.cpp:(.text+0x67): undefined reference to `FMOD::Studio::System::create(FMOD::Studio::System**, unsigned int)'
audioEngine.cpp:(.text+0x92): undefined reference to `FMOD::Studio::System::initialize(int, unsigned int, unsigned int, void*)'
audioEngine.cpp:(.text+0xbf): undefined reference to `FMOD::Studio::System::getLowLevelSystem(FMOD::System**) const'
audioEngine.o: In function `Implementation::~Implementation()':
audioEngine.cpp:(.text+0x13b): undefined reference to `FMOD::Studio::System::unloadAll()'
audioEngine.cpp:(.text+0x151): undefined reference to `FMOD::Studio::System::release()'
audioEngine.o: In function `Implementation::advance()':
audioEngine.cpp:(.text+0x2cf): undefined reference to `FMOD::Studio::System::update()'
collect2: error: ld returned 1 exit status
makefile:21: recipe for target 'a.out' failed
make: *** [a.out] Error 1
Here are the problem areas in audioEngine.cpp
In the header file "fmod.hpp" and "fmod_studio.hpp" are included.
Implementation::Implementation()
{
mpStudioSystem = NULL;
AudioEngine::ErrorCheck(FMOD::Studio::System::create(&mpStudioSystem));
AudioEngine::ErrorCheck(mpStudioSystem->initialize(32, FMOD_STUDIO_INIT_LIVEUPDATE, FMOD_INIT_PROFILE_ENABLE, NULL));
mpSystem = NULL;
AudioEngine::ErrorCheck(mpStudioSystem->getLowLevelSystem(&mpSystem));
}
Implementation::~Implementation()
{
AudioEngine::ErrorCheck(mpStudioSystem->unloadAll());
AudioEngine::ErrorCheck(mpStudioSystem->release());
}
void Implementation::advance()
{
vector<ChannelMap::iterator> pStoppedChannels;
for (auto it = mChannels.begin(), itEnd = mChannels.end(); it != itEnd; ++it)
{
bool bIsPlaying = false;
it->second->isPlaying(&bIsPlaying);
if (!bIsPlaying)
{
pStoppedChannels.push_back(it);
}
}
for (auto& it : pStoppedChannels)
{
mChannels.erase(it);
}
AudioEngine::ErrorCheck(mpStudioSystem->update());
}
Here is the relevant part of the makefile
LFLAGS = -I./include -L./lib -lfmod -lglut -lGLU -lGL
###############################################################
# Build the main game
###############################################################
a.out: driver.o game.o uiInteract.o uiDraw.o audioEngine.o point.o velocity.o flyingObject.o ship.o bullet.o rocks.o pause.o keyBind.o asteroid.o
g++ driver.o game.o uiInteract.o uiDraw.o audioEngine.o point.o velocity.o flyingObject.o ship.o bullet.o rocks.o pause.o keyBind.o asteroid.o $(LFLAGS)
The .so library files are in a "lib" folder in the project folder where the makefile is, and the .h and .hpp files are in an "include" folder in the same place.
I realized the answer to this question moments before posting, but I spent enough time trying to figure it out I'm posing anyway for future reference if anyone else follows the Debian instructions and wonders why they get an undefined reference.
If you are including the "fmod_studio.hpp" file you also need to include the fmod studio library. Add -lfmodstudio after -lfmod and provided you have everything else right it will now compile without an undefined reference.
The solution is so obvious I feel like an idiot. Of course if I want fmodstudio I need to include the fmodstudio library! It's like I was flooring the accelerator without an engine then checking the oil.
I just made a program that compiles and runs perfectly in Visual Studio, and should be compatible with Android (uses no OS-Specific includes), but there is a red error squiggle in Android Studio under the C++ stl list begin and end iterator function (as well as compilation failing as a direct result of it). I have very little experience with cmake, and being that it is one of the only differences from VS, it seems a likely culprit.
cpp file:
void cellStats::removeAllMatches(int row, int col, int val)
{
std::list<layout>::iterator Layout = layoutListPointer.begin(); // Error here
while (Layout != layoutListPointer.end()) { // Error here
if (Layout->get(row, col) != val) {
layoutListPointer.erase(Layout);
}
else {
Layout++;
}
}
update();
}
header file:
public:
void cellStats::removeAllMatches(int row, int col, int val)
//More
private:
std::list<layout> layoutListPointer;
//more
CMakeLists.txt:
cmake_minimum_required(VERSION 3.4.1)
set (CMAKE_CXX_STANDARD 11)
include_directories(${MY_SOURCE_DIR}/src/main/cpp)
add_library(native-lib SHARED src/main/cpp/native-lib.cpp )
add_library(cellStats-class SHARED src/main/cpp/cellStats.cpp)
add_library(board-class SHARED src/main/cpp/board.cpp)
add_library(cell-class SHARED src/main/cpp/cell.cpp)
add_library(layout-class SHARED src/main/cpp/layout.cpp)
find_library( # Sets the name of the path variable.
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
log )
target_link_libraries( # Specifies the target library.
native-lib
# Links the target library to the log library
# included in the NDK.
${log-lib} )
Edit: The Error Log is:
Build command failed.
Error while executing process C:\Users\Metagross\AppData\Local\Android\Sdk\cmake\3.6.4111459\bin\cmake.exe with arguments {--build C:\Users\Metagross\AndroidStudioProjects\VoltorbFlipCalculator2\app\.externalNativeBuild\cmake\debug\x86 --target cellStats-class}
[1/2] Building CXX object CMakeFiles/cellStats-class.dir/src/main/cpp/cellStats.cpp.o
[2/2] Linking CXX shared library ..\..\..\..\build\intermediates\cmake\debug\obj\x86\libcellStats-class.so
FAILED: cmd.exe /C "cd . && C:\Users\Metagross\AppData\Local\Android\Sdk\ndk-bundle\toolchains\llvm\prebuilt\windows-x86_64\bin\clang++.exe --target=i686-none-linux-android --gcc-toolchain=C:/Users/Metagross/AppData/Local/Android/Sdk/ndk-bundle/toolchains/x86-4.9/prebuilt/windows-x86_64 --sysroot=C:/Users/Metagross/AppData/Local/Android/Sdk/ndk-bundle/sysroot -fPIC -isystem C:/Users/Metagross/AppData/Local/Android/Sdk/ndk-bundle/sysroot/usr/include/i686-linux-android -D__ANDROID_API__=21 -g -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -mstackrealign -Wa,--noexecstack -Wformat -Werror=format-security -std=c++11 -std=c++11 -O0 -fno-limit-debug-info -Wl,--exclude-libs,libgcc.a -Wl,--exclude-libs,libatomic.a -nostdlib++ --sysroot C:/Users/Metagross/AppData/Local/Android/Sdk/ndk-bundle/platforms/android-21/arch-x86 -Wl,--build-id -Wl,--warn-shared-textrel -Wl,--fatal-warnings -LC:/Users/Metagross/AppData/Local/Android/Sdk/ndk-bundle/sources/cxx-stl/llvm-libc++/libs/x86 -Wl,--no-undefined -Wl,-z,noexecstack -Qunused-arguments -Wl,-z,relro -Wl,-z,now -shared -Wl,-soname,libcellStats-class.so -o ..\..\..\..\build\intermediates\cmake\debug\obj\x86\libcellStats-class.so CMakeFiles/cellStats-class.dir/src/main/cpp/cellStats.cpp.o -latomic -lm "C:/Users/Metagross/AppData/Local/Android/Sdk/ndk-bundle/sources/cxx-stl/llvm-libc++/libs/x86/libc++_static.a" "C:/Users/Metagross/AppData/Local/Android/Sdk/ndk-bundle/sources/cxx-stl/llvm-libc++/libs/x86/libc++abi.a" && cd ."
C:\Users\Metagross\AndroidStudioProjects\VoltorbFlipCalculator2\app\src\main\cpp/cellStats.cpp:39: error: undefined reference to 'layout::get(int, int)'
C:\Users\Metagross\AndroidStudioProjects\VoltorbFlipCalculator2\app\src\main\cpp/cellStats.cpp:91: error: undefined reference to 'layout::get(int, int)'
C:/Users/Metagross/AppData/Local/Android/Sdk/ndk-bundle/sources/cxx-stl/llvm-libc++/include/memory:1687: error: undefined reference to 'layout::~layout()'
C:/Users/Metagross/AppData/Local/Android/Sdk/ndk-bundle/sources/cxx-stl/llvm-libc++/include/memory:1687: error: undefined reference to 'layout::~layout()'
C:/Users/Metagross/AppData/Local/Android/Sdk/ndk-bundle/sources/cxx-stl/llvm-libc++/include/memory:1687: error: undefined reference to 'layout::~layout()'
C:/Users/Metagross/AppData/Local/Android/Sdk/ndk-bundle/sources/cxx-stl/llvm-libc++/include/memory:1687: error: undefined reference to 'layout::~layout()'
clang++.exe: error: linker command failed with exit code 1 (use -v to see invocation)
ninja: build stopped: subcommand failed.
The problem is due to how you organized your project. You have several small shared libraries that all seems to depend on each other, but you probably don't link with them as needed.
Like the cellStats-class library depends on the layout-class library (where I assume you define all the layout class functions), but you probably don't link with it.
Unless you are going to use all the different libraries separately for different programs, I suggest you don't make libraries at all. Instead add all the sources to the main target you build.
On another note, you have undefined behavior in your code.
From this std::list::erase reference:
References and iterators to the erased elements are invalidated.
That means you can no longer use the iterator Layout once you called erase. And even if you could you never advance the iterator if the condition Layout->get(row, col) != val is true.
You need to use what erase returns:
Layout = layoutListPointer.erase(Layout);
I'm getting some strange compiler/linker errors when trying to use boost::shared_mutex. I'm using boost v1.61 on a VM running 32-bit rhel 6.2.
Code that causes error:
hpp file:
#include <boost/thread/shared_mutex.hpp>
class SharedData
{
public:
SharedData();
~SharedData();
void packMessage(std::shared_ptr<Message> s);
private:
// mutex that allows multiple read, single write protection
boost::shared_mutex m_sharedMutex;
};
cpp file:
void SharedData::packMessage(std::shared_ptr<Message> s)
{
// get shared read access
boost::shared_lock<boost::shared_mutex> lock(m_sharedMutex); // <- this line causes the errors
// read stuff here
}
make output:
CMakeFiles/tester.dir/__/src/SharedData/SharedData.cpp.o: In function `boost::detail::interruption_checker::interruption_checker(pthread_mutex_t*, pthread_cond_t*)':
/usr/local/include/boost/thread/pthread/thread_data.hpp:195: undefined reference to `boost::detail::get_current_thread_data()'
CMakeFiles/tester.dir/__/src/SharedData/SharedData.cpp.o: In function `boost::condition_variable::wait(boost::unique_lock<boost::mutex>&)':
/usr/local/include/boost/thread/pthread/condition_variable.hpp:81: undefined reference to `boost::this_thread::interruption_point()'
CMakeFiles/tester.dir/__/src/SharedData/SharedData.cpp.o: In function `boost::shared_mutex::lock_shared()':
/usr/local/include/boost/thread/pthread/shared_mutex.hpp:186: undefined reference to `boost::this_thread::disable_interruption::disable_interruption()'
/usr/local/include/boost/thread/pthread/shared_mutex.hpp:193: undefined reference to `boost::this_thread::disable_interruption::~disable_interruption()'
/usr/local/include/boost/thread/pthread/shared_mutex.hpp:193: undefined reference to `boost::this_thread::disable_interruption::~disable_interruption()'
collect2: error: ld returned 1 exit status
make[2]: *** [bin/tester] Error 1
Everywhere I've searched has said that these errors mean I need to link the boost_thread library, which I've done in my cmake file (boost_system is included for other code in this same project):
target_link_libraries(${BINARY_NAME} boost_thread boost_system)
But the errors persist.
Originally I was using the boost 1.41 libraries that were already installed on my machine. When I hit these errors I ran yum remove boost-devel and then manually installed boost 1.61 to see if that would correct the errors. Is there something extra I needed to add to the ./bootstrap.sh or ./b2 install commands? I can see libboost_thread.a in /usr/local/lib, so I assumed that meant the thread library was built correctly.
Any thoughts on what is causing these errors? Thanks!
Edit:
Cmake's log didn't have anything useful I could see, but make VERBOSE=1 gives the following output:
cd /home/craig/dev/myProject/build/test && /usr/bin/cmake -E cmake_link_script CMakeFiles/tester.dir/link.txt --verbose=1
/opt/rh/devtoolset-2/root/usr/bin/c++ -std=c++11 -ggdb -Wall -Werror -fprofile-arcs -ftest-coverage -fPIC -O0 -pedantic -Wl,--export-dynamic CMakeFiles/tester.dir/utilities/googletest/googletest/src/gtest-all.cc.o CMakeFiles/tester.dir/tester.cpp.o CMakeFiles/tester.dir/SharedData/testSharedData.cpp.o CMakeFiles/tester.dir/Common/testFifo.cpp.o CMakeFiles/tester.dir/Common/testCsu.cpp.o CMakeFiles/tester.dir/Messages/testMessage.cpp.o CMakeFiles/tester.dir/__/src/SharedData/SharedData.cpp.o CMakeFiles/tester.dir/__/src/Common/Fifo.cpp.o CMakeFiles/tester.dir/__/src/Common/Csu.cpp.o -o ../bin/tester -rdynamic -lboost_system -lpthread
CMakeFiles/tester.dir/__/src/SharedData/SharedData.cpp.o: In function `boost::detail::interruption_checker::interruption_checker(pthread_mutex_t*, pthread_cond_t*)':
/usr/local/include/boost/thread/pthread/thread_data.hpp:195: undefined reference to `boost::detail::get_current_thread_data()'
CMakeFiles/tester.dir/__/src/SharedData/SharedData.cpp.o: In function `boost::condition_variable::wait(boost::unique_lock<boost::mutex>&)':
/usr/local/include/boost/thread/pthread/condition_variable.hpp:81: undefined reference to `boost::this_thread::interruption_point()'
CMakeFiles/tester.dir/__/src/SharedData/SharedData.cpp.o: In function `boost::shared_mutex::lock_shared()':
/usr/local/include/boost/thread/pthread/shared_mutex.hpp:186: undefined reference to `boost::this_thread::disable_interruption::disable_interruption()'
/usr/local/include/boost/thread/pthread/shared_mutex.hpp:193: undefined reference to `boost::this_thread::disable_interruption::~disable_interruption()'
/usr/local/include/boost/thread/pthread/shared_mutex.hpp:193: undefined reference to `boost::this_thread::disable_interruption::~disable_interruption()'
Turns out my question is just like everyone else's.
#jww suggested I show the actual compile and link command invocation, not CMake's output, which I've added to my question. As you can see, the command is linking boost_system and pthread, but not boost_thread.
Digging into my project I realized that I had added boost_thread to my release build, but not into my unit test build, which is what I was trying to compile. Adding boost_thread to the unit test's CMakeLists.txt removed the error immediately.
I'm following this tutorial however it does not state which libaries I need to include in order to get boost to work,current options for links are:
-I/usr/include/opencv2 -I/usr/include/boost_1_55_0 -I/usr/include/boost_1_55_0/boost -O0 -g3 -Wall -c -fmessage-length=0
however this returns the following erro:
which states that it can't find asio, am I doing something wrong or was assio the wrong library to link to? Or is there any other way to find out. Note that this is my 2nd c++ project(through I have a lot of java experience) and first with the heavy use of libraries so details are somewhat required.
Removing boost/asio gave me the following errors:
make all
Building target: DisplayImage
Invoking: GCC C++ Linker
g++ -L/usr/include/opencv2 -L/usr/include/boost_1_55_0/boost -L/usr/include/boost_1_55_0 -L/usr/include/opencv2 -L/usr/lib -o "DisplayImage" ./src/Cap.o ./src/DisplayImage.o ./src/Filters.o ./src/sender.o -lopencv_imgproc -lopencv_highgui -lopencv_core
./src/sender.o: In function `__static_initialization_and_destruction_0':
/usr/include/boost_1_55_0/boost/system/error_code.hpp:222: undefined reference to `boost::system::generic_category()'
/usr/include/boost_1_55_0/boost/system/error_code.hpp:223: undefined reference to `boost::system::generic_category()'
/usr/include/boost_1_55_0/boost/system/error_code.hpp:224: undefined reference to `boost::system::system_category()'
./src/sender.o: In function `error_code':
/usr/include/boost_1_55_0/boost/system/error_code.hpp:323: undefined reference to `boost::system::system_category()'
./src/sender.o: In function `boost::asio::error::get_system_category()':
/usr/include/boost_1_55_0/boost/asio/error.hpp:224: undefined reference to `boost::system::system_category()'
collect2: ld returned 1 exit status
make: *** [DisplayImage] Error 1
Build Finished **
I use an ubuntu (x64) laptop if it matters.
Most of boost is implemented in what's called "header-only" code. Through the generous use of C++ templates, there is no actual library code to which your code needs to link. However, there are, as you've seen some actual libraries as well. Generally, the help you seek is probably here: http://www.boost.org/doc/libs/1_55_0/more/getting_started/unix-variants.html#link-your-program-to-a-boost-library
Your particular program uses the timer and system libraries and so you can probably use this command line to link your program:
g++ timer.cpp -o timer -lboost_timer -lboost_system
You can look at the bjam in boost/libs/asio/example/cpp03/tutorial/Jamfile.v2:
project
: requirements
<library>/boost/system//boost_system
<library>/boost/thread//boost_thread
<define>BOOST_ALL_NO_LIB=1
<threading>multi
<os>SOLARIS:<library>socket
<os>SOLARIS:<library>nsl
<os>NT:<define>_WIN32_WINNT=0x0501
<os>NT,<toolset>gcc:<library>ws2_32
<os>NT,<toolset>gcc:<library>mswsock
<os>NT,<toolset>gcc-cygwin:<define>__USE_W32_SOCKETS
<os>HPUX,<toolset>gcc:<define>_XOPEN_SOURCE_EXTENDED
<os>HPUX:<library>ipv6
;
You can see that they build all the tutorial steps with
-lboost_system -lboost_thread -DBOOST_ALL_NO_LIB=1
on linux