-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCMakeLists.txt
71 lines (66 loc) · 3.13 KB
/
CMakeLists.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
cmake_minimum_required(VERSION 3.22.0)
# We can version our project using CMake
project(foo VERSION 0.1.0)
# Sometimes, a C++ project might require a certain C++ standard to build.
# The following directives make sure that the compiler supports the required
# standard
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# This adds a library target called "foo"
add_library(foolib)
# We assume our project also has a binary target called "fooapp"
add_executable(fooapp)
# The source files for both the library and the application are added in
add_subdirectory(src)
# This step makes the library foolib usable for fooapp.
# There are three linkage categories: PRIVATE, INTERFACE and PUBLIC.
# For applications, only PRIVATE linkage makes sense (although public is possible too)
# The three linkage categories are best shown with an example
#
# PRIVATE linkage:
# Library A wants to use target B. It links B privately
#
# PUBLIC linkage:
# Library A wants to use target B but also exposes parts of B as part of its API.
# It needs to link B publicly. Another application C which links A now links A and B
#
# INTERFACE linkage:
# Library A wants to expose target B to a target but does not use B itself.
# It can use INTERFACE linkage to do so.
#
# These properties can be applied to source files (target_source command)
# and include directories as well (target_include_directories).
# For example, a library might be interested to use another internal include
# structure than the one exposes to users. PRIVATE include directories can be
# used for the internal structure, while INTERFACE includes are used for the externally exposed
# include structure. If both are the same, PUBLIC can be used.
target_link_libraries(fooapp PRIVATE foolib)
if(${CMAKE_PROJECT_NAME} STREQUAL ${PROJECT_NAME})
include(GNUInstallDirs)
# Steps here based on excellent guide: https://dominikberner.ch/cmake-interface-lib/
# Which also details all steps
include(CMakePackageConfigHelpers)
install(TARGETS foolib
EXPORT foolibTargets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/foo)
# Generate the package configuration files using CMake provided macros
write_basic_package_version_file(
"${PROJECT_NAME}ConfigVersion.cmake"
COMPATIBILITY SameMajorVersion)
configure_package_config_file(
"${PROJECT_SOURCE_DIR}/cmake/${PROJECT_NAME}Config.cmake.in"
"${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
INSTALL_DESTINATION
${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/cmake)
# Install target file, then package configuration files, and finally the headers
install(EXPORT foolibTargets
FILE foolibTargets.cmake
NAMESPACE ${PROJECT_NAME}::
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/cmake)
install(FILES "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
"${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/cmake)
endif()