I am building two C++ libraries(2 CMake projects). library2 depends on library1. I am installing my first library header files at ${CMAKE_INSTALL_INCLUDEDIR}/mylibraries. Now to include library1 header files in my library2, I am doing include_directories(${CMAKE_INSTALL_FULL_INCLUDEDIR}/mylibraries) in the library2's CMakeLists.txt.
But the make is failing with no such file or directory error.
library1.h no such file or directory from library2.cpp
library1's CmakeLists.txt
cmake_minimum_required (VERSION 3.5)
include(GNUInstallDirs)
project (logger)
set (VERSION_MAJOR 1)
set (VERSION_MINOR 0)
set (Umbrella "ferryfair")
# configure a header file to pass some of the CMake settings
# to the source code
configure_file (
"${PROJECT_SOURCE_DIR}/config.h.in"
"${PROJECT_BINARY_DIR}/config.h"
)
configure_file(
"${PROJECT_SOURCE_DIR}/pkgconfig.pc.in"
"${PROJECT_BINARY_DIR}/pkgconfig.pc"
)
set (GCC_COVERAGE_COMPILE_FLAGS "-std=c++14")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GCC_COVERAGE_COMPILE_FLAGS}")
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GCC_COVERAGE_LINK_FLAGS}")
file(GLOB HEADERS *.h)
file(GLOB SOURCES *.cpp)
include_directories(${PROJECT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_INSTALL_FULL_INCLUDEDIR}/${Umbrella})
add_library(${PROJECT_NAME}Static STATIC ${SOURCES} ${HEADERS})
add_library(${PROJECT_NAME} SHARED ${SOURCES} ${HEADERS})
set_target_properties(${PROJECT_NAME}Static PROPERTIES OUTPUT_NAME ${PROJECT_NAME})
set_target_properties(${PROJECT_NAME}
PROPERTIES
VERSION ${VERSION_MAJOR}.${VERSION_MINOR}
SOVERSION ${VERSION_MAJOR}
)
set_target_properties(${PROJECT_NAME}Static
PROPERTIES
VERSION ${VERSION_MAJOR}.${VERSION_MINOR}
SOVERSION ${VERSION_MAJOR}
)
target_link_libraries(${PROJECT_NAME}Static ferrybase)
target_link_libraries(${PROJECT_NAME} ferrybase)
install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR})
install(TARGETS ${PROJECT_NAME}Static DESTINATION ${CMAKE_INSTALL_LIBDIR})
install(FILES ${HEADERS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${Umbrella})
install(FILES "${PROJECT_BINARY_DIR}/config.h"
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${Umbrella}
RENAME ${PROJECT_NAME}Config.h)
install(FILES "${PROJECT_BINARY_DIR}/pkgconfig.pc"
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig
RENAME "${PROJECT_NAME}.pc")
install(FILES "${PROJECT_BINARY_DIR}/pkgconfig.pc"
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig
RENAME "${PROJECT_NAME}.pc")
library2's CMakeLists.txt
cmake_minimum_required (VERSION 3.5)
include(GNUInstallDirs)
project (FFJSON)
IF (DEFINED _DEBUG)
ADD_DEFINITIONS(-D_DEBUG=${_DEBUG})
ENDIF()
set (VERSION_MAJOR 1)
set (VERSION_MINOR 0)
set (Umbrella "ferryfair")
IF(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
# Mac OS X specific code
SET(macOS ON)
ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
# configure a header file to pass some of the CMake settings
# to the source code
configure_file (
"${PROJECT_SOURCE_DIR}/config.h.in"
"${PROJECT_BINARY_DIR}/config.h"
)
configure_file(
"${PROJECT_SOURCE_DIR}/pkgconfig.pc.in"
"${PROJECT_BINARY_DIR}/pkgconfig.pc"
)
set (GCC_COVERAGE_COMPILE_FLAGS "-std=c++14")
set (GCC_COVERAGE_LINK_FLAGS "-Wl,-unresolved-symbols=ignore-in-shared-libs")
IF (DEFINED _DEBUG)
set (GCC_COVERAGE_COMPILE_FLAGS "${GCC_COVERAGE_COMPILE_FLAGS} -g -O0")
set (GCC_COVERAGE_LINK_FLAGS "${GCC_COVERAGE_LINK_FLAGS} -g -O0")
ENDIF()
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GCC_COVERAGE_COMPILE_FLAGS}")
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GCC_COVERAGE_LINK_FLAGS}")
file(GLOB HEADERS *.h)
file(GLOB SOURCES *.cpp)
include_directories(${PROJECT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_INSTALL_FULL_INCLUDEDIR}/${Umbrella})
add_library(${PROJECT_NAME}Static STATIC ${SOURCES} ${HEADERS})
add_library(${PROJECT_NAME} SHARED ${SOURCES} ${HEADERS})
set_target_properties(${PROJECT_NAME}Static PROPERTIES OUTPUT_NAME ${PROJECT_NAME})
set_target_properties(${PROJECT_NAME}
PROPERTIES
VERSION ${VERSION_MAJOR}.${VERSION_MINOR}
SOVERSION ${VERSION_MAJOR}
)
set_target_properties(${PROJECT_NAME}Static
PROPERTIES
VERSION ${VERSION_MAJOR}.${VERSION_MINOR}
SOVERSION ${VERSION_MAJOR}
)
target_link_libraries(${PROJECT_NAME}Static logger ferrybase)
target_include_directories(TestFFJSON PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:include/${Umbrella}>
)
add_executable(IteratorIncrement tests/iteratorincrement.cpp)
target_link_libraries(IteratorIncrement FFJSON logger ferrybase)
target_include_directories(IteratorIncrement PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:include/${Umbrella}>
)
add_test(test1 TestFFJSON)
add_test(test2 IteratorIncrement)
ENDIF()
Its weird! ridiculous! pathetic!
executing cmake twice fixed the issue. Its an another entry into accidental discoveries.
Related
I have two (or more) libraries containing header files that have the same name (e.g., "point.h"). In my project(s), I need to use attributes from the classes defined in those headers in different contexts, but of course, is not possible to include the correct file in the common way, having the ambiguity of same name.
Many libraries solve this issue by "namespacing" their headers (e.g., "#include <rapidjson/document.h>"). I would like to do this. How can I configure CMake to achieve this? Is there a common (and possibly simple) way to do this?
Here is my CMakeLists.txt:
cmake_minimum_required(VERSION 3.5)
project(GISManager LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(OSMManager REQUIRED) #First libray
find_package(GeoJSONParser REQUIRED) #Second library
set(GISManager_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src)
set(GISManager_H ${CMAKE_CURRENT_SOURCE_DIR}/include)
set(Hdrs ${GISManager_H}/gismanager.h )
set(Srcs ${GISManager_SRC}/gismanager.cpp)
add_library(GISManager ${Hdrs} ${Srcs})
target_include_directories(GISManager PUBLIC
$<BUILD_INTERFACE:${GISManager_H}/>
${OSMManager_INCLUDE_DIRS}/
${GeoJSONParser_INCLUDE_DIRS}/
)
target_link_libraries(GISManager ${OSMManager_LIBRARIES} ${GeoJSONParser_LIBRARIES})
add_executable(GISManager_Test ${Hdrs} ${Srcs} ${GISManager_SRC}/main.cpp)
target_include_directories(GISManager_Test PUBLIC
$<BUILD_INTERFACE:${GISManager_H}/>
${OSMManager_INCLUDE_DIRS}/
${GeoJSONParser_INCLUDE_DIRS}/
)
target_link_libraries(GISManager_Test ${OSMManager_LIBRARIES} ${GeoJSONParser_LIBRARIES})
install(FILES ${Hdrs} DESTINATION include/GISManager-${version})
install(TARGETS GISManager
DESTINATION lib/GISManager-${version}
EXPORT GISManager-targets)
install(EXPORT GISManager-targets
DESTINATION lib/GISManager-${version})
configure_file(
${GISManager_SOURCE_DIR}/pkg/gismanager-config.cmake.in
${GISManager_BINARY_DIR}/pkg/gismanager-config.cmake #ONLY)
configure_file(
${GISManager_SOURCE_DIR}/pkg/gismanager-config-version.cmake.in
${GISManager_BINARY_DIR}/pkg/gismanager-config-version.cmake #ONLY)
install(FILES ${GISManager_BINARY_DIR}/pkg/gismanager-config.cmake
${GISManager_BINARY_DIR}/pkg/gismanager-config-version.cmake
DESTINATION lib/GISManager-${version})
The libraries are generated using the next two CMakeLists.txt files:
cmake_minimum_required(VERSION 3.5)
project(GeoJSONParser LANGUAGES CXX)
set(version 1.0)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(GeoJSONParser_H ${CMAKE_CURRENT_SOURCE_DIR}/include)
set(GeoJSONParser_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src)
find_path(RapidJSON_INCLUDE_DIRS rapidjson)
set(HDRS
${GeoJSONParser_H}/object.h
${GeoJSONParser_H}/featurecollection.h
${GeoJSONParser_H}/feature.h
${GeoJSONParser_H}/geometry.h
${GeoJSONParser_H}/point.h
${GeoJSONParser_H}/multipoint.h
${GeoJSONParser_H}/linestring.h
${GeoJSONParser_H}/multilinestring.h
${GeoJSONParser_H}/polygon.h
${GeoJSONParser_H}/multipolygon.h
${GeoJSONParser_H}/geometrycollection.h
${GeoJSONParser_H}/utils.h
${GeoJSONParser_H}/types.h
)
set(SRCS
${GeoJSONParser_SRC}/featurecollection.cpp
${GeoJSONParser_SRC}/feature.cpp
${GeoJSONParser_SRC}/point.cpp
${GeoJSONParser_SRC}/multipoint.cpp
${GeoJSONParser_SRC}/linestring.cpp
${GeoJSONParser_SRC}/multilinestring.cpp
${GeoJSONParser_SRC}/polygon.cpp
${GeoJSONParser_SRC}/multipolygon.cpp
${GeoJSONParser_SRC}/geometrycollection.cpp
${GeoJSONParser_SRC}/utils.cpp
)
add_library(GeoJSONParser ${HDRS} ${SRCS})
target_include_directories(GeoJSONParser PUBLIC $<BUILD_INTERFACE:${GeoJSONParser_H}/> ${RapidJSON_INCLUDE_DIRS})
add_executable(GeoJSONParser_Test ${HDRS} ${SRCS} ${GeoJSONParser_SRC}/main.cpp)
target_include_directories(GeoJSONParser_Test PUBLIC $<BUILD_INTERFACE:${GeoJSONParser_H}/> ${RapidJSON_INCLUDE_DIRS})
install(FILES ${HDRS} DESTINATION include/GeoJSONParser-${version})
install(TARGETS GeoJSONParser
DESTINATION lib/GeoJSONParser-${version}
EXPORT GeoJSONParser-targets)
install(EXPORT GeoJSONParser-targets
DESTINATION lib/GeoJSONParser-${version})
configure_file(
${GeoJSONParser_SOURCE_DIR}/pkg/geojsonparser-config.cmake.in
${GeoJSONParser_BINARY_DIR}/pkg/geojsonparser-config.cmake #ONLY)
configure_file(
${GeoJSONParser_SOURCE_DIR}/pkg/geojsonparser-config-version.cmake.in
${GeoJSONParser_BINARY_DIR}/pkg/geojsonparser-config-version.cmake #ONLY)
install(FILES ${GeoJSONParser_BINARY_DIR}/pkg/geojsonparser-config.cmake
${GeoJSONParser_BINARY_DIR}/pkg/geojsonparser-config-version.cmake
DESTINATION lib/GeoJSONParser-${version})
cmake_minimum_required(VERSION 3.5)
project(OSMManager LANGUAGES CXX)
set(version 1.0)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(OSMManager_H ${CMAKE_CURRENT_SOURCE_DIR}/include)
set(OSMManager_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src)
find_path(RapidJSON_INCLUDE_DIRS rapidjson)
find_package(PROJ)
set(HDRS
${OSMManager_H}/root.h
${OSMManager_H}/node.h
${OSMManager_H}/way.h
${OSMManager_H}/relation.h
${OSMManager_H}/coordinatesconverter.h
${OSMManager_H}/utils.h
${OSMManager_H}/types.h
${OSMManager_H}/tinyxml2.h
)
set(SRCS
${OSMManager_SRC}/root.cpp
${OSMManager_SRC}/node.cpp
${OSMManager_SRC}/way.cpp
${OSMManager_SRC}/relation.cpp
${OSMManager_SRC}/coordinatesconverter.cpp
${OSMManager_SRC}/tinyxml2.cpp
)
add_library(OSMManager ${HDRS} ${SRCS})
target_include_directories(OSMManager PUBLIC $<BUILD_INTERFACE:${OSMManager_H}/> ${RapidJSON_INCLUDE_DIRS} ${PROJ_INCLUDE_DIRS})
target_link_libraries(OSMManager ${PROJ_LIBRARIES})
add_executable(OSMManager_Test ${HDRS} ${SRCS} ${OSMManager_SRC}/main.cpp)
target_include_directories(OSMManager_Test PUBLIC $<BUILD_INTERFACE:${OSMManager_H}/> ${RapidJSON_INCLUDE_DIRS} ${PROJ_INCLUDE_DIRS})
target_link_libraries(OSMManager_Test ${PROJ_LIBRARIES})
install(FILES ${HDRS} DESTINATION include/OSMManager-${version})
install(TARGETS OSMManager
DESTINATION lib/OSMManager-${version}
EXPORT OSMManager-targets)
install(EXPORT OSMManager-targets
DESTINATION lib/OSMManager-${version})
configure_file(
${OSMManager_SOURCE_DIR}/pkg/osmmanager-config.cmake.in
${OSMManager_BINARY_DIR}/pkg/osmmanager-config.cmake #ONLY)
configure_file(
${OSMManager_SOURCE_DIR}/pkg/osmmanager-config-version.cmake.in
${OSMManager_BINARY_DIR}/pkg/osmmanager-config-version.cmake #ONLY)
install(FILES ${OSMManager_BINARY_DIR}/pkg/osmmanager-config.cmake
${OSMManager_BINARY_DIR}/pkg/osmmanager-config-version.cmake
DESTINATION lib/OSMManager-${version})
The files library-config.cmake.in have more or less the same structure in the two libraries, here is the one for GeoJSONParser:
# Compute installation prefix relative to this file.
get_filename_component(_dir "${CMAKE_CURRENT_LIST_FILE}" PATH)
get_filename_component(_prefix "${_dir}/../.." ABSOLUTE)
# Import the targets.
include("${_prefix}/lib/GeoJSONParser-#version#/GeoJSONParser-targets.cmake")
# Report other information.
set(GeoJSONParser_INCLUDE_DIRS "${_prefix}/include/GeoJSONParser-#version#/")
file(GLOB GeoJSONParser_LIBRARIES "${_prefix}/lib/GeoJSONParser-#version#/lib*")
As you can see above, the two libraries have both a "utils.h", including some functions that are specific to the library in question.
Just make it so that the include directories passed to the compiler are directories that contain such an intermediate directory that does the namespacing that you want to have for the #include directives.
You'll want to make it so for both the source tree and the install tree.
If you'd like an answer with config code, please provide a minimal, respresentative example setup.
So I have my root CMakeLists.txt here:
cmake_minimum_required(VERSION 3.16)
project(Vibranium_Core)
set(CMAKE_CXX_STANDARD 14)
find_package(Boost 1.72.0)
if(NOT Boost_FOUND)
message(FATAL_ERROR "Could not find boost!")
endif()
include_directories(${Boost_INCLUDE_DIR})
if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
message(STATUS "Target is 64 bits")
if (WIN32)
set(WINXXBITS Win64)
endif(WIN32)
else("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
message(STATUS "Target is 32 bits")
if (WIN32)
set(WINXXBITS Win32)
endif(WIN32)
endif("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/")
find_package(MySQL REQUIRED)
include_directories(${MYSQL_INCLUDE_DIR})
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/Source/Common)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/Source/Core/WorldServer)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/Source/Core/AuthServer)
add_subdirectory(Tests)
set_target_properties(VibraniumCoreTests PROPERTIES EXCLUDE_FROM_ALL TRUE)
set_target_properties(gtest PROPERTIES EXCLUDE_FROM_ALL TRUE)
set_target_properties(gmock PROPERTIES EXCLUDE_FROM_ALL TRUE)
set_target_properties(gtest_main PROPERTIES EXCLUDE_FROM_ALL TRUE)
set_target_properties(gmock_main PROPERTIES EXCLUDE_FROM_ALL TRUE)
set_target_properties(
Common WorldServer AuthServer
PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/lib"
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/lib"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
)
What I want to achieve is both AuthServer & WorldServer targets to use shared library called by me Common. So far so good. I come to a stage where I want to provide mysql functionalities to my Common library. In order to do that I have to include it in Common and link the MySQL Connector.
So here is my Common CMakeLists.txt file contents:
add_library(
Common
SHARED
Config.cpp
Config.h
Logger.cpp
Logger.h
Database/DatabaseLoader.cpp
Database/DatabaseLoader.h
Database/MySQLConnection.h
Database/MySQLConnection.cpp
Database/MySQLTable.h
Database/MySQLTable.cpp
)
if(WIN32)
target_include_directories(Common PUBLIC
${FULL_PATH_TO_MYSQL_CONNECTOR_CPP_DIR}/include
)
# Link the MySQL library to your executable.
target_link_libraries(Common PUBLIC
${FULL_PATH_TO_MYSQL_CONNECTOR_CPP_DIR}/lib64/vs14/mysqlcppconn8.lib
)
else()
target_link_libraries(Common LINK_PUBLIC ${MYSQL_LIBRARY} mysqlcppconn)
endif()
target_include_directories(Common PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
So with this my AuthServer target builds successfully. However when I try to start it it says:
The code execution cannot proceed because mysqlcppconn8-2-vs14.dll was not found. Reinstalling the program may fix this problem.
In order to make the program run I have to manually copy from here C:\Program Files\MySQL\Connector C++ 8.0\lib64\mysqlcppconn8-2-vs14.dll into the /bin folder of AuthServer.
What I want to achive is to force AuthServer and WorldServer to look for mysqlcppconn8-2-vs14.dll inside build_dir/lib folder instead of the root build directory.
How can I achieve that ?
My project was working fine before but I changed it to be compiled as a dynamic library in order to have it perform self-update, like so:
Launcher -> Executable
Server -> Library (Core project, multi-threaded with std::thread)
Updater -> Library
Now, on Linux (Debian Bullseye), I get a runtime error undefined symbol: pthread_create when the launcher tries to dlopen the Server library. Windows equivalent works fine.
I've tried splitting my big CMakeLists in several subprojects, thinking it could be a CMake bug, but that was of course not the problem.
I've included below a simplified version of the parent CMakeLists and the subproject CMakeLists for the Server and the launcher.
Parent:
################################
# Project settings
################################
cmake_minimum_required (VERSION 3.8)
set(TARGET_NAME "Server")
set(SERVER_VERSION "1.0.0")
set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY")
project(${TARGET_NAME} VERSION ${SERVER_VERSION} DESCRIPTION "My Server")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
################################
# Sources
################################
configure_file(
${CMAKE_SOURCE_DIR}/src/Resource.h
${CMAKE_CURRENT_BINARY_DIR}/src/Resource.h
COPYONLY)
configure_file(
${CMAKE_SOURCE_DIR}/src/Resource.rc.in
${CMAKE_CURRENT_BINARY_DIR}/src/Resource.rc
#ONLY)
set_source_files_properties("../Server.ico" PROPERTIES LANGUAGE RC)
include_directories("includes")
################################
# Subprojects
################################
add_subdirectory("src/Server")
add_subdirectory("src/Launcher")
add_subdirectory("src/Updater")
Server lib Subproject:
################################
# Project settings
################################
cmake_minimum_required (VERSION 3.8)
set(TARGET_NAME "Server-Core")
if (LIB)
set(EXE_NAME "ServerCore")
else ()
set(EXE_NAME "Server")
endif ()
project(${TARGET_NAME} VERSION ${SERVER_VERSION} DESCRIPTION "My Server")
################################
# Sources
################################
configure_file(
Server.hh.in
Server.hh
#ONLY)
include_directories(. "${CMAKE_BINARY_DIR}/src/Server/")
file(GLOB_RECURSE SRC "*.hh" "*.hpp" "*.cpp" "${CMAKE_BINARY_DIR}/src/*.hh")
if (LIB)
add_library(${TARGET_NAME} SHARED ${SRC})
elseif (WIN32)
add_executable(${TARGET_NAME} ${SRC} ${CMAKE_BINARY_DIR}/src/Resource.rc)
else ()
add_executable(${TARGET_NAME} ${SRC})
endif ()
################################
# Libs
################################
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
target_link_libraries(${TARGET_NAME} Threads::Threads)
if(WIN32)
target_link_libraries(${TARGET_NAME} wsock32 ws2_32)
target_link_libraries(${TARGET_NAME} Crypt32)
target_link_libraries(${TARGET_NAME} ${CMAKE_SOURCE_DIR}/libs/libssl.lib)
target_link_libraries(${TARGET_NAME} ${CMAKE_SOURCE_DIR}/libs/libcrypto.lib)
elseif(UNIX)
target_link_libraries(${TARGET_NAME} -static-libgcc -static-libstdc++)
target_link_libraries(${TARGET_NAME} ${CMAKE_SOURCE_DIR}/libs/libssl.a)
target_link_libraries(${TARGET_NAME} ${CMAKE_SOURCE_DIR}/libs/libcrypto.a)
endif()
################################
# Compiler settings
################################
set_target_properties(${TARGET_NAME} PROPERTIES VERSION ${SERVER_VERSION})
set_target_properties(${TARGET_NAME} PROPERTIES PREFIX "")
set_property(TARGET ${TARGET_NAME} PROPERTY CXX_STANDARD 20)
set_property(TARGET ${TARGET_NAME} PROPERTY CXX_STANDARD_REQUIRED ON)
set_property(TARGET ${TARGET_NAME} PROPERTY OUTPUT_NAME ${EXE_NAME})
if(MSVC)
target_compile_options(${TARGET_NAME} PUBLIC /std:c++latest)
target_compile_options(${TARGET_NAME} PUBLIC /Zc:__cplusplus)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /MANIFEST:NO")
endif()
Launcher subproject:
################################
# Project settings
################################
cmake_minimum_required (VERSION 3.8)
set(LAUNCHER_TARGET "Launcher")
set(LAUNCHER_EXE_NAME "Server")
set(LAUNCHER_VERSION "1.0.0")
project(${LAUNCHER_TARGET} VERSION ${LAUNCHER_VERSION} DESCRIPTION "My Server")
################################
# Sources
################################
if (LIB)
file(GLOB_RECURSE SRC "*.hh" "*.hpp" "*.cpp"
"../Server/Utils/DynamicLibrary/DynamicLibraryWindows.cpp" "../Server/Utils/DynamicLibrary/DynamicLibraryLinux.cpp"
"../Server/Utils/DynamicLibrary/IDynamicLibrary.cpp")
if (WIN32)
add_executable(${LAUNCHER_TARGET} ${SRC} ${CMAKE_BINARY_DIR}/src/Resource.rc)
else ()
add_executable(${LAUNCHER_TARGET} ${SRC})
endif ()
endif ()
################################
# Libs
################################
if (UNIX)
if (LIB)
target_link_libraries(${LAUNCHER_TARGET} ${CMAKE_DL_LIBS})
endif ()
endif ()
################################
# Compiler settings
################################
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
target_link_libraries(${LAUNCHER_TARGET} Threads::Threads)
if (LIB)
set_target_properties(${LAUNCHER_TARGET} PROPERTIES VERSION ${LAUNCHER_VERSION})
set_property(TARGET ${LAUNCHER_TARGET} PROPERTY CXX_STANDARD 20)
set_property(TARGET ${LAUNCHER_TARGET} PROPERTY CXX_STANDARD_REQUIRED ON)
set_property(TARGET ${LAUNCHER_TARGET} PROPERTY OUTPUT_NAME ${LAUNCHER_EXE_NAME})
endif ()
I'm using CMake 3.16.3 and gcc 9.3.0
What did I do wrong? I'm still not extremely comfortable with CMake
I have been able to fix the problem by adding
target_link_libraries(${TARGET} pthread)
after
target_link_libraries(${TARGET} Threads::Threads)
for the Launcher, when compiling for Linux.
And I need to include <thread> in the launcher and have a piece of code such as
std::thread t([](){});
t.join();
This is extremely weird
I am trying to write a cmake file to create a shared library and use it in the executable file in my project. In the main I include heades as <pattern_follower/header_file_name.h>, but when I run make install it says pattern_follower/header_file_name.h does not exist.
cmake_minimum_required(VERSION 2.8)
project(pattern_follower)
add_definitions(-std=c++14)
file(GLOB SOURCES src/*)
file(GLOB HEADERS include/*)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_RELEASE} -Wall -O4 -march=native -Wfatal-errors")
find_package(OpenCV REQUIRED)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
add_library(${PROJECT_NAME} SHARED ${SOURCES})
target_link_libraries( ${PROJECT_NAME} ${OpenCV_LIBS})
add_executable(${PROJECT_NAME}-main main.cpp)
set_target_properties(${PROJECT_NAME}-main PROPERTIES OUTPUT_NAME ${PROJECT_NAME})
target_link_libraries( ${PROJECT_NAME}-main ${PROJECT_NAME})
install(TARGETS ${PROJECT_NAME} DESTINATION lib)
install(TARGETS ${PROJECT_NAME}-main DESTINATION bin)
install(DIRECTORY include DESTINATION include/${PROJECT_NAME})
I have the following project structure:
libs is the directory where the standalone library I'm writing lives.
src is where I consume the library
My three CMakeLists.txt files are the following:
The main entry point:
cmake_minimum_required(VERSION 3.4)
add_subdirectory(src)
add_subdirectory(libs)
The libs/CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
project(Fibula)
message(STATUS "Fibula: v2.0.0")
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake_modules")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -framework OpenGl -lsfml-graphics -lsfml-audio -lsfml-window -lsfml-system -lGLEW -std=c++14 -Wall -pedantic")
set(FIBULA_INCLUDE_DIR "include")
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_LIST_DIR})
set(LIBRARY_OUTPUT_PATH ${CMAKE_CURRENT_LIST_DIR})
include_directories(${FIBULA_INCLUDE_DIR})
# This stuff needed to put every include file into needed directory when we do make install
file(GLOB BRIDGE ${FIBULA_INCLUDE_DIR}/Bridge/*.hpp)
file(GLOB CORE ${FIBULA_INCLUDE_DIR}/Core/*.hpp)
file(GLOB EVENTS ${FIBULA_INCLUDE_DIR}/Events/*.hpp)
file(GLOB GRAPHICS ${FIBULA_INCLUDE_DIR}/Graphics/*.hpp)
file(GLOB GRAPHICS_TILEMAP ${FIBULA_INCLUDE_DIR}/Graphics/TileMap/*.hpp)
file(GLOB_RECURSE SOURCE_LIST src/*.cpp)
set(HEADER_LIST
${BRIDGE}
${CORE}
${EVENTS}
${GRAPHICS}
${GRAPHICS_TILEMAP}
)
# GLM
find_package(GLM REQUIRED)
if (NOT GLM_FOUND)
message(SEND_ERROR "Failed to find GLM")
return()
else ()
include_directories(${GLM_INCLUDE_DIRS})
endif ()
# GLEW
find_package(GLEW REQUIRED)
if (NOT GLEW_FOUND)
message(SEND_ERROR "Failed to find GLEW")
return()
else ()
include_directories(${GLEW_INCLUDE_DIRS})
endif ()
# SFML
find_package(SFML 2.2 REQUIRED)
if (NOT SFML_FOUND)
message(SEND_ERROR "Failed to find SFML 2")
return()
else ()
include_directories(${SFML_INCLUDE_DIRS})
endif ()
add_library(Fibula SHARED ${SOURCE_LIST} ${HEADER_LIST})
target_link_libraries(Fibula
${GLM_LIBRARIES}
${GLEW_LIBRARIES}
${SFML_LIBARIES}
)
# When we do 'make install' it will put .so file into lib directory and include files into include directory
install(TARGETS ${PROJECT_NAME} LIBRARY DESTINATION ${PROJECT_NAME})
install(FILES ${BRIDGE} DESTINATION include/${PROJECT_NAME}/Bridge/)
install(FILES ${CORE} DESTINATION include/${PROJECT_NAME}/Core/)
install(FILES ${EVENTS} DESTINATION include/${PROJECT_NAME}/Events/)
install(FILES ${GRAPHICS} DESTINATION include/${PROJECT_NAME}/Graphics/)
install(FILES ${GRAPHICS_TILEMAP} DESTINATION include/${PROJECT_NAME}/Graphics/TileMap/)
add_custom_target(install_${PROJECT_NAME}
make install
DEPENDS ${PROJECT_NAME}
COMMENT "Installing ${PROJECT_NAME}")
And the src/CMakeLists.txt:
cmake_minimum_required(VERSION 3.4)
project(demo-game)
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake_modules")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -Wall")
find_library(FIBULA_LIBRARY
NAMES Fibula
HINTS "${CMAKE_CURRENT_LIST_DIR}/../libs/include/")
include_directories(
"${CMAKE_CURRENT_LIST_DIR}/../libs/include"
Core
)
file(GLOB SOURCE_LIST
*.cpp
../../src/Core/*.cpp
)
add_executable(demo-game ${SOURCE_LIST})
target_link_libraries(demo-game Fibula)
add_custom_target(valgrind)
When I try to include my library as:
#include <Fibula/Core/Kernel.hpp>
I get the following error: