Merge remote-tracking branch 'bitbucket_mthread/thread/LP-104_HOTT_SUMD_Support_15...
[librepilot.git] / tool_install.sh
blob1ad5244f42498761fcb80ac2801f5f714bd7eb32
1 #!/bin/bash
3 # Exit if an error or an unset variable
4 set -e -u
6 # make sure unmatched glob gives empty
7 shopt -s nullglob
9 root_dir=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
10 tools_dir=${TOOLS_DIR:-${root_dir}/tools}
11 downloads_dir=${DL_DIR:-${root_dir}/downloads}
12 tool_overrides_dir=$root_dir/make/tool_install
14 batch=${BATCH:-false}
15 force=false
16 remove=false
17 includes=true
19 for arg in "${@:1}"
21 [ "$arg" = "-r" ] && remove=true
22 [ "$arg" = "-f" ] && force=true
23 [ "$arg" = "-n" ] && includes=false
25 done
27 tool=${@: -1}
29 uname=$(uname)
30 if [[ "$uname" != [LD]* ]]
31 then
32 uname=Windows
36 # Batch mode
37 if $batch
38 then
39 CURL_OPTIONS=(--silent -L)
40 else
41 CURL_OPTIONS=(-L)
44 ################################################################################
45 # Helper functions
46 ################################################################################
48 function exit_error
50 error=$?
51 echo "${@}"
52 exit $error
55 ## Downloads a file if it doesn't exist
56 #1 URL
57 #2 Output filename (optional)
58 #3+ Additional options to pass to curl
59 ## Sets:
60 #out_file: path of the downloaded file
61 function download_file
63 out_file="$downloads_dir/${2:-$(basename "$1")}"
65 if ! [ -f "$out_file" ]
66 then
67 mkdir -p "$downloads_dir" && \
68 cd "$downloads_dir" && \
69 echo "Downloading $1" && \
70 curl "${CURL_OPTIONS[@]}" "${@:3}" -o "$out_file" "$1"
74 ## Unzips a file
75 #1 The file to unzip
76 #2 The output directory
77 function zip_extract
79 if [ "$uname" = Windows ]
80 then
81 7za.exe x -o"$2" "$1"
82 else
83 unzip "$1" -d "$2"
87 ## Extracts a 7zip file
88 #1 The file to extract
89 #2 The output directory
90 function sevenzip_extract
92 if [ "$uname" = Windows ]
93 then
94 7za.exe x -o"$2" "$1"
95 else
96 7zr x -o"$2" "$1"
100 ## Extracts a tar file
101 #1 The file to extract
102 #2 The output directory
103 function tar_extract
105 tar -xf "$1" -C "$2"
108 ## Extracts a file
109 #1 File to extract
110 #2 Extract directory (optional)
111 no_extract=false # Optional
112 ## Sets:
113 #out_dir: directory the file was extracted into
114 function extract_file
116 out_dir="${2:-.}"
118 echo "Extracting $1"
120 mkdir -p "$out_dir" && \
121 case "$1" in
122 *.zip)
123 zip_extract "$1" "$out_dir"
125 *.7z)
126 sevenzip_extract "$1" "$out_dir"
128 *.tar*)
129 tar_extract "$1" "$out_dir"
132 if $no_extract
133 then
134 cp "$1" "$out_dir"
135 else
136 return 1
138 esac
141 ## Verifies an md5 file
142 #1 md5 file
143 #2 file to check
144 function md5_verify_file
146 if [ "$uname" = Darwin ]
147 then
148 [[ "$(md5 "$2")" = *"$(awk '{print $1}' "$1")"* ]]
149 else
150 ( cd "$downloads_dir" && md5sum -c "$1" )
154 ################################################################################
155 # Default functions
156 ################################################################################
158 function validate_target { false; }
160 function remove
162 rm -rf "$tools_dir/$tool_install_name"
163 rm -f "$tools_dir/$tool".{sh,mk}
166 declare -a depends=()
167 function install_deps
169 # Workaround for set -u and empty array
170 for dep in "${depends[@]:+${depends}}"
172 BATCH="$batch" "${BASH_SOURCE[0]}" "$dep"
173 done && \
174 source_includes
177 ## Downloads and verifies the tool
178 ## Required:
179 #tool_url: the url to download the tool from
180 ## Optional:
181 #tool_md5
182 #tool_md5_url
183 function download_and_verify
185 verified=true
186 download_file "$tool_url" && \
187 downloaded_file=$out_file && \
188 if [ -n "${tool_md5_url:-}" ]
189 then
190 download_file "$tool_md5_url" "$(basename "$downloaded_file").md5" --silent && \
191 if ! md5_verify_file "$out_file" "$downloaded_file"
192 then
193 mv -f "$downloaded_file"{,.rej} && \
194 mv -f "$downloaded_file".md5{,.rej} && \
195 verified=false
197 elif [ -n "${tool_md5:-}" ]
198 then
199 if [[ "$tool_md5"* != "$(cd "$downloads_dir" && md5sum "$downloaded_file")" ]]
200 then
201 mv -f "$downloaded_file"{,.rej} && \
202 verified=false
204 fi && \
205 $verified
208 function tool_is_installed { [ -e "$full_tool_install_name" ] || which "$tool" &>/dev/null; }
210 ## Downloads and extracts the tool
211 ## Required:
212 #tool_url: the url to download the tool from
213 #tool_install_name: the directory or file the tool will be installed as
214 ## Optional:
215 #tool_extract_dir: Directory to extract into (useful if build required)
216 function download_and_extract
218 local full_tool_install_name="$tools_dir/$tool_install_name"
219 if ! tool_is_installed || $force
220 then
221 download_and_verify || exit_error "Failed to verify $downloaded_file"
222 rm -rf "$full_tool_install_name" && \
223 extract_file "$downloaded_file" "${tool_extract_dir:-$tools_dir}"
227 function build_and_install { true; } # Most tools don't need this step
229 ## Write modules that are included by this script and make
230 ## Optional:
231 bin_dir=""
232 bin_subdir="" #
233 module_file=$tool
234 function write_modules
236 if [ -n "$bin_subdir" ]
237 then
238 bin_dir="$tools_dir/$tool_install_name/$bin_subdir"
241 if [ -n "$bin_dir" ]
242 then
243 local new_path="$bin_dir"':${PATH}'
244 # Write shell module file
245 echo 'if [[ ":$PATH:" != *":'"$bin_dir"':"* ]]; then export PATH='"$new_path"'; fi' > "$tools_dir/$module_file".sh
246 # Write make module file
247 echo 'ifeq ($(findstring :'"$bin_dir"':,:$(PATH):),)' > "$tools_dir/$module_file".mk
248 echo "export PATH := $new_path" >> "$tools_dir/$module_file".mk
249 echo "endif" >> "$tools_dir/$module_file".mk
254 function source_includes
256 if $includes
257 then
258 for module in "$tools_dir"/*.sh
260 source "$module"
261 done
265 ################################################################################
266 # Peform tool install
267 ################################################################################
268 source_includes || exit_error "failed to source includes"
270 source "$tool_overrides_dir/${tool}.sh"
272 if $remove
273 then
274 remove || exit_error "Failed to remove ${tool}"
275 else
276 validate_target || exit_error "${tool} is not a valid target"
278 install_deps || exit_error "Failed to install dependencies for ${tool}"
280 download_and_extract || exit_error "Failed to download and extract ${tool}"
282 build_and_install || exit_error "Failed to build and install ${tool}"
284 write_modules || exit_error "Failed to write modules for ${tool}"