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 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 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 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355
|
#!/bin/bash
set -e
# Copyright 2019 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Mounts the components of soong into a directory structure that Go tools
# and editors expect.
#####################################################################
# Print the message to stderr with the prefix ERROR and abort this
# script.
#####################################################################
function log_FATAL() {
echo "ERROR:" "$*" >&2
exit 1
}
#####################################################################
# Print the message to stderr with the prefix WARN
#####################################################################
function log_WARN() {
echo "WARN:" "$*" >&2
}
#####################################################################
# Print the message with the prefix INFO.
#####################################################################
function log_INFO() {
echo "INFO:" "$*"
}
#####################################################################
# Find the root project directory of this repo. This is done by
# finding the directory of where this script lives and then go up one
# directory to check the ".repo" directory exist. If not, keep going
# up until we find the ".repo" file or we reached to the filesystem
# root. Project root directory is printed to stdout.
#####################################################################
function root_dir() (
local dir
if ! dir="$("${readlink}" -e $(dirname "$0"))"; then
log_FATAL "failed to read the script's current directory."
fi
dir=${dir}/../../..
if ! dir="$("${readlink}" -e "${dir}")"; then
log_FATAL "Cannot find the root project directory"
fi
echo "${dir}"
)
#####################################################################
# executes a shell command by printing out to the screen first and
# then evaluating the command.
#####################################################################
function execute() {
echo "$@"
eval "$@"
}
#####################################################################
# Returns the source directory of a passed in path from BIND_PATHS
# array.
#####################################################################
function bind_path_src_dir() (
local -r bind_path="$1"
echo "${bind_path/%|*/}"
)
#####################################################################
# Returns the destination directory of a passed in path from
# BIND_PATHS array.
#####################################################################
function bind_path_dst_dir() (
local -r bind_path="$1"
echo "${bind_path/#*|}"
)
#####################################################################
# Executes the bindfs command in linux. Expects $1 to be src
# directory and $2 to be destination directory.
#####################################################################
function linux_bind_dir() (
execute bindfs "$1" "$2"
)
#####################################################################
# Executes the fusermount -u command in linux. Expects $1 to be the
# destination directory.
#####################################################################
function linux_unbind_dir() (
execute fusermount -u "$1"
)
#####################################################################
# Executes the bindfs command in darwin. Expects $1 to be src
# directory and $2 to be destination directory.
#####################################################################
function darwin_bind_dir() (
execute bindfs -o allow_recursion -n "$1" "$2"
)
#####################################################################
# Execute the umount command in darwin to unbind a directory. Expects
# $1 to be the destination directory
#####################################################################
function darwin_unbind_dir() (
execute umount -f "$1"
)
#####################################################################
# Bind all the paths that are specified in the BIND_PATHS array.
#####################################################################
function bind_all() (
local src_dir
local dst_dir
for path in ${BIND_PATHS[@]}; do
src_dir=$(bind_path_src_dir "${path}")
dst_dir=$(bind_path_dst_dir "${path}")
mkdir -p "${dst_dir}"
"${bind_dir}" ${src_dir} "${dst_dir}"
done
echo
log_INFO "Created GOPATH-compatible directory structure at ${OUTPUT_PATH}."
)
#####################################################################
# Unbind all the paths that are specified in the BIND_PATHS array.
#####################################################################
function unbind_all() (
local dst_dir
local exit_code=0
# need to go into reverse since several parent directory may have been
# first before the child one.
for (( i=${#BIND_PATHS[@]}-1; i>=0; i-- )); do
dst_dir=$(bind_path_dst_dir "${BIND_PATHS[$i]}")
# continue to unmount even one of them fails
if ! "${unbind_dir}" "${dst_dir}"; then
log_WARN "Failed to umount ${dst_dir}."
exit_code=1
fi
done
if [[ ${exit_code} -ne 0 ]]; then
exit ${exit_code}
fi
echo
log_INFO "Unmounted the GOPATH-compatible directory structure at ${OUTPUT_PATH}."
)
#####################################################################
# Asks the user to create the GOPATH-compatible directory structure.
#####################################################################
function confirm() (
while true; do
echo "Will create GOPATH-compatible directory structure at ${OUTPUT_PATH}"
echo -n "Ok [Y/n]?"
read decision
if [ "${decision}" == "y" -o "${decision}" == "Y" -o "${decision}" == "" ]; then
return 0
else
if [ "${decision}" == "n" ]; then
return 1
else
log_WARN "Invalid choice ${decision}; choose either 'y' or 'n'"
fi
fi
done
)
#####################################################################
# Help function.
#####################################################################
function help() (
cat <<EOF
Mounts the components of soong into a directory structure that Go tools
and editors expect.
--help
This help
--bind
Create the directory structure that Go tools and editors expect by
binding the one to aosp build directory.
--unbind
Reverse operation of bind.
If no flags were specified, the --bind one is selected by default.
EOF
)
#####################################################################
# Parse the arguments passed in to this script.
#####################################################################
function parse_arguments() {
while [[ -n "$1" ]]; do
case "$1" in
--bind)
ACTION="bind"
shift
;;
--unbind)
ACTION="unbind"
shift
;;
--help )
help
shift
exit 0
;;
*)
log_WARN "Unknown option: $1"
help
exit 1
;;
esac
done
if [[ -z "${ACTION}" ]]; then
ACTION=bind
fi
}
#####################################################################
# Verifies that a list of required binaries are installed in the
# host in order to run this script.
#####################################################################
function check_exec_existence() (
function check() {
if ! hash "$1" &>/dev/null; then
log_FATAL "missing $1"
fi
}
local bins
case "${os_type}" in
Darwin)
bins=("bindfs" "greadlink")
;;
Linux)
bins=("bindfs" "fusermount")
;;
*)
log_FATAL "${os_type} is not a recognized system."
esac
for bin in "${bins[@]}"; do
check "${bin}"
done
)
function main() {
parse_arguments "$@"
check_exec_existence
if [[ "${ACTION}" == "bind" ]]; then
if confirm; then
echo
bind_all
else
echo "skipping due to user request"
exit 1
fi
else
echo
unbind_all
fi
}
readonly os_type="$(uname -s)"
case "${os_type}" in
Darwin)
bind_dir=darwin_bind_dir
unbind_dir=darwin_unbind_dir
readlink=greadlink
;;
Linux)
bind_dir=linux_bind_dir
unbind_dir=linux_unbind_dir
readlink=readlink
;;
*)
log_FATAL "${os_type} is not a recognized system."
esac
readonly bind_dir
readonly unbind_dir
readonly readlink
if ! ANDROID_PATH="$(root_dir)"; then
log_FATAL "failed to find the root of the repo checkout"
fi
readonly ANDROID_PATH
#if GOPATH contains multiple paths, use the first one
if ! OUTPUT_PATH="$(echo ${GOPATH} | sed 's/\:.*//')"; then
log_FATAL "failed to extract the first GOPATH environment variable"
fi
readonly OUTPUT_PATH
if [ -z "${OUTPUT_PATH}" ]; then
log_FATAL "Could not determine the desired location at which to create a" \
"Go-compatible workspace. Please update GOPATH to specify the" \
"desired destination directory."
fi
# Below are the paths to bind from src to dst. The paths are separated by |
# where the left side is the source and the right side is destination.
readonly BIND_PATHS=(
"${ANDROID_PATH}/build/blueprint|${OUTPUT_PATH}/src/github.com/google/blueprint"
"${ANDROID_PATH}/build/soong|${OUTPUT_PATH}/src/android/soong"
"${ANDROID_PATH}/art/build|${OUTPUT_PATH}/src/android/soong/art"
"${ANDROID_PATH}/external/golang-protobuf|${OUTPUT_PATH}/src/github.com/golang/protobuf"
"${ANDROID_PATH}/external/llvm/soong|${OUTPUT_PATH}/src/android/soong/llvm"
"${ANDROID_PATH}/external/clang/soong|${OUTPUT_PATH}/src/android/soong/clang"
"${ANDROID_PATH}/external/robolectric-shadows/soong|${OUTPUT_PATH}/src/android/soong/robolectric"
)
main "$@"
|