compile.sh 13.1 KB
Newer Older
1
#! /bin/sh
2
set -e
3

4 5 6 7
#############
# FUNCTIONS #
#############

8 9 10 11 12
diagnostic()
{
    echo "$@" 1>&2;
}

13
fail()
14
{
15 16
    diagnostic "$1"
    exit 1
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
# Try to check whether a patch file has already been applied to the current directory tree
# Warning: this function assumes:
# - The patch file contains a Message-Id header. This can be generated with `git format-patch --thread ...` option
# - The patch has been applied with `git am --message-id ...` option to keep the Message-Id in the commit description
check_patch_is_applied()
{
    patch_file=$1
    diagnostic "Checking presence of patch $1"
    message_id=$(grep -E '^Message-Id: [^ ]+' "$patch_file" | sed 's/^Message-Id: \([^\ ]+\)/\1/')
    if [ -z "$message_id" ]; then
        diagnostic "Error: patch $patch_file does not contain a Message-Id."
        diagnostic "Please consider generating your patch files with the 'git format-patch --thread ...' option."
        diagnostic ""
        exit 1
    fi
    if [ -z "$(git log --grep="$message_id")" ]; then
        diagnostic "Cannot find patch $patch_file in tree, aborting."
        diagnostic "There can be two reasons for that:"
        diagnostic "- you forgot to apply the patch on this tree, or"
        diagnostic "- you applied the patch without the 'git am --message-id ...' option."
        diagnostic ""
        exit 1
    fi
}

Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
44 45
# Read the Android Wiki http://wiki.videolan.org/AndroidCompile
# Setup all that stuff correctly.
46
# Get the latest Android SDK Platform or modify numbers in configure.sh and libvlc/default.properties.
Rafaël Carré's avatar
Rafaël Carré committed
47

48
RELEASE=0
49 50
while [ $# -gt 0 ]; do
    case $1 in
51
        help|--help|-h)
52
            echo "Use -a to set the ARCH:"
53 54
            echo "  ARM:     (armeabi-v7a|arm)"
            echo "  ARM64:   (arm64-v8a|arm64)"
55
            echo "  X86:     x86, x86_64"
56
            echo "Use --release to build in release mode"
57
            echo "Use --signrelease to build in release mode and sign apk, see vlc-android/build.gradle"
58
            echo "Use -s to set your keystore file and -p for the password"
Thomas Guillem's avatar
Thomas Guillem committed
59
            echo "Use -c to get a ChromeOS build"
60
            echo "Use -l to build only LibVLC"
61
            echo "Use -b to bypass libvlc source checks (vlc custom sources)"
62
            exit 0
63 64 65 66 67 68 69 70
            ;;
        a|-a)
            ANDROID_ABI=$2
            shift
            ;;
        -r|release|--release)
            RELEASE=1
            ;;
71 72 73 74
        signrelease|--signrelease)
            SIGNED_RELEASE=1
            RELEASE=1
            ;;
75 76 77 78 79 80 81 82
        -s|--signature)
            KEYSTORE_FILE=$2
            shift
            ;;
        -p|--password)
            PASSWORD_KEYSTORE=$2
            shift
            ;;
83 84
        -l)
            BUILD_LIBVLC=1
85
            NO_ML=1
86
            ;;
87 88 89
        -ml)
            BUILD_MEDIALIB=1
            ;;
90 91 92
        run)
            RUN=1
            ;;
Duncan McNAMARA's avatar
Duncan McNAMARA committed
93 94 95
        test)
            TEST=1
            ;;
96 97 98
        --no-ml)
            NO_ML=1
            ;;
99 100 101 102
        --publish)
            RELEASE=1
            PUBLISH=1
            ;;
103 104 105
        --init)
            GRADLE_SETUP=1
            ;;
106 107 108
        -b)
            BYPASS_VLC_SRC_CHECKS=1
            ;;
109
        *)
