11# Common functions and settings for LSL
22
33message (STATUS "Included LSL CMake helpers, rev. 11" )
4+ option (LSL_DEPLOYAPPLIBS "Copy library dependencies (at the moment Qt + liblsl) to the installation dir" ON )
45
56# set build type and default install dir if not done already
67if (NOT CMAKE_BUILD_TYPE )
@@ -71,13 +72,8 @@ function(installLSLAuxFiles target)
7172 endif ()
7273endfunction ()
7374
74- # installLSLApp: adds the specified target to the install list
75- #
76- # there are two install types for different use cases
77- # Windows users mostly want a folder per app that contains
78- # everything needed to run the app, whereas on Linux,
79- # OS X (homebrew) and Conda the libraries are installed
80- # separately to save space, ease upgrading and distribution
75+ # installLSLApp: adds the specified target to the install list and
76+ # add some quality-of-life improvements for Qt executables
8177function (installLSLApp target )
8278 get_target_property (TARGET_LIBRARIES ${target} LINK_LIBRARIES )
8379 string (REGEX MATCH ";Qt5::" qtapp ";${TARGET_LIBRARIES} " )
@@ -89,145 +85,114 @@ function(installLSLApp target)
8985 AUTORCC ON
9086 )
9187 endif ()
88+ # add start menu shortcut if supported by installer
89+ set_property (INSTALL "${PROJECT_NAME} /$<TARGET_FILE_NAME:${target} >" PROPERTY
90+ CPACK_START_MENU_SHORTCUTS "${target} " )
91+
9292 if (LSL_UNIXFOLDERS)
93- install (TARGETS ${target}
94- COMPONENT "${PROJECT_NAME} "
95- RUNTIME DESTINATION bin
96- BUNDLE DESTINATION bin
97- LIBRARY DESTINATION lib
98- )
93+ include (GNUInstallDirs)
94+ set (lsldir "\$ {CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR} " )
9995 else ()
100- installLSLAppSingleFolder(${target} "${qtapp} " )
96+ set (CMAKE_INSTALL_BINDIR ${PROJECT_NAME} )
97+ set (CMAKE_INSTALL_LIBDIR ${PROJECT_NAME} )
98+ set (lsldir "\$ {CMAKE_INSTALL_PREFIX}/LSL" )
10199 endif ()
102100 set_property (GLOBAL APPEND PROPERTY
103101 "LSLDEPENDS_${PROJECT_NAME} " liblsl)
104- endfunction ()
105-
106- function (findQtInstallationTool qtdeploytoolname)
107- if (QT_DEPLOYQT_EXECUTABLE)
102+ install (TARGETS ${target} COMPONENT ${PROJECT_NAME}
103+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
104+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
105+ BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR} )
106+ # skip copying libraries if disabled or on Linux
107+ if (NOT LSL_DEPLOYAPPLIBS OR UNIX AND NOT APPLE )
108108 return ()
109109 endif ()
110- get_target_property (QT_QMAKE_EXE Qt5::qmake IMPORTED_LOCATION )
111- get_filename_component (QT_BIN_DIR "${QT_QMAKE_EXE} " DIRECTORY )
112- find_program (QT_DEPLOYQT_EXECUTABLE ${qtdeploytoolname} HINTS "${QT_BIN_DIR} " )
113- if (QT_DEPLOYQT_EXECUTABLE)
114- message (STATUS "Qt deploy tool found at ${QT_DEPLOYQT_EXECUTABLE} " )
115- else ()
116- message (WARNING "Windeployqt wasn't found, installing ${PROJECT_NAME} will fail!" )
110+
111+ # skip exe deployment for libraries
112+ get_target_property (target_type ${target} TYPE )
113+ if (NOT target_type STREQUAL "EXECUTABLE" )
117114 return ()
118115 endif ()
119- endfunction ()
120-
121- # installLSLAppSingleFolder: installs the app its folder and copies needed libraries
122- #
123- # when calling make install / ninja install the executable is installed to
124- # CMAKE_INSTALL_PREFIX/PROJECT_NAME/TARGET_NAME
125- # e.g. C:/LSL/BrainAmpSeries/BrainAmpSeries.exe
126- function (installLSLAppSingleFolder target deployqt)
127- install (TARGETS ${target}
128- COMPONENT "${PROJECT_NAME} "
129- BUNDLE DESTINATION ${PROJECT_NAME}
130- RUNTIME DESTINATION ${PROJECT_NAME}
131- LIBRARY DESTINATION ${PROJECT_NAME} /lib
132- )
133- set (appbin "${CMAKE_INSTALL_PREFIX} /${PROJECT_NAME} /${target}${CMAKE_EXECUTABLE_SUFFIX} " )
134116
135117 # Copy lsl library for WIN32 or MacOS.
136118 # On Mac, dylib is only needed for macdeployqt and for non bundles when not using system liblsl.
137119 # Copy anyway, and fixup_bundle can deal with the dylib already being present.
138- if (WIN32 OR APPLE )
139- installLSLAuxFiles(${target} $<TARGET_FILE:LSL::lsl>)
140- set_property (INSTALL "${PROJECT_NAME} /$<TARGET_FILE_NAME:${target} >" PROPERTY
141- CPACK_START_MENU_SHORTCUTS "${target} " )
142- endif ()
143-
144- # do we need to install with Qt5?
145- if (deployqt)
146- if (WIN32 )
147- findQtInstallationTool("windeployqt" )
148- if (QT_DEPLOYQT_EXECUTABLE)
149- file (TO_NATIVE_PATH "${QT_BIN_DIR} " QT_BIN_DIR_NATIVE)
150- # It's safer to use `\` separators in the Path, but we need to escape them
151- string (REPLACE "\\ " "\\\\ " QT_BIN_DIR_NATIVE "${QT_BIN_DIR_NATIVE} " )
152- set (QT_DEPLOYQT_FLAGS --no -translations --no -system -d3d-compiler --no -opengl-sw --no -compiler-runtime)
153- file (GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR} /${target} _$<CONFIG>_path"
154- CONTENT "$<TARGET_FILE:${target} >" # Full path to .exe file
155- )
156- get_filename_component (appdir ${appbin} DIRECTORY CACHE )
157- install (CODE "
158- file(READ \" ${CMAKE_CURRENT_BINARY_DIR} /${target} _${CMAKE_BUILD_TYPE} _path\" _file)
159- message (STATUS \" Running Qt Deploy Tool for \$ {_file}\" )
160- if (CMAKE_INSTALL_CONFIG_NAME STREQUAL \" Debug\" )
161- set(QT_DEPLOYQT_FLAGS \"\$ {QT_DEPLOYQT_FLAGS} --debug\" )
162- else ()
163- set(QT_DEPLOYQT_FLAGS \"\$ {QT_DEPLOYQT_FLAGS} --release\" )
164- endif ()
165- execute_process(COMMAND
166- \" ${CMAKE_COMMAND} \" -E env
167- \" Path=${QT_BIN_DIR_NATIVE} ;\$ ENV{SystemRoot}\\\\ System32;\$ ENV{SystemRoot}\"
168- \" ${QT_DEPLOYQT_EXECUTABLE} \"
169- ${QT_DEPLOYQT_FLAGS} --dry-run --list mapping
170- \" ${appbin} \"
171- OUTPUT_VARIABLE output
172- OUTPUT_STRIP_TRAILING_WHITESPACE
173- )
174- string(REPLACE \"\\\\\" \" /\" _output \$ {output})
175- separate_arguments(_files WINDOWS_COMMAND \$ {_output})
176- while(_files)
177- list(GET _files 0 _src)
178- list(GET _files 1 _dest)
179- execute_process(
180- COMMAND \" ${CMAKE_COMMAND} \" -E
181- copy_if_different \$ {_src} \"\$ {CMAKE_INSTALL_PREFIX}/${PROJECT_NAME} /$\{ _dest}\"
182- )
183- list(REMOVE_AT _files 0 1)
184- endwhile()
185- " COMPONENT ${target} )
186- #add_custom_command(TARGET ${target} POST_BUILD
187- # COMMAND "${CMAKE_COMMAND}" -E env PATH="${QT_BIN_DIR}" "${QT_DEPLOYQT_EXECUTABLE}"
188- # ${QT_DEPLOYQT_FLAGS}
189- # \"$<TARGET_FILE:${target}>\")
190- endif ()
191- elseif (APPLE )
192- # It should be enough to call fixup_bundle (see below),
193- # but this fails to install qt plugins (cocoa).
194- # Use macdeployqt instead (but this is bad at grabbing lsl dylib, so we did that above)
195- findQtInstallationTool("macdeployqt" )
196- if (QT_DEPLOYQT_EXECUTABLE)
197- set (QT_DEPLOYQT_FLAGS "-verbose=1" ) # Adding -libpath=${CMAKE_INSTALL_PREFIX}/LSL/lib seems to do nothing, maybe deprecated
198- install (CODE "
199- message(STATUS \" Running Qt Deploy Tool...\" )
200- #list(APPEND QT_DEPLOYQT_FLAGS -dmg)
201- if(CMAKE_INSTALL_CONFIG_NAME STREQUAL \" Debug\" )
202- list(APPEND QT_DEPLOYQT_FLAGS -use-debug-libs)
203- endif()
204- execute_process(COMMAND
205- \" ${QT_DEPLOYQT_EXECUTABLE} \"
206- \" ${appbin} .app\"
207- ${QT_DEPLOYQT_FLAGS}
208- )
209- " )
210- endif ()
211- endif ()
212- elseif (APPLE )
120+ installLSLAuxFiles(${target} $<TARGET_FILE:LSL::lsl>)
121+ if (APPLE AND NOT qtapp)
213122 # fixup_bundle appears to be broken for Qt apps. Use only for non-Qt.
214123 get_target_property (target_is_bundle ${target} MACOSX_BUNDLE )
215124 if (target_is_bundle)
216125 install (CODE "
217126 include(BundleUtilities)
218127 set(BU_CHMOD_BUNDLE_ITEMS ON)
219- fixup_bundle(
220- ${appbin} .app
221- \"\"
222- \" ${CMAKE_INSTALL_PREFIX} /LSL/lib\"
223- )
128+ fixup_bundle(\$ {CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR} /${target} .app \"\" \" ${lsldir} \" )
224129 "
225130 COMPONENT ${PROJECT_NAME}
226131 )
227132 endif ()
228133 endif ()
134+
135+ # skip the rest if qt doesn't need to be deployed
136+ if (NOT qtapp)
137+ return ()
138+ endif ()
139+
140+ cmake_minimum_required (VERSION 3.15) # generator expressions in install(CODE)
141+ if (WIN32 )
142+ findQtInstallationTool("windeployqt" )
143+ install (CODE "
144+ message (STATUS \" Running windeployqt on $<TARGET_FILE:${target} >\" )
145+ execute_process(
146+ COMMAND ${QT_DEPLOYQT_EXECUTABLE} --no-translations
147+ --no-system-d3d-compiler --no-opengl-sw --no-virtualkeyboard
148+ --no-compiler-runtime --dry-run --list mapping
149+ $<TARGET_FILE:${target} >
150+ OUTPUT_VARIABLE output
151+ OUTPUT_STRIP_TRAILING_WHITESPACE
152+ )
153+ file(TO_CMAKE_PATH \$ {output} output) # convert slashes
154+ separate_arguments(_files WINDOWS_COMMAND \$ {output})
155+ while(_files)
156+ list(POP_FRONT _files _src)
157+ list(POP_FRONT _files _dest)
158+ get_filename_component(_dest \$ {_dest} DIRECTORY RELATIVE)
159+ file(COPY \$ {_src} DESTINATION \$ {CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR} /\$ {_dest})
160+ endwhile()"
161+ COMPONENT ${target} )
162+ elseif (APPLE )
163+ # It should be enough to call fixup_bundle (see below),
164+ # but this fails to install qt plugins (cocoa).
165+ # Use macdeployqt instead (but this is bad at grabbing lsl dylib, so we did that above)
166+ findQtInstallationTool("macdeployqt" )
167+ install (CODE "
168+ if(\$ {CMAKE_INSTALL_CONFIG_NAME} STREQUAL Debug)
169+ set(debug 1)
170+ endif()
171+ message(STATUS \" Running Qt Deploy Tool for $<TARGET_FILE:${target} >...\" )
172+ execute_process(COMMAND
173+ echo \" ${QT_DEPLOYQT_EXECUTABLE} \"
174+ $<TARGET_FILE:${target} >
175+ -verbose=1
176+ $<$<BOOL:\$ {debug}>:--use-debug-libs>
177+ )
178+ " )
179+ endif ()
229180endfunction ()
230181
182+ function (findQtInstallationTool qtdeploytoolname)
183+ if (QT_DEPLOYQT_EXECUTABLE)
184+ return ()
185+ endif ()
186+ get_target_property (QT_QMAKE_EXE Qt5::qmake IMPORTED_LOCATION )
187+ get_filename_component (QT_BIN_DIR "${QT_QMAKE_EXE} " DIRECTORY )
188+ find_program (QT_DEPLOYQT_EXECUTABLE ${qtdeploytoolname} HINTS "${QT_BIN_DIR} " )
189+ if (QT_DEPLOYQT_EXECUTABLE)
190+ message (STATUS "Qt deploy tool found at ${QT_DEPLOYQT_EXECUTABLE} " )
191+ else ()
192+ message (WARNING "Qt deploy tool wasn't found, installing ${PROJECT_NAME} will fail!" )
193+ return ()
194+ endif ()
195+ endfunction ()
231196
232197# default paths, versions and magic to guess it on windows
233198# guess default paths for Windows / VC
@@ -330,12 +295,12 @@ macro(LSLGenerateCPackConfig)
330295 set (CPACK_PACKAGE_VENDOR "Labstreaminglayer" )
331296 if (APPLE )
332297 set (CPACK_GENERATOR "TBZ2" )
333- if (DEFINED ENV{OSXVER})
334- # Configured by Travis-CI for multi-osx builds.
335- set (LSL_OS "$ENV{OSXVER} " )
336- else ()
337- set (LSL_OS "OSX${lslplatform} " )
338- endif (DEFINED ENV{OSXVER})
298+ if (DEFINED ENV{OSXVER})
299+ # Configured by Travis-CI for multi-osx builds.
300+ set (LSL_OS "$ENV{OSXVER} " )
301+ else ()
302+ set (LSL_OS "OSX${lslplatform} " )
303+ endif (DEFINED ENV{OSXVER})
339304 elseif (WIN32 )
340305 set (CPACK_GENERATOR ZIP) # you can create NSIS packages by calling 'cpack -G NSIS'
341306 set (CPACK_NSIS_MODIFY_PATH ON )
@@ -365,9 +330,7 @@ macro(LSLGenerateCPackConfig)
365330 get_cmake_property (CPACK_COMPONENTS_ALL COMPONENTS)
366331 foreach (component ${CPACK_COMPONENTS_ALL} )
367332 string (TOUPPER ${component} COMPONENT )
368- message (STATUS "Setting packages name for ${COMPONENT} " )
369333 set (LSL_CPACK_FILENAME "${component} -${PROJECT_VERSION_MAJOR} .${PROJECT_VERSION_MINOR} .${PROJECT_VERSION_PATCH} -${LSL_OS} " )
370- message (STATUS "File name: ${LSL_CPACK_FILENAME} " )
371334 get_property (LSLDEPENDS GLOBAL PROPERTY "LSLDEPENDS_${component} " )
372335 if (LSLDEPENDS)
373336 list (REMOVE_DUPLICATES LSLDEPENDS)
0 commit comments