I am using timer_create in a c++ program with Cmake. However, on Raspian (= Debian?) the linker tells me
CppTimer.cpp:(.text+0xd8): undefined reference to timer_create'`
On Opensuse it works.
I have searched and it is mentiond that the option -lrt shall go after the source files.
How can I force cmake to set the library at the end of the CC command line?
The CmakeLists.txt looks like this:
cmake_minimum_required(VERSION 3.0)
# include(FindPkgConfig)
# pkg_check_modules(CURLPP REQUIRED curlpp)
set(CMAKE_CXX_STANDARD 17) # C++11...
set(CMAKE_CXX_STANDARD_REQUIRED ON) #...is required...
set(CMAKE_CXX_EXTENSIONS OFF) #...without compiler extensions like gnu++11
project(energycons)
find_library(CURLPP curlpp)
find_library(CURL curl)
find_library(TZ date-tz)
add_executable(energycons main.cpp
CppTimer.h CppTimer.cpp CppTimerCallback.h
....)
add_link_options(-lrt)
TARGET_LINK_LIBRARIES(energycons ${CURL} ${CURLPP} ${TZ})
install(TARGETS energycons RUNTIME DESTINATION bin)
Already tried to place add_link_options(-lrt) at different places.
Related
I want to be able to call my C++ code as a python package. To do this I am using pybind11 with CMakelists (following this example https://github.com/pybind/cmake_example). My problem is that I have to include GSL libraries in the compilation of the code, and these need an explicit linker -lgsl .
If I were just to compile and run the C++ without wrapping it with python, the following Cmakelists.txt file does the job
cmake_minimum_required(VERSION 3.0)
set(CMAKE_BUILD_TYPE Debug)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")
project(myProject)
add_executable(
myexecutable
main.cpp
function1.cpp
)
find_package(GSL REQUIRED)
target_link_libraries(myexecutable GSL::gsl GSL::gslcblas)
but when using pybind11 the template I found doesn't allow the add_executable therefore target_link_libraries doesn't work.
I have trie this
project(myProject)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED YES) # See below (1)
# Set source directory
set(SOURCE_DIR "project")
# Tell CMake that headers are also in SOURCE_DIR
include_directories(${SOURCE_DIR})
set(SOURCES "${SOURCE_DIR}/functions.cpp")
# Generate Python module
add_subdirectory(lib/pybind11)
pybind11_add_module(namr ${SOURCES} "${SOURCE_DIR}/bindings.cpp")
FIND_PACKAGE(GSL REQUIRED)
target_link_libraries(GSL::gsl GSL::gslcblas)
but this produces errors in the building.
Any idea ?
Function pybind11_add_module creates a library target, which can be used for link added module with other libraries:
pybind11_add_module(namr ${SOURCES} "${SOURCE_DIR}/bindings.cpp")
target_link_libraries(namr PUBLIC GSL::gsl GSL::gslcblas)
This is explicitely stated in documentation:
This function behaves very much like CMake’s builtin add_library (in fact, it’s a wrapper function around that command). It will add a library target called <name> to be built from the listed source files. In addition, it will take care of all the Python-specific compiler and linker flags as well as the OS- and Python-version-specific file extension. The produced target <name> can be further manipulated with regular CMake commands.
I have an undefined reference while trying to compile my Qt5 project.
I am usually pretty confident with using CMake but this time I have a strange error that I can't figure out:
undefined reference to boost::system::generic_category()
/usr/local/include/boost/system/error_code.hpp:223: undefined reference to 'boost::system::generic_category()'
My configurations are:
gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
Qt5.15
cmake version 3.16.3
After typing whereis boost the outcome wasboost: /usr/include/boost and after applying the great power of dpkg -s libboost-dev | grep 'Version' :) the version is Version: 1.71.0.0ubuntu2
I don't understand what is happening, below an example of how my CMakeLists.txt is structured:
cmake_minimum_required (VERSION 3.1)
project(projectA)
set (OpenCV_DIR /home/to/opencv/build)
find_package( OpenCV REQUIRED )
find_package( Boost COMPONENTS system thread filesystem REQUIRED)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(CMAKE_INCLUDE_CURRENT_DIR ON)
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIR})
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
find_package(Qt5Widgets)
find_package(Qt5PrintSupport)
#make them into headers
qt5_wrap_ui (UI_HDRS ${UI})
add_executable(projectA main/main.cpp ui/qdarkstyle/style.qrc ${SRCS} ${UI_HDRS} ${UI_SRCS})
target_link_libraries (projectA Qt5::Widgets ${Boost_LIBRARIES} ${OpenCV_LIBS} Qt5::PrintSupport)
add_library(projectA_lib SHARED ${SRCS} ${UI_HDRS})
target_include_directories (projectA_lib PUBLIC "src/" "ui/")
link_directories(${Boost_LIBRARY_DIRS})
target_link_libraries (projectA_lib Qt5::Widgets ${Boost_LIBRARIES} ${OpenCV_LIBS})
I have searched and applied solutions I saw on all possible sources I was able to find such as:
This source but that didn't work.
Also from here it seems that this solution shall be applied:
set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
find_package(Boost REQUIRED COMPONENTS system)
# the call to include_directories is now useless:
# the Boost::system imported target used below
# embeds the include directories
project(APP C CXX)
add_executable(APP src.cpp)
target_link_libraries(APP Boost::system)
However that also didn't do any specific benefits to finding the solution.
Other posts I consulted were this, this one but no answer was provided.
This post was useful but that also didn't provide any advice that didn't already know.
Thanks for pointing to the right direction and trying to find a solution.
Using cmake I am not able to use boost::log
I still get this error undefined reference to:
boost::log::v2_mt_posix::trivial::logger::get()
I am using boost 1.71. I have this working like:
- g++ ../log_example.cpp -DBOOST_LOG_DYN_LINK -lpthread -lboost_log -o log_example
linker error while linking boost log (undefined references to boost::log::v2_mt_posix::sinks)
linking boost log using cmake error
However, With cmake I have try several different options mention before. Not a single one has works for cmake.
The cmake is as follows
cmake_minimum_required(VERSION 3.10)
project(log_example)
set(CMAKE_CXX_STANDARD 17)
set(Boost_USE_DEBUG_LIBS OFF) # ignore debug libs and
set(Boost_USE_RELEASE_LIBS ON) # only find release libs
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
set(CMAKE_CXX_COMPILER "g++")
ADD_DEFINITIONS(-DBOOST_LOG_DYN_LINK)
find_package(Boost 1.70.0 COMPONENTS thread log REQUIRED log_setup)
include_directories(${BOOST_INCLUDE_DIRS})
add_executable(log_example log_example.cpp)
target_link_libraries(log_example pthread ${Boost_LIBRARIES} ${Boost_LOG_LIBRARY} )
set(CMAKE_CXX_FLAGS "-g -Wall -DBOOST_LOG_DYN_LINK")
solved
Awesome thanks every one. The cmake now looks like this and works perfectly, less clutter and to the point.
cmake_minimum_required(VERSION 3.10)
project(log_example)
set(CMAKE_CXX_STANDARD 17)
find_package(Boost 1.70.0 COMPONENTS thread log log_setup)
include_directories(${BOOST_INCLUDE_DIRS})
add_executable(log_example log_example.cpp)
target_link_libraries(log_example pthread Boost::log Boost::log_setup )
I'm trying to build a C++ application which uses the library libpamg0-dev.
I installed it with the following command on my elementaryOS VM.
apt-get install libpam0g-dev
When I try to compile the application, the compiler spits out the following errors:
undefined reference to `pam_start`
undefined reference to `pam_authenticate`
undefined reference to `pam_end`
My CMakeLists.txt looks like this:
cmake_minimum_required(VERSION 3.10)
project(application)
set(CMAKE_CXX_STANDARD 11)
INCLUDE_DIRECTORIES(/home/dnagl/dev/libs/restbed/distribution/include /usr/include/security)
LINK_DIRECTORIES(/home/dnagl/dev/libs/restbed/distribution/library /usr/lib/x86_64-linux-gnu)
add_executable(application main.cpp Utils/Json/Json.cpp Utils/Json/Json.h Utils/Stringhelper/Stringhelper.cpp Utils/Stringhelper/Stringhelper.h Utils/File/Filehelper.cpp Utils/File/Filehelper.h Utils/System/SystemHelper.cpp Utils/System/SystemHelper.h Controller/Info/InfoController.cpp Controller/Info/InfoController.h Rest/ResourceHandler/ResourceHandler.cpp Rest/ResourceHandler/ResourceHandler.h Controller/System/SystemController.cpp Controller/System/SystemController.h Rest/Log/RequestLogger.cpp Rest/Log/RequestLogger.h Controller/Authentication/AuthenticationController.cpp Controller/Authentication/AuthenticationController.h Controller/Log/LogController.cpp Controller/Log/LogController.h)
target_link_libraries(application restbed)
Maybe one of you knows how to link the library in the right way.
I have found a nice solution with find_package option from CMake. CMake provides a way to find packages/libraries with specified FindModule.cmake file.
A really good news is that there are a lot of existing module files. You can use this version to find PAM package on Linux. Put it to cmake/modules/ in your project folder and update your CMakeLists.txt:
cmake_minimum_required(VERSION 3.10)
project(restbed)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
# Notify CMake that we have module files to find packages/libs.
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/modules/")
find_package(PAM REQUIRED)
# Check if we found PAM.
if (NOT PAM_FOUND)
message(FATAL_ERROR "PAM library was not found.")
endif ()
# Source configuration.
include_directories(
${PAM_INCLUDE_DIR}
${CMAKE_BINARY_DIR}
${CMAKE_CURRENT_BINARY_DIR}
)
set(EXECUTABLE_NAME "application")
# Add sources to this project's executable.
add_executable(${EXECUTABLE_NAME}
"main.cpp"
"Utils/Json/Json.cpp"
"Utils/Json/Json.h"
"Utils/Stringhelper/Stringhelper.cpp"
"Utils/Stringhelper/Stringhelper.h"
"Utils/File/Filehelper.cpp"
"Utils/File/Filehelper.h"
"Utils/System/SystemHelper.cpp"
"Utils/System/SystemHelper.h"
"Controller/Info/InfoController.cpp"
"Controller/Info/InfoController.h"
"Rest/ResourceHandler/ResourceHandler.cpp"
"Rest/ResourceHandler/ResourceHandler.h"
"Controller/System/SystemController.cpp"
"Controller/System/SystemController.h"
"Rest/Log/RequestLogger.cpp"
"Rest/Log/RequestLogger.h"
"Controller/Authentication/AuthenticationController.cpp"
"Controller/Authentication/AuthenticationController.h"
"Controller/Log/LogController.cpp"
"Controller/Log/LogController.h"
)
target_link_libraries(${EXECUTABLE_NAME}
${PAM_LIBRARIES}
)
set_target_properties(${EXECUTABLE_NAME} PROPERTIES LINKER_LANGUAGE CXX)
Hope this helps!
Unable to link protobuf library using CMake. My CMakeLists is
cmake_minimum_required(VERSION 3.6)
project(addressbook)
set(CMAKE_CXX_STANDARD 11)
set(PROJECT_NAME addressbook)
ADD_SUBDIRECTORY(proto)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
ADD_EXECUTABLE(main main.cpp)
TARGET_LINK_LIBRARIES(main proto ${PROTOBUF_LIBRARY})
and in proto subdirectory there is another CMakeLists.txt (that way it is done in github repo https://github.com/shaochuan/cmake-protobuf-example)
INCLUDE(FindProtobuf)
FIND_PACKAGE(Protobuf REQUIRED)
INCLUDE_DIRECTORIES(${PROTOBUF_INCLUDE_DIR})
PROTOBUF_GENERATE_CPP(PROTO_SRC PROTO_HEADER message.proto)
ADD_LIBRARY(proto ${PROTO_HEADER} ${PROTO_SRC})
But my IDE still outputs buch of lines like
CMakeFiles/main.dir/main.cpp.o: In function main':
/home/camille/ClionProjects/protobuf/main.cpp:42: undefined reference
togoogle::protobuf::internal::VerifyVersion(int, int, char const*)'
/home/camille/ClionProjects/protobuf/main.cpp:49: undefined reference
to tutorial::AddressBook::AddressBook()'
/home/camille/ClionProjects/protobuf/main.cpp:54: undefined reference
togoogle::protobuf::Message::ParseFromIstream(std::istream*)'
Where is my mistake? How do I make it work?
Your program fails to link because ${PROTOBUF_LIBRARY} is empty in the scope of your top-level CMakeLists.txt. This happens because calling add_subdirectory creates a child scope, and the Protobuf_XXX variables set by find_package(Protobuf REQUIRED) are only in that child scope.
A good way to fix this is to add the following to proto/CMakeLists.txt:
target_link_libraries(proto INTERFACE ${Protobuf_LIBRARIES})
This instructs targets that link to proto to also link to ${Protobuf_LIBRARIES}. Now you can simplify target_link_libraries in your top-level CMakeLists.txt:
target_link_libraries(addressbook proto)
On a side note, you could also use e.g.
target_link_libraries(${PROJECT_NAME} INTERFACE ... )
${PROJECT_NAME} resolves to whatever you have set in the project(...) statement in that CMakeLists.txt file.
Finally, note that this links to Protobuf_LIBRARIES instead of PROTOBUF_LIBRARY. Protobuf_LIBRARIES includes both the Protocol Buffers libraries and the dependent Pthreads library.
Watch out for variable name case: With CMake 3.6 and later, the FindProtobuf module input and output variables were all renamed from PROTOBUF_ to Protobuf_ (see release notes), so using Protobuf_ works with CMake 3.6, but fails with undefined reference with an earlier version.
To be on the safe side, either use the old style
target_link_libraries(${PROJECT_NAME} INTERFACE ${PROTOBUF_LIBRARIES}))
or force everyone to use at least CMake 3.6
cmake_minimum_required(VERSION 3.6)
Also, there is a resolved bug report in the Kitware cmake issue tracker with more information on how to diagnose such issues.
The variable you need to pass to target_link_libraries is Protobuf_LIBRARIES. See documentation.
CMakeLists.txt:
cmake_minimum_required(VERSION 3.12)
project(protobuf)
SET(CMAKE_CXX_FLAGS "-g -Wall -Werror -std=c++11")
set(CMAKE_CXX_STANDARD 11)
INCLUDE(FindProtobuf)
FIND_PACKAGE(Protobuf REQUIRED)
INCLUDE_DIRECTORIES(${PROTOBUF_INCLUDE_DIR})
PROTOBUF_GENERATE_CPP(PROTO_SRC PROTO_HEADER addressbook.proto)
ADD_LIBRARY(proto2 ${PROTO_HEADER} ${PROTO_SRC})
TARGET_LINK_LIBRARIES(proto2)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
add_executable(protobuf main.cpp)
TARGET_LINK_LIBRARIES(protobuf proto2 ${PROTOBUF_LIBRARY})