-
Notifications
You must be signed in to change notification settings - Fork 74
/
Copy pathLSLCMake.cmake
358 lines (329 loc) · 13.3 KB
/
LSLCMake.cmake
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
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
# Common functions and settings for LSL
option(LSL_DEPLOYAPPLIBS "Copy library dependencies (at the moment Qt + liblsl) to the installation dir" ON)
option(LSL_COMFY_DEFAULTS "Set some quality of life options, e.g. a sensible 'install' directory" OFF)
macro(LSLAPP_Setup_Boilerplate)
message(WARNING "This function is deprecated, set LSL_COMFY_DEFAULTS instead")
set(LSL_COMFY_DEFAULTS ON)
endmacro()
# helper script to determine the target architecture for package naming
# The code below is compiled with the target compiler so it should work even
# when cross compiling and doesn't require the executable to be run
function(LSL_get_target_arch)
if(LSL_ARCH)
return()
endif()
file(WRITE "${CMAKE_BINARY_DIR}/arch.c" "
#if defined(__ARM_ARCH_ISA_A64) || defined(__aarch64__)
#error cmake_ARCH arm64
#elif defined(__arm__) || defined(__TARGET_ARCH_ARM)
#error cmake_ARCH arm
#elif defined(__i386) || defined(__i386__) || defined(_M_IX86)
#error cmake_ARCH i386
#elif defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64)
#error cmake_ARCH amd64
#elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64)
#error cmake_ARCH ia64
#elif defined(__ppc__) || defined(__ppc) || defined(__powerpc__) \\
|| defined(_ARCH_COM) || defined(_ARCH_PWR) || defined(_ARCH_PPC) \\
|| defined(_M_MPPC) || defined(_M_PPC)
#if defined(__ppc64__) || defined(__powerpc64__) || defined(__64BIT__)
#error cmake_ARCH ppc64
#else
#error cmake_ARCH powerpc
#endif
#else
#error cmake_ARCH unknown
#endif")
enable_language(C)
try_compile(dummy_result "${CMAKE_BINARY_DIR}"
SOURCES "${CMAKE_BINARY_DIR}/arch.c"
OUTPUT_VARIABLE ARCH)
string(REGEX REPLACE ".*cmake_ARCH ([a-z0-9]+).*" "\\1" ARCH "${ARCH}")
message(STATUS "Detected architecture: ${ARCH}")
set(LSL_ARCH "${ARCH}" CACHE INTERNAL "target architecture")
endfunction()
message(STATUS "Included LSL CMake helpers, rev. 15, ${CMAKE_CURRENT_LIST_DIR}")
# set build type and default install dir if not done already or undesired
if(LSL_COMFY_DEFAULTS AND NOT CMAKE_BUILD_TYPE)
message(STATUS "CMAKE_BUILD_TYPE was default initialized to Release")
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Build type" FORCE)
endif()
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT AND LSL_COMFY_DEFAULTS)
set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/install" CACHE PATH
"Where to put redistributable binaries" FORCE)
endif()
if(LSL_COMFY_DEFAULTS)
# Generate folders for IDE targets (e.g., VisualStudio solutions)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
# Qt5, include e.g. "mainwindow.h"
set(CMAKE_INCLUDE_CURRENT_DIR ON)
endif()
# LSL functions, mostly for Apps
# installs additional files (configuration etc.)
function(installLSLAuxFiles target)
get_target_property(is_bundle ${target} MACOSX_BUNDLE)
set(destdir ${PROJECT_NAME})
if(LSL_UNIXFOLDERS)
include(GNUInstallDirs)
set(destdir "${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME}")
elseif(is_bundle AND APPLE)
set(destdir ${destdir}/${target}.app/Contents/MacOS)
endif()
if("${ARGV1}" STREQUAL "directory")
install(DIRECTORY ${ARGV2} DESTINATION ${destdir} COMPONENT "${PROJECT_NAME}")
else()
install(FILES ${ARGN} DESTINATION ${destdir} COMPONENT "${PROJECT_NAME}")
endif()
endfunction()
# installLSLApp: adds the specified target to the install list and
# add some quality-of-life improvements for Qt executables
# After the target, additional libraries to install alongside the target can be
# specified, e.g. installLSLApp(FooApp libXY libZ)
function(installLSLApp target)
get_target_property(TARGET_LIBRARIES ${target} LINK_LIBRARIES)
string(REGEX MATCH ";Qt[56]?::" qtapp ";${TARGET_LIBRARIES}")
if(qtapp)
# Enable automatic compilation of .cpp->.moc, xy.ui->ui_xy.h and resource files
set_target_properties(${target} PROPERTIES
AUTOMOC ON
AUTOUIC ON
AUTORCC ON
)
endif()
# Set runtime path, i.e. where shared libs are searched relative to the exe
# CMake>=3.16: set(LIBDIR "../$<IF:$<BOOL:${LSL_UNIXFOLDERS}>,lib/,LSL/lib/>")
if(LSL_UNIXFOLDERS)
set(LIBDIR "../lib")
else()
set(LIBDIR "../LSL/lib")
endif()
if(APPLE AND NOT CMAKE_INSTALL_RPATH)
set_property(TARGET ${target} APPEND
PROPERTY INSTALL_RPATH "@executable_path/;@executable_path/${LIBDIR};@executable_path/../Frameworks")
elseif(UNIX AND NOT CMAKE_INSTALL_RPATH)
set_property(TARGET ${target}
PROPERTY INSTALL_RPATH "\$ORIGIN:\$ORIGIN/${LIBDIR}")
endif()
if(LSL_UNIXFOLDERS)
include(GNUInstallDirs)
set(lsldir "\${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}")
else()
set(CMAKE_INSTALL_BINDIR ${PROJECT_NAME})
set(CMAKE_INSTALL_LIBDIR ${PROJECT_NAME})
set(lsldir "\${CMAKE_INSTALL_PREFIX}/LSL")
endif()
# add start menu shortcut if supported by installer
set_property(INSTALL "${CMAKE_INSTALL_BINDIR}/$<TARGET_FILE_NAME:${target}>" PROPERTY
CPACK_START_MENU_SHORTCUTS "${target}")
# install additional library dependencies supplied after the target argument
foreach(libdependency ${ARGN})
if(NOT TARGET ${libdependency})
message(FATAL_ERROR "Additional arguments to installLSLApp must be library targets, ${libdependency} isn't.")
endif()
install(CODE "file(INSTALL $<TARGET_FILE:${libdependency}> DESTINATION \${CMAKE_INSTALL_PREFIX}/$<IF:$<PLATFORM_ID:Windows>,${CMAKE_INSTALL_BINDIR},${CMAKE_INSTALL_LIBDIR}>)")
endforeach()
if(NOT PROJECT_NAME STREQUAL "liblsl")
set_property(GLOBAL APPEND PROPERTY "LSLDEPENDS_${PROJECT_NAME}" liblsl)
endif()
install(TARGETS ${target} COMPONENT ${PROJECT_NAME}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR})
# skip copying libraries if disabled or on Linux
if(NOT LSL_DEPLOYAPPLIBS OR UNIX AND NOT APPLE)
return()
endif()
# skip exe deployment for libraries
get_target_property(target_type ${target} TYPE)
if(NOT target_type STREQUAL "EXECUTABLE")
return()
endif()
# Some Windows installers have problems with several components having the same file,
# so libs shared between targets are copied into the SHAREDLIBCOMPONENT component if set
if(NOT SHAREDLIBCOMPONENT)
set(SHAREDLIBCOMPONENT ${PROJECT_NAME})
endif()
# For MacOS we need to know if the installed target will be a .app bundle...
if(APPLE)
get_target_property(target_is_bundle ${target} MACOSX_BUNDLE)
set(APPLE_APP_PATH "\${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}/${target}.app")
endif(APPLE)
# Copy lsl library. Logic is a bit complicated.
# If we are not building liblsl, and the (app) target is not using system liblsl
# (LSL_UNIXFOLDERS is maybe a poor proxy for use of system liblsl...),
# then the application needs to have liblsl in an expected location.
if(NOT TARGET liblsl AND NOT LSL_UNIXFOLDERS)
if(APPLE AND target_is_bundle)
# Copy the dylib into the bundle
install(FILES $<TARGET_FILE:LSL::lsl>
DESTINATION ${CMAKE_INSTALL_BINDIR}/${target}.app/Contents/MacOS/
COMPONENT ${SHAREDLIBCOMPONENT})
else()
# Copy the dll/dylib/so next to the executable binary.
install(FILES $<TARGET_FILE:LSL::lsl>
DESTINATION ${CMAKE_INSTALL_BINDIR}
COMPONENT ${SHAREDLIBCOMPONENT})
endif(APPLE AND target_is_bundle)
endif(NOT TARGET liblsl AND NOT LSL_UNIXFOLDERS)
# Mac bundles need further fixup (mostly for 3rd party libs)
# Only use fixup_bundle for non-Qt, as it is too complicated to provide all Qt libs
# to the third argument of fixup_bundle, especially when macdeployqt can do it for us.
if(APPLE AND target_is_bundle AND NOT qtapp)
install(CODE
"
get_filename_component(LIBDIR $<TARGET_FILE:LSL::lsl> DIRECTORY)
message(STATUS \${LIBDIR})
include(BundleUtilities)
set(BU_CHMOD_BUNDLE_ITEMS ON)
fixup_bundle(${APPLE_APP_PATH} \"\" \"\${LIBDIR}\")
"
COMPONENT ${PROJECT_NAME}
)
endif()
# skip the rest if qt doesn't need to be deployed
if(NOT qtapp)
return()
endif()
cmake_minimum_required(VERSION 3.15) # generator expressions in install(CODE)
if(WIN32)
findQtInstallationTool("windeployqt")
install(CODE "
message (STATUS \"Running windeployqt on $<TARGET_FILE:${target}>\")
set(qml_dir $<TARGET_PROPERTY:${target},qml_directory>)
message(STATUS \"qml directory: \${qml_dir}\")
execute_process(
COMMAND \"${QT_DEPLOYQT_EXECUTABLE}\"
\$<\$<BOOL:\${qml_dir}>:--qmldir \"\${qml_dir}\">
--no-translations
--no-system-d3d-compiler --no-opengl-sw
--no-compiler-runtime --dry-run --list mapping
\"$<TARGET_FILE:${target}>\"
OUTPUT_VARIABLE output
OUTPUT_STRIP_TRAILING_WHITESPACE
)
file(TO_CMAKE_PATH \"\${output}\" output) # convert slashes
separate_arguments(_files WINDOWS_COMMAND \${output})
while(_files)
list(POP_FRONT _files _src)
list(POP_FRONT _files _dest)
get_filename_component(_dest \${_dest} DIRECTORY RELATIVE)
file(COPY \${_src} DESTINATION \${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}/\${_dest})
endwhile()"
COMPONENT ${SHAREDLIBCOMPONENT})
elseif(APPLE)
# It should be enough to call fixup_bundle (see above),
# but this fails to install qt plugins (cocoa).
# Use macdeployqt instead. This is bad at grabbing lsl dylib, so we already did it above.
findQtInstallationTool("macdeployqt")
install(CODE "
message(STATUS \"Running Qt Deploy Tool for $<TARGET_FILE:${target}>...\")
execute_process(COMMAND
\"${QT_DEPLOYQT_EXECUTABLE}\"
\"${APPLE_APP_PATH}\"
-verbose=1 -always-overwrite
\$<\$<STREQUAL:\${CMAKE_INSTALL_CONFIG_NAME},\"Debug\">:--use-debug-libs>
COMMAND_ECHO STDOUT
OUTPUT_VARIABLE DEPLOYOUTPUT
ERROR_VARIABLE DEPLOYOUTPUT
RESULT_VARIABLE DEPLOYSTATUS
)
if(\${DEPLOYSTATUS})
message(WARNING \"\${DEPLOYOUTPUT}\")
endif()
" COMPONENT ${PROJECT_NAME})
endif()
endfunction()
function(findQtInstallationTool qtdeploytoolname)
if(QT_DEPLOYQT_EXECUTABLE)
return()
endif()
get_target_property(QT_QMAKE_EXE Qt::qmake IMPORTED_LOCATION)
get_filename_component(QT_BIN_DIR "${QT_QMAKE_EXE}" DIRECTORY)
find_program (QT_DEPLOYQT_EXECUTABLE ${qtdeploytoolname} HINTS "${QT_BIN_DIR}")
if (QT_DEPLOYQT_EXECUTABLE)
message(STATUS "Qt deploy tool found at ${QT_DEPLOYQT_EXECUTABLE}")
else()
message(WARNING "Qt deploy tool wasn't found, installing ${PROJECT_NAME} will fail!")
return()
endif()
endfunction()
macro(LSLGenerateCPackConfig)
# CPack configuration
string(TOUPPER "${PROJECT_NAME}" PROJECT_NAME_UPPER)
if(NOT PROJECT_DESCRIPTION)
set(PROJECT_DESCRIPTION "${PROJECT_NAME} ${PROJECT_VERSION}")
endif()
set("CPACK_COMPONENT_${PROJECT_NAME_UPPER}_DESCRIPTION" "${PROJECT_DESCRIPTION}" CACHE INTERNAL "CPack Description")
# top level CMakeLists.txt?
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
LSL_get_target_arch()
# CPack configuration
set(CPACK_PACKAGE_INSTALL_DIRECTORY "lsl")
set(CPACK_STRIP_FILES ON)
set(CPACK_ARCHIVE_COMPONENT_INSTALL ON)
set(CPACK_PACKAGE_NAME lsl)
set(CPACK_PACKAGE_VENDOR "Labstreaminglayer")
if(APPLE)
set(LSL_CPACK_DEFAULT_GEN TBZ2)
if(DEFINED ENV{OSXVER})
# Configured by Travis-CI for multi-osx builds.
set(LSL_OS "$ENV{OSXVER}")
else()
set(LSL_OS "OSX${lslplatform}")
endif(DEFINED ENV{OSXVER})
elseif(WIN32)
set(LSL_CPACK_DEFAULT_GEN ZIP)
set(CPACK_NSIS_MODIFY_PATH ON)
set(CPACK_WIX_CMAKE_PACKAGE_REGISTRY ON)
set(CPACK_WIX_UPGRADE_GUID "ee28a351-3b27-4c2b-8b48-259c87d1b1b4")
set(CPACK_WIX_PROPERTY_ARPHELPLINK
"https://labstreaminglayer.readthedocs.io/info/getting_started.html#getting-help")
set(LSL_OS "Win")
elseif(UNIX)
set(LSL_CPACK_DEFAULT_GEN DEB)
set(LSL_OS "Linux")
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Tristan Stenner <ttstenner@gmail.com>")
set(CPACK_DEBIAN_ENABLE_COMPONENT_DEPENDS ON)
set(CPACK_DEB_COMPONENT_INSTALL ON)
set(CPACK_DEBIAN_PACKAGE_PRIORITY optional)
set(CPACK_DEBIAN_LIBLSL_PACKAGE_SHLIBDEPS ON)
set(CPACK_DEBIAN_PACKAGE_GENERATE_SHLIBS ON)
# include distribution name (e.g. trusty or xenial) in the file name
find_program(LSB_RELEASE lsb_release)
execute_process(COMMAND ${LSB_RELEASE} -cs
OUTPUT_VARIABLE LSB_RELEASE_CODENAME
OUTPUT_STRIP_TRAILING_WHITESPACE
RESULT_VARIABLE LSB_RELEASE_RESULT
)
if(LSB_RELEASE_CODENAME AND NOT LSB_RELEASE_CODENAME STREQUAL "n/a")
set(CPACK_DEBIAN_PACKAGE_RELEASE ${LSB_RELEASE_CODENAME})
set(LSL_OS "${LSB_RELEASE_CODENAME}")
endif()
endif()
set(CPACK_GENERATOR ${LSL_CPACK_DEFAULT_GEN} CACHE STRING "CPack pkg type(s) to generate")
get_cmake_property(LSL_COMPONENTS COMPONENTS)
foreach(component ${LSL_COMPONENTS})
string(TOUPPER ${component} COMPONENT)
set(LSL_CPACK_FILENAME "${component}-${PROJECT_VERSION}-${LSL_OS}_${LSL_ARCH}")
get_property(LSLDEPENDS GLOBAL PROPERTY "LSLDEPENDS_${component}")
if(LSLDEPENDS)
list(REMOVE_DUPLICATES LSLDEPENDS)
# remove dependencies we don't package ourselves
set(MISSING ${LSLDEPENDS})
list(REMOVE_ITEM MISSING ${LSL_COMPONENTS})
if(MISSING)
list(REMOVE_ITEM LSLDEPENDS ${MISSING})
endif()
set("CPACK_COMPONENT_${COMPONENT}_DEPENDS" ${LSLDEPENDS})
endif()
set("CPACK_DEBIAN_${COMPONENT}_PACKAGE_NAME" ${component})
set("CPACK_DEBIAN_${COMPONENT}_FILE_NAME" "${LSL_CPACK_FILENAME}.deb")
set("CPACK_ARCHIVE_${COMPONENT}_FILE_NAME" ${LSL_CPACK_FILENAME})
endforeach()
message(STATUS "Installing Components: ${LSL_COMPONENTS}")
# force component install even if only one component is to be installed
set(CPACK_COMPONENTS_ALL ${LSL_COMPONENTS})
include(CPack)
endif()
endmacro()