config_brpc.sh 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421
  1. SYSTEM=$(uname -s)
  2. if [ "$SYSTEM" = "Darwin" ]; then
  3. if [ -z "$BASH" ] || [ "$BASH" = "/bin/sh" ] ; then
  4. ECHO=echo
  5. else
  6. ECHO='echo -e'
  7. fi
  8. SO=dylib
  9. LDD="otool -L"
  10. if [ "$(getopt -V)" = " --" ]; then
  11. >&2 $ECHO "gnu-getopt must be installed and used"
  12. exit 1
  13. fi
  14. else
  15. if [ -z "$BASH" ]; then
  16. ECHO=echo
  17. else
  18. ECHO='echo -e'
  19. fi
  20. SO=so
  21. LDD=ldd
  22. fi
  23. TEMP=`getopt -o v: --long headers:,libs:,cc:,cxx:,with-glog,with-thrift,with-mesalink,nodebugsymbols -n 'config_brpc' -- "$@"`
  24. WITH_GLOG=0
  25. WITH_THRIFT=0
  26. WITH_MESALINK=0
  27. DEBUGSYMBOLS=-g
  28. if [ $? != 0 ] ; then >&2 $ECHO "Terminating..."; exit 1 ; fi
  29. # Note the quotes around `$TEMP': they are essential!
  30. eval set -- "$TEMP"
  31. if [ "$SYSTEM" = "Darwin" ]; then
  32. REALPATH=realpath
  33. else
  34. REALPATH="readlink -f"
  35. fi
  36. # Convert to abspath always so that generated mk is include-able from everywhere
  37. while true; do
  38. case "$1" in
  39. --headers ) HDRS_IN="$(${REALPATH} $2)"; shift 2 ;;
  40. --libs ) LIBS_IN="$(${REALPATH} $2)"; shift 2 ;;
  41. --cc ) CC=$2; shift 2 ;;
  42. --cxx ) CXX=$2; shift 2 ;;
  43. --with-glog ) WITH_GLOG=1; shift 1 ;;
  44. --with-thrift) WITH_THRIFT=1; shift 1 ;;
  45. --with-mesalink) WITH_MESALINK=1; shift 1 ;;
  46. --nodebugsymbols ) DEBUGSYMBOLS=; shift 1 ;;
  47. -- ) shift; break ;;
  48. * ) break ;;
  49. esac
  50. done
  51. if [ -z "$CC" ]; then
  52. if [ ! -z "$CXX" ]; then
  53. >&2 $ECHO "--cc and --cxx must be both set or unset"
  54. exit 1
  55. fi
  56. CC=gcc
  57. CXX=g++
  58. if [ "$SYSTEM" = "Darwin" ]; then
  59. CC=clang
  60. CXX=clang++
  61. fi
  62. elif [ -z "$CXX" ]; then
  63. >&2 $ECHO "--cc and --cxx must be both set or unset"
  64. exit 1
  65. fi
  66. GCC_VERSION=$($CXX tools/print_gcc_version.cc -o print_gcc_version && ./print_gcc_version && rm ./print_gcc_version)
  67. if [ $GCC_VERSION -gt 0 ] && [ $GCC_VERSION -lt 40800 ]; then
  68. >&2 $ECHO "GCC is too old, please install a newer version supporting C++11"
  69. exit 1
  70. fi
  71. if [ -z "$HDRS_IN" ] || [ -z "$LIBS_IN" ]; then
  72. >&2 $ECHO "config_brpc: --headers=HDRPATHS --libs=LIBPATHS must be specified"
  73. exit 1
  74. fi
  75. find_dir_of_lib() {
  76. local lib=$(find ${LIBS_IN} -name "lib${1}.a" -o -name "lib${1}.$SO" 2>/dev/null | head -n1)
  77. if [ ! -z "$lib" ]; then
  78. dirname $lib
  79. fi
  80. }
  81. find_dir_of_lib_or_die() {
  82. local dir=$(find_dir_of_lib $1)
  83. if [ -z "$dir" ]; then
  84. >&2 $ECHO "Fail to find $1 from --libs"
  85. exit 1
  86. else
  87. $ECHO $dir
  88. fi
  89. }
  90. find_bin() {
  91. TARGET_BIN=$(find ${LIBS_IN} -type f -name "$1" 2>/dev/null | head -n1)
  92. if [ ! -z "$TARGET_BIN" ]; then
  93. $ECHO $TARGET_BIN
  94. else
  95. which "$1" 2>/dev/null
  96. fi
  97. }
  98. find_bin_or_die() {
  99. TARGET_BIN=$(find_bin "$1")
  100. if [ ! -z "$TARGET_BIN" ]; then
  101. $ECHO $TARGET_BIN
  102. else
  103. >&2 $ECHO "Fail to find $1"
  104. exit 1
  105. fi
  106. }
  107. find_dir_of_header() {
  108. find -L ${HDRS_IN} -path "*/$1" | head -n1 | sed "s|$1||g"
  109. }
  110. find_dir_of_header_excluding() {
  111. find -L ${HDRS_IN} -path "*/$1" | grep -v "$2\$" | head -n1 | sed "s|$1||g"
  112. }
  113. find_dir_of_header_or_die() {
  114. if [ -z "$2" ]; then
  115. local dir=$(find_dir_of_header $1)
  116. else
  117. local dir=$(find_dir_of_header_excluding $1 $2)
  118. fi
  119. if [ -z "$dir" ]; then
  120. >&2 $ECHO "Fail to find $1 from --headers"
  121. exit 1
  122. fi
  123. $ECHO $dir
  124. }
  125. if [ "$SYSTEM" = "Darwin" ]; then
  126. OPENSSL_LIB="/usr/local/opt/openssl/lib"
  127. OPENSSL_HDR="/usr/local/opt/openssl/include"
  128. else
  129. # User specified path of openssl, if not given it's empty
  130. OPENSSL_LIB=$(find_dir_of_lib ssl)
  131. # Inconvenient to check these headers in baidu-internal
  132. #PTHREAD_HDR=$(find_dir_of_header_or_die pthread.h)
  133. OPENSSL_HDR=$(find_dir_of_header_or_die openssl/ssl.h)
  134. fi
  135. if [ $WITH_MESALINK != 0 ]; then
  136. MESALINK_HDR=$(find_dir_of_header_or_die mesalink/openssl/ssl.h)
  137. OPENSSL_HDR="$OPENSSL_HDR\n$MESALINK_HDR"
  138. fi
  139. STATIC_LINKINGS=
  140. DYNAMIC_LINKINGS="-lpthread -lssl -lcrypto -ldl -lz"
  141. if [ $WITH_MESALINK != 0 ]; then
  142. DYNAMIC_LINKINGS="$DYNAMIC_LINKINGS -lmesalink"
  143. fi
  144. if [ "$SYSTEM" = "Linux" ]; then
  145. DYNAMIC_LINKINGS="$DYNAMIC_LINKINGS -lrt"
  146. fi
  147. if [ "$SYSTEM" = "Darwin" ]; then
  148. DYNAMIC_LINKINGS="$DYNAMIC_LINKINGS -framework CoreFoundation"
  149. DYNAMIC_LINKINGS="$DYNAMIC_LINKINGS -framework CoreGraphics"
  150. DYNAMIC_LINKINGS="$DYNAMIC_LINKINGS -framework CoreData"
  151. DYNAMIC_LINKINGS="$DYNAMIC_LINKINGS -framework CoreText"
  152. DYNAMIC_LINKINGS="$DYNAMIC_LINKINGS -framework Security"
  153. DYNAMIC_LINKINGS="$DYNAMIC_LINKINGS -framework Foundation"
  154. DYNAMIC_LINKINGS="$DYNAMIC_LINKINGS -Wl,-U,_MallocExtension_ReleaseFreeMemory"
  155. DYNAMIC_LINKINGS="$DYNAMIC_LINKINGS -Wl,-U,_ProfilerStart"
  156. DYNAMIC_LINKINGS="$DYNAMIC_LINKINGS -Wl,-U,_ProfilerStop"
  157. DYNAMIC_LINKINGS="$DYNAMIC_LINKINGS -Wl,-U,_RegisterThriftProtocol"
  158. fi
  159. append_linking() {
  160. if [ -f $1/lib${2}.a ]; then
  161. if [ "$SYSTEM" = "Darwin" ]; then
  162. # *.a must be explicitly specified in clang
  163. STATIC_LINKINGS="$STATIC_LINKINGS $1/lib${2}.a"
  164. else
  165. STATIC_LINKINGS="$STATIC_LINKINGS -l$2"
  166. fi
  167. export STATICALLY_LINKED_$2=1
  168. else
  169. DYNAMIC_LINKINGS="$DYNAMIC_LINKINGS -l$2"
  170. export STATICALLY_LINKED_$2=0
  171. fi
  172. }
  173. GFLAGS_LIB=$(find_dir_of_lib_or_die gflags)
  174. append_linking $GFLAGS_LIB gflags
  175. PROTOBUF_LIB=$(find_dir_of_lib_or_die protobuf)
  176. append_linking $PROTOBUF_LIB protobuf
  177. LEVELDB_LIB=$(find_dir_of_lib_or_die leveldb)
  178. # required by leveldb
  179. if [ -f $LEVELDB_LIB/libleveldb.a ]; then
  180. if [ -f $LEVELDB_LIB/libleveldb.$SO ]; then
  181. if $LDD $LEVELDB_LIB/libleveldb.$SO | grep -q libsnappy; then
  182. SNAPPY_LIB=$(find_dir_of_lib snappy)
  183. REQUIRE_SNAPPY="yes"
  184. fi
  185. fi
  186. if [ -z "$REQUIRE_SNAPPY" ]; then
  187. if [ "$SYSTEM" = "Darwin" ]; then
  188. STATIC_LINKINGS="$STATIC_LINKINGS $LEVELDB_LIB/libleveldb.a"
  189. else
  190. STATIC_LINKINGS="$STATIC_LINKINGS -lleveldb"
  191. fi
  192. elif [ -f $SNAPPY_LIB/libsnappy.a ]; then
  193. if [ "$SYSTEM" = "Darwin" ]; then
  194. STATIC_LINKINGS="$STATIC_LINKINGS $LEVELDB_LIB/libleveldb.a $SNAPPY_LIB/libsnappy.a"
  195. else
  196. STATIC_LINKINGS="$STATIC_LINKINGS -lleveldb -lsnappy"
  197. fi
  198. else
  199. DYNAMIC_LINKINGS="$DYNAMIC_LINKINGS -lleveldb"
  200. fi
  201. else
  202. DYNAMIC_LINKINGS="$DYNAMIC_LINKINGS -lleveldb"
  203. fi
  204. PROTOC=$(find_bin_or_die protoc)
  205. GFLAGS_HDR=$(find_dir_of_header_or_die gflags/gflags.h)
  206. # namespace of gflags may not be google, grep it from source.
  207. GFLAGS_NS=$(grep "namespace [_A-Za-z0-9]\+ {" $GFLAGS_HDR/gflags/gflags_declare.h | head -1 | awk '{print $2}')
  208. if [ "$GFLAGS_NS" = "GFLAGS_NAMESPACE" ]; then
  209. GFLAGS_NS=$(grep "#define GFLAGS_NAMESPACE [_A-Za-z0-9]\+" $GFLAGS_HDR/gflags/gflags_declare.h | head -1 | awk '{print $3}')
  210. fi
  211. if [ -z "$GFLAGS_NS" ]; then
  212. >&2 $ECHO "Fail to grep namespace of gflags source $GFLAGS_HDR/gflags/gflags_declare.h"
  213. exit 1
  214. fi
  215. PROTOBUF_HDR=$(find_dir_of_header_or_die google/protobuf/message.h)
  216. LEVELDB_HDR=$(find_dir_of_header_or_die leveldb/db.h)
  217. HDRS=$($ECHO "$GFLAGS_HDR\n$PROTOBUF_HDR\n$LEVELDB_HDR\n$OPENSSL_HDR" | sort | uniq)
  218. LIBS=$($ECHO "$GFLAGS_LIB\n$PROTOBUF_LIB\n$LEVELDB_LIB\n$OPENSSL_LIB\n$SNAPPY_LIB" | sort | uniq)
  219. absent_in_the_list() {
  220. TMP=`$ECHO "$1\n$2" | sort | uniq`
  221. if [ "${TMP}" = "$2" ]; then
  222. return 1
  223. fi
  224. return 0
  225. }
  226. OUTPUT_CONTENT="# Generated by config_brpc.sh, don't modify manually"
  227. append_to_output() {
  228. OUTPUT_CONTENT="${OUTPUT_CONTENT}\n$*"
  229. }
  230. # $1: libname, $2: indentation
  231. append_to_output_headers() {
  232. if absent_in_the_list "$1" "$HDRS"; then
  233. append_to_output "${2}HDRS+=$1"
  234. HDRS=`$ECHO "${HDRS}\n$1" | sort | uniq`
  235. fi
  236. }
  237. # $1: libname, $2: indentation
  238. append_to_output_libs() {
  239. if absent_in_the_list "$1" "$LIBS"; then
  240. append_to_output "${2}LIBS+=$1"
  241. LIBS=`$ECHO "${LIBS}\n$1" | sort | uniq`
  242. fi
  243. }
  244. # $1: libdir, $2: libname, $3: indentation
  245. append_to_output_linkings() {
  246. if [ -f $1/lib$2.a ]; then
  247. append_to_output_libs $1 $3
  248. if [ "$SYSTEM" = "Darwin" ]; then
  249. append_to_output "${3}STATIC_LINKINGS+=$1/lib$2.a"
  250. else
  251. append_to_output "${3}STATIC_LINKINGS+=-l$2"
  252. fi
  253. export STATICALLY_LINKED_$2=1
  254. else
  255. append_to_output_libs $1 $3
  256. append_to_output "${3}DYNAMIC_LINKINGS+=-l$2"
  257. export STATICALLY_LINKED_$2=0
  258. fi
  259. }
  260. #can't use \n in texts because sh does not support -e
  261. append_to_output "SYSTEM=$SYSTEM"
  262. append_to_output "HDRS=$($ECHO $HDRS)"
  263. append_to_output "LIBS=$($ECHO $LIBS)"
  264. append_to_output "PROTOC=$PROTOC"
  265. append_to_output "PROTOBUF_HDR=$PROTOBUF_HDR"
  266. append_to_output "CC=$CC"
  267. append_to_output "CXX=$CXX"
  268. append_to_output "GCC_VERSION=$GCC_VERSION"
  269. append_to_output "STATIC_LINKINGS=$STATIC_LINKINGS"
  270. append_to_output "DYNAMIC_LINKINGS=$DYNAMIC_LINKINGS"
  271. CPPFLAGS="-DBRPC_WITH_GLOG=$WITH_GLOG -DGFLAGS_NS=$GFLAGS_NS"
  272. if [ ! -z "$DEBUGSYMBOLS" ]; then
  273. CPPFLAGS="${CPPFLAGS} $DEBUGSYMBOLS"
  274. fi
  275. if [ "$SYSTEM" = "Darwin" ]; then
  276. CPPFLAGS="${CPPFLAGS} -Wno-deprecated-declarations"
  277. version=`sw_vers -productVersion | awk -F '.' '{print $1 "." $2}'`
  278. if [[ `echo "$version<10.12" | bc -l` == 1 ]]; then
  279. CPPFLAGS="${CPPFLAGS} -DNO_CLOCK_GETTIME_IN_MAC"
  280. fi
  281. fi
  282. if [ $WITH_THRIFT != 0 ]; then
  283. THRIFT_LIB=$(find_dir_of_lib_or_die thriftnb)
  284. THRIFT_HDR=$(find_dir_of_header_or_die thrift/Thrift.h)
  285. append_to_output_libs "$THRIFT_LIB"
  286. append_to_output_headers "$THRIFT_HDR"
  287. CPPFLAGS="${CPPFLAGS} -DENABLE_THRIFT_FRAMED_PROTOCOL"
  288. if [ -f "$THRIFT_LIB/libthriftnb.$SO" ]; then
  289. append_to_output "DYNAMIC_LINKINGS+=-lthriftnb -levent -lthrift"
  290. else
  291. append_to_output "STATIC_LINKINGS+=-lthriftnb"
  292. fi
  293. fi
  294. if [ $WITH_MESALINK != 0 ]; then
  295. CPPFLAGS="${CPPFLAGS} -DUSE_MESALINK"
  296. fi
  297. append_to_output "CPPFLAGS=${CPPFLAGS}"
  298. append_to_output "ifeq (\$(NEED_LIBPROTOC), 1)"
  299. PROTOC_LIB=$(find $PROTOBUF_LIB -name "libprotoc.*" | head -n1)
  300. if [ -z "$PROTOC_LIB" ]; then
  301. append_to_output " \$(error \"Fail to find libprotoc\")"
  302. else
  303. # libprotobuf and libprotoc must be linked same statically or dynamically
  304. # otherwise the bin will crash.
  305. if [ $STATICALLY_LINKED_protobuf -gt 0 ]; then
  306. if [ "$SYSTEM" = "Darwin" ]; then
  307. append_to_output " STATIC_LINKINGS+=$(find $PROTOBUF_LIB -name "libprotoc.a" | head -n1)"
  308. else
  309. append_to_output " STATIC_LINKINGS+=-lprotoc"
  310. fi
  311. else
  312. append_to_output " DYNAMIC_LINKINGS+=-lprotoc"
  313. fi
  314. fi
  315. append_to_output "endif"
  316. OLD_HDRS=$HDRS
  317. OLD_LIBS=$LIBS
  318. append_to_output "ifeq (\$(NEED_GPERFTOOLS), 1)"
  319. # required by cpu/heap profiler
  320. TCMALLOC_LIB=$(find_dir_of_lib tcmalloc_and_profiler)
  321. if [ -z "$TCMALLOC_LIB" ]; then
  322. append_to_output " \$(error \"Fail to find gperftools\")"
  323. else
  324. append_to_output_libs "$TCMALLOC_LIB" " "
  325. if [ -f $TCMALLOC_LIB/libtcmalloc.$SO ]; then
  326. append_to_output " DYNAMIC_LINKINGS+=-ltcmalloc_and_profiler"
  327. else
  328. if [ "$SYSTEM" = "Darwin" ]; then
  329. append_to_output " STATIC_LINKINGS+=$TCMALLOC_LIB/libtcmalloc.a"
  330. else
  331. append_to_output " STATIC_LINKINGS+=-ltcmalloc_and_profiler"
  332. fi
  333. fi
  334. fi
  335. append_to_output "endif"
  336. if [ $WITH_GLOG != 0 ]; then
  337. GLOG_LIB=$(find_dir_of_lib_or_die glog)
  338. GLOG_HDR=$(find_dir_of_header_or_die glog/logging.h windows/glog/logging.h)
  339. append_to_output_libs "$GLOG_LIB"
  340. append_to_output_headers "$GLOG_HDR"
  341. if [ -f "$GLOG_LIB/libglog.$SO" ]; then
  342. append_to_output "DYNAMIC_LINKINGS+=-lglog"
  343. else
  344. if [ "$SYSTEM" = "Darwin" ]; then
  345. append_to_output "STATIC_LINKINGS+=$GLOG_LIB/libglog.a"
  346. else
  347. append_to_output "STATIC_LINKINGS+=-lglog"
  348. fi
  349. fi
  350. fi
  351. # required by UT
  352. #gtest
  353. GTEST_LIB=$(find_dir_of_lib gtest)
  354. HDRS=$OLD_HDRS
  355. LIBS=$OLD_LIBS
  356. append_to_output "ifeq (\$(NEED_GTEST), 1)"
  357. if [ -z "$GTEST_LIB" ]; then
  358. append_to_output " \$(error \"Fail to find gtest\")"
  359. else
  360. GTEST_HDR=$(find_dir_of_header_or_die gtest/gtest.h)
  361. append_to_output_libs $GTEST_LIB " "
  362. append_to_output_headers $GTEST_HDR " "
  363. append_to_output_linkings $GTEST_LIB gtest " "
  364. append_to_output_linkings $GTEST_LIB gtest_main " "
  365. fi
  366. append_to_output "endif"
  367. # generate src/butil/config.h
  368. cat << EOF > src/butil/config.h
  369. // This file is auto-generated by $(basename "$0"). DON'T edit it!
  370. #ifndef BUTIL_CONFIG_H
  371. #define BUTIL_CONFIG_H
  372. #ifdef BRPC_WITH_GLOG
  373. #undef BRPC_WITH_GLOG
  374. #endif
  375. #define BRPC_WITH_GLOG $WITH_GLOG
  376. #endif // BUTIL_CONFIG_H
  377. EOF
  378. # write to config.mk
  379. $ECHO "$OUTPUT_CONTENT" > config.mk