config_brpc.sh 13.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
#!/usr/bin/env sh

# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You 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.

gejun's avatar
gejun committed
18 19
SYSTEM=$(uname -s)
if [ "$SYSTEM" = "Darwin" ]; then
20 21 22 23 24
    if [ -z "$BASH" ] || [ "$BASH" = "/bin/sh" ] ; then
        ECHO=echo
    else
        ECHO='echo -e'
    fi
gejun's avatar
gejun committed
25 26 27 28 29 30
    SO=dylib
    LDD="otool -L"
    if [ "$(getopt -V)" = " --" ]; then
        >&2 $ECHO "gnu-getopt must be installed and used"
        exit 1
    fi
31
else
gejun's avatar
gejun committed
32 33 34 35 36 37 38
    if [ -z "$BASH" ]; then
        ECHO=echo
    else
        ECHO='echo -e'
    fi
    SO=so
    LDD=ldd
39
fi
gejun's avatar
gejun committed
40

41
TEMP=`getopt -o v: --long headers:,libs:,cc:,cxx:,with-glog,with-thrift,with-mesalink,nodebugsymbols -n 'config_brpc' -- "$@"`
42
WITH_GLOG=0
43
WITH_THRIFT=0
44
WITH_MESALINK=0
45
DEBUGSYMBOLS=-g
46

gejun's avatar
gejun committed
47
if [ $? != 0 ] ; then >&2 $ECHO "Terminating..."; exit 1 ; fi
48 49 50 51

# Note the quotes around `$TEMP': they are essential!
eval set -- "$TEMP"

52 53 54 55 56 57
if [ "$SYSTEM" = "Darwin" ]; then
    REALPATH=realpath
else
    REALPATH="readlink -f"
fi

58 59 60
# Convert to abspath always so that generated mk is include-able from everywhere
while true; do
    case "$1" in
61 62
        --headers ) HDRS_IN="$(${REALPATH} $2)"; shift 2 ;;
        --libs ) LIBS_IN="$(${REALPATH} $2)"; shift 2 ;;
63 64
        --cc ) CC=$2; shift 2 ;;
        --cxx ) CXX=$2; shift 2 ;;
65
        --with-glog ) WITH_GLOG=1; shift 1 ;;
66
        --with-thrift) WITH_THRIFT=1; shift 1 ;;
67
        --with-mesalink) WITH_MESALINK=1; shift 1 ;;
68
        --nodebugsymbols ) DEBUGSYMBOLS=; shift 1 ;;
69 70 71 72
        -- ) shift; break ;;
        * ) break ;;
    esac
done
73

74 75 76 77 78 79 80
if [ -z "$CC" ]; then
    if [ ! -z "$CXX" ]; then
        >&2 $ECHO "--cc and --cxx must be both set or unset"
        exit 1
    fi
    CC=gcc
    CXX=g++
81 82 83 84
    if [ "$SYSTEM" = "Darwin" ]; then
        CC=clang
        CXX=clang++
    fi
85 86 87 88
elif [ -z "$CXX" ]; then
    >&2 $ECHO "--cc and --cxx must be both set or unset"
    exit 1
fi
89

90
GCC_VERSION=$($CXX tools/print_gcc_version.cc -o print_gcc_version && ./print_gcc_version && rm ./print_gcc_version)
91 92 93 94
if [ $GCC_VERSION -gt 0 ] && [ $GCC_VERSION -lt 40800 ]; then
    >&2 $ECHO "GCC is too old, please install a newer version supporting C++11"
    exit 1
fi
95

96
if [ -z "$HDRS_IN" ] || [ -z "$LIBS_IN" ]; then
97
    >&2 $ECHO "config_brpc: --headers=HDRPATHS --libs=LIBPATHS must be specified"
98 99
    exit 1
fi
100

101
find_dir_of_lib() {
有张纸's avatar
有张纸 committed
102
    local lib=$(find ${LIBS_IN} -name "lib${1}.a" -o -name "lib${1}.$SO" 2>/dev/null | head -n1)
103 104 105
    if [ ! -z "$lib" ]; then
        dirname $lib
    fi
106
}
107 108 109
find_dir_of_lib_or_die() {
    local dir=$(find_dir_of_lib $1)
    if [ -z "$dir" ]; then
110
        >&2 $ECHO "Fail to find $1 from --libs"
111 112
        exit 1
    else
113
        $ECHO $dir
114 115
    fi
}
116

