Modern CMake target_include_directories include alias for - cmake

Here is an example of project structure :
CMakeLists.txt
A/
includes/a.h
src/a.cpp
CMakeLists.txt
B/
includes/b.h
src/b.cpp
CMakeLists.txt
And here is a sumup of my CMake config
cmake_minimum_required(VERSION 3.16)
project("WeedEngine")
# add_subdirectory(A)
add_library(A src/a.cpp)
target_include_directories(A PUBLIC includes)
# add_subdirectory(B)
add_library(B src/b.cpp)
target_link_libraries(B PRIVATE A)
I would like to link in my b.cpp the headers from my lib A like this
// b.cpp
#include "A/a.h"
But i can't manage to give an alias to my headers properly.
Should I use something like this :
target_include_directories(A
PUBLIC
$<TARGET_NAME:${CMAKE_CURRENT_SOURCE_DIR}/includes>
)
Best regards,

Related

Modify CMakeLists.txt for googletests in order to use googlemock

I was checking the quickstarter to use googletest with cmake. I was wondering how I should modify the CMakeLists.txt they provide (given below) in order to use googlemock.
cmake_minimum_required(VERSION 3.14)
project(my_project)
# GoogleTest requires at least C++14
set(CMAKE_CXX_STANDARD 14)
include(FetchContent)
FetchContent_Declare(
googletest
URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip
)
# For Windows: Prevent overriding the parent project's compiler/linker settings
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)
enable_testing()
add_executable(
hello_test
hello_test.cc
)
target_link_libraries(
hello_test
GTest::gtest_main
)
include(GoogleTest)
gtest_discover_tests(hello_test)
for the moment, #include <gtest/gtest.h> works but #include <gmock/gmock.h> doesn't
GMock should be available via GTest::gmock cmake target. At least this is the target name used in the cmake configuration files of a GTest build installed via cmake.
target_link_libraries(
hello_test
GTest::gmock
)

CMake find packages using find_package in submodules folder

Root
CMakeLists.txt
Valyrie/
CMakeLists.txt
Submodules/
CMakeLists.txt
SubmodulePackage/
CMakeLists.txt
I have a directory structure listed like above. However even if I add_subdirectory("submodules") so the submodule packages get added first cmake won't find the packages with find_package inside the Valkyrie cmakelists.txt. Is there a way to do that? I'd do relative path, but some submodules don't seem to get brought in correctly by just relative pathing their header files for some reason (header-only library).
Root Level Cmake
cmake_minimum_required (VERSION 3.8)
project (Valkyrie)
# Include sub-projects.
add_subdirectory("submodules")
add_subdirectory("Valkyrie")
Submodules CMake
cmake_minimum_required (VERSION 3.8)
set(GLFW_BUILD_DOCS OFF CACHE BOOL "" FORCE)
set(GLFW_BUILD_TESTS OFF CACHE BOOL "" FORCE)
set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
add_subdirectory("json")
add_subdirectory("spdlog")
add_subdirectory("glfw")
add_subdirectory("entt")
add_subdirectory("glm")
Valkyrie
cmake_minimum_required (VERSION 3.8)
find_package(Vulkan REQUIRED)
find_package(spdlog REQUIRED) #Error here
file(GLOB_RECURSE sources CONFIGURE_DEPENDS "*.cpp")
file(GLOB_RECURSE headers CONFIGURE_DEPENDS "*.h")
add_library(Valkyrie ${headers} ${sources})
target_compile_features(Valkyrie PUBLIC cxx_std_20)
target_include_directories(Valkyrie
PUBLIC "../submodules/glfw/include"
PUBLIC "../submodules/glm"
PUBLIC "../submodules/entt/single_include"
PUBLIC "../submodules/spdlog/include"
PUBLIC ${Vulkan_INCLUDE_DIRS}
)
target_link_libraries(Valkyrie
"${CMAKE_BINARY_DIR}/submodules/glfw/src/glfw3.lib"
${Vulkan_LIBRARIES}
)

how to split 'header', 'src', 'test' dir in cmake?(and donot add cmakelist.txt in each dir)

