Skip to content

Commit

Permalink
Build macOS package with CPack (#256)
Browse files Browse the repository at this point in the history
Co-authored-by: Ruslan Iusupov <[email protected]>
  • Loading branch information
rus0000 and Ruslan Iusupov authored Feb 8, 2022
1 parent ce2fb77 commit 726d975
Show file tree
Hide file tree
Showing 27 changed files with 428 additions and 207 deletions.
10 changes: 4 additions & 6 deletions .github/workflows/BuildPR.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,15 @@ jobs:
- name: Set XCode Version
run: sudo xcode-select -s /Applications/${{ matrix.xcode }}.app
- name: install build environment
run: scripts/linux/install.sh
run: scripts/darwin/install.sh
- name: Build project
run: scripts/linux/build.sh
run: scripts/darwin/build.sh
- name: Archive artifact
uses: actions/[email protected]
if: ${{ success() }}
with:
name: DLTViewer-${{ matrix.macos }}-x86_64
path: build/dist
path: build/dist/DLTViewer*.tgz

buildLinux:
name: Build ${{ matrix.ubuntu }}
Expand All @@ -60,9 +60,7 @@ jobs:
if: ${{ success() }}
with:
name: DLTViewer-linux-x86_64
path: |
build/dist/DLTViewer*.AppImage
build/dist/*.md
path: build/dist/DLTViewer*.tgz

buildWindows:
name: Build Windows
Expand Down
27 changes: 16 additions & 11 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,8 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
get_target_property(DLT_QT5_LIBRARY_PATH Qt5::Core LOCATION)
get_filename_component(DLT_QT5_LIB_DIR ${DLT_QT5_LIBRARY_PATH} DIRECTORY)

if(NOT WIN32)
option(DLT_USE_QT_RPATH "Use RPATH for QT_LIBRARY_PATH to support non-standard QT install locations" ON)
if (DLT_USE_QT_RPATH)
# Add Qt to the RPATH, so that there is no need to set LD_LIBRARY_PATH at runtime if Qt is installed in a non-standard location
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_RPATH};${DLT_QT5_LIB_DIR}")
endif()
endif()
# Add Qt to the RPATH, so that there is no need to set LD_LIBRARY_PATH at runtime if Qt is installed in a non-standard location
option(DLT_USE_QT_RPATH "Use RPATH for QT_LIBRARY_PATH to support non-standard QT install locations" ON)

# Injection of the GCC-specific compilation flags
if(CMAKE_COMPILER_IS_GNUCXX)
Expand All @@ -73,6 +68,12 @@ add_compile_definitions(QT5)

option(DLT_USE_STANDARD_INSTALLATION_LOCATION "Use standard GNU installation locations" OFF)
if(NOT WIN32)
if(NOT DLT_APP_DIR_NAME)
set(DLT_APP_DIR_NAME "DLTViewer")
if(APPLE)
set(DLT_APP_DIR_NAME "DLTViewer.app")
endif()
endif()
if(DLT_USE_STANDARD_INSTALLATION_LOCATION)
include(GNUInstallDirs)
set(DLT_PLUGIN_INSTALLATION_PATH "${CMAKE_INSTALL_FULL_LIBDIR}/dlt-viewer/plugins")
Expand All @@ -84,19 +85,22 @@ if(NOT WIN32)
set(CMAKE_INSTALL_PREFIX "DLTViewer")
endif()
if(NOT DLT_PLUGIN_INSTALLATION_PATH)
set(DLT_PLUGIN_INSTALLATION_PATH "usr/bin/plugins")
set(DLT_PLUGIN_INSTALLATION_PATH "${DLT_APP_DIR_NAME}/usr/bin/plugins")
endif()
if(NOT DLT_RESOURCE_INSTALLATION_PATH)
set(DLT_RESOURCE_INSTALLATION_PATH "usr/share")
set(DLT_RESOURCE_INSTALLATION_PATH "${DLT_APP_DIR_NAME}/usr/share")
endif()
if(NOT DLT_EXECUTABLE_INSTALLATION_PATH)
set(DLT_EXECUTABLE_INSTALLATION_PATH "usr/bin")
set(DLT_EXECUTABLE_INSTALLATION_PATH "${DLT_APP_DIR_NAME}/usr/bin")
endif()
if(NOT DLT_LIBRARY_INSTALLATION_PATH)
set(DLT_LIBRARY_INSTALLATION_PATH "usr/lib")
set(DLT_LIBRARY_INSTALLATION_PATH "${DLT_APP_DIR_NAME}/usr/lib")
endif()
endif()
else()
if(NOT DLT_APP_DIR_NAME)
set(DLT_APP_DIR_NAME "./")
endif()
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
# AppData is a modern install location. No Admin rights required.
file(TO_CMAKE_PATH "$ENV{LOCALAPPDATA}/Programs/dlt-viewer" CMAKE_INSTALL_PREFIX)
Expand Down Expand Up @@ -137,3 +141,4 @@ message(STATUS "\tDLT_QT5_LIB_DIR: ${DLT_QT5_LIB_DIR}\n")
# Must be last
include(scripts/windows/package.cmake)
include(scripts/linux/package.cmake)
include(scripts/darwin/package.cmake)
2 changes: 1 addition & 1 deletion parser/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ target_link_libraries(dlt-parser Qt5::Widgets)

set_target_properties(dlt-parser PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
INSTALL_RPATH "$ORIGIN/../lib;$<$<BOOL:${DLT_USE_QT_RPATH}>:${DLT_QT5_LIB_DIR}>")
INSTALL_RPATH "$<$<BOOL:${LINUX}>:$ORIGIN/../lib;>$<$<BOOL:${APPLE}>:@loader_path/../Frameworks;>$<$<BOOL:${DLT_USE_QT_RPATH}>:${DLT_QT5_LIB_DIR}>")

if(CMAKE_COMPILER_IS_GNUCXX)
# https://stackoverflow.com/questions/45329372/ubuntu-recognizes-executable-as-shared-library-and-wont-run-it-by-clicking
Expand Down
2 changes: 1 addition & 1 deletion plugin/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ function(add_plugin NAME)
set_target_properties(${NAME} PROPERTIES
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin/plugins
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin/plugins
INSTALL_RPATH "$ORIGIN/../../lib;$<$<BOOL:${DLT_USE_QT_RPATH}>:${DLT_QT5_LIB_DIR}>")
INSTALL_RPATH "$<$<BOOL:${LINUX}>:$ORIGIN/../../lib;>$<$<BOOL:${APPLE}>:@loader_path/../../Frameworks;>$<$<BOOL:${DLT_USE_QT_RPATH}>:${DLT_QT5_LIB_DIR}>")

install(TARGETS ${NAME}
DESTINATION "${DLT_PLUGIN_INSTALLATION_PATH}"
Expand Down
15 changes: 11 additions & 4 deletions qdlt/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -65,20 +65,27 @@ endif()
set_target_properties(qdlt PROPERTIES
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
INSTALL_RPATH "$ORIGIN;$<$<BOOL:${DLT_USE_QT_RPATH}>:${DLT_QT5_LIB_DIR}>")
INSTALL_RPATH "$<$<BOOL:${LINUX}>:$ORIGIN;>$<$<BOOL:${APPLE}>:@loader_path;>$<$<BOOL:${DLT_USE_QT_RPATH}>:${DLT_QT5_LIB_DIR}>")

install(TARGETS qdlt
LIBRARY DESTINATION "${DLT_LIBRARY_INSTALLATION_PATH}"
RUNTIME DESTINATION "${DLT_LIBRARY_INSTALLATION_PATH}"
COMPONENT qdlt)

# Install QDLT SDK

if(WIN32)
set(DLT_ADDITIONAL_FILES_INSTALLATION_PATH "${DLT_EXECUTABLE_INSTALLATION_PATH}")
else()
set(DLT_ADDITIONAL_FILES_INSTALLATION_PATH ".")
endif()

install(TARGETS qdlt
DESTINATION "${DLT_EXECUTABLE_INSTALLATION_PATH}/sdk/lib"
DESTINATION "${DLT_ADDITIONAL_FILES_INSTALLATION_PATH}/sdk/lib"
COMPONENT qdlt_sdk)

install(DIRECTORY "."
DESTINATION "${DLT_EXECUTABLE_INSTALLATION_PATH}/sdk/include"
DESTINATION "${DLT_ADDITIONAL_FILES_INSTALLATION_PATH}/sdk/include"
COMPONENT qdlt_sdk
FILES_MATCHING PATTERN "*.h")

Expand All @@ -90,6 +97,6 @@ set(SDK_EXAMPLES

foreach(SDK_EXAMPLE IN ITEMS ${SDK_EXAMPLES})
install(DIRECTORY "../plugin/${SDK_EXAMPLE}"
DESTINATION "${DLT_EXECUTABLE_INSTALLATION_PATH}/sdk/src"
DESTINATION "${DLT_ADDITIONAL_FILES_INSTALLATION_PATH}/sdk/src"
COMPONENT qdlt_sdk)
endforeach()
38 changes: 38 additions & 0 deletions scripts/darwin/Info.plist.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>@MACOSX_BUNDLE_EXECUTABLE_NAME@</string>
<key>CFBundleGetInfoString</key>
<string>@MACOSX_BUNDLE_INFO_STRING@</string>
<key>CFBundleIconFile</key>
<string>@MACOSX_BUNDLE_ICON_FILE@</string>
<key>CFBundleIdentifier</key>
<string>@MACOSX_BUNDLE_GUI_IDENTIFIER@</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleLongVersionString</key>
<string>@MACOSX_BUNDLE_LONG_VERSION_STRING@</string>
<key>CFBundleName</key>
<string>@MACOSX_BUNDLE_BUNDLE_NAME@</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>@MACOSX_BUNDLE_SHORT_VERSION_STRING@</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>@MACOSX_BUNDLE_BUNDLE_VERSION@</string>
<key>CSResourcesFileMapped</key>
<true/>
<key>NSHumanReadableCopyright</key>
<string>@MACOSX_BUNDLE_COPYRIGHT@</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>NSHighResolutionCapable</key>
<true/>
</dict>
</plist>
11 changes: 11 additions & 0 deletions scripts/darwin/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
## DLT Viewer on Windows
- [Installation](../windows/install.md) - for regular users
- [Build and contribute](../windows/build.md) - for developers

## DLT Viewer on Linux
- [Installation](../linux/install.md) - for regular users
- [Build and contribute](../linux/build.md) - for developers

## DLT Viewer on macOS
- [Installation](./install.md) - for regular users
- [Build and contribute](./build.md) - for developers
30 changes: 30 additions & 0 deletions scripts/darwin/build.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# CMake + MS Visual Studio Code
Please see also [DLT Viewer: CMake + MS Visual Studio Code](../windows/build.md)

# macOs development environment setup
For DLT Viewer development on **MS Windows** please see [Windows development environment setup](../windows/build.md)
For DLT Viewer development on **Linux** please see [Linux development environment setup](../linux/build.md)

Configuration:
- macOS Catalina 10.15+
- Administrator rights `sudo`
- Build environment [install.sh](./install.sh)
- `sudo dlt-viewer/scripts/linux/install.sh`
- MS Visual Studio Code
- https://code.visualstudio.com/docs/setup/mac
- Setup `.vscode` folder
- Copy content of `dlt-viewer/scripts/windows/.vscode_example/*.json` into `dlt-viewer/.vscode/`
- `.vscode` folder contains developer specific settings and not committed to the project.

# Development with Visual Studio Code
- Please see [windows/build.md](../windows/build.md) on how to use CMake and VS Code with DLT Viewer project.

# "Build from sources" use-case
- Build Release configuration
- [windows/build.md](../windows/build.md#command-line-build)
- Do NOT use `cmake --install .` for system-wide install.
- Do `cpack -G External` to generate macOS Application bundle.
- Copy/drag DltViewer.app to Applications folder.

# Build release package
- Same as "Build from sources" use-case.
61 changes: 61 additions & 0 deletions scripts/darwin/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#!/usr/bin/env bash
set -ex

SRC_DIR=$(pwd)
BUILD_DIR="${SRC_DIR}/build"
INSTALL_DIR="${BUILD_DIR}/install"
APP_DIR_NAME="DLTViewer.app"

rm -rf "${INSTALL_DIR}"
rm -rf "${SRC_DIR}/build"
mkdir -p "${BUILD_DIR}"
cd "${BUILD_DIR}"

echo Build with QMake
Qt5_DIR="/usr/local/opt/qt"
qmake ../BuildDltViewer.pro
make

echo Cleanup
rm -rf "${INSTALL_DIR}"
rm -rf "${SRC_DIR}/build"
mkdir -p "${BUILD_DIR}"
cd "${BUILD_DIR}"

echo Build with CMake
# Installation paths configuration creates proper macOS Application bundle structure
# https://developer.apple.com/library/archive/documentation/CoreFoundation/Conceptual/CFBundles/BundleTypes/BundleTypes.html
cmake -G Ninja \
-DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} \
-DCMAKE_PREFIX_PATH=/opt/qt512/lib/cmake \
-DCMAKE_BUILD_TYPE=Release \
-DDLT_USE_QT_RPATH=ON \
-DDLT_PARSER=OFF \
-DDLT_APP_DIR_NAME=${APP_DIR_NAME} \
-DDLT_LIBRARY_INSTALLATION_PATH="${APP_DIR_NAME}/Contents/Frameworks" \
-DDLT_EXECUTABLE_INSTALLATION_PATH="${APP_DIR_NAME}/Contents/MacOS" \
-DDLT_RESOURCE_INSTALLATION_PATH="${APP_DIR_NAME}/Contents/Resources" \
-DDLT_PLUGIN_INSTALLATION_PATH="${APP_DIR_NAME}/Contents/MacOS/plugins" \
"${SRC_DIR}"
cmake --build "${BUILD_DIR}"

# See src/cmake/Darwin.cmake and scripts/darwin/package.cmake
#
# CPack macOS "Bundle generator" and "DragNDrop Generator" are NOT used. Their functionality is replaced by macdeployqt.
# - https://cmake.org/cmake/help/latest/cpack_gen/bundle.html
# - https://cmake.org/cmake/help/latest/module/CPackDMG.html
#
# External CPack generator calls "cmake --install" and "macdeployqt"
# - https://doc.qt.io/qt-5/macos-deployment.html
#
# CMake install takes care of proper macOs Application bundle setup. Each CMake target has a pre-configured path in bundle.
# macdeployqt copies all used QT5 Frameworks into bundle and patches RPATH in project binaries.
cpack -G External

cd "${BUILD_DIR}"
FULL_VERSION=$(cat "${BUILD_DIR}/full_version.txt")
echo "FULL_VERSION=${FULL_VERSION}"

mkdir -p dist
cp ../scripts/darwin/install.md dist
tar -czvf "dist/DLTViewer-${FULL_VERSION}.tgz" -C ${INSTALL_DIR} .
18 changes: 13 additions & 5 deletions scripts/darwin/install.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
# Installation of DLT Viewer on macOS
# Requirements
- Supported platforms
- macOS 10.15.4+ x86
- Supported platforms:
- macOS Catalina 10.15 x86_64 and later.
- Administrator rights. Needed to override bundle signature.

# Developer signature override
- DLT Viewer Application bundle is not yet signed.
- You can temporarily override your Mac security settings to open it.
- Go to *Security & Privacy*, click on the lock symbol and choose choose *Anywhere*.
- https://support.apple.com/en-us/HT202491
- https://www.google.com/search?q=macos+allow+unsigned+application

# Installation
## Install QT5
- `brew install qt@5`
- `brew link qt@5 --force`
- Download and unpack DLT Viewer archive.
- Drag DLTViewer.dmg to Applications folder, making it available in the macOS Launchpad.
- As an alternative DLTViewer.app folder is also included in the archive.
16 changes: 16 additions & 0 deletions scripts/darwin/install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/usr/bin/env bash
set -ex

id
env
pwd

brew install qt@5
brew link qt@5 --force
# https://github.com/Homebrew/homebrew-core/issues/8392
# https://github.com/Homebrew/legacy-homebrew/issues/29938
QT_VERSION=$(brew list --versions qt@5 | sed -n '/qt@5/s/^.*[^0-9]\([0-9]*\.[0-9]*\.[0-9]*.*\).*$/\1/p')
sudo ln -s "/usr/local/Cellar/qt@5/${QT_VERSION}/mkspecs" /usr/local/mkspecs
sudo ln -s "/usr/local/Cellar/qt@5/${QT_VERSION}/plugins" /usr/local/plugins

brew install ninja tree
45 changes: 45 additions & 0 deletions scripts/darwin/macdeployqt.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
set(MACDEPLOYQT_EXECUTABLE "@MACDEPLOYQT_EXECUTABLE@")
set(CMAKE_BINARY_DIR "@CMAKE_BINARY_DIR@")
set(CMAKE_INSTALL_PREFIX "@CMAKE_INSTALL_PREFIX@")
set(DLT_APP_DIR_NAME "@DLT_APP_DIR_NAME@")
set(DLT_PLUGIN_INSTALLATION_PATH "@DLT_PLUGIN_INSTALLATION_PATH@")

# See CMAKE_INSTALL_PREFIX
execute_process(COMMAND ${CMAKE_COMMAND} "--install" "." "--prefix" "${CMAKE_INSTALL_PREFIX}"
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
RESULT_VARIABLE STATUS)

if(STATUS AND NOT STATUS EQUAL 0)
message(SEND_ERROR "Failure: ${STATUS}")
else()
message(STATUS "Success.")
endif()

# execute_process(COMMAND ls -l
# WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
# RESULT_VARIABLE STATUS)

# execute_process(COMMAND tree
# WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
# RESULT_VARIABLE STATUS)

file(GLOB DLT_PLUGINS_SO "${CMAKE_INSTALL_PREFIX}/${DLT_PLUGIN_INSTALLATION_PATH}/*.so")
list(TRANSFORM DLT_PLUGINS_SO PREPEND "-executable=")

message(STATUS "Call ${MACDEPLOYQT_EXECUTABLE} ${DLT_APP_DIR_NAME} ${DLT_PLUGINS_SO}")
execute_process(COMMAND
"${MACDEPLOYQT_EXECUTABLE}"
"${DLT_APP_DIR_NAME}"
-verbose=1
-always-overwrite
-dmg
-libpath=${CMAKE_INSTALL_PREFIX}/${DLT_APP_DIR_NAME}/Contents/Frameworks
${DLT_PLUGINS_SO}
WORKING_DIRECTORY "${CMAKE_INSTALL_PREFIX}"
RESULT_VARIABLE STATUS)

if(STATUS AND NOT STATUS EQUAL 0)
message(SEND_ERROR "Failure: ${STATUS}")
else()
message(STATUS "Success.")
endif()
15 changes: 15 additions & 0 deletions scripts/darwin/package.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
if(NOT APPLE)
return()
endif()

# See build.sh and src/cmake/Darwin.cmake
set(CPACK_GENERATOR External)

get_target_property(MOC_LOCATION Qt5::moc LOCATION)
get_filename_component(MACDEPLOYQT_EXECUTABLE ${MOC_LOCATION}/../macdeployqt ABSOLUTE)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/scripts/darwin/macdeployqt.cmake.in" "${CMAKE_BINARY_DIR}/macdeployqt.cmake" @ONLY)

set(CPACK_EXTERNAL_PACKAGE_SCRIPT "${CMAKE_BINARY_DIR}/macdeployqt.cmake")

# Must be last
include(CPack)
Loading

0 comments on commit 726d975

Please sign in to comment.