when I use CMakeLists.txt with:
find_library(cryptoppV libcryptopp.a)
target_link_libraries(${PROJenter code hereECT_NAME} ${cryptoppV})
then i can find a library under /usr/local/lib,and make the C++ programe right and got the right result.
but when i replace it with:
-- find_library(cryptoppV libcryptopp.a)
target_link_libraries(${PROJECT_NAME} cryptopp)
then i got the error message:
ld: library not found for -lcryptopp
why cmake do not link /usr/local/lib by default? did i do something wrong?
-- add by aijinsong Oct 7, 2018 6:37 AM
i'm in more confused. when the CMakeLists.txt was:
set(SOURCE_FILES main.cpp)
add_executable(${PROJECT_NAME} ${SOURCE_FILES})
find_package(Boost 1.58 REQUIRED thread)
target_link_libraries(${PROJECT_NAME} Boost::thread)
find_library(cryptoppV libcryptopp.a)
target_link_libraries(${PROJECT_NAME} ${cryptoppV})
the compiler can find cryptopp/sha.h. but when the CMakeLists.txt was:
set(SOURCE_FILES main.cpp)
add_executable(${PROJECT_NAME} ${SOURCE_FILES})
## find_package(Boost 1.58 REQUIRED thread)
## target_link_libraries(${PROJECT_NAME} Boost::thread)
find_library(cryptoppV libcryptopp.a)
target_link_libraries(${PROJECT_NAME} ${cryptoppV})
the error message was:
fatal error: 'cryptopp/sha.h' file not found
#include <cryptopp/sha.h>
when the CMakeLists.txt was:
set(SOURCE_FILES main.cpp)
add_executable(${PROJECT_NAME} ${SOURCE_FILES})
find_package(Boost 1.58 REQUIRED thread)
## target_link_libraries(${PROJECT_NAME} Boost::thread)
find_library(cryptoppV libcryptopp.a)
target_link_libraries(${PROJECT_NAME} ${cryptoppV})
the error message was still:
fatal error: 'cryptopp/sha.h' file not found
#include <cryptopp/sha.h>
why i use cryptopp that the cmake ask me to link with library Boost::thread? i'm in more confused.
-- add by aijinsong Oct 7, 2018 11:56 AM
And if i use g++ main.cpp -o main -lcryptopp, i can get the right result. This shows that the library cryptopp has been installed correcttly, and g++ can find the library. why when i do it by make, it can't find the library?
-- add for KamilCuk start
-- add by aijinsong at Oct 7, 2018 3:27 PM
when i make it by make VERBOSE=1, i got the following message:
cd /Users/aijinsong/Documents/projects/com.aijs.cxx/bolochain/src && /usr/local/Cellar/cmake/3.12.3/bin/cmake -E cmake_link_script CMakeFiles/bolochain.dir/link.txt --verbose=1
and the text in link.txt is:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ -g -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk -Wl,-search_paths_first -Wl,-headerpad_max_install_names CMakeFiles/bolochain.dir/main.cpp.o -o bolochain /usr/local/lib/libboost_thread-mt.dylib -lcryptopp /usr/local/lib/libboost_chrono-mt.dylib /usr/local/lib/libboost_system-mt.dylib /usr/local/lib/libboost_date_time-mt.dylib /usr/local/lib/libboost_atomic-mt.dylib
this command cause the failure link but when i edit it like following, then c++ link command process very well:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ -g -Wl,-search_paths_first -Wl,-headerpad_max_install_names CMakeFiles/bolochain.dir/main.cpp.o -o bolochain /usr/local/lib/libboost_thread-mt.dylib -lcryptopp /usr/local/lib/libboost_chrono-mt.dylib /usr/local/lib/libboost_system-mt.dylib /usr/local/lib/libboost_date_time-mt.dylib /usr/local/lib/libboost_atomic-mt.dylib
just delete:
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk
I'm still working on this problem.
-- add for KamilCuk end
Fist, Thanks #Kamil Cuk. The argument -VERBOSE=1 was so useful that I can get more detail messages that show me what happens when I use make.
The point is that when I use cmake under OSX system. It will generate a txt be named 'link.txt' which includes commands and part of it is as the following:
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk
when I delete this part, the commands will execute right. but when I add this line, the commands execute wrong. so the point is that this line maybe limited the search path of c++. Thanks #tsyvarev . You are right, -isysroot limited the c++ linkers searches /usr/local/lib.
Second, I did't find out how to remove the line -isysroot ... generated by OSX cmake. So, I need to find another solution.
When I search more information about find_package/include_directories/target_link_libraries, I found out that find_package need a FindXXX.cmake file to help it to find out the header file and libraries of the target. So I googled a FindCyptoPP.cmake file. and in this file it find out tow vars, one hold the value of cryptopp's header directory path, and one hold the value of cryptopp's library path. Then I use include_directories/target_link_libraries as following, the problem
war solved.
find_package(CryptoPP)
include_directories(${CRYPTOPP_INCLUDE_DIRS})
target_link_libraries(${PROJECT_NAME} ${CRYPTOPP_LIBRARIES})
and then when I use make -VERBOSE = 1, I fond that the output was a little different when I use the CMakeLists.txt as following:
target_link_libraries(${PROJECT_NAME} cryptopp)
When I use three lines, the output contains a line /usr/local/lib/libcryptopp.dylib. When I use one line, the output contains a line -lcryptopp.
So, with the command line -isysroot, the command line -lcryptopp will search library under the directory defined by -isysroot, and under the directory, there is no library named cryptopp but under /usr/local/lib. But with command line /usr/local/lib/libcryptopp.dylib, it gaves the absolute path of the library, so the linkes just do the linking task and need not search. Thanks #Kamil Cuk again.
Thrid, I knew include_directories/target_link_libraries are two separate steps which one is used for include header file and one is used for link libraries.
Still, there were some problems not soled:
- how to remove -isysroot?
- how to create a FindXXX.cmake file?
- how to make /usr/local/lib as a default search directory and was it a practice way to do so?
I will continue working on them, and come back a few days or weeks later.
Related
So I'm currently trying to compile my c++-program (originally written on Linux) on windows. As it is using ncurses, I'm compiling in a cygwin-terminal, where I have the ncurses libs installed:
cygcheck -c | grep curses
libncurses++w10 6.1-1.20190727 OK
libncurses-devel 6.1-1.20190727 OK
libncursesw10 6.1-1.20190727 OK
ncurses 6.1-1.20190727 OK
Also, it's using aubio, so I downloaded and extracted the precompiled binaries to C:\aubio and added C:\aubio\bin to PATH (where the binaries and the .dll are located).
CMake works fine:
cmake -G"Visual Studio 17" ..
But when compiling with:
cmake --build . --target dissonance --config Debug
I get the following errors (among others that I can handle myself):
fatal error C1083: Datei (Include) kann nicht geöffnet werden: "aubio/aubio.h": No such file or directory
fatal error C1083: Datei (Include) kann nicht geöffnet werden: "curses.h": No such file or directory
While all libraries previously installed with conan where found, obviously, aubio and ncurses libraries are not found. My problem is that I'm mainly not 100% sure what I did wrong, is it either
CMake not being configured correctly to find the libraries on windows
or did I miss some steps when "installing" aubio and ncurses.
So my question is whether someone can either point me in the direction, where the problem might lie (is it 1. or 2.)
Or someone even spotted either a) a missing step after installing the ncurses cygwin-package or while installing the precompiled aubio package or b) something missing/ wrong in my CMakeLists.txt.
I'm assuming that the problem is quite independent of aubio and it could technically be any other precompiled library.
Here is a slightly reduced version of my CMakeList.txt (everything left out is noted):
cmake_minimum_required(VERSION 3.10)
# set the project name and version
project(dissonance VERSION 1.0)
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup()
# specify the C++ standard
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
if(APPLE)
SET(CMAKE_CXX_FLAGS "-pthread -ldl -lm")
elseif(MSVC)
SET(CMAKE_CXX_FLAGS "-pthread -ldl -lm -lncursesw -lcurses")
else()
SET(CMAKE_CXX_FLAGS "-Wall -Werror -pthread -ldl -lm -lncursesw")
endif(APPLE)
add_compile_options(-fdiagnostics-color=always)
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/bin)
# Add source files needed for tests and game
set(SRC_FILES
[ removed for readility]
)
# Add soruce files needed for game only
set(SRC_FILES_GAME
src/main.cc
${SRC_FILES}
)
include_directories(/usr/local/lib/)
link_directories(/usr/local/lib/)
add_executable(dissonance ${SRC_FILES_GAME})
target_link_libraries(dissonance PUBLIC aubio curses ncurses ${CONAN_LIBS})
target_include_directories(dissonance PUBLIC "src")
I'm aware that I don't need to include curses and ncurses in the target_link_libraries and that adding -lncursesw -lcurses to CMAKE_CXX_FLAGS is not helping (just stuff I found while searching answers, but apparently it did not work. Leaving it here so people can see).
Here's the link to the github-project, For full code access: dissonance.
EDIT: Since on Linux the aubio libraries (libaubio.so, libaubio.so.5 ...) are located at /usr/share/lib/, which is (obviously not the case in Windows), I changed the following lines:
include_directories(/usr/local/lib/)
link_directories(/usr/local/lib/)
to now point to the locations where aubio and ncurses are:
include_directories(C:/cygwin64/lib/ C:/aubio/bin/)
link_directories(C:/cygwin64/lib/ C:/aubio/bin/)
However, this didn't change anything :D
I am trying to build an executable, and to change the link for boost library to static. The codes that I am trying to compile is here.
I am using Xubuntu 14.04, cmake 3.5.1, boost 1.54.
The error I got is:
Linking CXX shared library ../../lib/librexd.so
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/libboost_system.a(error_code.o): relocation R_X86_64_32 against `.rodata.str1.1' can not be used when making a shared object; recompile with -fPIC
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/libboost_system.a: error adding symbols: Bad value
Things I have done:
Set boost library to static link in CMakeLists.txt (an example):
set(Boost_USE_STATIC_LIBS ON)
FIND_PACKAGE(Boost 1.46.0 COMPONENTS system regex program_options thread filesystem REQUIRED)
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS})
TARGET_LINK_LIBRARIES(rexd ${Boost_LIBRARIES})
There are alot of CMakeLists.txt, so I did the above for 3 of them that uses Boost.
Next, I set the compiler flag to -fPIC for CMAKE_CXX_FLAGS and CMAKE_CXX_FLAGS_DEBUG, for example:
SET (CMAKE_CXX_FLAGS "-D_REENTRANT -fpic")
SET (CMAKE_CXX_FLAGS_DEBUG "-g -Wall -fpic")
Again, I did it for all CMakeLists that have CMAKE_CXX_FLAGS and CMAKE_CXX_FLAGS_DEBUG variables.
Lastly, I recompile boost with -fPIC option. I downloaded boost.tar.gz from sourceforge, extract it, and ran this:
bjam clean
bjam -d+2 link=static cxxflags="-fPIC" install
However, this does not seem to change anything. the date modification for libboost_system.a is dated a few years ago.
I have tried to tinker with add_library, making this static
ADD_LIBRARY(rexd STATIC ${sources_symbolic} ${sources_parsers} ${sources_lfit} ${sources_teacher} ${sources_rexd} ${sources_ippc_planner})
I got this error instead where it couldn't find a header .h:
No such file or directory
How should I proceed? I apologize if this question is too specific for my use case, but I can't find any other answers out there that I haven't tried.
I'm trying to link a C++ project to the RCpp library; the file is called Rcpp.so, not the linux-default libRcpp.so. Furthermore, the library resides at the non-standard location /usr/lib/R/site-library/Rcpp/libs.
So I tried using a combination of find_library and target_link_libraries:
cmake_minimum_required(VERSION 3.8)
project("R-Tests")
find_library(RCPP
NAMES Rcpp.so
HINTS /usr/lib/R/site-library/Rcpp/libs
)
if (NOT RCPP)
message(FATAL_ERROR "Could not find Rcpp - exiting.")
else()
message("Found Rcpp: " ${RCPP})
endif()
# test target
add_executable(rcpptest main.cpp)
target_link_libraries(rcpptest ${RCPP})
Configuring works fine, CMake outputs:
Found Rcpp: /usr/lib/R/site-library/Rcpp/libs/Rcpp.so
However, during build, CMake passes -lRcpp to the compiler, which causes the compilation to fail, since the library file is not named libRcpp.so but instead Rcpp.so:
[100%] Linking CXX executable rcpptest
/usr/bin/cmake -E cmake_link_script CMakeFiles/rcpptest.dir/link.txt --verbose=1
c++ CMakeFiles/rcpptest.dir/main.cpp.o -o rcpptest -L/usr/lib/R/site-library/Rcpp/libs -Wl,-rpath,/usr/lib/R/site-library/Rcpp/libs -lRcpp
/usr/bin/ld: cannot find -lRcpp
collect2: error: ld returned 1 exit status
Since the message line prints the full path to the Rcpp.so file just fine, is there any way to let target_link_libraries just add this path to the compiler instead of a combination of -L and -l?
According to this question, this should be disabled by adding cmake_policy(SET CMP0060 NEW); however, I can't see any change in the behavior of CMake if I set this to NEW or OLD.
You may have been bitten by the OLD (default) behavior of CMP0060, which converts absolute paths back to -lfoo.
Alternatively, define and use an IMPORTED target:
add_library(Rcpp SHARED IMPORTED)
set_property(TARGET Rcpp PROPERTY IMPORTED_LOCATION /usr/lib/R/site-library/Rcpp/libs/Rcpp.so)
target_link_libraries(rcpptest Rcpp)
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 use this line to compile a simple program:
g++ main.cc -lntl -lm -lgmp
How do you include this into CMake?
find_package(NTL REQUIRED)
find_package(GMP REQUIRED)
Doesn't work. And gives the following error:
CMake Error at CMakeLists.txt:30 (find_package):
Could not find module FindNTL.cmake or a configuration file for package
NTL.
...
.
and
SET(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} -std=c++0x -lntl -lm -lgmp)
Doesn't work either (but I think it's just wrong in general).
Thank you!
If ntl, m, and gmp libraries are usually installed to somewhere in the default path (e.g. /usr/ or /usr/local/), you could simply do something like:
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
project(Test)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
add_executable(test main.cc)
target_link_libraries(test ntl m gmp)
This is probably closest to your original g++ command, but it isn't very robust however; if any of the libraries aren't found, you won't know about it until you try linking. If you want to fail at configure time (i.e. while running CMake), you could add find_library calls for each of the required libs, e.g.
find_library(NTL_LIB ntl)
if(NOT NTL_LIB)
message(FATAL_ERROR "ntl library not found. Rerun cmake with -DCMAKE_PREFIX_PATH=\"<path to lib1>;<path to lib2>\"")
endif()
You'd then have to change your target_link_libraries command to
target_link_libraries(test ${NTL_LIB} ${M_LIB} ${GMP_LIB})
You'd probably also then have to do a find_file for one of each lib's header files to find out the appropriate path to add via the include_directories command (which translates to -I for g++).
Note, it's important to put quotes around the extra CXX_FLAGS arguments, or CMake treats them like separate values in a list and inserts a semi-colon between the flags.
For further information about find_library, find_file, etc. run:
cmake --help-command find_library
cmake --help-command find_file
Regarding your error:
It doesn't look like there's a FindNTL.cmake module included with CMake. That means you'll have to either:
Write your own FindNTL.cmake,
Find another that somebody else has written,
Hack together a solution that:
Checks if NTL is installed
Provides link targets, relevant flags, etc.
From a (rather quick) Google search, it appears somebody has an NTL module for CMake. Since NTL use GMP, you will probably need the associated GMP module for CMake. It doesn't look like a fully-featured CMake module, but it also appears to be the best thing out there (again, it was a quick Google search, and I don't use NTL).
To use, you'll want to add some things to your CMakeLists.txt:
# Let CMake know where you've put the FindNTL.cmake module.
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/build/CMake/Modules")
# Call the FindNTL module:
find_package(NTL REQUIRED)
SET(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} -std=c++0x -lntl -lm -lgmp)
Yes, this is wrong. You don't want to be setting your CXX_FLAGS with linking directives. I would use:
SET ( CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} -std=cxx0x )
to set the Cxx standard you want to use. To actually link to libraries, you'll want to:
Ensure that you've found the libraries (with the relevant find_package ( FOO ) lines)
Link those against your target, like this:
# Build the Foo executable. (Or library, or whatever)
add_executable (FooEXE ${Foo_SOURCES} )
target_link_libraries (FooEXE
${bar_LIBRARIES}
${baz_LIBRARY}
)
Please note! ${bar_LIBRARIES} and ${baz_LIBRARY} is not a typo; there's no standard way of setting the relevant libraries in the FindFOO.cmake modules, which is, in my opinion, an annoyance. If one doesn't work, try the other, or, worst case, have a look in the relevant FindFOO.cmake file (there's a bunch installed with CMake by default) to see what each one uses. With the link i provided, you can use ${NTL_LIB} and ${GMP_LIB}.