when building a project stucture like following:
LinearAlgebra
|---HEADER
|-----|---Linear.h
|---SRC
|-----|---Linear.cpp
|---TEST
|-----|---hello_test.cc
here is my CMakeList.txt:
cmake_minimum_required(VERSION 3.10)
project(LinearAlgebra )
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)
add_library(LA_HEADER INTERFACE header/Linear.h)
add_library(LA_SRC INTERFACE src/Linear.cpp)
target_include_directories(LA_HEADER INTERFACE "${PROJECT_SOURCE_DIR}/header" "${PROJECT_SOURCE_DIR}/src")
enable_testing()
add_executable(
hello_test
test/hello_test.cc
)
target_link_libraries(
hello_test
gtest_main
LA_HEADER
LA_SRC
)
include(GoogleTest)
gtest_discover_tests(hello_test)
it works fine with cmake -S . -B build, but when it comes to cmake --build build following error occured:
Undefined symbols for architecture x86_64:
"Linear::Linear()", referenced from:
HelloTest_BasicAssertions_Test::TestBody() in hello_test.cc.o
it seems something wrong with my cmake file that didn't tell Linear.h where Linear.cpp located. So how to fix it ?? thanks for your help...
seems i misunderstand add_library, change three lines and it works out:
cmake_minimum_required(VERSION 3.10)
project(LinearAlgebra )
include_directories(header) # include_directories instead of add_library for .h files
add_library(LA_LIB src/Linear.cpp) # use add_library for .cpp files only!!!
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)
enable_testing()
add_executable(
hello_test
test/hello_test.cc
)
target_link_libraries(
hello_test
gtest_main
LA_LIB # link LA_LIB only..
)
include(GoogleTest)
gtest_discover_tests(hello_test)
leave it here for anyone have the same requirements.

cmake linking libraries with internal dependency

First of all, I'm not sure if the way I setup my project is correct but it's like this,
A cmake project called Lib has two subdirectories Animal and Dog. Both are static libraries but Dog depends on Animal.
Lib's CMakeLists.txt
cmake_minimum_required(VERSION 3.16.3)
project(Lib VERSION 1.0.0 DESCRIPTION "My package." LANGUAGES CXX)
add_subdirectory(Animal)
add_subdirectory(Dog)
install(EXPORT LibConfig
FILE LibConfig.cmake
NAMESPACE Lib::
DESTINATION lib/Lib/cmake
)
Animal/CmakeLists.txt
set(TARGET_NAME Animal)
add_library(${TARGET_NAME}
src/Animal.cpp
)
target_include_directories(${TARGET_NAME} PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
)
install(TARGETS ${TARGET_NAME} EXPORT LibConfig
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
RUNTIME DESTINATION bin
)
install(DIRECTORY include/
DESTINATION include/${TARGET_NAME}
FILES_MATCHING PATTERN "*.hpp")
Dog/CMakeLists.txt. I'm not sure how to depend on Animal.
set(TARGET_NAME Dog)
add_library(${TARGET_NAME}
src/Dog.cpp
)
target_include_directories(${TARGET_NAME}
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
PRIVATE
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/Animal/include>
)
target_link_libraries(${TARGET_NAME}
PRIVATE
Animal
)
install(TARGETS ${TARGET_NAME} EXPORT LibConfig
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
RUNTIME DESTINATION bin
)
install(DIRECTORY include/
DESTINATION include/${TARGET_NAME}
FILES_MATCHING PATTERN "*.hpp")
This uses the library.
cmake_minimum_required(VERSION 3.10.2)
project(UseLib)
find_package(Lib REQUIRED)
add_executable(${PROJECT_NAME}
main.cpp
)
target_link_libraries(${PROJECT_NAME}
Lib::Dog
)
main.cpp
#include <Dog/Dog.hpp>
int main()
{
Dog d;
return 0;
}
The libraries compile fine but when I use it in a project I get an error saying Dog can't find the Animal header.
.../include/Dog/Dog.hpp:3:10: fatal error: Animal.hpp: No such file or directory
#include "Animal.hpp"
^~~~~~~~~~~~
compilation terminated.
make[2]: *** [CMakeFiles/UseLib.dir/build.make:63: CMakeFiles/UseLib.dir/main.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:76: CMakeFiles/UseLib.dir/all] Error 2
make: *** [Makefile:84: all] Error 2
Dog is not finding Animal because in Dog.hpp I have #include "Animal.hpp" but I have the headers installed in its own subdirectory so external projects includes it this way #include <Animal/Animal.hpp>. It's something I didn't understand.
target_include_directories(${TARGET_NAME}
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
$<INSTALL_INTERFACE:include/Animal>
)

