-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathCMakeLists.txt
206 lines (179 loc) · 8.76 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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
# 1. Requirements
cmake_minimum_required(VERSION 3.21)
project(
OpenAssetIO-MediaCreation
VERSION 1.0.0
)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# Additional include directories for CMake utils.
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/cmake)
#-----------------------------------------------------------------------
# Options
option(OPENASSETIO_MEDIACREATION_ENABLE_TEST "Run test on mediacreation traits" OFF)
option(OPENASSETIO_MEDIACREATION_GENERATE_PYTHON "Aditionally generate python library" OFF)
if (OPENASSETIO_MEDIACREATION_GENERATE_PYTHON)
# By default we'll compute the correct site-packages directory
# structure, but allow overriding.
set(OPENASSETIO_MEDIACREATION_PYTHON_SITEDIR
""
CACHE STRING
"Override default Python module install directory, relative to CMAKE_INSTALL_PREFIX")
set(OPENASSETIO_MEDIACREATION_ENABLE_PYTHON_INSTALL_DIST_INFO_desc
"Create a dist-info metadata directory alongside Python installation to provide"
" discoverability and prevent overwrite by package managers such as pip")
option(OPENASSETIO_MEDIACREATION_ENABLE_PYTHON_INSTALL_DIST_INFO
"${OPENASSETIO_MEDIACREATION_ENABLE_PYTHON_INSTALL_DIST_INFO_desc}" ON)
endif ()
message(STATUS "Test enabled = ${OPENASSETIO_MEDIACREATION_ENABLE_TEST}")
message(STATUS "Generate python library = ${OPENASSETIO_MEDIACREATION_GENERATE_PYTHON}")
#-----------------------------------------------------------------------
# Default install directory
# Default install to a `dist` directory under the build directory, ready
# for use in tests and for packaging. But don't override if user has
# explicitly set CMAKE_INSTALL_PREFIX.
if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT AND PROJECT_IS_TOP_LEVEL)
set(CMAKE_INSTALL_PREFIX "${PROJECT_BINARY_DIR}/dist" CACHE PATH "Installation location" FORCE)
endif ()
#-----------------------------------------------------------------------
# OpenAssetIO-MediaCreation generates its traits at configure time, via
# calling `openassetio-traitgen`.
# Some might be surprised by this, and expect code generation to be
# performed in a build step. However, with MediaCreation being a
# header only library, there is no "build-step" as such, (unless added
# coincidently, if you are building the test executable, for example.)
#
# There are alternate ways to have the generation be done in the build
# step which we explored.
# - Add a custom target with the `ALL` depencency, which forces in a
# build step, however, this has the downside of causing a regeneration
# on every build
# - Define the library as a PUBLIC rather than INTERFACE library.
# This however has the downside of needing to provide the sources up
# front, meaning one needs to know the output of the generator.
#
# Furthermore, generating sources at configure time serves to more
# directly mimic a non-generated project, and lowers risk that changes
# to the library structure later on will encounter issues caused by the
# generative nature of the project.
message("Generating Traits with openassetio-traitgen")
# Mark the traits source as a configure dependency by copying it to the
# binary dir, and use that file to run traitgen from.
# This means if the source traits file is changed, configure will rerun.
configure_file(${CMAKE_CURRENT_LIST_DIR}/traits.yml ${PROJECT_BINARY_DIR}/traits.yml)
execute_process(COMMAND openassetio-traitgen ${PROJECT_BINARY_DIR}/traits.yml
-o ${PROJECT_BINARY_DIR}/cpp -g cpp
COMMAND_ERROR_IS_FATAL ANY
COMMAND_ECHO STDERR)
if (OPENASSETIO_MEDIACREATION_GENERATE_PYTHON)
# Generate the python package by running traitgen.
# By running traitgen during the cmake step, using the traitgen that
# is available to the environment, just as the C++ generation does,
# we guarentee that the versions of traitgen used between c++ and
# python packages are identical. This isn't a guarentee when using
# the `pip install .` method of creating a python package, due to
# pip having a seperate dependency resolution method.
#
# At the time of writing, this produces the same artifact as doing
# `pip install .` (and invoking setup.py), but that's not a
# guarentee going forward, as additional elements of the python
# package may be added to mediacreation.
execute_process(COMMAND openassetio-traitgen ${PROJECT_BINARY_DIR}/traits.yml
-o ${PROJECT_BINARY_DIR}/python -g python
COMMAND_ERROR_IS_FATAL ANY
COMMAND_ECHO STDERR)
endif()
add_library(openassetio-mediacreation INTERFACE)
# add alias so the project can be used with add_subdirectory
add_library(OpenAssetIO-MediaCreation::openassetio-mediacreation ALIAS openassetio-mediacreation)
include(GNUInstallDirs)
# traitgen generates to _public_header_source_root/cpp location by default.
set(_public_header_source_root "${PROJECT_BINARY_DIR}/cpp/openassetio_mediacreation/include")
set(_config_install_dir "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}")
set(_project_config_file "${PROJECT_BINARY_DIR}/cpp/${PROJECT_NAME}Config.cmake")
set(_version_config_file "${PROJECT_BINARY_DIR}/cpp/${PROJECT_NAME}ConfigVersion.cmake")
set(_traitgen_data_dir "${CMAKE_INSTALL_DATADIR}/openassetio-traitgen")
#-----------------------------------------------------------------------
# Include directories
target_include_directories(openassetio-mediacreation
INTERFACE
# Use includes from source tree for building.
"$<BUILD_INTERFACE:${_public_header_source_root}>"
# Use includes from install tree for installed lib.
"$<INSTALL_INTERFACE:include>")
target_compile_features(openassetio-mediacreation INTERFACE cxx_std_17)
#-----------------------------------------------------------------------
# Package config (Create the Config/Targets .cmake files)
install (TARGETS openassetio-mediacreation
EXPORT ${PROJECT_NAME}_EXPORTED_TARGETS)
include(CMakePackageConfigHelpers)
write_basic_package_version_file(${_version_config_file}
VERSION ${PROJECT_VERSION}
COMPATIBILITY SameMajorVersion)
configure_package_config_file(
cmake/packaging/Config.cmake.in
${_project_config_file}
INSTALL_DESTINATION ${_config_install_dir}
)
install(
EXPORT ${PROJECT_NAME}_EXPORTED_TARGETS
DESTINATION ${_config_install_dir}
NAMESPACE ${PROJECT_NAME}::
FILE ${PROJECT_NAME}Targets.cmake
)
#-----------------------------------------------------------------------
# Optionally install python library
if (OPENASSETIO_MEDIACREATION_GENERATE_PYTHON)
include(ThirdParty)
install(
DIRECTORY ${PROJECT_BINARY_DIR}/python/openassetio_mediacreation
DESTINATION "${OPENASSETIO_MEDIACREATION_PYTHON_SITEDIR}"
FILES_MATCHING PATTERN "*.py"
)
#-------------------------------------------------------------------
# Install dist-info into the Python environment, to prevent
# accidental overwrite, e.g. pip.
if (OPENASSETIO_MEDIACREATION_ENABLE_PYTHON_INSTALL_DIST_INFO)
file(READ pyproject.toml _pyproject_toml)
string(REGEX MATCH [[version *= *"([^"]+)"]] _unused "${_pyproject_toml}")
set(OPENASSETIO_MEDIACREATION_PYTHON_PKG_VERSION ${CMAKE_MATCH_1})
if (NOT OPENASSETIO_MEDIACREATION_PYTHON_PKG_VERSION)
message(FATAL_ERROR "Failed to parse version from pyproject.toml")
endif ()
set(_dist_info_dir_name
openassetio_mediacreation-${OPENASSETIO_MEDIACREATION_PYTHON_PKG_VERSION}.dist-info)
file(
COPY
"${PROJECT_SOURCE_DIR}/cmake/packaging/python.dist-info/INSTALLER"
"${PROJECT_SOURCE_DIR}/cmake/packaging/python.dist-info/REQUESTED"
"${PROJECT_SOURCE_DIR}/cmake/packaging/python.dist-info/top_level.txt"
DESTINATION "${_dist_info_dir_name}"
)
configure_file(
"${PROJECT_SOURCE_DIR}/cmake/packaging/python.dist-info/METADATA.in"
"${_dist_info_dir_name}/METADATA"
)
install(
DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${_dist_info_dir_name}"
DESTINATION "${OPENASSETIO_MEDIACREATION_PYTHON_SITEDIR}"
)
endif ()
endif()
#-----------------------------------------------------------------------
# Copy CMake Files
install(
FILES ${_project_config_file} ${_version_config_file}
DESTINATION ${_config_install_dir}
)
#-----------------------------------------------------------------------
# Copy traitgen headers to install dir
install(DIRECTORY ${_public_header_source_root} DESTINATION .)
install(
FILES "${PROJECT_BINARY_DIR}/traits.yml"
DESTINATION ${_traitgen_data_dir}
RENAME "openassetio-mediacreation.yml"
)
#-----------------------------------------------------------------------
# C++ tests.
if (OPENASSETIO_MEDIACREATION_ENABLE_TEST)
add_subdirectory(tests/cpp)
endif ()