cmake does not consider -pthread - c++

I am trying to make a testbench to my program using gmock/gtest; Linux/Ubuntu; KDevelop/CMake. From the link error message I conclude that part of the gtest package is missing pthread support.
/home/projects/cpp/gmock/gtest/libgtest.a(gtest-all.cc.o): In function `testing::internal::ThreadLocal<testing::TestPartResultReporterInterface*>::~ThreadLocal()':
gtest-all.cc:(.text._ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEED2Ev[_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEED5Ev]+0x16): undefined reference to `pthread_getspecific'
gtest-all.cc:(.text._ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEED2Ev[_ZN7testing8internal11ThreadLocalIPNS_31TestPartResultReporterInterfaceEED5Ev]+0x2b): undefined reference to `pthread_key_delete'
I also read
googletest: how to setup?
Using g++ directly, everything works. So, since I am usinc KDevelop/CMake, I suspect either my code or CMake.
In my CMakeLists.txt I do use
add_definitions( -pthread -m64)
However, I do not see any effect in the Makefile.
Am I missing something from my CMakeLists.txt, or CMake does not consider the line above?
My CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
add_definitions( -Dpthread )
project(ThreadTest)
INCLUDE_DIRECTORIES(gmock/gtest/include)
set ( GTEST_LIBS libgtest.a )
link_directories( ~/projects/cpp/gmock/gtest)
add_executable(ThreadTest main_test.cpp)
target_link_libraries(ThreadTest ${GTEST_LIBS})
Do I misunderstand, that add_definitions should work in this situation?
After reading
How do I force cmake to include "-pthread" option during compilation?
my question really looks like duplicate. However,
cmake_minimum_required(VERSION 2.8)
add_definitions( -Dpthread )
project(ThreadTest)
INCLUDE_DIRECTORIES(gmock/gtest/include)
find_package( Threads )
set ( GTEST_LIBS libgtest.a )
link_directories( ~/projects/cpp/gmock/gtest)
add_executable(ThreadTest main_test.cpp)
target_link_libraries(ThreadTest ${GTEST_LIBS} ${CMAKE_THREAD_LIBS_INIT})
still gives the warning 'Could NOT find Threads'. I tried to search Ubuntu software center for "threads", with no result. After that, I installed libghc-threads-dev. However, when using
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
find_package(Threads REQUIRED)
I keep receiving 'Could NOT find Threads', as error. What shall I do to satisfy find_package, and why do I have this problem, when the simple Makefile produces what I expect?
PS: my main file:
#include "gmock/gtest/include/gtest/gtest.h"
TEST(blahTest, blah1) {
EXPECT_EQ(1, 1);
}
int main (int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
int returnValue;
returnValue = RUN_ALL_TESTS();
return returnValue;
}

After busy hours, I succeeded to compile my supercomplex test program, using KDevelop/CMake/gtest
#include "gtest-1.7.0/include/gtest/gtest.h"
TEST(blahTest, blah1) {
EXPECT_EQ(1, 1);
}
int main (int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
The CMakeLists.txt file that could do the task is
# http://stackoverflow.com/questions/13513905/how-to-properly-setup-googletest-on-linux/13513907#13513907
# http://stackoverflow.com/questions/15193785/how-to-get-cmake-to-recognize-pthread-on-ubuntu
# http://stackoverflow.com/questions/21116622/undefined-reference-to-pthread-key-create-linker-error
# http://stackoverflow.com/questions/1620918/cmake-and-libpthread
# https://meekrosoft.wordpress.com/2009/10/04/testing-c-code-with-the-googletest-framework/
# http://stackoverflow.com/questions/30106608/googletest-cmake-and-make-tests-not-running
# http://stackoverflow.com/questions/13521618/c-project-organisation-with-gtest-cmake-and-doxygen
# http://www.kaizou.org/2014/11/gtest-cmake/
cmake_minimum_required(VERSION 2.8)
project(ThreadTest C CXX)
ADD_SUBDIRECTORY (gtest-1.7.0)
enable_testing()
#set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
find_package(GTest REQUIRED)
include_directories(${gtest_SOURCE_DIR}/include ${gtest_SOURCE_DIR})
if(NOT MSVC)
set(PThreadLib -pthread)
endif()
add_executable(ThreadTest main_test.cpp)
target_link_libraries(ThreadTest ${PThreadLib} ${GTEST_LIBRARIES})
#add_test(ThreadTest ThreadTest)
I want to highlight some things: a few valuable links and
project(ThreadTest C CXX) rather than project(ThreadTest)
and
set(PThreadLib -pthread) rather than set(PThreadLib pthread)
I guess the rest can be managed. It could be a good starting point.

I integrated Google Test framework in my own project and this CMake file is working.
# Google C++ Testing Framework
# https://code.google.com/p/googletest/
find_package(GTest REQUIRED)
include_directories(${GTEST_INCLUDE_DIRS})
if(WIN32)
# GTest is static compiled by default
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
endif()
enable_testing()
add_executable(ThreadTest main_test.cpp)
target_link_libraries(ThreadTest ${GTEST_BOTH_LIBRARIES})
CMake warning "Could NOT find Threads" is related to a bug:
CMake failing to detect pthreads due to warnings

All you need to do is link with pthread:
target_link_libraries(BUILD_ARTIFACT pthread)
BUILD_ARTIFACT can be your project, or library name. You should add this line after defining your artifact.
For example, if your build artifact is ThreadTest:
add_executable(ThreadTest main_test.cpp)
target_link_libraries(ThreadTest pthread)

Related

Why does "#include <gtest/gtest.h>" fail even after having used "FetchContent_MakeAvailable" in my CMake file?

This is my first time attempting the Google Test API in C++ and one of my first experiences with CMake. If it's useful, I'm using CLion. My CMake file, shown below, should ostensibly allow for files to #include <gtest/gtest.h>:
cmake_minimum_required(VERSION 3.19)
project(chord)
# GoogleTest requires at least C++11
set(CMAKE_CXX_STANDARD 11)
include(FetchContent)
FetchContent_Declare(
googletest
URL https://github.com/google/googletest/archive/609281088cfefc76f9d0ce82e1ff6c30cc3591e5.zip
)
# For Windows: Prevent overriding the parent project's compiler/linker settings
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -pthread")
add_executable(
chord
main.cpp
src/node.h
src/node.cpp
src/log.h
src/log.cpp
src/sha1.h
src/sha1.cpp
src/messageParser.h
src/messageParser.cpp
src/fingerTable.h
src/fingerTable.cpp
src/key.h
src/key.cpp)
include(GoogleTest)
enable_testing()
add_executable(
unitTests
test/fingerTableTests.cc
test/keyTests.cc
test/logTests.cc
test/messageParserTests.cc
test/nodeTests.cc
test/messageParserTests.cc
)
target_link_libraries(
unitTests
gtest_main
)
include(GoogleTest)
gtest_discover_tests(unitTests)
However, when I attempt #include <gtest/gtest.h> from main.cpp, I receive the error gtest/gtest.h: No such file or directory. Can someone pinpoint the error in my CMake file? Thanks and sorry for the trouble.
Try to also link gtest:
target_link_libraries(
unitTests
gtest_main
gtest
)

Linking external HDFql library in CMake

I have downloaded the HDFql library and put the whole lot in /usr/local/ in my linux system. I now wish to use this library in a ROS application, so I have tried to link it in my CMakeList, which looks as following:
cmake_minimum_required(VERSION 3.2)
project(data_generator)
add_compile_options(-std=c++11)
set(CMAKE_BUILD_TYPE Release) # Release, RelWithDebInfo
set(CMAKE_CXX_FLAGS "-std=c++11 -pthread ${CMAKE_CXX_FLAGS}")
find_package(catkin_simple REQUIRED)
catkin_simple(ALL_DEPS_REQUIRED)
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
set(HDFQL_ROOT "/usr/local/hdfql-2.1.0")
include_directories(${HDFQL_ROOT}/include)
find_library(HDFQL_LIB HDFql)
if (HDFQL_LIB)
message("Library(HDFQL_LIB) found in ${HDFQL_LIB}")
else()
message(FATAL_ERROR "Library (HDFQL_LIB) not found")
endif()
cs_add_executable(
${PROJECT_NAME}
src/main.cpp
src/data_create.cpp
src/event_definitions.cpp
)
target_include_directories(${PROJECT_NAME}
PUBLIC "${HDFQL_ROOT}/include"
)
target_link_libraries(${PROJECT_NAME}
${OpenCV_LIBRARIES}
${HDFQL_LIB}
)
# CMake Indexing
FILE(GLOB_RECURSE LibFiles "include/*")
add_custom_target(headers SOURCES ${LibFiles})
cs_install()
cs_export()
When I build this, it works fine and outputs the message:
Library(HDFQL_LIB) found in /usr/local/hdfql-2.1.0/lib/libHDFql.so
with the following in my main.cpp file:
#include <HDFql.hpp>
....
std::cout <<"HDFql version: " << HDFql::Version << std::endl;
the output is: HDFql version: 2.1.0.
However, as soon as I try to actually use functions of the library - for example:
#include <HDFql.hpp>
....
std::cout <<"HDFql version: " << HDFql::Version << std::endl;
HDFql::execute("CREATE FILE /home/user/test.h5");
I get the error:
main.cpp:(.text+0x1858): undefined reference to `HDFql::execute(char const*)'
This suggests to me that while CMake has no issue with the includes, it is having trouble linking the actual library (ie including the libHDFql.a/libHDFql.so files). Can anyone tell me what I'm doing wrong here?
Many thanks!
The problem was that I needed to include the library /usr/local/hdfql-2.1.0/wrapper/cpp/libHDFql.so, where I was using /usr/local/hdfql-2.1.0/lib/libHDFql.so. It's pretty maddening, since the reference manual doesn't make any mention of this and I spent way too long figuring this out. Ohwell, I hope this helps anyone else with this problem.
For reference, here is a minimal catkin-style CMakeLists that will work:
cmake_minimum_required(VERSION 3.2)
project(project_name)
add_compile_options(-std=c++11)
find_package(catkin_simple REQUIRED)
catkin_simple(ALL_DEPS_REQUIRED)
set(HDFQL_ROOT "path/to/hdfql-2.1.0")
include_directories(${HDFQL_ROOT}/include)
set(CMAKE_BUILD_TYPE Release)
set(CMAKE_CXX_FLAGS "-std=c++11 -pthread ${CMAKE_CXX_FLAGS}")
cs_add_executable(
${PROJECT_NAME}
# your source file 1
# your source file 2
# ...
)
target_include_directories(${PROJECT_NAME}
PUBLIC "${HDFQL_ROOT}/include"
)
target_link_libraries(
${PROJECT_NAME}
${OpenCV_LIBRARIES}
)
target_link_libraries(
${PROJECT_NAME}
"${HDFQL_ROOT}/wrapper/cpp/libHDFql.so"
)
Of course the absolute paths aren't very pretty, the alternative is to add /usr/local/hdfql-2.1.0/lib to the environment variable CMAKE_PREFIX_PATH (eg export CMAKE_PREFIX_PATH="/usr/local/hdfql-2.1.0/lib:$CMAKE_PREFIX_PATH").