117
find_bin() {
118
    TARGET_BIN=$(find -L ${LIBS_IN} -type f -name "$1" 2>/dev/null | head -n1)
119 120 121
    if [ ! -z "$TARGET_BIN" ]; then
        $ECHO $TARGET_BIN
    else
gejun's avatar
gejun committed
122
        which "$1" 2>/dev/null
123 124 125 126
    fi
}
find_bin_or_die() {
    TARGET_BIN=$(find_bin "$1")
gejun's avatar
gejun committed
127 128 129 130
    if [ ! -z "$TARGET_BIN" ]; then
        $ECHO $TARGET_BIN
    else
        >&2 $ECHO "Fail to find $1"
131 132
        exit 1
    fi
133 134
}

135
find_dir_of_header() {
136
    find -L ${HDRS_IN} -path "*/$1" | head -n1 | sed "s|$1||g"
137
}
138 139

find_dir_of_header_excluding() {
140
    find -L ${HDRS_IN} -path "*/$1" | grep -v "$2\$" | head -n1 | sed "s|$1||g"
141 142
}

143
find_dir_of_header_or_die() {
144 145 146 147 148
    if [ -z "$2" ]; then
        local dir=$(find_dir_of_header $1)
    else
        local dir=$(find_dir_of_header_excluding $1 $2)
    fi
149
    if [ -z "$dir" ]; then
150
        >&2 $ECHO "Fail to find $1 from --headers"
151
        exit 1
152
    fi
153
    $ECHO $dir
154 155
}

wenweihu86's avatar
wenweihu86 committed
156 157 158 159 160 161 162 163 164 165
if [ "$SYSTEM" = "Darwin" ]; then
    OPENSSL_LIB="/usr/local/opt/openssl/lib"
    OPENSSL_HDR="/usr/local/opt/openssl/include"
else
    # User specified path of openssl, if not given it's empty
    OPENSSL_LIB=$(find_dir_of_lib ssl)
    # Inconvenient to check these headers in baidu-internal
    #PTHREAD_HDR=$(find_dir_of_header_or_die pthread.h)
    OPENSSL_HDR=$(find_dir_of_header_or_die openssl/ssl.h)
fi
166

167 168 169 170 171
if [ $WITH_MESALINK != 0 ]; then
    MESALINK_HDR=$(find_dir_of_header_or_die mesalink/openssl/ssl.h)
    OPENSSL_HDR="$OPENSSL_HDR\n$MESALINK_HDR"
fi

172
STATIC_LINKINGS=
173
DYNAMIC_LINKINGS="-lpthread -lssl -lcrypto -ldl -lz"
174 175 176 177 178

if [ $WITH_MESALINK != 0 ]; then
    DYNAMIC_LINKINGS="$DYNAMIC_LINKINGS -lmesalink"
fi

179
if [ "$SYSTEM" = "Linux" ]; then
wangxuefeng's avatar
wangxuefeng committed
180
    DYNAMIC_LINKINGS="$DYNAMIC_LINKINGS -lrt"
181 182
fi
if [ "$SYSTEM" = "Darwin" ]; then
wangxuefeng's avatar
wangxuefeng committed
183 184 185 186 187 188 189 190 191
	DYNAMIC_LINKINGS="$DYNAMIC_LINKINGS -framework CoreFoundation"
	DYNAMIC_LINKINGS="$DYNAMIC_LINKINGS -framework CoreGraphics"
	DYNAMIC_LINKINGS="$DYNAMIC_LINKINGS -framework CoreData"
	DYNAMIC_LINKINGS="$DYNAMIC_LINKINGS -framework CoreText"
	DYNAMIC_LINKINGS="$DYNAMIC_LINKINGS -framework Security"
	DYNAMIC_LINKINGS="$DYNAMIC_LINKINGS -framework Foundation"
	DYNAMIC_LINKINGS="$DYNAMIC_LINKINGS -Wl,-U,_MallocExtension_ReleaseFreeMemory"
	DYNAMIC_LINKINGS="$DYNAMIC_LINKINGS -Wl,-U,_ProfilerStart"
	DYNAMIC_LINKINGS="$DYNAMIC_LINKINGS -Wl,-U,_ProfilerStop"
192
	DYNAMIC_LINKINGS="$DYNAMIC_LINKINGS -Wl,-U,_RegisterThriftProtocol"
