Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
b96726c
unify splash with entrypoint
Jun 2, 2022
a7a9865
tweaks
Jun 2, 2022
db41920
splash
Jun 2, 2022
b3df9b6
guard
Jun 2, 2022
be33664
splash
Jun 2, 2022
85b35d9
format
Jun 2, 2022
cbf73eb
Merge remote-tracking branch 'origin/main' into silverjam/unify-splash
Jun 2, 2022
3af6dfe
remove unused import
Jun 2, 2022
e26ae27
try to cleanup macOS bundle
Jun 2, 2022
710f06d
tweaks
Jun 2, 2022
8e0f59d
Use Qt splash
Jun 2, 2022
815884d
handle when splash-version doesn't exist
Jun 3, 2022
a4b2658
format
Jun 3, 2022
6cec12a
remvoe unused import
Jun 3, 2022
ba3ffa6
try alternate resource paths
Jun 3, 2022
b5beeac
build splash before rcc
Jun 3, 2022
9e2ac8a
install imagemagick
Jun 3, 2022
2c15781
app constants
Jun 3, 2022
efff571
use old splash on linux
Jun 3, 2022
4625427
autocrlf
Jun 3, 2022
d41dda9
remove BOM
Jun 3, 2022
b434734
don't panic
Jun 3, 2022
f4c5cf6
lint
Jun 3, 2022
b4bde3e
argh
Jun 3, 2022
bd4a1a5
Merge branch 'silverjam/unify-splash' into silverjam/macos-bundle-cle…
Jun 3, 2022
b421698
remove dupe import
Jun 3, 2022
ab29348
Merge remote-tracking branch 'origin/main' into silverjam/macos-bundl…
Jun 3, 2022
f19256e
pythonhome_dir
Jun 3, 2022
ba4c3a6
format
Jun 3, 2022
f33e486
Merge branch 'main' into silverjam/macos-bundle-cleanup
Jun 4, 2022
6ada8f4
fmt
Jun 4, 2022
b1255f2
Merge branch 'main' into silverjam/macos-bundle-cleanup
Jun 4, 2022
bae8a43
Merge branch 'main' into silverjam/macos-bundle-cleanup
Jun 4, 2022
ae112dd
bundle improvements
Jun 5, 2022
0f64085
edit
Jun 5, 2022
5e2f20b
don't purge plugins
Jun 5, 2022
d52a500
fixup version and resource heuristic
swiftnav-svc-jenkins Jun 5, 2022
cd9ecdf
python fmt
swiftnav-svc-jenkins Jun 5, 2022
ca9e384
remove purge
swiftnav-svc-jenkins Jun 5, 2022
c1d5b40
ws
Jun 5, 2022
7d4e18b
bugfix
Jun 5, 2022
db539cd
store version
Jun 5, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 16 additions & 7 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -456,24 +456,26 @@ jobs:
shell: bash
run: |
cd "application/target/installer/Swift Console.app"

for f in $(find Contents/Resources/lib/ -name '*.dylib' -or -name '*.so')
do
codesign \
codesign -vvvv \
-s "${{ secrets.APPLE_DEVELOPER_ID }}" \
--timestamp \
"$f"
done

for f in $(ls Contents/Resources/lib/python3.9/site-packages/**/Qt/lib/*.framework/Versions/5/*)
do
codesign \
codesign -vvvv \
-s "${{ secrets.APPLE_DEVELOPER_ID }}" \
--timestamp \
"$f"
done

cd ../../../
codesign \

codesign -vvvv \
-s "${{ secrets.APPLE_DEVELOPER_ID }}" --deep \
--entitlements installers/macOS/entitlements.plist \
--timestamp \
Expand Down Expand Up @@ -626,11 +628,14 @@ jobs:
shell: bash
run: |
cd installer
codesign \

codesign -vvvv \
-s "${{ secrets.APPLE_DEVELOPER_ID }}" \
-f --timestamp \
$(cat installer-archive.filename)

xcrun altool \
--verbose \
--notarize-app \
--file $(cat installer-archive.filename) \
--primary-bundle-id ${{ env.APP_BUNDLE_ID }} \
Expand All @@ -654,6 +659,7 @@ jobs:
cd installer

xcrun altool \
--verbose \
--notarization-info ${{ env.REQUEST_UUID }} \
--apiKey ${{ secrets.APPLE_KEY_ID }} \
--apiIssuer ${{ secrets.APPLE_ISSUER_ID }} | tee notarize_status.log
Expand All @@ -666,7 +672,7 @@ jobs:
exit 1
fi

xcrun stapler staple "$(cat installer-archive.filename)"
xcrun stapler staple -v "$(cat installer-archive.filename)"

- name: Add archive to path.
shell: bash
Expand Down Expand Up @@ -743,7 +749,7 @@ jobs:
shell: bash
working-directory: binaries
run: |
codesign \
codesign -vvvv \
-s "${{ secrets.APPLE_DEVELOPER_ID }}" \
--timestamp \
--options=runtime \
Expand Down Expand Up @@ -840,10 +846,13 @@ jobs:
shell: bash
working-directory: binaries-all
run: |
codesign \

codesign -vvvv \
-s "${{ secrets.APPLE_DEVELOPER_ID }}" \
-f --timestamp "swift-binaries_${{ matrix.os.short_name }}_${{ env.VERSION }}-all.zip"

xcrun altool \
--verbose \
--notarize-app \
--file swift-binaries_${{ matrix.os.short_name }}_${{ env.VERSION }}-all.zip\
--primary-bundle-id ${{ env.APP_BUNDLE_ID }} \
Expand Down
30 changes: 25 additions & 5 deletions Makefile.toml
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,9 @@ app_name = get_env APP_NAME
cp target/release/${app_name} py39-dist/${app_name}
os = os_family
if eq ${os} mac
exec --fail-on-error install_name_tool -change /install/lib/libpython3.9.dylib @executable_path/lib/libpython3.9.dylib py39-dist/${app_name}
exec --fail-on-error install_name_tool -change /install/lib/libpython3.9.dylib @rpath/libpython3.9.dylib py39-dist/${app_name}
exec --fail-on-error install_name_tool -add_rpath @executable_path/../Resources/lib py39-dist/${app_name}
exec --fail-on-error install_name_tool -add_rpath @executable_path/lib py39-dist/${app_name}
elseif eq ${os} linux
cp target/release/windowpos py39-dist/windowpos
end
Expand Down Expand Up @@ -482,6 +484,7 @@ py_folders = array test tests examples __pycache__ demos turtledemo translations
qt_folders = array plugins/geoservices plugins/virtualkeyboard plugins/sqldrivers lib/Tix8.4.3 tcl/tix8.4.3 Qt/resources PySide2/resources
qml_folders = array qml/QtWeb* qml/QtBluetooth* qml/QtNfc* qml/QtGamepad qml/QtTest qml/QtQuick3D qml/Qt3D qml/QtSensors qml/QtLocation qml/QtPositioning
all_folders = array_concat ${py_folders} ${qt_folders} ${qml_folders}

for name in ${all_folders}
folders = glob_array **/${name}/
for folder in ${folders}
Expand All @@ -490,6 +493,7 @@ for name in ${all_folders}
end

file_exts = array pyc pyi tcl gif png

for ext in ${file_exts}
files = glob_array **/*.${ext}
for file in ${files}
Expand All @@ -505,6 +509,7 @@ for ext in ${file_exts}
end

libs = array QtSensors QtLocation Qt5Location QtPositioning Qt3D Qt53D Qt5Nfc Qt5Web QtWeb Qt5Pdf Qt5Designer Qt5DesignerComponents Qt5VirtualKeyboard Qt5Bluetooth Qt5Quick3D

for lib in ${libs}
files = glob_array ./**/*${lib}*
for file in ${files}
Expand All @@ -514,6 +519,7 @@ for lib in ${libs}
end

os = os_family

if eq ${os} windows
rm -r ./Scripts

Expand Down Expand Up @@ -580,6 +586,18 @@ else
end
endif

if eq ${os} mac
rm -r lib/python3.9/site-packages/PySide2/Designer.app/

rm lib/python3.9/lib-dynload/_testcapi.cpython-39-darwin.so
rm lib/python3.9/lib-dynload/xxlimited.cpython-39-darwin.so

rm -r lib/python3.9/venv/

rm -r lib/pkgconfig/
rm -r lib/thread2.8.5/
endif

py_internal_libs = array Lib/email Lib/distutils Lib/http Lib/multiprocessing Lib/msilib Lib/http Lib/dbm Lib/curses Lib/xml Lib/xmlrpc Lib/urllib Lib/ensurepip Lib/venv Lib/wsgiref Lib/lib2to3

for name in ${py_internal_libs}
Expand All @@ -590,6 +608,7 @@ for name in ${py_internal_libs}
end

files = glob_array ./**/*.py

for file in ${files}
rm ${file}
end
Expand Down Expand Up @@ -671,7 +690,7 @@ set_env BACKGROUND_PATH "resources/images/LogoBackground.jpg"

[tasks.dist-to-installer-app]
[tasks.dist-to-installer-app.mac]
dependencies = ["dist-to-installer-env"]
dependencies = ["dist-to-installer-env", "store-version"]
script_runner = "@duckscript"
script = '''
final_dir = get_env FINAL_DIR
Expand All @@ -686,6 +705,9 @@ contents_resources_dir = get_env CONTENTS_RESOURCES_DIR
contents_resources_dir = set ${contents_dir}/${contents_resources_dir}
info_plist_path = get_env INFO_PLIST_PATH
icns_path = get_env ICNS_PATH
version_path = get_env VERSION_PATH
version = readfile ${version_path}
version = trim_end ${version}

if is_path_exists ${tmp_dir}
rm -r ${tmp_dir}
Expand All @@ -695,10 +717,8 @@ mkdir ${contents_dir}
mkdir ${contents_mac_os}
exec --fail-on-error cp -r py39-dist "${contents_resources_dir}"
exec --fail-on-error mv ./${contents_resources_dir}/${app_original_name} "./${contents_mac_os}/${app_file_prefix}"
exec --fail-on-error ln -s "../Resources/lib" ${contents_mac_os}/lib
exec --fail-on-error ln -s "../Resources/.frozen" ${contents_mac_os}/.frozen
exec --fail-on-error ln -s "../Resources/resources" ${contents_mac_os}/resources
cp ./${info_plist_path} ./${contents_dir}/Info.plist
exec --fail-on-error sed -i "" -e "s/@@VERSION@@/${version}/g" "${contents_dir}/Info.plist"
mkdir ${contents_resources_dir}
cp ${icns_path} ./${contents_resources_dir}/${app_file_prefix}.icns
'''
Expand Down
39 changes: 33 additions & 6 deletions entrypoint/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
#![cfg_attr(target_os = "windows", windows_subsystem = "windows")]
#![cfg_attr(target_os = "windows", windows_subsystem = "windows")]

use std::path::{Path, PathBuf};

use pyo3::prelude::*;
use pyo3::types::PyTuple;

use entrypoint::attach_console;

type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;
type Error = Box<dyn std::error::Error>;
type Result<T> = std::result::Result<T, Error>;

fn handle_wayland() {
#[cfg(target_os = "linux")]
Expand Down Expand Up @@ -34,14 +37,38 @@ fn handle_splash() {
}
}

fn app_dir() -> Result<PathBuf> {
let current_exe = std::env::current_exe()?;
current_exe
.parent()
.ok_or("no parent directory".into())
.map(Path::to_path_buf)
}

fn pythonhome_dir() -> Result<PathBuf> {
let app_dir = app_dir()?.to_path_buf();
if cfg!(target_os = "macos") {
if let Some(parent) = app_dir.parent() {
let resources = parent.join("Resources/lib");
if resources.exists() {
Ok(parent.join("Resources"))
Comment on lines +52 to +54
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What controls whether the path is Resources or Resources/lib?

Copy link
Contributor Author

@silverjam silverjam Jun 6, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is basically tweaking the heuristic that's used to detect if we're living inside of a macOS .app bundle -- before I was trying to use just "resources" but the heuristic was triggered when running a build from "py39-dist". The PYTHONHOME var wants a path that contains a "lib" directory (technically lib/python3.9) so we have to supply just the "Resources" path so that Python loads correctly.

} else {
Ok(app_dir)
}
} else {
Ok(app_dir)
}
} else {
Ok(app_dir)
}
}

fn main() -> Result<()> {
attach_console();
handle_wayland();
let current_exe = std::env::current_exe()?;
let parent = current_exe.parent().ok_or("no parent directory")?;
let args: Vec<_> = std::env::args().collect();
std::env::set_var("SWIFTNAV_CONSOLE_FROZEN", parent);
std::env::set_var("PYTHONHOME", parent);
std::env::set_var("SWIFTNAV_CONSOLE_FROZEN", app_dir()?);
std::env::set_var("PYTHONHOME", pythonhome_dir()?);
std::env::set_var("PYTHONDONTWRITEBYTECODE", "1");
handle_splash();
let exit_code = Python::with_gil(|py| {
Expand Down
37 changes: 30 additions & 7 deletions installers/macOS/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,34 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at https://github.com/mherrmann/fbs/blob/d6dbde2bdff01907c4b83524f67a38df83fa0f2c/fbs/_defaults/src/freeze/mac/Contents/Info.plist looks like we're missing

    <key>LSBackgroundOnly</key>
    <string>0</string>

and

    <!-- Enable Retina support on OS X: -->
    <key>NSPrincipalClass</key>
    <string>NSApplication</string>

Were these intentionally skipped?

Copy link
Contributor Author

@silverjam silverjam Jun 6, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These looked like they could potentially change the behavior of the app (based on naming, didn't look up the docs), so I skipped them intentionally-- the new keys I did add felt more like metadata.

<key>CFBundleIconFile</key>
<string>Swift Console.icns</string>
<key>NSHighResolutionCapable</key>
<string>True</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleIconFile</key>
<string>Swift Console.icns</string>

<key>NSHighResolutionCapable</key>
<string>True</string>

<key>CFBundlePackageType</key>
<string>APPL</string>

<key>CFBundleExecutable</key>
<string>Swift Console</string>

<key>CFBundleDisplayName</key>
<string>Swift Console</string>

<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>

<key>CFBundleIdentifier</key>
<string>com.swift-nav.SwiftConsole</string>

<key>CFBundleName</key>
<string>Swift Console</string>

<key>CFBundleShortVersionString</key>
<string>@@VERSION@@</string>

<key>CFBundleVersion</key>
<string>@@VERSION@@</string>
</dict>
</plist>
</plist>
2 changes: 2 additions & 0 deletions installers/macOS/entitlements.plist
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,7 @@
<key>com.apple.security.cs.disable-executable-page-protection</key>
<true/>

<key>com.apple.security.app-sandbox</key>
<false/>
</dict>
</plist>
21 changes: 17 additions & 4 deletions swiftnav_console/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -557,15 +557,27 @@ def is_frozen() -> bool:
Returns:
bool: Whether the application is frozen.
"""
me = os.path.dirname(sys.executable)
me = get_app_dir()
var_frozen = os.environ.get("SWIFTNAV_CONSOLE_FROZEN", "") != ""
path_frozen = os.path.exists(os.path.join(me, ".frozen"))
return var_frozen or path_frozen


def get_app_dir() -> str:
def get_app_dir(alt: bool = False) -> str:
"""Fetches the application resources directory.

Args:
alt (bool): fetch an alternate data directory (only valid on macOS)

Returns:
str: path to the resoure dir (accounting for OS differences)
"""
var_frozen = os.environ.get("SWIFTNAV_CONSOLE_FROZEN", "")
if var_frozen != "":
if platform.system() == "Darwin":
if alt:
return var_frozen
return os.path.join(var_frozen, "../Resources")
return var_frozen
return os.path.dirname(sys.executable)

Expand All @@ -576,10 +588,11 @@ def get_capnp_path() -> str:
Returns:
str: The path to the capnp file.
"""
d = get_app_dir()
path = ""
if is_frozen():
path = os.path.join(d, "resources/base", CONSOLE_BACKEND_CAPNP_PATH)
path = os.path.join(get_app_dir(), "resources/base", CONSOLE_BACKEND_CAPNP_PATH)
if not os.path.exists(path):
path = os.path.join(get_app_dir(alt=True), "resources/base", CONSOLE_BACKEND_CAPNP_PATH)
else:
path = os.path.join(
os.path.dirname(os.path.dirname(__file__)), "src/main/resources/base", CONSOLE_BACKEND_CAPNP_PATH
Expand Down