I have a cmake project and i'm using qtcreator 4.5 to develop on a Ubuntu environment. Right now i try to use the TBB library to parallelize my code but i get this error on compilation:
/usr/include/tbb/parallel_for.h:87: error: undefined reference to `tbb::task_group_context::~task_group_context()'
From what i understand I'm not linking my TBB library, is that the problem ? If yes, how to do so ?
EDIT 1: I installed TBB trough the command sudo apt-get install libtbb-dev, so i am not sure where it is installed, but there is a libtbb.so in /usr/lib/x86_64-linux-gnu, is that it ?
EDIT 2: I founded the solution, I didn't have to go through th cmake files because I am adding the library path through Qtcreator. I founded the lib in /usr/include.
So, if you have the same problem you can link your library by going to projects section in Qtcreator, the find TBB in the window and give the path of your lib.
I do not know if you have installed the developnment lib in your Ubuntu:
sudo apt-get install libtbb-dev
The next step should be link in the .pro file against the tbb lib (-ltbb)
In my case, also I am working "indirectly" with tbb lib and I am setting the next lines in my .pro file for a static compilation:
## OTHER LIBS
LIBS += -L/myopencvpath/share/OpenCV/3rdparty/lib
LIBS += -lIlmImf -lippicv -llibjasper -llibjpeg -llibpng -llibtiff -ltbb -lzlib
Also this entry could help you: how to get Threaded Building Blocks working in Ubuntu 14.04
I hope this helps you.
EDIT1: I am so far away of being a cmake expert, but you could try something like this:
IF ( USE_TBB )
MESSAGE( STATUS "Including TBB on MyLib build" )
FIND_PACKAGE( tbb REQUIRED )
LINK_DIRECTORIES( ${LIBRARYPATH} )
ENDIF ()
Related
I'm totally confused and in need of help from someone who has created C++ shared library that will work on any platform using any IDE.
What i have done so far:
1) Created a shared library using cmake in Ubuntu.
2) Transferred source files and Makefile (cmake) to MacOSX (El Capitan)
3) Created the build directory
4) Using Terminal in Mac OS, i ran :
$ cmake ..
$ sudo make install
5) Created an Xcode iOS Project that support armv7 and arm64 architectures
6) Used header search path and library search path to find the headers and library i had installed in
/usr/local/include/
and
/usr/local/lib
7) Used one of the included one of the library header file in main.mm (renamed main.m) and created an object for the class
8) Build the project gives me error because of following reason
ld: warning: ignoring file /usr/local/lib/libMyLibrary.dylib, file was built for x86_64 which is not the architecture being linked (arm64): /usr/local/lib/libMyLibrary.dylib
Here are the contents of my cmake
cmake_minimum_required(VERSION 2.8)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -lsqlite3")
#Adding source files
file(GLOB SOURCES "src/*.cpp")
#Generate the shared library from the sources
add_library(MyLibraryName SHARED ${SOURCES})
target_compile_options(MyLibraryFolder PRIVATE -std=c++11 -lsqlite3)
add_executable(MyLibraryName ${SOURCES})
target_link_libraries(MyLibraryName PRIVATE -lsqlite3)
#Set the location for library installation. Use "sudo make install" to apply
install(TARGETS MyLibraryName DESTINATION /usr/local/lib)
install(DIRECTORY inc/${MyLibraryName_CPP} DESTINATION /usr/local/include)
Can anyone help me with this, Please...
In your step 4, you're compiling the library on MacOS, which is x86_64; you can NOT just copy it to iOS's project, because iOS uses arm64.
So you should cross-compile the library for arm64 and use it for your iOS project.
I installed boost 1.60 via brew on OS X, El Capitan 10.11.4
> brew install boost
==> Downloading https://homebrew.bintray.com/bottles/boost-1.60.0_1.el_capitan.bottle.tar.gz
######################################################################## 100.0%
==> Pouring boost-1.60.0_1.el_capitan.bottle.tar.gz
🍺 /usr/local/Cellar/boost/1.60.0_1: 11,139 files, 436.0M
However, it's not easy to use <boost/...> in my clang tool chains. It simply can't find the boost directory.
> make
Scanning dependencies of target foo
[ 50%] Building CXX object CMakeFiles/foo.dir/foo.cpp.o
foo.cpp:16:10: fatal error: 'boost/type_index.hpp' file not found
#include <boost/type_index.hpp>
^
1 error generated.
I know that I have to set some environment variables or add -I. But I'd like to see the best way to resolve this problem for boost.
From the descriptions, I think there are two possible solutions for your problem
Install boost locally somewhere and set BOOST_ROOT variable to that folder.
Update boost's include and libraries variables to corresponding boost brew's directories.
Below is is the code segment that you need to add to your CMakeLists.txt
set(Boost_NO_SYSTEM_PATHS TRUE)
if (Boost_NO_SYSTEM_PATHS)
set(BOOST_ROOT "${ROOT_DIR}/")
set(BOOST_INCLUDE_DIRS "${ROOT_DIR}/include")
set(BOOST_LIBRARY_DIRS "${ROOT_DIR}/lib")
endif (Boost_NO_SYSTEM_PATHS)
After searching everywhere I could not find anything or anyone to help me figure out how to add GL GLEW and SDL2 Libraries to my CMakeLists.txt. I am using Ubuntu 14.04 LTS and I installed the following libraries with
sudo apt-get install libsdl2-dev #for SDL-2
sudo apt-get install libgl-dev #for GL
sudo apt-get install libglew-dev #for GLEW
This all worked great, and i was able to compile in g++ with this commmand
g++ ./main.cpp ./display.h ./display.cpp ./shader.cpp ./shader.h -l SDL2 -l GL -l GLEW
Now I need to switch to CMake Compiler and I have no clue how to add the libraries GL, GLEW, and SDL2 to the CMakeLists.txt.
The way to include the libraries depends on a few things. Some packages such as sdl2 have pkgconfig files that define the libraries and includes to use.
Cmake comes with a FindPkgConfig module that can get it for you.
For example:
include(FindPkgConfig)
pkg_check_modules(SDL2 REQUIRED sdl2)
target_link_libraries(executablename ${SDL2_LIBRARIES})
You can also manually add them with the target_link_libraries function.
Other packages have "Find" modules like GLEW: /usr/share/cmake-*/Modules/FindGLEW.cmake
CMake has lots of great docs in the man pages, and on their wiki as #Mikael Persson mentioned.
I want to compile an example code from this site (at the bottom). I downloaded GLFW 3.0.4 source code and I built it in a custom location. I used a default settings and GLFW was built as a static library. My CMakeLists.txt looks like this:
cmake_minimum_required(VERSION 2.8)
project(glfw_test_project)
SET(CMAKE_CXX_FLAGS "-Wall -Werror -g -std=c++11")
find_package(OpenGL REQUIRED)
include_directories(/home/user/MyLibs/OpenGL/glfw-3.0.4/include)
link_directories(/home/user/MyLibs/OpenGL/glfw-3.0.4/build/src)
add_executable(glfw_test main.cpp)
target_link_libraries(glfw_test ${OPENGL_gl_LIBRARY})
target_link_libraries(glfw_test glfw3)
When I run make I get following info:
Linking CXX executable glfw_test
/usr/bin/ld: /home/user/MyLibs/OpenGL/glfw-3.0.4/build/src/libglfw3.a(x11_clipboard.c.o): undefined reference to symbol 'XConvertSelection'
//usr/lib/x86_64-linux-gnu/libX11.so.6: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
make[2]: *** [glfw_test] Error 1
make[1]: *** [CMakeFiles/glfw_test.dir/all] Error 2
make: *** [all] Error 2
What is wrong ?
Edit1
When I build GLFW as a dynamic library everything works fine. Then the last line in my CMakeLists.txt have to be replaced with:
target_link_libraries(glfw_test glfw)
What is wrong when using a static library ?
I experienced the same problems on Ubuntu 14.04 LTS.
First: error adding symbols: DSO missing from command line shows a wrong order of linker command line parameters. This post made me realise that. You need to call $ make VERBOSE=1 to see the linker call and check it with your own eyes. Remember: TARGET_LINK_LIBRARIES() should be the last command in your CMakeLists.txt And have a look at this order explanation.
Second: if you build against static GLFW3 libraries all the X11 libraries are not automatically added to your linker call, as atsui already showed above. In the GLFW-Documentation you can find a cmake variable which should fit your needs: ${GLFW_STATIC_LIBRARIES}. To make use of it and enable a more automatic build process, let pkg-config find all dependencies for X11 libs:
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
PROJECT(myProject)
FIND_PACKAGE( PkgConfig REQUIRED )
pkg_search_module( GLFW3 REQUIRED glfw3 ) # sets GLFW3 as prefix for glfw vars
# now ${GLFW3_INCLUDE_DIR}, ${GLFW3_LIBRARIES} and ${GLFW3_STATIC_LIBRARIES}
# are set
INCLUDE_DIRECTORIES( ${GLFW3_INCLUDE_DIR} )
ADD_EXECUTABLE( myProject mySource.cpp )
TARGET_LINK_LIBRARIES( myProject ${GLFW_STATIC_LIBRARIES} )
# they include X11 libs
Now check the linker lib parameters again with $ make VERBOSE=1 and you should find many more X11 libs like:
-lXrandr -lXi -lXrender -ldrm -lXdamage -lXxf86vm -lXext -lX11 and -lpthread.
Third: when linking against the shared library, the dependencies to X11 etc. are resolved dynamically. That is why you don't need to explicitly add X11 lib flags to the linker. In that case you only need:
TARGET_LINK_LIBRARIES( myProject ${GLFW_LIBRARIES} )
Fourth: it happened to me, that some glfwCommands had undefined reference to - linker errors. I found out, that I installed GLFW3 in /usr/local/lib but the linker was given only the LD_LIBRARY_PATH environment variable which was only set to /usr/lib32. Adding the parameter -L/usr/local/lib solved the reference problem. To avoid it in future I've set LD_LIBRARY_PATH=/usr/lib32;/usr/local/lib;.
Hint: to check what values are in your GLFW cmake variables, print them during build:
FOREACH(item ${GLFW3_STATIC_LIBRARIES})
MESSAGE(STATUS " using lib: " ${item})
ENDFOREACH()
It seems that you resolved your own issue by rebuilding GLFW as a shared library and linking the example code with that. Instead, I'll try to answer your followup question about why it doesn't work when you try to link the static library.
Basically, if you want to link against the static library libglfw3.a, you need to link all of the dependent X11 libraries. You get an error linking the static library because you didn't specify any additional libraries to link, and CMake doesn't know what these dependencies are. You don't get an error when you link the shared library libglfw.so because the X11 libraries are linked to the shared library, and CMake knows to pull those in for you automatically.
If you want to use the static library, you can determine the necessary libraries to link as follows. According to the .pc file in GLFW, you can type this in the command-line to find out what these are:
pkg-config --static --libs x11 xrandr xi xxf86vm gl
If you translate this into a CMake command, it would look like this:
target_link_libraries( glfw_test glfw3 Xrandr Xrender Xi GL m dl drm Xdamage X11-xcb xcb-glx xcb-dri2 xcb-dri3 xcb-present xcb-sync xshmfence Xxf86vm Xfixes Xext X11 pthread xcb Xau Xdmcp)
So if you add this to the CMakeLists.txt, the example code should build without an issue.
By the way, you can automatically find the X11 libraries using CMake in the following way:
find_package(X11 REQUIRED)
target_link_libraries( my_program ${X11_LIBRARIES} )
However, the set of libraries stored in the X11_LIBRARIES variable will only contain a subset of the libraries needed for statically linking GLFW.
I'm not really sure how to properly handle static/dynamic linking in CMake, but I hope this helps.
I downloaded libboost1.50-all in Raspberry Pi and has successfully compiled and execute a program using threads. Libraries were also found in CMake. I then copied the libraries of the boost and its include from /usr/lib and /usr/include/boost respectively to C:\Boost such that the hierarchy becomes:
C:
-> Boost
-> lib
... files
-> include
-> boost
... files
I then used the same CMakeLists.txt and the source code but the library was not found.
NOTE: The cross compiler that I used is fully working and I was able to produce an executable with CMake in Cygwin using the std library. I even specified the location of the library and the user and the root.
Is there anything that I missed out?
cmake_minimum_required(VERSION 2.8)
set(BOOST_ROOT C:/Boost/)
set(BOOST_INCLUDEDIR C:/Boost/include/)
set(BOOST_LIBRARYDIR C:/Boost/lib/)
SET(Boost_DEBUG ON)
find_package(Boost 1.50.0 COMPONENTS thread system)
if (Boost_FOUND)
include_directories (${Boost_INCLUDE_DIRS})
add_executable (thread thread.cpp)
target_link_libraries(thread ${Boost_LIBRARIES})
endif()
Use CMAKE -GUI and then check whether your boost libraries are detected . If not then manually set in the CMAKE-GUI and configure again.
TEMPORARY SOLUTION that I was able to come up to!
I placed the boost lib and include to where the cross compiler is installed since the cross compile was able to link the source code to libstdc++.
The library is placed here:
C:\cygwin\opt\cross\x-tools\arm-unknown-linux-gnueabi\arm-unknown-linux-gnueabi\sysroot\lib
The include files are placed here:
C:\cygwin\opt\cross\x-tools\arm-unknown-linux-gnueabi\arm-unknown-linux-gnueabi\include\c++\4.6.3
The CMakeLists content is as follows now:
cmake_minimum_required(VERSION 2.8)
add_executable (thread main.cpp)
target_link_libraries(thread boost_thread boost_system)
Open Cygwin terminal and invoke cmake there, then make. Viola! It now compiles successfully! :>
The magic lies in here:
target_link_libraries(thread boost_thread boost_system)
I found this in one of the questions here in Stackoverflow where someone said to manually link the libraries..
Even though that it worked, why is it that CMake cannot detect the boost library both in Windows (Cygwin terminal) and Linux (VMware) -- These I tried -- but the library was found in Raspberry Pi (Raspbian) using the same CMakeLists.txt and main.cpp. Isn't it the purpose of CMake is to find the libraries itself? If I were just to link them manually, better do it like this then:
arm-unknown-linux-gnueabi-g++.exe -lboost_thread -lboost_system