cmake link error on linking shared library hierarchy to executable

In my project I have the following configuration:
low level shared library
shared library that is a wrapper of low level shared library
executable
so the files tree is :
CMakeLists.txt
SharedLibraryBase
CMakeLists.txt
inc
myLibBase.h -> defines MyLibBaseFunction()
src
myLibBase.cpp -> implements MyLibBaseFunction()
MySharedLibrary
CMakeLists.txt
inc
myLib.h -> defines MyLibFunction()
src
myLib.cpp -> implements MyLibFunction()
Executables
CMakeLists.txt
inc
main.h
src
main.cpp -> calls MyLibFunction()
When I perform make , I get a following link error:
ld.exe: cannot find -lMySharedLibrary
the main CMakeLists.txt is:
cmake_minimum_required(VERSION 3.5)
project(TestSharedLibraryProject)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "my_outputs")
message("Binary tree path : ${PROJECT_BINARY_DIR}")
add_subdirectory(SharedLibraryBase)
add_subdirectory(MySharedLibrary)
add_subdirectory(Executables)
the low level shared library CMakeLists.txt is:
###########################
# SharedLibraiesBase #
###########################
project(SharedLibraryBase)
# include directories
include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${Boost_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR}/inc)
# find source files
set(${PROJECT_NAME}_headers inc/myLibBase.h)
set(${PROJECT_NAME}_sources src/myLib.cpp)
# create shared library
add_library(${PROJECT_NAME} SHARED ${${PROJECT_NAME}_headers} ${${PROJECT_NAME}_sources})
# add files to export to 'include'
set_property(TARGET ${PROJECT_NAME} PROPERTY PUBLIC_HEADER inc/myLibBase.h)
install (TARGETS ${PROJECT_NAME}
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib/static
PUBLIC_HEADER DESTINATION include)
the wrapper shared library CMakeLists.txt is:
#######################
# SharedLibraies #
#######################
project(MySharedLibrary)
# include directories
include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${Boost_INCLUDE_DIRS} inc ../SharedLibraryBase/inc)
# find source files
set(${PROJECT_NAME}_headers inc/myLib.h)
set(${PROJECT_NAME}_sources src/myLib.cpp)
# create shared library
add_library(${PROJECT_NAME} SHARED ${${PROJECT_NAME}_headers} ${${PROJECT_NAME}_sources})
#dependency shared library (from this project)
target_link_libraries(${PROJECT_NAME} SharedLibraryBase)
# add files to export to 'include'
set_property(TARGET ${PROJECT_NAME} PROPERTY PUBLIC_HEADER inc/myLib.h)
install (TARGETS ${PROJECT_NAME}
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib/static
PUBLIC_HEADER DESTINATION include)
the executable CMakeLists.txt is:
####################
# Executables #
####################
project(Executables)
# include directories
include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${Boost_INCLUDE_DIRS}/inc ${CMAKE_CURRENT_SOURCE_DIR}/../MySharedLibrary/inc)
set(${PROJECT_NAME}_headers inc/main.h)
set(${PROJECT_NAME}_sources src/main.cpp)
#create executable
add_executable(${PROJECT_NAME} ${${PROJECT_NAME}_headers} ${${PROJECT_NAME}_sources})
#dependency shared library (from this project)
target_link_libraries(${PROJECT_NAME} MyShraedLibrary)
install (TARGETS ${PROJECT_NAME}
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib/static)
You have ordinary type error MyShraedLibrary instead of MySharedLibrary