make.bash 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. #!/usr/bin/env bash
  2. set -e -x
  3. if [ ! -f make.bash ]; then
  4. echo "make.bash must be run from $GOPATH/src/github.com/Psiphon-Labs/psiphon-tunnel-core/ConsoleClient"
  5. exit 1
  6. fi
  7. EXE_BASENAME="psiphon-tunnel-core"
  8. # The "OPENSSL" tag enables support of OpenSSL for use by IndistinguishableTLS.
  9. # This needs to be outside of prepare_build because it's used by go-get.
  10. WINDOWS_BUILD_TAGS="OPENSSL"
  11. LINUX_BUILD_TAGS=
  12. OSX_BUILD_TAGS=
  13. prepare_build () {
  14. BUILDINFOFILE="${EXE_BASENAME}_buildinfo.txt"
  15. BUILDDATE=$(date --iso-8601=seconds)
  16. BUILDREPO=$(git config --get remote.origin.url)
  17. BUILDREV=$(git rev-parse --short HEAD)
  18. GOVERSION=$(go version | perl -ne '/go version (.*?) / && print $1')
  19. # - starts the string with a `{`
  20. # - uses the `go list` command and passes it a template string (using the Go template syntax) saying I want all the dependencies of the package in the current directory, printing 1/line via printf
  21. # - pipes to `xargs` to run a command on each line output from the first command
  22. # - uses `go list` with a template string to print the "Import Path" (from just below `$GOPATH/src`) if the package is not part of the standard library
  23. # - pipes to `xargs` again, specifiying `pkg` as the placeholder name for each item being operated on (which is the list of non standard library import paths from the previous step)
  24. # - `xargs` runs a bash script (via `-c`) which changes to each import path in sequence, then echoes out `"<import path>":"<subshell output of getting the short git revision>",`
  25. # - this leaves a trailing `,` at the end, and no close to the JSON object, so simply `sed` replace the comma before the end of the line with `}` and you now have valid JSON
  26. DEPENDENCIES=$(echo -n "{" && go list -f '{{range $dep := .Deps}}{{printf "%s\n" $dep}}{{end}}' | xargs go list -f '{{if not .Standard}}{{.ImportPath}}{{end}}' | xargs -I pkg bash -c 'cd $GOPATH/src/pkg && echo -n "\"pkg\":\"$(git rev-parse --short HEAD)\","' | sed 's/,$/}/')
  27. LDFLAGS="\
  28. -X github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common.buildDate=$BUILDDATE \
  29. -X github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common.buildRepo=$BUILDREPO \
  30. -X github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common.buildRev=$BUILDREV \
  31. -X github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common.goVersion=$GOVERSION \
  32. -X github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common.dependencies=$DEPENDENCIES \
  33. "
  34. echo -e "${BUILDDATE}\n${BUILDREPO}\n${BUILDREV}\n" > $BUILDINFOFILE
  35. echo "Variables for ldflags:"
  36. echo " Build date: ${BUILDDATE}"
  37. echo " Build repo: ${BUILDREPO}"
  38. echo " Build revision: ${BUILDREV}"
  39. echo " Go version: ${GOVERSION}"
  40. echo " Dependencies: ${DEPENDENCIES}"
  41. echo ""
  42. }
  43. if [ ! -d bin ]; then
  44. mkdir bin
  45. fi
  46. build_for_windows () {
  47. echo "...Getting project dependencies (via go get) for Windows. Parameter is: '$1'"
  48. GOOS=windows go get -d -v -tags "$WINDOWS_BUILD_TAGS" ./...
  49. prepare_build
  50. if [ $? != 0 ]; then
  51. echo "....'go get' failed, exiting"
  52. exit $?
  53. fi
  54. if [ -z $1 ] || [ "$1" == "32" ]; then
  55. unset PKG_CONFIG_PATH
  56. export PKG_CONFIG_PATH=$PKG_CONFIG_PATH_32
  57. echo "...Building windows-i686"
  58. echo "....PKG_CONFIG_PATH=$PKG_CONFIG_PATH"
  59. CGO_CFLAGS="-I $PKG_CONFIG_PATH/include/" \
  60. CGO_LDFLAGS="-L $PKG_CONFIG_PATH -L /usr/i686-w64-mingw32/lib/ -lssl -lcrypto -lwsock32 -lcrypt32 -lgdi32" \
  61. CC=/usr/bin/i686-w64-mingw32-gcc \
  62. gox -verbose -ldflags "$LDFLAGS" -osarch windows/386 -tags "$WINDOWS_BUILD_TAGS" -output bin/windows/${EXE_BASENAME}-i686
  63. RETVAL=$?
  64. echo ".....gox completed, exit code: $?"
  65. if [ $RETVAL != 0 ]; then
  66. echo ".....gox failed, exiting"
  67. exit $RETVAL
  68. fi
  69. unset RETVAL
  70. ## We are finding that UPXing the full Windows Psiphon client produces better results if psiphon-tunnel-core.exe is not already UPX'd.
  71. echo "....No UPX for this build"
  72. fi
  73. if [ -z $1 ] || [ "$1" == "64" ]; then
  74. unset PKG_CONFIG_PATH
  75. export PKG_CONFIG_PATH=$PKG_CONFIG_PATH_64
  76. echo "...Building windows-x86_64"
  77. echo "....PKG_CONFIG_PATH=$PKG_CONFIG_PATH"
  78. CGO_CFLAGS="-I $PKG_CONFIG_PATH/include/" \
  79. CGO_LDFLAGS="-L $PKG_CONFIG_PATH -L /usr/x86_64-w64-mingw32/lib/ -lssl -lcrypto -lwsock32 -lcrypt32 -lgdi32" \
  80. CC=/usr/bin/x86_64-w64-mingw32-gcc \
  81. gox -verbose -ldflags "$LDFLAGS" -osarch windows/amd64 -tags "$WINDOWS_BUILD_TAGS" -output bin/windows/${EXE_BASENAME}-x86_64
  82. RETVAL=$?
  83. if [ $RETVAL != 0 ]; then
  84. echo ".....gox failed, exiting"
  85. exit $RETVAL
  86. fi
  87. unset RETVAL
  88. # We are finding that UPXing the full Windows Psiphon client produces better results if psiphon-tunnel-core.exe is not already UPX'd.
  89. echo "....No UPX for this build"
  90. fi
  91. }
  92. build_for_linux () {
  93. echo "Getting project dependencies (via go get) for Linux. Parameter is: '$1'"
  94. GOOS=linux go get -d -v -tags "$LINUX_BUILD_TAGS" ./...
  95. prepare_build
  96. if [ $? != 0 ]; then
  97. echo "...'go get' failed, exiting"
  98. exit $?
  99. fi
  100. if [ -z $1 ] || [ "$1" == "32" ]; then
  101. echo "...Building linux-i686"
  102. CFLAGS=-m32 gox -verbose -ldflags "$LDFLAGS" -osarch linux/386 -tags "$LINUX_BUILD_TAGS" -output bin/linux/${EXE_BASENAME}-i686
  103. RETVAL=$?
  104. if [ $RETVAL != 0 ]; then
  105. echo ".....gox failed, exiting"
  106. exit $RETVAL
  107. fi
  108. unset RETVAL
  109. echo "....UPX packaging output"
  110. goupx --best bin/linux/${EXE_BASENAME}-i686
  111. RETVAL=$?
  112. if [ $RETVAL != 0 ]; then
  113. echo ".....goupx failed, exiting"
  114. exit $RETVAL
  115. fi
  116. unset RETVAL
  117. fi
  118. if [ -z $1 ] || [ "$1" == "64" ]; then
  119. echo "...Building linux-x86_64"
  120. gox -verbose -ldflags "$LDFLAGS" -osarch linux/amd64 -tags "$LINUX_BUILD_TAGS" -output bin/linux/${EXE_BASENAME}-x86_64
  121. RETVAL=$?
  122. if [ $RETVAL != 0 ]; then
  123. echo "....gox failed, exiting"
  124. exit $RETVAL
  125. fi
  126. unset RETVAL
  127. echo "....UPX packaging output"
  128. goupx --best bin/linux/${EXE_BASENAME}-x86_64
  129. RETVAL=$?
  130. if [ $RETVAL != 0 ]; then
  131. echo ".....goupx failed, exiting"
  132. exit $RETVAL
  133. fi
  134. unset RETVAL
  135. fi
  136. }
  137. build_for_osx () {
  138. echo "Getting project dependencies (via go get) for OSX"
  139. GOOS=darwin go get -d -v -tags "$OSX_BUILD_TAGS" ./...
  140. prepare_build
  141. if [ $? != 0 ]; then
  142. echo "..'go get' failed, exiting"
  143. exit $?
  144. fi
  145. echo "Building darwin-x86_64..."
  146. echo "..Disabling CGO for this build"
  147. CGO_ENABLED=0 gox -verbose -ldflags "$LDFLAGS" -osarch darwin/amd64 -tags "$OSX_BUILD_TAGS" -output bin/darwin/${EXE_BASENAME}-x86_64
  148. # Darwin binaries don't seem to be UPXable when built this way
  149. echo "..No UPX for this build"
  150. }
  151. TARGET=$1
  152. case $TARGET in
  153. windows)
  154. echo "..Building for Windows"
  155. build_for_windows $2
  156. exit $?
  157. ;;
  158. linux)
  159. echo "..Building for Linux"
  160. build_for_linux $2
  161. exit $?
  162. ;;
  163. osx)
  164. echo "..Building for OSX"
  165. build_for_osx
  166. exit $?
  167. ;;
  168. all)
  169. echo "..Building all"
  170. build_for_windows $2
  171. if [ $? != 0 ]; then
  172. exit $?
  173. fi
  174. build_for_linux $2
  175. if [ $? != 0 ]; then
  176. exit $?
  177. fi
  178. build_for_osx
  179. if [ $? != 0 ]; then
  180. exit $?
  181. fi
  182. ;;
  183. *)
  184. echo "..No selection made, building all"
  185. build_for_windows $2
  186. if [ $? != 0 ]; then
  187. exit $?
  188. fi
  189. build_for_linux $2
  190. if [ $? != 0 ]; then
  191. exit $?
  192. fi
  193. build_for_osx
  194. if [ $? != 0 ]; then
  195. exit $?
  196. fi
  197. ;;
  198. esac
  199. echo "Done"