Skip to content

Commit

Permalink
bf: osx qt deployment
Browse files Browse the repository at this point in the history
  • Loading branch information
ahoopes committed Jan 8, 2019
1 parent 03b3035 commit 1ddc3ee
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 85 deletions.
42 changes: 16 additions & 26 deletions cmake/FindQT.cmake
Original file line number Diff line number Diff line change
@@ -1,45 +1,35 @@
# Qt Find Module

# default search path
if(USE_QT4)
set(PACKAGES_QT ${FS_PACKAGES_DIR}/qt/4.8.5)
if(NOT QT_QMAKE_EXECUTABLE AND EXISTS ${PACKAGES_QT})
set(QT_INSTALL_DIR ${PACKAGES_QT})
set(QT_QMAKE_EXECUTABLE ${QT_INSTALL_DIR}/bin/qmake)
if(NOT Qt5_DIR)
# default search path
if(EXISTS ${FS_PACKAGES_DIR}/qt/5.11/lib/cmake/Qt5)
set(Qt5_DIR ${FS_PACKAGES_DIR}/qt/5.11/lib/cmake/Qt5)
elseif(EXISTS ${FS_PACKAGES_DIR}/qt/5.6/lib/cmake/Qt5)
set(Qt5_DIR ${FS_PACKAGES_DIR}/qt/5.6/lib/cmake/Qt5)
endif()
else()
set(PACKAGES_QT ${FS_PACKAGES_DIR}/qt/5.6/lib/cmake/Qt5)
if(NOT Qt5_DIR AND EXISTS ${PACKAGES_QT})
set(Qt5_DIR ${PACKAGES_QT})
endif()
get_filename_component(QT_INSTALL_DIR "${Qt5_DIR}/../../.." ABSOLUTE)
endif()
get_filename_component(QT_INSTALL_DIR "${Qt5_DIR}/../../.." ABSOLUTE)

# find Qt components and trace back root of install
if(USE_QT4)
set(QT_COMPONENTS QtCore QtGui)
find_package(Qt4 COMPONENTS ${QT_COMPONENTS})
else()
set(QT_COMPONENTS Core Widgets)
if(NOT APPLE)
set(QT_COMPONENTS ${QT_COMPONENTS} X11Extras)
endif()
find_package(Qt5 COMPONENTS ${QT_COMPONENTS})
set(QT_COMPONENTS Core Widgets)
if(NOT APPLE)
set(QT_COMPONENTS ${QT_COMPONENTS} X11Extras)
endif()

find_package(Qt5 COMPONENTS ${QT_COMPONENTS})

# install the shared libraries to the freesurfer lib directory
if(((NOT USE_QT4 AND Qt5_FOUND) OR (USE_QT4 AND Qt4_FOUND)) AND NOT APPLE)
if(Qt5_FOUND AND NOT APPLE)
file(GLOB QT_LIBRARIES_TO_INSTALL "${QT_INSTALL_DIR}/lib/lib*.so*")
if(QT_LIBRARIES_TO_INSTALL)
install(PROGRAMS ${QT_LIBRARIES_TO_INSTALL} DESTINATION lib/qt/lib)
# add Qt library directory to rpath
set(CMAKE_INSTALL_RPATH "$ORIGIN/../lib/qt/lib:${CMAKE_INSTALL_RPATH}")
# install the platform plugins as well, and make sure executables know
#where to find the plugins directory
if(NOT USE_QT4 AND EXISTS ${QT_INSTALL_DIR}/plugins/platforms)
# where to find the plugins directory
if(EXISTS ${QT_INSTALL_DIR}/plugins/platforms)
install(DIRECTORY ${QT_INSTALL_DIR}/plugins/platforms DESTINATION lib/qt/plugins)
install(FILES ${CMAKE_SOURCE_DIR}/cmake/qt.conf DESTINATION bin)
install(FILES ${CMAKE_SOURCE_DIR}/qt/qt.conf DESTINATION bin)
endif()
endif()
endif()

25 changes: 25 additions & 0 deletions cmake/functions.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,31 @@ function(install_tarball)
endfunction()


