This question already has answers here:
How to add "-l" (ell) compiler flag in CMake
(2 answers)
Closed 2 years ago.
In trying to link restbed with CMake I get the usual undefined function error. However, trying the exact same code linked with g++ test.cpp -o test -lrestbed works fine.
Furthermore, when I first implemented the CMakeLists.txt it also worked fine and as I added to the project it started facing issues. Now even a single restbed function is not defined.
My restbed includes are located at /usr/local/include and the shared objects to link at /usr/local/lib. Pretty standard locations.
CMakeLists.txt
cmake_minimum_required(VERSION 3.0)
project(vcar-server)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread -lrestbed")
file(GLOB CXX_EXEC "src/*.cpp")
add_subdirectory(vcar-embedded)
add_executable(vcar-server ${CXX_EXEC})
target_link_libraries(vcar-server vcar)
Do not use CMAKE_CXX_FLAGS, or rather use it as a "last resort" when configuring the build system as a user. Prefer to use object model in place of global variables. The modern cmake way would most probably be something along:
cmake_minimum_required(VERSION 3.11)
project(vcar-server)
add_subdirectory(vcar-embedded)
find_package(Threads REQUIRED)
add_executable(vcar-server ${cxx_exec})
target_link_libraries(vcar-server PUBLIC vcar restbed Threads::Threads)
set_target_properties(vcar-server PUBLIC CXX_STANDARD 20)
Related
When I was using Github Action CI, I found that no matter what method I used to link, there was no way to link pthread_create
But this error only appears in the Ubuntu environment, Windows, macOS are no problem
I tried:
Not Working
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
find_package(Threads REQUIRED)
add_executable(xxx xxx.c)
target_link_libraries(xxx PRIVATE Threads::Threads)
Not Working
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pthread")
You can view the compiled log here:
https://github.com/YuzukiTsuru/lessampler/runs/6640320037?check_suite_focus=true
If you read the build log carefully
/usr/bin/ld: CMakeFiles/GenerateAudioModelTest.dir/__/src/GenerateAudioModel.cpp.o: in function `GenerateAudioModel::GenerateModelFromFile()':
GenerateAudioModel.cpp:(.text+0x27aa): undefined reference to `pthread_create'
You notice the error has happened while linking the target GenerateAudioModelTest that is located in the directory test and CMakeLists.txt there does not have the compiler flags you shown. Just add -pthread in test/CMakeLists.txt.
This is a bad idea.
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
Use
target_compile_options(GenerateAudioModelTest PRIVATE -pthread)
See What is the modern method for setting general compile flags in CMake?
Not Working
You did not link with Thread::Thread nor any library that the target links to.
https://github.com/YuzukiTsuru/lessampler/blob/a6bb7e7d7ac30b6b4043d4f717a2d4deb7fb7638/test/CMakeLists.txt#L22
Not Working
Flags have to be set before add_executable. Which means before all the add_subdirectories. And flags have directory scope. Use targe_compile_options.
https://github.com/YuzukiTsuru/lessampler/blob/master/src/CMakeLists.txt
Consider just making it one library, why so many, and so many CMakeLists.txt in every directory. If the tools are not so separate and you are never going to use them separately, just make it one library with one CMakeLists.txt that links with all the libraries.
This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 1 year ago.
This post was edited and submitted for review 1 year ago and failed to reopen the post:
Original close reason(s) were not resolved
I have started to learn CMake framework to build cmake recently and started a dummy project to understand how it works.
My project structure is as shown in the image. The CMakeLists.txt at the root level (myapp->CMakeLists.txt) is shown below:
cmake_minimum_required(VERSION 3.20)
project(dummyCMake)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra")
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release")
endif()
set(CMAKE_CXX_FLAGS_DEBUG "-g -Wall -Wextra")
set(CMAKE_CXX_FLAGS_RELEASE "-o0")
add_subdirectory(libs)
include_directories(includes)
file(GLOB SOURCES "src/*.cpp")
add_executable(${PROJECT_NAME} ${SOURCES})
get_filename_component(parent_dir ../ ABSOLUTE)
target_link_libraries(${PROJECT_NAME} PUBLIC uiolibs)
target_link_libraries(${PROJECT_NAME} PUBLIC mathlibs)
target_include_directories(${PROJECT_NAME} PUBLIC
"${PROJECT_BINARY_DIR}"
"${PROJECT_SOURCE_DIR}/libs/uiolibs/includes"
"${PROJECT_SOURCE_DIR}/libs/mathlibs/includes"
)
sub directories CMakeLists.txt is as follows:
file(GLOB sources "src/*cpp")
message(${sources}) #for debugging
add_library(uiolibs STATIC ${sources})
Getting linking error
undefined reference to `mathlibs::AddInit(int, int)
undefined reference to `userinput::getInit()
Any suggestion to fix this issue (or in general on cmake framework) will be appreciated.
The project code folder: github link
It's good that you linked your code here because it's not a cmake problem.
using namespace userinput;
int getInit() {}
This doesn't define userinput::getInit as you expect, it just defines getInit.
I have a code with multiple files, that uses the GSL Library. When I compile the code through the terminal with the command
g++ main.cpp -lm -lgsl -lgslcblas -o Exec
This compiles and gives the correct output and no errors.
However, when I try and build the code in CLion I get the error
undefined reference to `gsl_rng_uniform'
I have linked the various .cpp files in my code through the CMakeLists.txt, but I think, I have to something similar to the flags to link to GSL.
My CMakeLists.txt file is as follows currently (only the .cpp files are included in the source files, not the .h files):
cmake_minimum_required(VERSION 3.7)
project(Unitsv1)
set(CMAKE_CXX_STANDARD 11)
set(SOURCE_FILES main.cpp
transition.cpp
random.cpp)
add_executable(Unitsv1 ${SOURCE_FILES})
I'm very new to C++, and can't seem to find any answers online.
Thanks
You haven't linked in the GSL libraries, so the linker won't find any of the symbols it provides. Something like this should get you most of the way there:
cmake_minimum_required(VERSION 3.7)
project(Unitsv1)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED YES) # See below (1)
set(SOURCE_FILES main.cpp
transition.cpp
random.cpp)
add_executable(Unitsv1 ${SOURCE_FILES})
find_package(GSL REQUIRED) # See below (2)
target_link_libraries(Unitsv1 GSL::gsl GSL::gslcblas)
If your code uses C++11, then you need the line at (1) to ensure you actually get C++11 support. Without CMAKE_CXX_STANDARD_REQUIRED YES, the CMAKE_CXX_STANDARD variable acts only as "Use it if it is available, or fall back to the closest standard the compiler can provide". You can find a detailed write-up here if you're curious.
The more important part for your question is at (2). The find_package() command looks for the GSL libraries, etc. and makes them available as import targets GSL::gsl and GSL::gslcblas. You then use target_link_libraries() to link your executable to them as shown. The CMake documentation explains how the find_package() side of things works in plenty of detail:
Start here: find_package()
Specifics for GSL: FindGSL module
Linking: target_link_libraries()
This question already has answers here:
CMake link to external library
(6 answers)
Closed 12 months ago.
I have 2 files: library.dll and library.h with some code that I need in my own project. I'm working on Windows with Clion where I should config this with CMake.
I tried this way:
cmake_minimum_required(VERSION 3.6)
project(test2)
set(CMAKE_CXX_STANDARD 11)
link_directories(C:\\Users\\Johny\\CLionProjects\\test2)
set(SOURCE_FILES main.cpp)
add_executable(test2 ${SOURCE_FILES})
target_link_libraries(test2 library.dll)
It compiled but didnt work. Returns code -1073741515
How can I handle with it?
Although this question is old. You are targeting the link library wrongly.
target_link_libraries(test2 library.dll) is wrong. This is an example linking SDL2. In the main CMakeList.txt
cmake_minimum_required(VERSION 3.12)
project(GraphicTest)
set(CMAKE_CXX_STANDARD 11)
include_directories("${PROJECT_SOURCE_DIR}/SDL")
add_subdirectory(SDL)
add_executable(GraphicTest main.cpp)
target_link_libraries(GraphicTest SDL2)
and in the library folder. Here SDL, add a CMakeLists.txt
message("-- Linking SDL")
add_library(SDL2 SDL2.dll)
set_target_properties(SDL2 PROPERTIES LINKER_LANGUAGE C)
I am new in clion. on gcc i always use:
g++ bin/obj/main.o -o bin/main -lboost_filesystem -lboost_system -lcrypto
How to do it in clion?
It seems my CMakeList does not work:
cmake_minimum_required(VERSION 3.1)
project(motion_simulation)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(SOURCE_FILES main.cpp)
add_executable(motion_simulation ${SOURCE_FILES})
link_libraries(lboost_filesystem)
link_libraries(lboost_system)
link_libraries(lcrypto)
Try including the keyword "CMake" into your search next time. This question is actually not CLion specific because CLion actually uses CMake as buildsystem.
CMake is very well documented, and you should be able to find a lot of answers regarding your problem.
You could first try to get rid of that "l":
link_libraries(boost_filesystem)
If that doesn't work you should take a look how the find_package() command works. http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries
And here is a detailed explanation how to find Boost libs and include directory.
http://www.cmake.org/cmake/help/v3.0/module/FindBoost.html
As you are using CMake 3.1 you can use some more advanced features of CMake.
With CMAKE_CXX_STANDARD you can select which C++ version you want to use and CMake will select the corresponding compiler flags (see docs).
link_libraries is one possibility, but it has to be called before add_executable or add_library. The alternative is target_link_libraries which links only to a single target, but can also manage transitive dependencies (docs).
CMake comes with find_package modules for OpenSSL and Boost to find dependencies and with the option REQUIRED, you can ensure that they are found on the system. Boost also supports COMPONENTS to select which libraries you need.
In case you ever work on a system, where OpenSSL and Boost are not installed in /usr/, you can already use target_include_directories to specify where the headers for your executable is found. Like target_link_libraries, target_include_directories can work with transitive dependencies, in this case PRIVATE.
cmake_minimum_required(VERSION 3.1)
project(motion_simulation)
set(CMAKE_CXX_STANDARD 11)
find_package(Boost REQUIRED COMPONENTS filesystem system)
find_package(OpenSSL REQUIRED)
set(SOURCE_FILES main.cpp)
add_executable(motion_simulation ${SOURCE_FILES})
target_include_directories(motion_simulation PRIVATE ${Boost_INCLUDE_DIRS} ${OPENSSL_INCLUDE_DIR})
target_link_libraries( motion_simulation PRIVATE ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES})