Skip to content

Commit f177ce8

Browse files
authored
Logic to build multi-architecture Android libraries (#189)
* Logic to build multi-architecture Android libraries
1 parent d524dd5 commit f177ce8

File tree

3 files changed

+244
-63
lines changed

3 files changed

+244
-63
lines changed

.github/workflows/android.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ jobs:
9595
- name: Build SDK (Android)
9696
shell: bash
9797
run: |
98-
./build_android.sh
98+
./build_android.sh -d
9999
100100
- name: Upload Build
101101
uses: actions/upload-artifact@v2

aar_builder/merge_aar.sh

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
#!/bin/bash -eu
2+
#
3+
# Copyright 2016 Google inc. All rights Reserved.
4+
5+
help() {
6+
echo "
7+
Usage: $(basename "$0") -i aar_list -o aar -h
8+
Merges a set of Android Archives (AARs) into a single AAR.
9+
-i aar_list
10+
Space separated list of aars to merge.
11+
When conflicting empty / non-empty files are found in the set of AARs
12+
the non-empty files are copied to the output AAR. If multiple
13+
non-empty files are found and conflicting the first file in the list
14+
is selected.
15+
-o aar
16+
Where to place the output aar.
17+
-h
18+
Display this help message.
19+
" >&1
20+
exit 1
21+
}
22+
23+
main() {
24+
local -a input=
25+
local output=
26+
while getopts "i:o:h" option "$@"; do
27+
case "${option}" in
28+
i ) input=(${OPTARG});;
29+
o ) output="${OPTARG}";;
30+
h ) help;;
31+
* ) help;;
32+
esac
33+
done
34+
if [[ -z "${input[*]}" || \
35+
-z "${output}" ]]; then
36+
echo "Required argument not specified." >&2
37+
help
38+
fi
39+
local -r aar_temp="$(mktemp -d)"
40+
local -r remove_aar_temp="rm -rf \"${aar_temp}\""
41+
# shellcheck disable=SC2064
42+
trap "${remove_aar_temp}" SIGKILL SIGTERM SIGQUIT EXIT
43+
44+
# Copy each AAR's contents into the staging folder.
45+
local -r aar_staging="${aar_temp}/staging"
46+
local -r aar_unzipped="${aar_temp}/unzipped"
47+
mkdir -p "${aar_staging}"
48+
mkdir -p "${aar_unzipped}"
49+
for input_aar in "${input[@]}"; do
50+
# Ignore empty AARs.
51+
if [[ $(($(stat --printf="%s" "${input_aar}"))) -eq 0 ]]; then
52+
continue
53+
fi
54+
unzip -q -d "${aar_unzipped}" "${input_aar}"
55+
(
56+
cd "${aar_unzipped}"
57+
# shellcheck disable=SC2044
58+
for filename in $(find . -type f); do
59+
target_filename="${aar_staging}/${filename}"
60+
# Copy an empty file to the staging area if a file does not
61+
# already exist there.
62+
if [[ $(($(stat --printf="%s" "${filename}"))) -eq 0 ]]; then
63+
if [[ -e "${target_filename}" ]]; then
64+
continue
65+
fi
66+
fi
67+
chmod +w "${filename}"
68+
mkdir -p "$(dirname "${target_filename}")"
69+
cp -a "${filename}" "${target_filename}"
70+
done
71+
rm -rf *
72+
)
73+
done
74+
# Create the output AAR.
75+
if [[ -e "${output}" ]]; then
76+
output="$(cd "$(dirname "${output}")" &&
77+
echo "$(pwd)/$(basename "${output}")")"
78+
fi
79+
(
80+
cd "${aar_staging}"
81+
mkdir -p "$(dirname "${output}")"
82+
zip -q -X -r "${output}_output" .
83+
chmod +w "${output}"
84+
mv "${output}_output" "${output}"
85+
)
86+
}
87+
88+
main "$@"

build_android.sh

Lines changed: 155 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -14,86 +14,179 @@
1414
# See the License for the specific language governing permissions and
1515
# limitations under the License.
1616
#
17-
# Builds and runs the tests, meant to be used on a bash environment.
18-
19-
# Stop display commands being run.
20-
set +x
21-
22-
# Set exit code to first failure
23-
FIRST_FAILED_EXITCODE=0
24-
25-
function check_exit_code {
26-
if [ "$1" -ne "0" ] && [ "$FIRST_FAILED_EXITCODE" -eq 0 ]; then
27-
FIRST_FAILED_EXITCODE=$1
28-
fi
17+
# Builds the Android version of the Firebase Unity SDK.
18+
19+
help() {
20+
echo "Usage: $(basename "$0") -a arch_list -c cmake_extra -d -h
21+
Builds the Android SDK, possibly merging multiple architectures.
22+
-a arch_list
23+
Space separated list of Android architectures to build for.
24+
These are passed to CMake with the ANDROID_ABI flag.
25+
If not provided (and -m not used), defaults to (armeabi-v7a).
26+
-c cmake_extra
27+
Additional flags to pass to the CMake configure step.
28+
-d
29+
Use the default set of architecture flags,
30+
armeabi-v7a arm64-v8a x86 x86_64
31+
If set, the -a flag is ignored.
32+
-h
33+
Display this help message.
34+
" >&1
35+
exit 1
2936
}
3037

31-
CMAKE_OPTIONS=
38+
main() {
39+
local -a arch_list=(armeabi-v7a)
40+
local -a cmake_extra=
41+
local build_default=false
42+
while getopts "a:c:dh" option "$@"; do
43+
case "${option}" in
44+
a ) arch_list="${OPTARG}";;
45+
c ) cmake_extra="${OPTARG}";;
46+
d ) build_default=true;;
47+
h ) help;;
48+
* ) help;;
49+
esac
50+
done
51+
52+
53+
if $build_default; then
54+
arch_list=(armeabi-v7a arm64-v8a x86 x86_64)
55+
fi
3256

33-
if [ -d "../firebase-cpp-sdk" ]; then
34-
CMAKE_OPTIONS="-DFIREBASE_CPP_SDK_DIR=`realpath ../firebase-cpp-sdk` "
35-
cd ../firebase-cpp-sdk
36-
./gradlew
37-
cd ../firebase-unity-sdk
38-
fi
57+
# Set exit code to first failure
58+
FIRST_FAILED_EXITCODE=0
3959

40-
if [[ -z "${ANDROID_NDK_HOME}" ]]; then #ANDROID_NDK_HOME not set
41-
echo "Using ANDROID_NDK_HOME: ${ANDROID_NDK_HOME} android tool chain"
42-
shopt -s nullglob
43-
list=(${ANDROID_HOME}/**/build/cmake/android.toolchain.cmake)
44-
shopt -u nullglob
60+
function check_exit_code {
61+
if [ "$1" -ne "0" ] && [ "$FIRST_FAILED_EXITCODE" -eq 0 ]; then
62+
FIRST_FAILED_EXITCODE=$1
63+
fi
64+
}
65+
66+
CMAKE_OPTIONS=
67+
if [ -d "../firebase-cpp-sdk" ]; then
68+
CMAKE_OPTIONS="-DFIREBASE_CPP_SDK_DIR=`realpath ../firebase-cpp-sdk` "
69+
cd ../firebase-cpp-sdk
70+
./gradlew
71+
cd ../firebase-unity-sdk
72+
fi
4573

46-
if [ ! -f "${list[0]}" ]; then
47-
# Some installations of the NDK have it in NDK/version, instead of just
48-
# ndk-bundle, and ** sometimes does not recurse correctly, so check that case.
74+
if [[ -z "${ANDROID_NDK_HOME}" ]]; then #ANDROID_NDK_HOME not set
75+
echo "Using ANDROID_NDK_HOME: ${ANDROID_NDK_HOME} android tool chain"
4976
shopt -s nullglob
50-
list=(${ANDROID_HOME}/*/*/build/cmake/android.toolchain.cmake)
77+
list=(${ANDROID_HOME}/**/build/cmake/android.toolchain.cmake)
5178
shopt -u nullglob
5279

5380
if [ ! -f "${list[0]}" ]; then
54-
echo "Failed to find android.toolchain.cmake. Please ensure ANDROID_HOME is set to a valid ndk directory."
55-
exit -1
56-
fi
81+
# Some installations of the NDK have it in NDK/version, instead of just
82+
# ndk-bundle, and ** sometimes does not recurse correctly, so check that case.
83+
shopt -s nullglob
84+
list=(${ANDROID_HOME}/*/*/build/cmake/android.toolchain.cmake)
85+
shopt -u nullglob
86+
87+
if [ ! -f "${list[0]}" ]; then
88+
echo "Failed to find android.toolchain.cmake. Please ensure ANDROID_HOME is set to a valid ndk directory."
89+
exit -1
90+
fi
91+
fi
92+
else
93+
echo "Using ANDROID_NDK_HOME: ${ANDROID_NDK_HOME} android tool chain"
94+
shopt -s nullglob
95+
list=(${ANDROID_NDK_HOME}/build/cmake/android.toolchain.cmake)
96+
shopt -u nullglob
5797
fi
58-
else
59-
echo "Using ANDROID_NDK_HOME: ${ANDROID_NDK_HOME} android tool chain"
60-
shopt -s nullglob
61-
list=(${ANDROID_NDK_HOME}/build/cmake/android.toolchain.cmake)
62-
shopt -u nullglob
63-
fi
98+
echo "Using android toolchain: ${list[0]}"
6499

65-
echo "Using android toolchain: ${list[0]}"
100+
if [ -n "$UNITY_ROOT_DIR" ]; then
101+
CMAKE_OPTIONS="${CMAKE_OPTIONS} -DUNITY_ROOT_DIR=${UNITY_ROOT_DIR}"
102+
fi
103+
CMAKE_OPTIONS="${CMAKE_OPTIONS} -DANDROID_NDK=$ANDROID_NDK_HOME"
104+
CMAKE_OPTIONS="${CMAKE_OPTIONS} -DCMAKE_TOOLCHAIN_FILE=${list[0]}"
105+
CMAKE_OPTIONS="${CMAKE_OPTIONS} -DFIREBASE_ANDROID_BUILD=true"
106+
CMAKE_OPTIONS="${CMAKE_OPTIONS} -DCMAKE_BUILD_TYPE=release"
66107

67-
CMAKE_OPTIONS="${CMAKE_OPTIONS} -DUNITY_ROOT_DIR=${UNITY_ROOT_DIR}"
68-
CMAKE_OPTIONS="${CMAKE_OPTIONS} -DANDROID_NDK=$ANDROID_NDK"
69-
CMAKE_OPTIONS="${CMAKE_OPTIONS} -DCMAKE_TOOLCHAIN_FILE=${list[0]}"
70-
CMAKE_OPTIONS="${CMAKE_OPTIONS} -DANDROID_ABI=armeabi-v7a"
71-
CMAKE_OPTIONS="${CMAKE_OPTIONS} -DFIREBASE_ANDROID_BUILD=true"
72-
CMAKE_OPTIONS="${CMAKE_OPTIONS} -DCMAKE_BUILD_TYPE=release"
108+
# Make a directory to work in (if doesn't exist)
109+
mkdir -p android_build
73110

74-
# Display commands being run.
75-
set -x
111+
pushd android_build
76112

77-
# Make a directory to work in (if doesn't exist)
78-
mkdir -p android_build
113+
multi_arch=false
114+
path_up=".."
115+
if [ "${#arch_list[@]}" -gt 1 ]; then
116+
multi_arch=true
117+
path_up="../.."
118+
fi
119+
for arch in "${arch_list[@]}"; do
120+
# If building more than one architecture, move into a subdirectory
121+
if $multi_arch; then
122+
mkdir -p "${arch}"
123+
pushd "${arch}"
124+
fi
79125

80-
pushd android_build
126+
# Configure cmake with option value
127+
cmake $path_up ${CMAKE_OPTIONS} -DANDROID_ABI="${arch}" ${cmake_extra}
128+
check_exit_code $?
81129

82-
# Configure cmake with option value
83-
cmake .. ${CMAKE_OPTIONS} "$@"
84-
check_exit_code $?
130+
# Build the SDK
131+
make
132+
check_exit_code $?
85133

86-
# Build the SDK
87-
make # -j 8
88-
check_exit_code $?
134+
# Package build output into zip
135+
cpack .
136+
check_exit_code $?
89137

90-
# Package build output into zip
91-
cpack .
92-
check_exit_code $?
138+
if $multi_arch; then
139+
popd
140+
fi
141+
done
142+
143+
# If building for multiple architectures, merge the results
144+
if $multi_arch; then
145+
local -r unzip_dir="$(mktemp -d)"
146+
local -r remove_temp_dir="rm -rf \"${unzip_dir}\""
147+
trap "${remove_temp_dir}" SIGKILL SIGTERM SIGQUIT EXIT
148+
149+
zip_basename=
150+
srcaar_list=
151+
for arch in "${arch_list[@]}"; do
152+
zip_name=$(find ${arch} -name '*Android.zip' -depth 1)
153+
154+
if [ -z "${zip_basename}" ]; then
155+
# If this is the first srcaar being handled, unzip everything
156+
# to the primary unzip_dir.
157+
unzip -q -d "${unzip_dir}" "${zip_name}"
158+
159+
# Get the list of srcaar files, to merge into later
160+
srcaar_list=$(find ${unzip_dir} -type f -name '*.srcaar')
161+
zip_basename=$(basename ${zip_name})
162+
else
163+
# Unzip the other architectures into a different temp directory
164+
tmp_dir="$(mktemp -d)"
165+
echo "TMPDIR: ${tmp_dir}"
166+
trap "rm -rf ${tmp_dir}" SIGKILL SIGTERM SIGQUIT EXIT
167+
unzip -q -d "${tmp_dir}" "${zip_name}" *.srcaar
168+
for srcaar in "${srcaar_list[@]}"; do
169+
# Get the path to the new srcaar that matches the original
170+
srcaar_name=$(basename ${srcaar})
171+
echo "Looking for ${srcaar_name}"
172+
new_srcaar=$(find ${tmp_dir} | grep ${srcaar_name})
173+
# Merge into the first srcaar
174+
../aar_builder/merge_aar.sh -i "${srcaar} ${new_srcaar}" -o ${srcaar}
175+
done
176+
fi
177+
done
178+
179+
# Zip up the result into a new zipfile with the correct name
180+
final_zip="$(pwd)/${zip_basename}"
181+
pushd ${unzip_dir}
182+
zip -q -X -r ${final_zip} .
183+
popd
184+
fi
93185

94-
# Stop display commands being run.
95-
set +x
186+
# popd android_build
187+
popd
96188

97-
popd
189+
exit $FIRST_FAILED_EXITCODE
190+
}
98191

99-
exit $FIRST_FAILED_EXITCODE
192+
main "$@"

0 commit comments

Comments
 (0)