undefined reference to boost::iostreams::mapped_file_source::init() using CMake

Linking error on minimal example with Boost Iostreams. Looks like I have not linked with libboost_iostream, however CMake reports that library is found and other applications with Boost compile and link without any problems.
Using Cmake for build:
cmake_minimum_required(VERSION 3.0)
project(mmap_example CXX)
set(TARGET mmap_example)
set(BOOST_MIN_VERSION "1.61.0")
set(Boost_ADDITIONAL_VERSIONS "1.61.0" "1.61")
set(Boost_USE_STATIC_LIBS ON)
set(BOOST_ROOT ${MY_BOOST_DIR})
find_package(Boost ${BOOST_MIN_VERSION} COMPONENTS iostreams REQUIRED)
set(CMAKE_CXX_FLAGS "-std=c++11 -std=gnu++1y -pthread")
set(CMAKE_EXE_LINKER_FLAGS "-std=c++11 -std=gnu++1y -pthread")
file(GLOB SOURCES *.cpp)
include_directories(${Boost_INCLUDE_DIRS})
add_executable(${TARGET} ${SOURCES})
target_link_libraries(${TARGET} ${Boost_IOSTREAMS})
C++ itself:
#include <boost/iostreams/device/mapped_file.hpp>
namespace boost_io = boost::iostreams;
int main(int argc, char** argv) {
boost_io::mapped_file_source file(argv[1]);
return 0;
}
GCC output:
Linking CXX executable mmap_example
CMakeFiles/mmap_example.dir/mmap.cpp.o: In function boost::iostreams::mapped_file_source::mapped_file_source<char*>(char* const&, unsigned int, long long):
mmap.cpp:(.text._ZN5boost9iostreams18mapped_file_sourceC2IPcEERKT_jx[_ZN5boost9iostreams18mapped_file_sourceC5IPcEERKT_jx]+0x43): undefined reference to boost::iostreams::mapped_file_source::init()
gcc (Debian 4.9.2-10) 4.9.2
Cmake 3.0.2
Boost 1.61
I'm not sure that ${Boost_IOSTREAMS} is the correct variable to use, AFAIK it should be ${Boost_LIBRARIES} (at least that is what I always use).
You can check if the variable is really set by using
message(STATUS "Boost_IOSTREAMS: ${Boost_IOSTREAMS}")
in your cmake file.
You can also use
make all VERBOSE=1
to list all the commands, to check what libraries are present on the linker command line.

