-
-
Notifications
You must be signed in to change notification settings - Fork 158
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add script to package libs * Install gstreamer on macOS CI * Add cargo packager to macOS * Install cargo-packager on macos * Update version env variable * Move step order * Update artifact path * Add develop installer * Use fallback path instead * Move env variable to build steps instead * Manually export instead * Move dylib to framework instead * Try ad-hoc codesign * Try frameworks * Test custom package script * Update dmg version * Add rpath in build script * Add entitlements * Cleanup * Revert CI condition for packaging
- Loading branch information
Showing
5 changed files
with
143 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -127,6 +127,7 @@ jobs: | |
uses: dsherret/rust-toolchain-file@v1 | ||
|
||
- name: Install Rust toolchain for packager | ||
if: ${{ github.event_name == 'schedule' }} | ||
uses: actions-rust-lang/setup-rust-toolchain@v1 | ||
with: | ||
toolchain: stable | ||
|
@@ -148,6 +149,7 @@ jobs: | |
uses: Mozilla-Actions/[email protected] | ||
|
||
- name: Install Cargo Packager | ||
if: ${{ github.event_name == 'schedule' }} | ||
run: cargo +stable install cargo-packager | ||
|
||
- name: Build | ||
|
@@ -196,37 +198,61 @@ jobs: | |
- name: Install Rust | ||
uses: dsherret/rust-toolchain-file@v1 | ||
|
||
- name: Install Rust toolchain for packager | ||
if: ${{ github.event_name == 'schedule' }} | ||
uses: actions-rust-lang/setup-rust-toolchain@v1 | ||
with: | ||
toolchain: stable | ||
|
||
- name: Install Python | ||
uses: actions/setup-python@v5 | ||
with: | ||
python-version: '3.12' | ||
|
||
- name: Install dependencies | ||
run: | | ||
brew install cmake pkg-config | ||
brew install cmake | ||
python -m pip install mako | ||
curl https://gstreamer.freedesktop.org/data/pkg/osx/1.24.6/gstreamer-1.0-1.24.6-universal.pkg -o runtime.pkg | ||
sudo installer -pkg runtime.pkg -target / | ||
curl https://gstreamer.freedesktop.org/data/pkg/osx/1.24.6/gstreamer-1.0-devel-1.24.6-universal.pkg -o develop.pkg | ||
sudo installer -pkg develop.pkg -target / | ||
- name: Run sccache-cache | ||
uses: Mozilla-Actions/[email protected] | ||
|
||
- name: Install Cargo Packager | ||
if: ${{ github.event_name == 'schedule' }} | ||
run: cargo +stable install cargo-packager | ||
|
||
- name: Build | ||
run: | | ||
export PATH="/Library/Frameworks/GStreamer.framework/Versions/1.0/bin${PATH:+:$PATH}" | ||
export DYLD_LIBRARY_PATH="/Library/Frameworks/GStreamer.framework/Versions/1.0/lib${DYLD_LIBRARY_PATH:+:$DYLD_LIBRARY_PATH}" | ||
cargo build --release | ||
# - name: Test | ||
# run: | | ||
# cargo test --release | ||
|
||
- name: Tar Binary | ||
- name: Bundle | ||
if: ${{ github.event_name == 'schedule' }} | ||
run: | | ||
export PATH="/Library/Frameworks/GStreamer.framework/Versions/1.0/bin${PATH:+:$PATH}" | ||
export DYLD_LIBRARY_PATH="/Library/Frameworks/GStreamer.framework/Versions/1.0/lib${DYLD_LIBRARY_PATH:+:$DYLD_LIBRARY_PATH}" | ||
cargo packager --release | ||
- name: Fetch Verso version | ||
if: ${{ github.event_name == 'schedule' }} | ||
run: tar -czvf verso-${{ matrix.platform.target }}.tar.gz -C ./target/release/ verso | ||
run: | | ||
echo "VERSO_VERSION=$(cargo metadata --format-version=1 --no-deps | jq -r '.packages[] | select(.name == "verso") | .version')" >> $GITHUB_ENV | ||
- name: Upload artifact | ||
if: ${{ github.event_name == 'schedule' }} | ||
uses: actions/upload-artifact@v4 | ||
with: | ||
name: verso-${{ matrix.platform.target }} | ||
path: verso-${{ matrix.platform.target }}.tar.gz | ||
name: verso_${{ env.VERSO_VERSION }}_${{ matrix.platform.arch }} | ||
path: target/release/verso_${{ env.VERSO_VERSION }}_${{ matrix.platform.arch }}.dmg | ||
|
||
build-result: | ||
name: Build Result | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
import os | ||
import os.path as path | ||
import shutil | ||
import subprocess | ||
import sys | ||
|
||
def otool(s): | ||
o = subprocess.Popen(['/usr/bin/otool', '-L', s], stdout=subprocess.PIPE) | ||
for line in map(lambda s: s.decode('ascii'), o.stdout): | ||
if line[0] == '\t': | ||
yield line.split(' ', 1)[0][1:] | ||
|
||
|
||
def install_name_tool(binary, *args): | ||
try: | ||
subprocess.check_call(['install_name_tool', *args, binary]) | ||
except subprocess.CalledProcessError as e: | ||
print("install_name_tool exited with return value %d" % e.returncode) | ||
|
||
|
||
def change_link_name(binary, old, new): | ||
install_name_tool(binary, '-change', old, f"@executable_path/{new}") | ||
|
||
|
||
def is_system_library(lib): | ||
return lib.startswith("/System/Library") or lib.startswith("/usr/lib") or ".asan." in lib | ||
|
||
|
||
def is_relocatable_library(lib): | ||
return lib.startswith("@rpath/") | ||
|
||
|
||
def change_non_system_libraries_path(libraries, relative_path, binary): | ||
for lib in libraries: | ||
if is_system_library(lib) or is_relocatable_library(lib): | ||
continue | ||
new_path = path.join(relative_path, path.basename(lib)) | ||
change_link_name(binary, lib, new_path) | ||
|
||
|
||
def resolve_rpath(lib, rpath_root): | ||
if not is_relocatable_library(lib): | ||
return lib | ||
|
||
rpaths = ['', '../', 'gstreamer-1.0/'] | ||
for rpath in rpaths: | ||
full_path = rpath_root + lib.replace('@rpath/', rpath) | ||
if path.exists(full_path): | ||
return path.normpath(full_path) | ||
|
||
raise Exception("Unable to satisfy rpath dependency: " + lib) | ||
|
||
|
||
def copy_dependencies(binary_path, lib_path, gst_lib_dir): | ||
relative_path = path.relpath(lib_path, path.dirname(binary_path)) + "/" | ||
|
||
# Update binary libraries | ||
binary_dependencies = set(otool(binary_path)) | ||
change_non_system_libraries_path(binary_dependencies, relative_path, binary_path) | ||
|
||
# Update dependencies libraries | ||
need_checked = binary_dependencies | ||
checked = set() | ||
while need_checked: | ||
checking = set(need_checked) | ||
need_checked = set() | ||
for f in checking: | ||
# No need to check these for their dylibs | ||
if is_system_library(f): | ||
continue | ||
full_path = resolve_rpath(f, gst_lib_dir) | ||
need_relinked = set(otool(full_path)) | ||
new_path = path.join(lib_path, path.basename(full_path)) | ||
if not path.exists(new_path): | ||
shutil.copyfile(full_path, new_path) | ||
change_non_system_libraries_path(need_relinked, relative_path, new_path) | ||
need_checked.update(need_relinked) | ||
checked.update(checking) | ||
need_checked.difference_update(checked) | ||
|
||
def package_gstreamer_dylibs(bin): | ||
gst_root = "/Library/Frameworks/GStreamer.framework/Versions/1.0" | ||
lib_dir = path.join(path.dirname(bin), "lib") | ||
if os.path.exists(lib_dir): | ||
shutil.rmtree(lib_dir) | ||
os.mkdir(lib_dir) | ||
try: | ||
copy_dependencies(bin, lib_dir, path.join(gst_root, 'lib', '')) | ||
except Exception as e: | ||
print("ERROR: could not package required dylibs") | ||
print(e) | ||
return False | ||
return True | ||
|
||
if __name__ == '__main__': | ||
try: | ||
subprocess.check_call(['cargo', 'build', '--release', '--features', 'packager']) | ||
except subprocess.CalledProcessError as e: | ||
print("cargo build exited with return value %d" % e.returncode) | ||
|
||
if sys.platform == "darwin": | ||
binary = "./target/release/verso" | ||
package_gstreamer_dylibs(binary) |