How to set library flags after source file in cmake? - c++

I'm trying to compile a project using hwloc with CMake. However, I get a ton of undefined reference errors when linking:
undefined reference to `hwloc_get_type_depth'
undefined reference to `hwloc_bitmap_zero'
[...]
According to this answer to a similar question the order of flags is important.
So, how can I generate a command like this in CMake? :
g++ -Wall -std=c++11 source.cpp-lhwloc
Excerpt from my CMakeLists.txt:
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++11 -lhwloc")
set(SOURCE_FILES source.cpp)
add_executable(source ${SOURCE_FILES})
Any help is greatly appreciated!
Edit: My question was proposed as a possible duplicate of this one, however the flag I wanted to add was to link against a library and not a normal compile flag as seems to be the case in the above mentioned question. #Edgar Rokyan provided the right answer for my problem.

If you need to link against hwloc library you might use target_link_libraries command:
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++11") # <== remove *-lhwloc*
set(SOURCE_FILES source.cpp)
add_executable(source ${SOURCE_FILES})
target_link_libraries(source hwloc) # <== add this line

Related

CMake undefined reference to `pthread_create` in Github Action Ubuntu image

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.

Linking GSL in CMakeLists.txt

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()

How to link compiled cmph library in my project using CMake

In order to use cmph, a perfect minimal hashing library, in my project organised using CMake, I installed cmph library in a ubuntu machine and tested it using a single c file called main.c.
If I try to compile this file using gcc 5.3.0 using the following command:
gcc main.c
I will get the following output
/tmp/ccSOH5ob.o: In function `main':
testperfect.c:(.text+0x63): undefined reference to `cmph_io_vector_adapter'
testperfect.c:(.text+0x73): undefined reference to `cmph_config_new'
testperfect.c:(.text+0x88): undefined reference to `cmph_config_set_algo'
testperfect.c:(.text+0x9b): undefined reference to `cmph_config_set_mphf_fd'
testperfect.c:(.text+0xa7): undefined reference to `cmph_new'
testperfect.c:(.text+0xb7): undefined reference to `cmph_config_destroy'
testperfect.c:(.text+0xca): undefined reference to `cmph_dump'
testperfect.c:(.text+0xd6): undefined reference to `cmph_destroy'
testperfect.c:(.text+0xe2): undefined reference to `cmph_load'
testperfect.c:(.text+0x118): undefined reference to `cmph_search'
testperfect.c:(.text+0x153): undefined reference to `cmph_destroy'
testperfect.c:(.text+0x15f): undefined reference to `cmph_io_vector_adapter_destroy'
But if I run this command:
gcc main.c $(pkg-config --libs cmph) -o main
It will be compiled and run normally.
Now I need to add a similar piece of code in my project and the CMakeList.txt is written like this:
set(PROJECT_EXECUTABLE ${PROJECT_NAME})
# Compiling flags.
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR
CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(CMAKE_CXX_FLAGS_RELEASE "-O2")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g")
set(CMAKE_CXX_FLAGS_DEBUG "-g")
set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os")
endif()
# Inject project config.
configure_file(
${PROJECT_INCLUDE_DIR}/phsim/config.hpp.in
${PROJECT_INCLUDE_DIR}/phsim/config.hpp
)
include(FindPkgConfig)
find_package(PkgConfig REQUIRED)
pkg_search_module(CMPH REQUIRED cmph)
target_link_libraries(Phsim ${CMPH_LIBRARIES})
target_include_directories(Phsim PUBLIC ${CMPH_INCLUDE_DIRS})
target_compile_options(Phsim PUBLIC ${CMPH_CFLAGS_OTHER})
# Compile executable.
file(GLOB SOURCES ${PROJECT_SRC_DIR}/*.cpp)
add_executable(${PROJECT_EXECUTABLE} ${SOURCES})
set_target_properties(${PROJECT_EXECUTABLE} PROPERTIES
VERSION ${PHSIM_VERSION_LITER}
)
And then I try to run cmake . and make, but only get the error message:
CMake Error at src/CMakeLists.txt:20 (target_link_libraries):
Cannot specify link libraries for target "Phsim" which is not built by this
project.
But I won't get target executable file unless I compile the project. If I try to compile my project without those commands related to library linking, the compiler will give similar link errors provided in the beginning of my question.
I have checked the following questions:
Undefined reference to cmph functions even after installing cpmh library
And I tried instructions provided by these sites:
https://cmake.org/Wiki/CMake:How_To_Find_Libraries
https://cmake.org/cmake/help/v3.6/module/FindPkgConfig.html
Many thanks in advance.
Finally Solved.
cmake_minimum_required(VERSION 3.0.2)
project(TestGamma)
set(GAMMATEST_VERSION_MAJOR 1)
set(GAMMATEST_VERSION_MINOR 0)
set(CMPH_INCLUDE_DIR /usr/local/lib)
include(FindPkgConfig)
configure_file(
"${PROJECT_SOURCE_DIR}/TestGammaConfig.h.in"
"${PROJECT_BINARY_DIR}/TestGammaConfig.h"
)
include_directories(${PROJECT_BINARY_DIR})
set(CMAKE_CXX_FLAGS " ${CMAKE_CXX_FLAGS} -std=c++11")
set(SOURCE_FILES main.cpp)
add_executable(testgamma ${SOURCE_FILES})
pkg_check_modules(CMPH REQUIRED cmph)
include_directories(${CMPH_INDLUDE_DIR})
link_directories(${CMPH_INCLUDE_DIR})
target_link_libraries(testgamma cmph ${CMPH_INCLUDE_DIR})
Make sure to include pkgconfig at first and add link operations after calling "add_executable"
#usr1234567 Thank you for your attention.

How to link ws2_32 in Clion

I am using Clion, which uses MinGW and Cmake. When I try to use the standalone asio library I am getting
undefined reference to `WSAStartup#8'
undefined reference to `WSASetLastError#4'
undefined reference to `closesocket#4'
...
I believe I have to link the C:/Windows/System32/ws2_32.dll library. I tried adding something like -L C:/Windows/System32 -lws2_32:
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GCC_COVERAGE_LINK_FLAGS} -static -lws2_32")
But that didn't help. How can I fix these errors ?
The following CMakeLists.txt compiled error-less. Only 1 line is really required: link_libraries(ws2_32 wsock32)
cmake_minimum_required(VERSION 3.3)
project(server_client)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -s -O3 -I C:/Users/Shiro/Desktop/asio-1.10.6/include")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GCC_COVERAGE_LINK_FLAGS} -static")
link_libraries(ws2_32 wsock32)
set(SOURCE_FILES chat_server.cpp)
add_executable(server_client ${SOURCE_FILES})