193
fi
194 195
append_linking() {
    if [ -f $1/lib${2}.a ]; then
196 197 198 199 200 201
        if [ "$SYSTEM" = "Darwin" ]; then
            # *.a must be explicitly specified in clang
            STATIC_LINKINGS="$STATIC_LINKINGS $1/lib${2}.a"
        else
            STATIC_LINKINGS="$STATIC_LINKINGS -l$2"
        fi
202
        export STATICALLY_LINKED_$2=1
203
    else
204 205
        DYNAMIC_LINKINGS="$DYNAMIC_LINKINGS -l$2"
        export STATICALLY_LINKED_$2=0
206 207
    fi
}
208

209 210
GFLAGS_LIB=$(find_dir_of_lib_or_die gflags)
append_linking $GFLAGS_LIB gflags
211

212 213
PROTOBUF_LIB=$(find_dir_of_lib_or_die protobuf)
append_linking $PROTOBUF_LIB protobuf
214

215
LEVELDB_LIB=$(find_dir_of_lib_or_die leveldb)
216
# required by leveldb
217
if [ -f $LEVELDB_LIB/libleveldb.a ]; then
gejun's avatar
gejun committed
218 219
    if [ -f $LEVELDB_LIB/libleveldb.$SO ]; then
        if $LDD $LEVELDB_LIB/libleveldb.$SO | grep -q libsnappy; then
220
            SNAPPY_LIB=$(find_dir_of_lib snappy)
gejun's avatar
gejun committed
221
            REQUIRE_SNAPPY="yes"
222 223
        fi
    fi
gejun's avatar
gejun committed
224
    if [ -z "$REQUIRE_SNAPPY" ]; then
225 226 227 228 229
        if [ "$SYSTEM" = "Darwin" ]; then
	        STATIC_LINKINGS="$STATIC_LINKINGS $LEVELDB_LIB/libleveldb.a"
        else
	        STATIC_LINKINGS="$STATIC_LINKINGS -lleveldb"
        fi
230
    elif [ -f $SNAPPY_LIB/libsnappy.a ]; then
231 232 233 234 235
        if [ "$SYSTEM" = "Darwin" ]; then
	        STATIC_LINKINGS="$STATIC_LINKINGS $LEVELDB_LIB/libleveldb.a $SNAPPY_LIB/libsnappy.a"
        else
	        STATIC_LINKINGS="$STATIC_LINKINGS -lleveldb -lsnappy"
        fi
236 237 238
    else
	    DYNAMIC_LINKINGS="$DYNAMIC_LINKINGS -lleveldb"
    fi
239 240
else
	DYNAMIC_LINKINGS="$DYNAMIC_LINKINGS -lleveldb"
241 242
fi

243
PROTOC=$(find_bin_or_die protoc)
244

245
GFLAGS_HDR=$(find_dir_of_header_or_die gflags/gflags.h)
246
# namespace of gflags may not be google, grep it from source.
gejun's avatar
gejun committed
247
GFLAGS_NS=$(grep "namespace [_A-Za-z0-9]\+ {" $GFLAGS_HDR/gflags/gflags_declare.h | head -1 | awk '{print $2}')
gejun's avatar
gejun committed
248
if [ "$GFLAGS_NS" = "GFLAGS_NAMESPACE" ]; then
gejun's avatar
gejun committed
249 250
    GFLAGS_NS=$(grep "#define GFLAGS_NAMESPACE [_A-Za-z0-9]\+" $GFLAGS_HDR/gflags/gflags_declare.h | head -1 | awk '{print $3}')
fi
251
if [ -z "$GFLAGS_NS" ]; then
gejun's avatar
gejun committed
252
    >&2 $ECHO "Fail to grep namespace of gflags source $GFLAGS_HDR/gflags/gflags_declare.h"
253 254 255
    exit 1
fi

256 257
PROTOBUF_HDR=$(find_dir_of_header_or_die google/protobuf/message.h)
LEVELDB_HDR=$(find_dir_of_header_or_die leveldb/db.h)
258

gejun's avatar
gejun committed
259
HDRS=$($ECHO "$GFLAGS_HDR\n$PROTOBUF_HDR\n$LEVELDB_HDR\n$OPENSSL_HDR" | sort | uniq)
260
LIBS=$($ECHO "$GFLAGS_LIB\n$PROTOBUF_LIB\n$LEVELDB_LIB\n$OPENSSL_LIB\n$SNAPPY_LIB" | sort | uniq)
261 262

absent_in_the_list() {
gejun's avatar
gejun committed
263
    TMP=`$ECHO "$1\n$2" | sort | uniq`
264 265 266 267 268
    if [ "${TMP}" = "$2" ]; then
        return 1
    fi
    return 0
}
269

