zhangkun83 | 488162d | 2015-03-25 16:07:50 -0700 | [diff] [blame] | 1 | #!/bin/bash |
| 2 | |
Feng Xiao | 474fd31 | 2018-07-13 12:28:17 -0700 | [diff] [blame] | 3 | # Builds protoc executable into target/<OS>/<ARCH>/protoc.exe; optionally builds |
| 4 | # protoc plugins into target/<OS>/<ARCH>/protoc-gen-*.exe |
Jisi Liu | b879abc | 2017-11-09 17:16:42 -0800 | [diff] [blame] | 5 | # |
Feng Xiao | 474fd31 | 2018-07-13 12:28:17 -0700 | [diff] [blame] | 6 | # Usage: ./build-protoc.sh <OS> <ARCH> <TARGET> |
| 7 | # |
| 8 | # <TARGET> can be "protoc" or "protoc-gen-javalite". Supported <OS> <ARCH> |
| 9 | # combinations: |
| 10 | # HOST <OS> <ARCH> <COMMENT> |
| 11 | # cygwin windows x86_32 Requires: i686-w64-mingw32-gcc |
| 12 | # cygwin windows x86_64 Requires: x86_64-w64-mingw32-gcc |
| 13 | # linux linux aarch_64 Requires: g++-aarch64-linux-gnu |
| 14 | # linux linux x86_32 |
| 15 | # linux linux x86_64 |
| 16 | # linux windows x86_32 Requires: i686-w64-mingw32-gcc |
| 17 | # linux windows x86_64 Requires: x86_64-w64-mingw32-gcc |
| 18 | # macos osx x86_32 |
| 19 | # macos osx x86_64 |
| 20 | # mingw windows x86_32 |
| 21 | # mingw windows x86_64 |
| 22 | # |
| 23 | # Before running this script, make sure you have generated the configure script |
| 24 | # in the parent directory (i.e., run ./autogen.sh there). |
Jisi Liu | b879abc | 2017-11-09 17:16:42 -0800 | [diff] [blame] | 25 | |
Kun Zhang | c8eda8e | 2015-04-01 16:23:15 -0700 | [diff] [blame] | 26 | OS=$1 |
| 27 | ARCH=$2 |
Jisi Liu | b1aac0b | 2016-07-26 16:30:35 -0700 | [diff] [blame] | 28 | MAKE_TARGET=$3 |
Kun Zhang | c8eda8e | 2015-04-01 16:23:15 -0700 | [diff] [blame] | 29 | |
Jisi Liu | b1aac0b | 2016-07-26 16:30:35 -0700 | [diff] [blame] | 30 | if [[ $# < 3 ]]; then |
Feng Xiao | 474fd31 | 2018-07-13 12:28:17 -0700 | [diff] [blame] | 31 | echo "Not enough arguments provided." |
Kun Zhang | b00a5d7 | 2015-04-02 13:14:29 -0700 | [diff] [blame] | 32 | exit 1 |
| 33 | fi |
| 34 | |
Jisi Liu | b1aac0b | 2016-07-26 16:30:35 -0700 | [diff] [blame] | 35 | case $MAKE_TARGET in |
| 36 | protoc-gen-javalite) |
| 37 | ;; |
| 38 | protoc) |
| 39 | ;; |
| 40 | *) |
Feng Xiao | 9209a41 | 2018-07-15 18:16:40 -0700 | [diff] [blame] | 41 | echo "Target ""$MAKE_TARGET"" invalid." |
Jisi Liu | b1aac0b | 2016-07-26 16:30:35 -0700 | [diff] [blame] | 42 | exit 1 |
| 43 | esac |
| 44 | |
Kun Zhang | c8eda8e | 2015-04-01 16:23:15 -0700 | [diff] [blame] | 45 | # Under Cygwin, bash doesn't have these in PATH when called from Maven which |
| 46 | # runs in Windows version of Java. |
| 47 | export PATH="/bin:/usr/bin:$PATH" |
| 48 | |
| 49 | ############################################################################ |
| 50 | # Helper functions |
| 51 | ############################################################################ |
| 52 | E_PARAM_ERR=98 |
| 53 | E_ASSERT_FAILED=99 |
| 54 | |
Kun Zhang | b00a5d7 | 2015-04-02 13:14:29 -0700 | [diff] [blame] | 55 | # Usage: |
Kun Zhang | c8eda8e | 2015-04-01 16:23:15 -0700 | [diff] [blame] | 56 | fail() |
| 57 | { |
Kun Zhang | 6f2bc19 | 2015-04-07 20:43:20 -0700 | [diff] [blame] | 58 | echo "ERROR: $1" |
| 59 | echo |
Kun Zhang | c8eda8e | 2015-04-01 16:23:15 -0700 | [diff] [blame] | 60 | exit $E_ASSERT_FAILED |
| 61 | } |
| 62 | |
| 63 | # Usage: assertEq VAL1 VAL2 $LINENO |
| 64 | assertEq () |
| 65 | { |
| 66 | lineno=$3 |
| 67 | if [ -z "$lineno" ]; then |
| 68 | echo "lineno not given" |
| 69 | exit $E_PARAM_ERR |
| 70 | fi |
| 71 | |
| 72 | if [[ "$1" != "$2" ]]; then |
| 73 | echo "Assertion failed: \"$1\" == \"$2\"" |
| 74 | echo "File \"$0\", line $lineno" # Give name of file and line number. |
| 75 | exit $E_ASSERT_FAILED |
| 76 | fi |
| 77 | } |
Kun Zhang | b00a5d7 | 2015-04-02 13:14:29 -0700 | [diff] [blame] | 78 | |
| 79 | # Checks the artifact is for the expected architecture |
| 80 | # Usage: checkArch <path-to-protoc> |
| 81 | checkArch () |
| 82 | { |
Kun Zhang | 6f2bc19 | 2015-04-07 20:43:20 -0700 | [diff] [blame] | 83 | echo |
Kun Zhang | 5c265fa | 2015-04-07 21:06:37 -0700 | [diff] [blame] | 84 | echo "Checking file format ..." |
Kun Zhang | b00a5d7 | 2015-04-02 13:14:29 -0700 | [diff] [blame] | 85 | if [[ "$OS" == windows || "$OS" == linux ]]; then |
| 86 | format="$(objdump -f "$1" | grep -o "file format .*$" | grep -o "[^ ]*$")" |
Kun Zhang | 6f2bc19 | 2015-04-07 20:43:20 -0700 | [diff] [blame] | 87 | echo Format=$format |
Kun Zhang | b00a5d7 | 2015-04-02 13:14:29 -0700 | [diff] [blame] | 88 | if [[ "$OS" == linux ]]; then |
nashimus | 1f7837a | 2018-07-06 20:03:25 -0600 | [diff] [blame] | 89 | host_machine="$(uname -m)"; |
Kun Zhang | b00a5d7 | 2015-04-02 13:14:29 -0700 | [diff] [blame] | 90 | if [[ "$ARCH" == x86_32 ]]; then |
| 91 | assertEq $format "elf32-i386" $LINENO |
| 92 | elif [[ "$ARCH" == x86_64 ]]; then |
| 93 | assertEq $format "elf64-x86-64" $LINENO |
Jisi Liu | b879abc | 2017-11-09 17:16:42 -0800 | [diff] [blame] | 94 | elif [[ "$ARCH" == aarch_64 ]]; then |
| 95 | assertEq $format "elf64-little" $LINENO |
pravin-dsilva | 36ba04b | 2018-03-22 18:55:50 +0530 | [diff] [blame] | 96 | elif [[ "$ARCH" == ppcle_64 ]]; then |
nashimus | 1f7837a | 2018-07-06 20:03:25 -0600 | [diff] [blame] | 97 | if [[ $host_machine == ppc64le ]];then |
| 98 | assertEq $format "elf64-powerpcle" $LINENO |
| 99 | else |
| 100 | assertEq $format "elf64-little" $LINENO |
| 101 | fi |
Kun Zhang | b00a5d7 | 2015-04-02 13:14:29 -0700 | [diff] [blame] | 102 | else |
| 103 | fail "Unsupported arch: $ARCH" |
| 104 | fi |
| 105 | else |
| 106 | # $OS == windows |
| 107 | if [[ "$ARCH" == x86_32 ]]; then |
| 108 | assertEq $format "pei-i386" $LINENO |
| 109 | elif [[ "$ARCH" == x86_64 ]]; then |
| 110 | assertEq $format "pei-x86-64" $LINENO |
| 111 | else |
| 112 | fail "Unsupported arch: $ARCH" |
| 113 | fi |
| 114 | fi |
| 115 | elif [[ "$OS" == osx ]]; then |
| 116 | format="$(file -b "$1" | grep -o "[^ ]*$")" |
Kun Zhang | 6f2bc19 | 2015-04-07 20:43:20 -0700 | [diff] [blame] | 117 | echo Format=$format |
Kun Zhang | c5a2a7c | 2015-04-06 14:31:29 -0700 | [diff] [blame] | 118 | if [[ "$ARCH" == x86_32 ]]; then |
| 119 | assertEq $format "i386" $LINENO |
| 120 | elif [[ "$ARCH" == x86_64 ]]; then |
| 121 | assertEq $format "x86_64" $LINENO |
| 122 | else |
| 123 | fail "Unsupported arch: $ARCH" |
| 124 | fi |
Kun Zhang | b00a5d7 | 2015-04-02 13:14:29 -0700 | [diff] [blame] | 125 | else |
Kun Zhang | 6f2bc19 | 2015-04-07 20:43:20 -0700 | [diff] [blame] | 126 | fail "Unsupported system: $OS" |
Kun Zhang | b00a5d7 | 2015-04-02 13:14:29 -0700 | [diff] [blame] | 127 | fi |
Kun Zhang | 6f2bc19 | 2015-04-07 20:43:20 -0700 | [diff] [blame] | 128 | echo |
| 129 | } |
| 130 | |
| 131 | # Checks the dependencies of the artifact. Artifacts should only depend on |
| 132 | # system libraries. |
| 133 | # Usage: checkDependencies <path-to-protoc> |
| 134 | checkDependencies () |
| 135 | { |
| 136 | if [[ "$OS" == windows ]]; then |
| 137 | dump_cmd='objdump -x '"$1"' | fgrep "DLL Name"' |
| 138 | white_list="KERNEL32\.dll\|msvcrt\.dll" |
| 139 | elif [[ "$OS" == linux ]]; then |
nashimus | 1f7837a | 2018-07-06 20:03:25 -0600 | [diff] [blame] | 140 | host_machine="$(uname -m)"; |
Kun Zhang | 6f2bc19 | 2015-04-07 20:43:20 -0700 | [diff] [blame] | 141 | dump_cmd='ldd '"$1" |
| 142 | if [[ "$ARCH" == x86_32 ]]; then |
| 143 | white_list="linux-gate\.so\.1\|libpthread\.so\.0\|libm\.so\.6\|libc\.so\.6\|ld-linux\.so\.2" |
| 144 | elif [[ "$ARCH" == x86_64 ]]; then |
| 145 | white_list="linux-vdso\.so\.1\|libpthread\.so\.0\|libm\.so\.6\|libc\.so\.6\|ld-linux-x86-64\.so\.2" |
pravin-dsilva | 36ba04b | 2018-03-22 18:55:50 +0530 | [diff] [blame] | 146 | elif [[ "$ARCH" == ppcle_64 ]]; then |
nashimus | 1f7837a | 2018-07-06 20:03:25 -0600 | [diff] [blame] | 147 | if [[ $host_machine != ppc64le ]];then |
| 148 | dump_cmd='objdump -p '"$1"' | grep NEEDED' |
| 149 | fi |
pravin-dsilva | 36ba04b | 2018-03-22 18:55:50 +0530 | [diff] [blame] | 150 | white_list="linux-vdso64\.so\.1\|libpthread\.so\.0\|libm\.so\.6\|libc\.so\.6\|libz\.so\.1\|ld64\.so\.2" |
Jisi Liu | b879abc | 2017-11-09 17:16:42 -0800 | [diff] [blame] | 151 | elif [[ "$ARCH" == aarch_64 ]]; then |
| 152 | dump_cmd='objdump -p '"$1"' | grep NEEDED' |
Adam Cozzette | 6fc2bac | 2018-07-06 12:38:14 -0700 | [diff] [blame] | 153 | white_list="libpthread\.so\.0\|libm\.so\.6\|libc\.so\.6\|ld-linux-aarch64\.so\.1" |
Kun Zhang | 6f2bc19 | 2015-04-07 20:43:20 -0700 | [diff] [blame] | 154 | fi |
| 155 | elif [[ "$OS" == osx ]]; then |
Kun Zhang | 5c265fa | 2015-04-07 21:06:37 -0700 | [diff] [blame] | 156 | dump_cmd='otool -L '"$1"' | fgrep dylib' |
Kun Zhang | 62903ec | 2015-04-08 00:14:36 -0700 | [diff] [blame] | 157 | white_list="libz\.1\.dylib\|libstdc++\.6\.dylib\|libSystem\.B\.dylib" |
Kun Zhang | 6f2bc19 | 2015-04-07 20:43:20 -0700 | [diff] [blame] | 158 | fi |
| 159 | if [[ -z "$white_list" || -z "$dump_cmd" ]]; then |
| 160 | fail "Unsupported platform $OS-$ARCH." |
| 161 | fi |
| 162 | echo "Checking for expected dependencies ..." |
| 163 | eval $dump_cmd | grep -i "$white_list" || fail "doesn't show any expected dependencies" |
| 164 | echo "Checking for unexpected dependencies ..." |
| 165 | eval $dump_cmd | grep -i -v "$white_list" |
| 166 | ret=$? |
| 167 | if [[ $ret == 0 ]]; then |
| 168 | fail "found unexpected dependencies (listed above)." |
| 169 | elif [[ $ret != 1 ]]; then |
| 170 | fail "Error when checking dependencies." |
| 171 | fi # grep returns 1 when "not found", which is what we expect |
| 172 | echo "Dependencies look good." |
| 173 | echo |
Kun Zhang | b00a5d7 | 2015-04-02 13:14:29 -0700 | [diff] [blame] | 174 | } |
Kun Zhang | c8eda8e | 2015-04-01 16:23:15 -0700 | [diff] [blame] | 175 | ############################################################################ |
| 176 | |
Feng Xiao | 9209a41 | 2018-07-15 18:16:40 -0700 | [diff] [blame] | 177 | echo "Building protoc, OS=$OS ARCH=$ARCH TARGET=$MAKE_TARGET" |
Kun Zhang | c8eda8e | 2015-04-01 16:23:15 -0700 | [diff] [blame] | 178 | |
Kun Zhang | c8eda8e | 2015-04-01 16:23:15 -0700 | [diff] [blame] | 179 | CONFIGURE_ARGS="--disable-shared" |
| 180 | |
Kun Zhang | c8eda8e | 2015-04-01 16:23:15 -0700 | [diff] [blame] | 181 | if [[ "$OS" == windows ]]; then |
| 182 | MAKE_TARGET="${MAKE_TARGET}.exe" |
| 183 | fi |
| 184 | |
Kun Zhang | b00a5d7 | 2015-04-02 13:14:29 -0700 | [diff] [blame] | 185 | # Override the default value set in configure.ac that has '-g' which produces |
| 186 | # huge binary. |
| 187 | CXXFLAGS="-DNDEBUG" |
Kun Zhang | 6f2bc19 | 2015-04-07 20:43:20 -0700 | [diff] [blame] | 188 | LDFLAGS="" |
Kun Zhang | b00a5d7 | 2015-04-02 13:14:29 -0700 | [diff] [blame] | 189 | |
Kun Zhang | c8eda8e | 2015-04-01 16:23:15 -0700 | [diff] [blame] | 190 | if [[ "$(uname)" == CYGWIN* ]]; then |
| 191 | assertEq "$OS" windows $LINENO |
| 192 | # Use mingw32 compilers because executables produced by Cygwin compiler |
| 193 | # always have dependency on Cygwin DLL. |
| 194 | if [[ "$ARCH" == x86_64 ]]; then |
| 195 | CONFIGURE_ARGS="$CONFIGURE_ARGS --host=x86_64-w64-mingw32" |
| 196 | elif [[ "$ARCH" == x86_32 ]]; then |
| 197 | CONFIGURE_ARGS="$CONFIGURE_ARGS --host=i686-pc-mingw32" |
| 198 | else |
| 199 | fail "Unsupported arch by CYGWIN: $ARCH" |
| 200 | fi |
| 201 | elif [[ "$(uname)" == MINGW32* ]]; then |
| 202 | assertEq "$OS" windows $LINENO |
| 203 | assertEq "$ARCH" x86_32 $LINENO |
Kun Zhang | 90a7ed6 | 2015-04-16 17:30:07 -0700 | [diff] [blame] | 204 | elif [[ "$(uname)" == MINGW64* ]]; then |
| 205 | assertEq "$OS" windows $LINENO |
| 206 | assertEq "$ARCH" x86_64 $LINENO |
Kun Zhang | c8eda8e | 2015-04-01 16:23:15 -0700 | [diff] [blame] | 207 | elif [[ "$(uname)" == Linux* ]]; then |
Kun Zhang | 6f2bc19 | 2015-04-07 20:43:20 -0700 | [diff] [blame] | 208 | if [[ "$OS" == linux ]]; then |
| 209 | if [[ "$ARCH" == x86_64 ]]; then |
| 210 | CXXFLAGS="$CXXFLAGS -m64" |
| 211 | elif [[ "$ARCH" == x86_32 ]]; then |
| 212 | CXXFLAGS="$CXXFLAGS -m32" |
Jisi Liu | b879abc | 2017-11-09 17:16:42 -0800 | [diff] [blame] | 213 | elif [[ "$ARCH" == aarch_64 ]]; then |
| 214 | CONFIGURE_ARGS="$CONFIGURE_ARGS --host=aarch64-linux-gnu" |
pravin-dsilva | 36ba04b | 2018-03-22 18:55:50 +0530 | [diff] [blame] | 215 | elif [[ "$ARCH" == ppcle_64 ]]; then |
| 216 | CXXFLAGS="$CXXFLAGS -m64" |
nashimus | 1f7837a | 2018-07-06 20:03:25 -0600 | [diff] [blame] | 217 | CONFIGURE_ARGS="$CONFIGURE_ARGS --host=powerpc64le-linux-gnu" |
Kun Zhang | 6f2bc19 | 2015-04-07 20:43:20 -0700 | [diff] [blame] | 218 | else |
| 219 | fail "Unsupported arch: $ARCH" |
| 220 | fi |
| 221 | elif [[ "$OS" == windows ]]; then |
| 222 | # Cross-compilation for Windows |
Kun Zhang | 6f2bc19 | 2015-04-07 20:43:20 -0700 | [diff] [blame] | 223 | CONFIGURE_ARGS="$CONFIGURE_ARGS" |
| 224 | if [[ "$ARCH" == x86_64 ]]; then |
| 225 | CONFIGURE_ARGS="$CONFIGURE_ARGS --host=x86_64-w64-mingw32" |
| 226 | elif [[ "$ARCH" == x86_32 ]]; then |
| 227 | CONFIGURE_ARGS="$CONFIGURE_ARGS --host=i686-w64-mingw32" |
| 228 | else |
| 229 | fail "Unsupported arch: $ARCH" |
| 230 | fi |
Kun Zhang | c8eda8e | 2015-04-01 16:23:15 -0700 | [diff] [blame] | 231 | else |
Kun Zhang | 6f2bc19 | 2015-04-07 20:43:20 -0700 | [diff] [blame] | 232 | fail "Cannot build $OS on $(uname)" |
Kun Zhang | c8eda8e | 2015-04-01 16:23:15 -0700 | [diff] [blame] | 233 | fi |
| 234 | elif [[ "$(uname)" == Darwin* ]]; then |
| 235 | assertEq "$OS" osx $LINENO |
Kun Zhang | 62903ec | 2015-04-08 00:14:36 -0700 | [diff] [blame] | 236 | # Make the binary compatible with OSX 10.7 and later |
| 237 | CXXFLAGS="$CXXFLAGS -mmacosx-version-min=10.7" |
Kun Zhang | c5a2a7c | 2015-04-06 14:31:29 -0700 | [diff] [blame] | 238 | if [[ "$ARCH" == x86_64 ]]; then |
| 239 | CXXFLAGS="$CXXFLAGS -m64" |
| 240 | elif [[ "$ARCH" == x86_32 ]]; then |
| 241 | CXXFLAGS="$CXXFLAGS -m32" |
| 242 | else |
| 243 | fail "Unsupported arch: $ARCH" |
| 244 | fi |
Kun Zhang | c8eda8e | 2015-04-01 16:23:15 -0700 | [diff] [blame] | 245 | else |
| 246 | fail "Unsupported system: $(uname)" |
| 247 | fi |
Kun Zhang | ae9177d | 2015-03-31 18:26:28 -0700 | [diff] [blame] | 248 | |
Kun Zhang | e4f1f93 | 2015-03-31 16:28:57 -0700 | [diff] [blame] | 249 | # Statically link libgcc and libstdc++. |
Kun Zhang | 87b8501 | 2015-04-01 18:02:36 -0700 | [diff] [blame] | 250 | # -s to produce stripped binary. |
Jisi Liu | d909834 | 2017-08-15 13:15:37 -0700 | [diff] [blame] | 251 | if [[ "$OS" == windows ]]; then |
Jisi Liu | fa086c8 | 2017-08-15 12:27:46 -0700 | [diff] [blame] | 252 | # Also static link libpthread required by mingw64 |
| 253 | LDFLAGS="$LDFLAGS -static-libgcc -static-libstdc++ -Wl,-Bstatic -lstdc++ -lpthread -s" |
| 254 | elif [[ "$OS" != osx ]]; then |
| 255 | # And they don't work under Mac. |
Kun Zhang | 6f2bc19 | 2015-04-07 20:43:20 -0700 | [diff] [blame] | 256 | LDFLAGS="$LDFLAGS -static-libgcc -static-libstdc++ -s" |
Kun Zhang | 87b8501 | 2015-04-01 18:02:36 -0700 | [diff] [blame] | 257 | fi |
Kun Zhang | 36093ca | 2015-03-31 22:07:13 +0100 | [diff] [blame] | 258 | |
Kun Zhang | 6f2bc19 | 2015-04-07 20:43:20 -0700 | [diff] [blame] | 259 | export CXXFLAGS LDFLAGS |
| 260 | |
Feng Xiao | 474fd31 | 2018-07-13 12:28:17 -0700 | [diff] [blame] | 261 | # Nested double quotes are unintuitive, but it works. |
| 262 | cd "$(dirname "$0")" |
| 263 | |
| 264 | WORKING_DIR="$(pwd)" |
| 265 | BUILD_DIR="build/$OS/$ARCH" |
| 266 | TARGET_FILE="target/$OS/$ARCH/$MAKE_TARGET.exe" |
| 267 | |
| 268 | mkdir -p "$BUILD_DIR" && cd "$BUILD_DIR" && |
| 269 | ../../../../configure $CONFIGURE_ARGS && |
| 270 | cd src && make $MAKE_TARGET -j8 && |
| 271 | cd "$WORKING_DIR" && mkdir -p $(dirname $TARGET_FILE) && |
| 272 | cp $BUILD_DIR/src/$MAKE_TARGET $TARGET_FILE || |
Kun Zhang | 1c12612 | 2015-04-08 10:39:21 -0700 | [diff] [blame] | 273 | exit 1 |
| 274 | |
| 275 | if [[ "$OS" == osx ]]; then |
| 276 | # Since Mac linker doesn't accept "-s", we need to run strip |
| 277 | strip $TARGET_FILE || exit 1 |
| 278 | fi |
| 279 | |
| 280 | checkArch $TARGET_FILE && checkDependencies $TARGET_FILE |