110 111
            diagnostic "$0: Invalid option '$1'."
            diagnostic "$0: Try --help for more information."
112 113
            exit 1
            ;;
114
    esac
115
    shift
116 117
done

118
if [ -z "$ANDROID_NDK" -o -z "$ANDROID_SDK" ]; then
119 120
   diagnostic "You must define ANDROID_NDK, ANDROID_SDK before starting."
   diagnostic "They must point to your NDK and SDK directories."
121 122 123
   exit 1
fi

124
if [ -z "$ANDROID_ABI" ]; then
125
   diagnostic "*** No ANDROID_ABI defined architecture: using ARMv7"
126
   ANDROID_ABI="armeabi-v7a"
127 128
fi

129
if [ "$ANDROID_ABI" = "armeabi-v7a" -o "$ANDROID_ABI" = "arm" ]; then
130
    ANDROID_ABI="armeabi-v7a"
131
    GRADLE_ABI="ARMv7"
132
elif [ "$ANDROID_ABI" = "arm64-v8a" -o "$ANDROID_ABI" = "arm64" ]; then
133
    ANDROID_ABI="arm64-v8a"
134 135 136 137 138
    GRADLE_ABI="ARMv8"
elif [ "$ANDROID_ABI" = "x86" ]; then
    GRADLE_ABI="x86"
elif [ "$ANDROID_ABI" = "x86_64" ]; then
    GRADLE_ABI="x86_64"
139 140
elif [ "$ANDROID_ABI" = "all" ]; then
    GRADLE_ABI="all"
141 142 143 144 145 146
else
    diagnostic "Invalid arch specified: '$ANDROID_ABI'."
    diagnostic "Try --help for more information"
    exit 1
fi

147 148 149
####################
# Configure gradle #
####################
150

151 152 153 154 155
if [ -z "$KEYSTORE_FILE" ]; then
    KEYSTORE_FILE="$HOME/.android/debug.keystore"
    STOREALIAS="androiddebugkey"
else
    if [ -z "$PASSWORD_KEYSTORE" ]; then
156
        diagnostic "No password"
157 158 159 160 161 162
        exit 1
    fi
    rm -f gradle.properties
    STOREALIAS="vlc"
fi

163
if [ ! -f gradle.properties ]; then
164 165
    echo android.enableJetifier=true > gradle.properties
    echo android.useAndroidX=true >> gradle.properties
166 167 168
    echo kapt.incremental.apt=true >> gradle.properties
    echo kapt.use.worker.api=true >> gradle.properties
    echo kapt.include.compile.classpath=false >> gradle.properties
169
    echo keyStoreFile=$KEYSTORE_FILE >> gradle.properties
170
    echo storealias=$STOREALIAS >> gradle.properties
Geoffrey Métais's avatar
Geoffrey Métais committed
171
    if [ -z "$PASSWORD_KEYSTORE" ]; then
172 173
        echo storepwd=android >> gradle.properties
    fi
174
fi
175 176 177 178 179 180 181 182 183 184 185 186 187 188

init_local_props() {
    (
    # initialize the local.properties file,
    # or fix it if it was modified (by Android Studio, for example).
    echo_props() {
        echo "sdk.dir=$ANDROID_SDK"
        echo "ndk.dir=$ANDROID_NDK"
    }
    # first check if the file just needs to be created for the first time
    if [ ! -f "$1" ]; then
        echo_props > "$1"
        return 0
    fi
189 190 191 192 193 194
    # escape special chars to get regex that matches string
    make_regex() {
        echo "$1" | sed -e 's/\([[\^$.*]\)/\\\1/g' -
    }
    android_sdk_regex=`make_regex "${ANDROID_SDK}"`
    android_ndk_regex=`make_regex "${ANDROID_NDK}"`
195 196 197
    # check for lines setting the SDK directory
    sdk_line_start="^sdk\.dir="
    total_sdk_count=`grep -c "${sdk_line_start}" "$1"`
198
    good_sdk_count=`grep -c "${sdk_line_start}${android_sdk_regex}\$" "$1"`
199 200 201
    # check for lines setting the NDK directory
    ndk_line_start="^ndk\.dir="
    total_ndk_count=`grep -c "${ndk_line_start}" "$1"`
202
    good_ndk_count=`grep -c "${ndk_line_start}${android_ndk_regex}\$" "$1"`
203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234
    # if one of each is found and both match the environment vars, no action needed
    if [ "$total_sdk_count" -eq "1" -a "$good_sdk_count" -eq "1" \
	    -a "$total_ndk_count" -eq "1" -a "$good_ndk_count" -eq "1" ]
    then
        return 0
    fi
    # if neither property is set they can simply be appended to the file
    if [ "$total_sdk_count" -eq "0" -a "$total_ndk_count" -eq "0" ]; then
        echo_props >> "$1"
        return 0
    fi
    # if a property is set incorrectly or too many times,
    # remove all instances of both properties and append correct ones.
    replace_props() {
        temp_props="$1.tmp"
        while IFS= read -r LINE || [ -n "$LINE" ]; do
            line_sdk_dir="${LINE#sdk.dir=}"
            line_ndk_dir="${LINE#ndk.dir=}"
            if [ "x$line_sdk_dir" = "x$LINE" -a "x$line_ndk_dir" = "x$LINE" ]; then
                echo "$LINE"
            fi
        done <"$1" >"$temp_props"
        echo_props >> "$temp_props"
        mv -f -- "$temp_props" "$1"
    }
    echo "local.properties: Contains incompatible sdk.dir and/or ndk.dir properties. Replacing..."
    replace_props "$1"
    echo "local.properties: Finished replacing sdk.dir and/or ndk.dir with current environment variables."
    )
}
init_local_props local.properties || { echo "Error initializing local.properties"; exit $?; }

235 236
if [ ! -d "$ANDROID_SDK/licenses" ]; then
    mkdir "$ANDROID_SDK/licenses"
237
    echo "24333f8a63b6825ea9c5514f83c2829b004d1fee" > "$ANDROID_SDK/licenses/android-sdk-license"
238
    echo "d56f5187479451eabf01fb78af6dfcb131a6481e" >> "$ANDROID_SDK/licenses/android-sdk-license"
239
fi
240

241 242 243 244 245 246
##########
# GRADLE #
##########

if [ ! -d "gradle/wrapper" ]; then
    diagnostic "Downloading gradle"
247
    GRADLE_VERSION=5.4.1
248
    GRADLE_URL=https://download.videolan.org/pub/contrib/gradle/gradle-${GRADLE_VERSION}-bin.zip
249
    wget ${GRADLE_URL} 2>/dev/null || curl -O ${GRADLE_URL} || fail "gradle: download failed"
250

251
    unzip -o gradle-${GRADLE_VERSION}-bin.zip || fail "gradle: unzip failed"
252

253
    ./gradle-${GRADLE_VERSION}/bin/gradle wrapper || fail "gradle: wrapper failed"
254

255
    ./gradlew -version || fail "gradle: wrapper failed"
256 257 258 259
    chmod a+x gradlew
    rm -rf gradle-${GRADLE_VERSION}-bin.zip
fi

260
if [ "$GRADLE_SETUP" = 1 ]; then
261 262
    exit 0
fi
263 264 265
####################
# Fetch VLC source #
####################
266

Geoffrey Métais's avatar
Geoffrey Métais committed
267
TESTED_HASH=f3047d4
268
VLC_REPOSITORY=https://git.videolan.org/git/vlc/vlc-3.0.git
269
if [ ! -d "vlc" ]; then
270
    diagnostic "VLC sources: not found, cloning"
271
    git clone "${VLC_REPOSITORY}" vlc || fail "VLC sources: git clone failed"
272
    cd vlc
273
    diagnostic "VLC sources: resetting to the TESTED_HASH commit (${TESTED_HASH})"
274
    git reset --hard ${TESTED_HASH} || fail "VLC sources: TESTED_HASH ${TESTED_HASH} not found"
275
    diagnostic "VLC sources: applying custom patches"
276
    # Keep Message-Id inside commits description to track them afterwards
277
    git am --message-id ../libvlc/patches/vlc3/*.patch || fail "VLC sources: cannot apply custom patches"
278 279 280
    cd ..
else
    diagnostic "VLC source: found sources, leaving untouched"
281
fi
282 283 284 285 286 287
if [ "$BYPASS_VLC_SRC_CHECKS" = 1 ]; then
    diagnostic "VLC sources: Bypassing checks (required by option)"
else
    diagnostic "VLC sources: Checking TESTED_HASH and patches presence"
    diagnostic "NOTE: checks can be bypass by adding '-b' option to this script."
    cd vlc
288 289
    git cat-file -e ${TESTED_HASH} 2> /dev/null || \
        fail "Error: Your vlc checkout does not contain the latest tested commit: ${TESTED_HASH}"
290 291 292 293 294
    for patch_file in ../libvlc/patches/vlc3/*.patch; do
        check_patch_is_applied "$patch_file"
    done
    cd ..
fi
295

296 297 298
############
# Make VLC #
############
299
diagnostic "Configuring"
300
compile() {
301 302
    # Build LibVLC if asked for it, or needed by medialibrary
    copy_tmp="$1"
303

304 305 306
    OUT_DBG_DIR=.dbg/${ANDROID_ABI}
    mkdir -p $OUT_DBG_DIR

307
    if [ "$BUILD_MEDIALIB" != 1 -o ! -d "libvlc/jni/libs/$1" ]; then
308 309
        AVLC_SOURCED=1 . ./compile-libvlc.sh
        avlc_build
310

Thomas Guillem's avatar
Thomas Guillem committed
311
        $NDK_BUILD -C libvlc \
312 313 314 315 316 317 318 319 320 321 322 323 324 325
            VLC_SRC_DIR="$VLC_SRC_DIR" \
            VLC_BUILD_DIR="$VLC_BUILD_DIR" \
            VLC_OUT_LDLIBS="$VLC_OUT_LDLIBS" \
            APP_BUILD_SCRIPT=jni/Android.mk \
            APP_PLATFORM=android-${ANDROID_API} \
            APP_ABI=${ANDROID_ABI} \
            NDK_PROJECT_PATH=jni \
            NDK_TOOLCHAIN_VERSION=clang \
            NDK_DEBUG=${NDK_DEBUG}

        if [ "$copy_tmp" = "--copy-tmp=libvlc" ];then
            cp -r $VLC_OUT_PATH/libs/${ANDROID_ABI} libvlc/jni/libs/${ANDROID_ABI} build/tmp
        fi

326 327
        cp -a $VLC_OUT_PATH/obj/local/${ANDROID_ABI}/*.so ${OUT_DBG_DIR}
        cp -a ./libvlc/jni/obj/local/${ANDROID_ABI}/*.so ${OUT_DBG_DIR}
328
    fi
329

330
    if [ "$NO_ML" != 1 ]; then
331 332 333 334
        ANDROID_ABI=$ANDROID_ABI RELEASE=$RELEASE ./compile-medialibrary.sh
        if [ "$copy_tmp" = "--copy-tmp=medialibrary" ];then
            cp -r medialibrary/jni/libs/${ANDROID_ABI} build/tmp
        fi
335 336

        cp -a medialibrary/jni/obj/local/${ANDROID_ABI}/*.so ${OUT_DBG_DIR}
337 338
    fi
}
339

340
if [ "$ANDROID_ABI" = "all" ]; then
341 342
    if [ -d build/tmp ]; then
        rm -rf build/tmp
343
    fi
344
    mkdir -p build/tmp
345 346 347 348
    LIB_DIR="libvlc"
    if [ "$NO_ML" != 1 ]; then
        LIB_DIR="medialibrary"
    fi
349 350 351 352 353 354 355 356 357 358 359 360
    copy_tmp="--copy-tmp=$LIB_DIR"

    # The compile function is sourcing ./compile-libvlc.sh and is configured
    # with env variables (ANDROID_ABI), therefore it need to be run from a new
    # context for each ABI

    (ANDROID_ABI=armeabi-v7a RELEASE=$RELEASE compile $copy_tmp)
    (ANDROID_ABI=arm64-v8a RELEASE=$RELEASE compile $copy_tmp)
    (ANDROID_ABI=x86 RELEASE=$RELEASE compile $copy_tmp)
    (ANDROID_ABI=x86_64 RELEASE=$RELEASE compile $copy_tmp)
    rm -rf $LIB_DIR/jni/libs/
    mv build/tmp $LIB_DIR/jni/libs/
361 362

    GRADLE_VLC_SRC_DIRS="''"
363
else
364
    compile
365
    GRADLE_VLC_SRC_DIRS="$VLC_OUT_PATH/libs"
366
fi
367

368 369 370
##################
# Compile the UI #
##################
371
BUILDTYPE="Dev"
372 373 374
if [ "$SIGNED_RELEASE" = 1 ]; then
    BUILDTYPE="signedRelease"
elif [ "$RELEASE" = 1 ]; then
375 376
    BUILDTYPE="Release"
fi
377

378
if [ "$BUILD_LIBVLC" = 1 ];then
379
    GRADLE_VLC_SRC_DIRS="$GRADLE_VLC_SRC_DIRS" GRADLE_ABI=$GRADLE_ABI ./gradlew -p libvlc assemble${BUILDTYPE}
380
    RUN=0
381
    if [ "$PUBLISH" = 1 ];then
382
        GRADLE_VLC_SRC_DIRS="$GRADLE_VLC_SRC_DIRS" GRADLE_ABI=$GRADLE_ABI ./gradlew -p libvlc install bintrayUpload
383
    fi
384
elif [ "$BUILD_MEDIALIB" = 1 ]; then
385
    GRADLE_ABI=$GRADLE_ABI ./gradlew -p medialibrary assemble${BUILDTYPE}
386
    RUN=0
387 388 389
    if [ "$PUBLISH" = 1 ];then
        GRADLE_ABI=$GRADLE_ABI ./gradlew -p medialibrary install bintrayUpload
    fi
390
else
391 392 393 394 395
    if [ "$RUN" = 1 ]; then
        ACTION="install"
    else
        ACTION="assemble"
    fi
396
    TARGET="${ACTION}${BUILDTYPE}"
397
    GRADLE_VLC_SRC_DIRS="$GRADLE_VLC_SRC_DIRS" CLI="" GRADLE_ABI=$GRADLE_ABI ./gradlew $TARGET
398
fi
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
399

400 401 402 403
#######
# RUN #
#######
if [ "$RUN" = 1 ]; then
404
    export PATH="${ANDROID_SDK}/platform-tools/:$PATH"
Duncan McNAMARA's avatar
Duncan McNAMARA committed
405 406 407 408
    EXTRA=""
    if [ "$TEST" = 1 ]; then
        EXTRA="--ez 'extra_test_stubs' true"
    fi
409 410
    adb wait-for-device
    if [ "$RELEASE" = 1 ]; then
Duncan McNAMARA's avatar
Duncan McNAMARA committed
411
        adb shell am start -n org.videolan.vlc/org.videolan.vlc.StartActivity $EXTRA
412
    else
Duncan McNAMARA's avatar
Duncan McNAMARA committed
413
        adb shell am start -n org.videolan.vlc.debug/org.videolan.vlc.StartActivity $EXTRA
414 415
    fi
fi