270 271 272 273 274 275 276 277
OUTPUT_CONTENT="# Generated by config_brpc.sh, don't modify manually"
append_to_output() {
    OUTPUT_CONTENT="${OUTPUT_CONTENT}\n$*"
}
# $1: libname, $2: indentation
append_to_output_headers() {
    if absent_in_the_list "$1" "$HDRS"; then
        append_to_output "${2}HDRS+=$1"
gejun's avatar
gejun committed
278
        HDRS=`$ECHO "${HDRS}\n$1" | sort | uniq`
279
    fi
280 281 282 283 284
}
# $1: libname, $2: indentation
append_to_output_libs() {
    if absent_in_the_list "$1" "$LIBS"; then
        append_to_output "${2}LIBS+=$1"
gejun's avatar
gejun committed
285
        LIBS=`$ECHO "${LIBS}\n$1" | sort | uniq`
286
    fi
287 288 289 290
}
# $1: libdir, $2: libname, $3: indentation
append_to_output_linkings() {
    if [ -f $1/lib$2.a ]; then
291 292 293 294 295 296
        append_to_output_libs $1 $3
        if [ "$SYSTEM" = "Darwin" ]; then
            append_to_output "${3}STATIC_LINKINGS+=$1/lib$2.a"
        else
            append_to_output "${3}STATIC_LINKINGS+=-l$2"
        fi
297
        export STATICALLY_LINKED_$2=1
298
    else
299
        append_to_output_libs $1 $3
300 301
        append_to_output "${3}DYNAMIC_LINKINGS+=-l$2"
        export STATICALLY_LINKED_$2=0
302
    fi
303 304 305
}

#can't use \n in texts because sh does not support -e
gejun's avatar
gejun committed
306
append_to_output "SYSTEM=$SYSTEM"
307 308 309 310 311 312
append_to_output "HDRS=$($ECHO $HDRS)"
append_to_output "LIBS=$($ECHO $LIBS)"
append_to_output "PROTOC=$PROTOC"
append_to_output "PROTOBUF_HDR=$PROTOBUF_HDR"
append_to_output "CC=$CC"
append_to_output "CXX=$CXX"
313
append_to_output "GCC_VERSION=$GCC_VERSION"
314 315
append_to_output "STATIC_LINKINGS=$STATIC_LINKINGS"
append_to_output "DYNAMIC_LINKINGS=$DYNAMIC_LINKINGS"
gejun's avatar
gejun committed
316
CPPFLAGS="-DBRPC_WITH_GLOG=$WITH_GLOG -DGFLAGS_NS=$GFLAGS_NS"
317

gejun's avatar
gejun committed
318 319 320 321 322
if [ ! -z "$DEBUGSYMBOLS" ]; then
    CPPFLAGS="${CPPFLAGS} $DEBUGSYMBOLS"
fi
if [ "$SYSTEM" = "Darwin" ]; then
    CPPFLAGS="${CPPFLAGS} -Wno-deprecated-declarations"
zyearn's avatar
zyearn committed
323
    version=`sw_vers -productVersion | awk -F '.' '{print $1 "." $2}'`
324 325 326
    if [[ `echo "$version<10.12" | bc -l` == 1 ]]; then
        CPPFLAGS="${CPPFLAGS} -DNO_CLOCK_GETTIME_IN_MAC"
    fi
gejun's avatar
gejun committed
327
fi
328 329 330 331 332 333 334 335 336 337

if [ $WITH_THRIFT != 0 ]; then
    THRIFT_LIB=$(find_dir_of_lib_or_die thriftnb)
    THRIFT_HDR=$(find_dir_of_header_or_die thrift/Thrift.h)
    append_to_output_libs "$THRIFT_LIB"
    append_to_output_headers "$THRIFT_HDR"

    CPPFLAGS="${CPPFLAGS} -DENABLE_THRIFT_FRAMED_PROTOCOL"

    if [ -f "$THRIFT_LIB/libthriftnb.$SO" ]; then
wangxuefeng's avatar
wangxuefeng committed
338
        append_to_output "DYNAMIC_LINKINGS+=-lthriftnb -levent -lthrift"
339 340 341 342 343
    else
        append_to_output "STATIC_LINKINGS+=-lthriftnb"
    fi
fi

344 345 346 347
if [ $WITH_MESALINK != 0 ]; then
    CPPFLAGS="${CPPFLAGS} -DUSE_MESALINK"
fi

gejun's avatar
gejun committed
348
append_to_output "CPPFLAGS=${CPPFLAGS}"
349 350 351 352 353 354 355 356 357