# mac_deploy_qt(TARGET <target> BUNDLE <bundle> PLIST <plist> ICONS <icons>)
# Creates a mac app bundle from a given target. The ICONS argument is optional.
function(mac_deploy_qt)
cmake_parse_arguments(APP "" "TARGET;BUNDLE;PLIST;ICONS" "" ${ARGN})
# install binary
install(TARGETS ${APP_TARGET} DESTINATION ${APP_BUNDLE}/Contents/MacOS)
# install the plist
install(FILES ${APP_PLIST} DESTINATION ${APP_BUNDLE}/Contents)
# install the resources
if(${APP_ICONS})
install_symlinks(${APP_ICONS} TYPE files DESTINATION ${BUNDLE}/Contents/Resources)
endif()
# run the qt deployment script and create a wrapper script in the bin
# directory that will call the bundle binary
install(CODE "
message(STATUS \"Deploying ${APP_BUNDLE}\")
execute_process(COMMAND bash -c \"${CMAKE_SOURCE_DIR}/qt/mac_deploy ${QT_INSTALL_DIR} ${CMAKE_INSTALL_PREFIX}/${APP_BUNDLE}\" RESULT_VARIABLE retcode)
if(NOT \${retcode} STREQUAL 0)
message(FATAL_ERROR \"Could not deploy ${APP_TARGET}\")
endif()
file(WRITE ${CMAKE_INSTALL_PREFIX}/bin/${APP_TARGET} \"#!/usr/bin/env bash\\nexit $($FREESURFER_HOME/${APP_BUNDLE}/Contents/MacOS/${APP_TARGET} \"$@\")\")"
)
endfunction()


# add_help(<binary> <xml>)
# Link an xml helptext to a target binary. This will create a target dependency on
# the help file and will run xxd to create the xml header during the build
Expand Down
57 changes: 9 additions & 48 deletions freeview/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
project(freeview)

if(BUILD_GUIS AND (Qt5_FOUND OR Qt4_FOUND) AND VTK_FOUND AND ITK_FOUND AND PETSC_FOUND AND TARGET vtkutils)
if(BUILD_GUIS AND VTK_FOUND AND PETSC_FOUND AND TARGET vtkutils)

include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
Expand Down Expand Up @@ -187,40 +187,18 @@ if(BUILD_GUIS AND (Qt5_FOUND OR Qt4_FOUND) AND VTK_FOUND AND ITK_FOUND AND PETSC
freeview.qrc
)

if(USE_QT4)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/json)
set(SOURCES ${SOURCES}
json/qjsonarray.cpp
json/qjson.cpp
json/qjsondocument.cpp
json/qjsonobject.cpp
json/qjsonparser.cpp
json/qjsonvalue.cpp
json/qjsonwriter.cpp
)
endif()

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated -Wno-reorder -Wno-uninitialized -Wno-unused-variable -Wno-sign-compare")

set(QT_LIBRARIES Qt5::Core Qt5::Widgets)

if(APPLE)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -framework Cocoa -framework IOKit -framework Accelerate")
set(FREEVIEW_EXEC_NAME Freeview)
else()
set(FREEVIEW_EXEC_NAME freeview)
set(QT_LIBRARIES ${QT_LIBRARIES} Qt5::X11Extras)
endif()

if(USE_QT4)
set(QT_LIBRARIES Qt4::QtCore Qt4::QtGui)
else()
set(QT_LIBRARIES Qt5::Core Qt5::Widgets)
if(NOT APPLE)
set(QT_LIBRARIES ${QT_LIBRARIES} Qt5::X11Extras)
endif()
endif()

add_executable(${FREEVIEW_EXEC_NAME} ${SOURCES})

target_link_libraries(${FREEVIEW_EXEC_NAME}
add_executable(freeview ${SOURCES})
target_link_libraries(freeview
vtkutils
vtkfsio
lineprof
Expand All @@ -238,30 +216,13 @@ if(BUILD_GUIS AND (Qt5_FOUND OR Qt4_FOUND) AND VTK_FOUND AND ITK_FOUND AND PETSC
)

if(NOT APPLE)
target_link_libraries(${FREEVIEW_EXEC_NAME} ${GLUT_LIBRARIES} ${Xt_LIBRARIES} ${X11_LIBRARIES})
target_link_libraries(freeview ${GLUT_LIBRARIES} ${Xt_LIBRARIES} ${X11_LIBRARIES})
endif()

if(APPLE)
install(TARGETS ${FREEVIEW_EXEC_NAME} DESTINATION Freeview.app/Contents/MacOS)
install(PROGRAMS freeview_wrapper_osx DESTINATION bin RENAME freeview)
install(FILES Info.plist DESTINATION Freeview.app/Contents)
install(DIRECTORY DESTINATION Freeview.app/Contents/Resources/English.lproj)
install_symlinks(resource/icons/freeview.icns TYPE files DESTINATION Freeview.app/Contents/Resources)
install(CODE "
message(STATUS \"Deploying Freeview.app\")
# Add verbosity for debugging
# execute_process(COMMAND bash -c \"${QT_INSTALL_DIR}/bin/macdeployqt ${CMAKE_INSTALL_PREFIX}/Freeview.app -verbose=3 -always-overwrite\" RESULT_VARIABLE retcode)
execute_process(COMMAND bash -c \"${QT_INSTALL_DIR}/bin/macdeployqt ${CMAKE_INSTALL_PREFIX}/Freeview.app -verbose=2 -always-overwrite\" RESULT_VARIABLE retcode)
if(NOT \${retcode} STREQUAL 0)
message(FATAL_ERROR \"Could not run macdeployqt\")
endif()
execute_process(COMMAND bash -c \"${CMAKE_CURRENT_SOURCE_DIR}/macdeployqt_patch.py ${CMAKE_INSTALL_PREFIX}/Freeview.app/Contents\" RESULT_VARIABLE retcode)
if(NOT \${retcode} STREQUAL 0)
message(FATAL_ERROR \"Could not run install_name_tool commands to add rpath to Qt frameworks in application bundle\")
endif()"
)
mac_deploy_qt(TARGET freeview BUNDLE Freeview.app PLIST Info.plist ICONS resource/icons/freeview.icns)
else()
install(TARGETS ${FREEVIEW_EXEC_NAME} DESTINATION bin)
install(TARGETS freeview DESTINATION bin)
endif()

endif()
4 changes: 2 additions & 2 deletions freeview/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleExecutable</key>
<string>Freeview</string>
<string>freeview</string>
<key>CFBundleIdentifier</key>
<string>com.yourcompany.Freeview</string>
<string>com.yourcompany.freeview</string>
<key>NOTE</key>
<string>This file was generated by Qt/QMake.</string>
</dict>
Expand Down
9 changes: 0 additions & 9 deletions freeview/freeview_wrapper_osx

This file was deleted.

44 changes: 44 additions & 0 deletions qt/mac_deploy
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#!/usr/bin/env bash

set -e

# input checks
if [ "$#" -ne "2" ]; then
echo "error: mac_deploy requires 2 arguments"
echo "usage: mac_deploy <qt-directory> <bundle-directory>"
exit 1
fi

qtdir="$1"
if [ ! -d "$qtdir" ]; then
echo "error: qt directory '$qtdir' does not exist"
exit 1
fi

bundle="$2"
if [ ! -d "$bundle" ]; then
echo "error: bundle directory '$bundle' does not exist"
exit 1
fi

# create the proj language directory
mkdir -p ${bundle}/Contents/Resources/English.lproj

# locate the bundle binary
binary="$(ls ${bundle}/Contents/MacOS)"
if [ "$(echo $binary | wc -w)" -ne "1" ] ; then
echo "error: more than 1 file found in ${bundle}/Contents/MacOS"
exit 1
fi
binarypath="${bundle}/Contents/MacOS/${binary}"

# run macdeployqt
${qtdir}/bin/macdeployqt ${bundle} -always-overwrite

# if the final binary references the Qt frameworks via rpath, we need to actually
# add a relative rpath, since macdeployqt completely ignores this
if [ -n "$(otool -L $binarypath | grep '@rpath/Qt')" ] ; then
if [ -z "$(otool -l $binarypath | grep '@executable_path/../Frameworks')" ] ; then
install_name_tool -add_rpath "@executable_path/../Frameworks" $binarypath
fi
fi
File renamed without changes.

0 comments on commit 1ddc3ee

Please sign in to comment.