Clion how to deploy project?

I have the following CMakeLists.txt:
cmake_minimum_required(VERSION 3.3)
project(Thesis)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(SOURCE_FILES main.cpp Graph.h Graph.cpp)
add_executable(Thesis ${SOURCE_FILES})
I am using Run->Build (as release) on a custom folder ClionProjects\Thesis\exe\Release and I get a single executable Thesis.exe. If I open that, I get the following consecutive errors:
What am I missing exactly ?
My solution was to link the libraries statically. That was there is no need for an awkward .dll standing next to your .exe.
Adding a single line on the CMakeLists.txt
set(CMAKE_EXE_LINKER_FLAGS -static)
Fixed my problem. Here is other 2 options that also work, in case you need it for some reason.
#set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GCC_COVERAGE_LINK_FLAGS} -static-libgcc -static-libstdc++ -static")
#set(CMAKE_EXE_LINKER_FLAGS=-static-libgcc -static-libstdc++ -static)
My .exe went from 100KB to 1MB
Edit: A couple more cool options
Added -s and -O3 to my original CMakeLists.txt of my question.
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -s -O3")
-s reduced size from 1MB to 650KB. -s
-O3 is supposed to set optimization level to 3 which is the max -O3
You can see all the options from the gcc.gnu.org site. There are too many. Use the "find" option of your browser (Ctrl + f).
You are missing 2 of the required DLLs.
The easiest way to resolve this is to tell the compiler to link with every library statically by using the -static option in GCC.
Another way is to copy those DLLs in the folder in which your executable exists.
The third way is to find those DLLs and register them.