append_to_output "ifeq (\$(NEED_LIBPROTOC), 1)"
PROTOC_LIB=$(find $PROTOBUF_LIB -name "libprotoc.*" | head -n1)
if [ -z "$PROTOC_LIB" ]; then
    append_to_output "   \$(error \"Fail to find libprotoc\")"
else
    # libprotobuf and libprotoc must be linked same statically or dynamically
    # otherwise the bin will crash.
    if [ $STATICALLY_LINKED_protobuf -gt 0 ]; then
358 359 360 361 362
        if [ "$SYSTEM" = "Darwin" ]; then
            append_to_output "    STATIC_LINKINGS+=$(find $PROTOBUF_LIB -name "libprotoc.a" | head -n1)"
        else
            append_to_output "    STATIC_LINKINGS+=-lprotoc"
        fi
363
    else
364
        append_to_output "    DYNAMIC_LINKINGS+=-lprotoc"
365
    fi
366
fi
367 368
append_to_output "endif"

gejun's avatar
gejun committed
369 370
OLD_HDRS=$HDRS
OLD_LIBS=$LIBS
371 372 373 374 375 376 377
append_to_output "ifeq (\$(NEED_GPERFTOOLS), 1)"
# required by cpu/heap profiler
TCMALLOC_LIB=$(find_dir_of_lib tcmalloc_and_profiler)
if [ -z "$TCMALLOC_LIB" ]; then
    append_to_output "    \$(error \"Fail to find gperftools\")"
else
    append_to_output_libs "$TCMALLOC_LIB" "    "
378
    if [ -f $TCMALLOC_LIB/libtcmalloc.$SO ]; then
379
        append_to_output "    DYNAMIC_LINKINGS+=-ltcmalloc_and_profiler"
380
    else
381 382 383 384 385
        if [ "$SYSTEM" = "Darwin" ]; then
            append_to_output "    STATIC_LINKINGS+=$TCMALLOC_LIB/libtcmalloc.a"
        else
            append_to_output "    STATIC_LINKINGS+=-ltcmalloc_and_profiler"
        fi
386 387 388
    fi
fi
append_to_output "endif"
389

390
if [ $WITH_GLOG != 0 ]; then
391
    GLOG_LIB=$(find_dir_of_lib_or_die glog)
392
    GLOG_HDR=$(find_dir_of_header_or_die glog/logging.h windows/glog/logging.h)
393 394 395 396
    append_to_output_libs "$GLOG_LIB"
    append_to_output_headers "$GLOG_HDR"
    if [ -f "$GLOG_LIB/libglog.$SO" ]; then
        append_to_output "DYNAMIC_LINKINGS+=-lglog"
397
    else
398 399 400 401 402
        if [ "$SYSTEM" = "Darwin" ]; then
            append_to_output "STATIC_LINKINGS+=$GLOG_LIB/libglog.a"
        else
            append_to_output "STATIC_LINKINGS+=-lglog"
        fi
403 404
    fi
fi
405

406 407 408
# required by UT
#gtest
GTEST_LIB=$(find_dir_of_lib gtest)
gejun's avatar
gejun committed
409 410
HDRS=$OLD_HDRS
LIBS=$OLD_LIBS
411
append_to_output "ifeq (\$(NEED_GTEST), 1)"
412
if [ -z "$GTEST_LIB" ]; then
413
    append_to_output "    \$(error \"Fail to find gtest\")"
414
else
415 416 417 418 419
    GTEST_HDR=$(find_dir_of_header_or_die gtest/gtest.h)
    append_to_output_libs $GTEST_LIB "    "
    append_to_output_headers $GTEST_HDR "    "
    append_to_output_linkings $GTEST_LIB gtest "    "
    append_to_output_linkings $GTEST_LIB gtest_main "    "
420
fi
421
append_to_output "endif"
gejun's avatar
gejun committed
422

423 424 425 426 427 428 429 430 431 432 433 434 435 436
# generate src/butil/config.h
cat << EOF > src/butil/config.h
// This file is auto-generated by $(basename "$0"). DON'T edit it!
#ifndef  BUTIL_CONFIG_H
#define  BUTIL_CONFIG_H

#ifdef BRPC_WITH_GLOG
#undef BRPC_WITH_GLOG
#endif
#define BRPC_WITH_GLOG $WITH_GLOG

#endif  // BUTIL_CONFIG_H
EOF

437 438
# write to config.mk
$ECHO "$OUTPUT_CONTENT" > config.mk