File: build-universal.sh

package info (click to toggle)
tuxpaint 1%3A0.9.34-2
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 61,572 kB
  • sloc: ansic: 60,855; makefile: 1,397; sh: 790; objc: 303; cpp: 186; python: 182; php: 43
file content (155 lines) | stat: -rwxr-xr-x 4,175 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#!/usr/bin/env bash

function usage() {
    cat <<EOF
Build a macOS universal application bundle from one or more application
bundles.

Usage: ${SCRIPTNAME} [OPTIONS] TuxPaint-1.app TuxPaint-2.app ...

  TuxPaint-N.app        Bundle(s) to read.  If no bundles are specified, the
                        following files are read:
                        $(
                            for bundle in "${BUNDLES[@]}"; do
                                printf "\n%26s%s" "" "$bundle"
                            done
                        )

  -o OUTBUNDLE          Bundle to create.  [Default=${OUTBUNDLE}]

  -s IDENTITY           Re-sign the bundle with IDENTITY.  [Default=${IDENTITY}]

EOF
}


##############################################################################
# CONFIG

ARCHS=( arm64 x86_64 )
BUNDLES=( $(printf "TuxPaint-%s.app\n" "${ARCHS[@]}") )
OUTBUNDLE=TuxPaint.app
IDENTITY="-"
FORCE=0


##############################################################################
# PROGRAM BEGINS HERE

function main() {
    local OPTIND OPTARG OPTERR opt
    local bundle
    local isok=1

    # Process arguments
    while getopts "fo:s:h" opt; do
        case "$opt" in
            f)  FORCE=1           ;;
            o)  OUTBUNDLE=$OPTARG ;;
            s)  IDENTITY=$OPTARG  ;;
            h)  usage && exit 0   ;;
            *)  isok=0
        esac
    done
    shift $((OPTIND-1))

    # Use the specified bundles
    if (( $# )); then
        BUNDLES=( "$@" )
    fi

    # Sanity check
    if (( ! isok )); then
        usage 1>&2
        exit 1
    fi

    # Status
    echo "   * Creating universal app bundle $OUTBUNDLE by combining ${BUNDLES[*]}..."

    # Validate input
    for bundle in "${BUNDLES[@]}"; do
        if ! [[ -d "$bundle" ]]; then
            printf "     -> FAILED: No such input bundle named %s exists\n" "$bundle" 1>&2
            isok=0
        fi
    done
    (( isok)) || exit 1

    # Validate output
    if [[ -d "$OUTBUNDLE" ]] && (( FORCE )); then
        printf "     -> Deleting %s...\n" "$OUTBUNDLE"
        rm -rf "$OUTBUNDLE" || exitcode=1
    elif [[ -d "$OUTBUNDLE" ]]; then
        printf "     -> FAILED: Output bundled named %s already exists, use -f option to recreate.\n" "$OUTBUNDLE" 1>&2
        isok=0
    fi
    (( isok )) || exit 1

    build-universal
    resign-bundle
}


function build-universal() {
    local isok=1
    local i j

    # Create the base package without binaries or libraries
    echo "     -> Create skeleton app bundle ${OUTBUNDLE}..."     \
    && cp -a "${BUNDLES[0]}" "$OUTBUNDLE"                         \
    && rm -f "${OUTBUNDLE}/Contents/MacOS"/*                      \
    && find "$OUTBUNDLE" -name '*.dylib' -print0 | xargs -0 rm -f \
    || return 1

    # Create the universal version of each binary and library
    for (( i=0; i < ${#BUNDLES[@]}; i++ )); do
        local filelist=()
        local file

        # Binaries
        for file in "${BUNDLES[i]}/Contents/MacOS"/*; do
            filelist+=( "${file#${BUNDLES[i]}/}" )
        done

        # Dynamic Libraries
        while IFS= read -r file; do
            filelist+=( "${file#${BUNDLES[i]}/}" )
        done < <(find "${BUNDLES[i]}" -name '*.dylib')

        # Build each as universal
        for file in "${filelist[@]}"; do
            local instances=()

            # Skip if already built
            [[ -e "${OUTBUNDLE}/${file}" ]] && continue

            # Get this file's instances in all bundles
            for (( j=i; j < ${#BUNDLES[@]}; j++ )); do
                if [[ -e "${BUNDLES[j]}/${file}" ]]; then
                    instances+=( "${BUNDLES[j]}/${file}" )
                fi
            done

            # Build into $OUTBUNDLE
            echo "     -> Combine ${file}..."
            lipo -create -output "${OUTBUNDLE}/${file}" "${instances[@]}" || isok=0
        done
    done

    (( isok ))
}


function resign-bundle() {
    echo "   * Sign $OUTBUNDLE..."
    codesign --remove-signature "$OUTBUNDLE"
    codesign -s "$IDENTITY" "$OUTBUNDLE"
    echo "     -> Done!"
}


##############################################################################
# ENTRY POINT

main "$@"