Linking freetype with cmake

I'm having troubles with linking freetype 2 under linux using cmake when building a C++11 project with an extern C library.
With cmake and freetype 2 I basically have 2 options :
use the utility freetype-config like freetype-config --libs
use the FindFreetype cmake module
Now I'm trying to implement the second option and I'm not very skilled with cmake nor I understand the logic of it.
My problem is the linking phase, I have no idea how to do that properly plus this module is not as complete as the result of freetype-config --libs which really includes all the libraries and flags that I need, and not just the path of a file; so I'm assuming that I have to do the same for zlib and libpng.
CMakeLists.txt
cmake_minimum_required (VERSION 2.6)
project (FreetypeTutorials1)
include(FindFreetype)
include_directories(${FREETYPE_INCLUDE_DIRS})
SET(CMAKE_CXX_FLAGS "-O2 -std=c++11")
SET(CMAKE_EXE_LINKER_FLAGS "-v -lfreetype")
add_executable( demo "${CMAKE_CURRENT_SOURCE_DIR}/src/main.cpp")
./src/main.cpp ( just some random code so I have something to feed to the compiler )
extern "C" {
#include <ft2build.h>
#include FT_FREETYPE_H
}
#include <iostream>
int main()
{
FT_Library library;
auto error = FT_Init_FreeType(&library);
if (error)
{
std::cout << "An error !\n";
}
}
To load a module like FindFreetype.cmake you need to use it in cmake with the find_package-command. The first argument is the package name. The "Find" of its corresponding filename is added automatically by cmake.
While include might work with find_package you can add some flags. For example, as shown below, REQUIRED, to make cmake fail when freetype wasn't found.
Additionally linking with cmake should be done with the command target_link_libraries.
This is how I would write you CMakeLists.txt:
cmake_minimum_required (VERSION 2.6)
project (FreetypeTutorials1)
find_package(Freetype REQUIRED)
SET(CMAKE_CXX_FLAGS "-O2 -std=c++11")
SET(CMAKE_EXE_LINKER_FLAGS "-v")
add_executable( demo src/main.cpp) # CMAKE_CURRENT_SOURCE_DIR is implicit here
target_link_libraries(demo ${FREETYPE_LIBRARIES})
target_include_directories(demo PRIVATE ${FREETYPE_INCLUDE_DIRS})
target_link_libraries is platform independent whereas '-lfreetype in CMAKE_EXE_LINKER_FLAGS is not.
The CMakeLists.txt will work on other platforms where freetype is available.
(Edit 2019: use target_include_directories() instead of include_directories()

Trouble getting QPrinter to link using cmake

So I've been trying to get my programs with QPrinter to work compile with cmake+mingw+qt5.2 but I'm having issues: the following test program doesn't compile because it cant find QPrinter which should be part of QtCore
#include <QPrinter>
#include <QApplication>
#include <windows.h>
int main()
{
QApplication a( argc, argv );
return 0;
} // end
this is my cmake file
SET(CMAKE_C_COMPILER E:/Qt/Qt5.2.1/Tools/mingw48_32/bin/gcc.exe)
SET(CMAKE_CXX_COMPILER E:/Qt/Qt5.2.1/Tools/mingw48_32/bin/g++.exe)
cmake_minimum_required(VERSION 2.8)
PROJECT (test_prog)
add_definitions(-std=c++11)
SET( test_prog_SRCS test.cpp)
# Tell CMake to run moc when necessary:
set(CMAKE_AUTOMOC ON)
# As moc files are generated in the binary dir, tell CMake
# to always look for includes there:
set(CMAKE_INCLUDE_CURRENT_DIR ON)
# Widgets finds its own dependencies.
find_package(Qt5Widgets REQUIRED)
find_package(Qt5Core REQUIRED)
find_package(Qt5Gui REQUIRED)
include_directories(
${Qt5Widgets_INCLUDE_DIRS}
${Qt5Gui_INCLUDE_DIRS}
${Qt5Core_INCLUDE_DIRS}
)
add_executable(test_prog WIN32 ${test_prog_SRCS})
target_link_libraries(test_prog ${Qt5Widgets_LIBRARIES} ${Qt5Core_LIBRARIES} ${Qt5Gui_LIBRARIES} )
The Error is:
test.cpp:1:20: fatal error: QPrinter: No such file or directory
#include <QPrinter>
Does anyone know the right incantations to get this to work?
With CMake 2.8.11:
SET(CMAKE_C_COMPILER E:/Qt/Qt5.2.1/Tools/mingw48_32/bin/gcc.exe)
SET(CMAKE_CXX_COMPILER E:/Qt/Qt5.2.1/Tools/mingw48_32/bin/g++.exe)
cmake_minimum_required(VERSION 2.8.11)
PROJECT (test_prog)
add_definitions(-std=c++11)
SET( test_prog_SRCS test.cpp)
# Tell CMake to run moc when necessary:
set(CMAKE_AUTOMOC ON)
# As moc files are generated in the binary dir, tell CMake
# to always look for includes there:
set(CMAKE_INCLUDE_CURRENT_DIR ON)
find_package(Qt5PrintSupport REQUIRED)
add_executable(test_prog WIN32 ${test_prog_SRCS})
target_link_libraries(test_prog Qt5::PrintSupport)