boost全平臺編譯方法

















  1. 通用規則

  2. iOS平臺編譯

    1. 環境

    2. 步驟

    3. 集成到Xcode

  3. Android平臺編譯

    1. 環境

    2. 步驟

  4. Windows平臺編譯

    1. 環境

    2. 步驟

    3. 集成到VS

  5. Linux平臺編譯

    1. 環境

    2. 步驟

  6. Mac OS X編譯

    1. 環境

    2. 步驟

原文地址: http://blog.csdn.net/hursing/article/details/45439087

1.通用規則

多數庫是不需要預先編譯的,include hpp文件就能用。如果出現鏈接失敗,那就是可能需要編譯庫了。

boost自帶一套編譯工具bjam,bjam本身是跨平臺的,並且也要自行編譯出來。在boost目錄下有bootstrap.sh和bootstrap.bat兩個腳本分別用來編譯*nix和windows下的bjam。bootstrap腳本可以傳入參數,以在編譯bjam過程中生成特定的編譯boost的配置。這些配置保存在新生成的project-config.jam裏,但還可以在運行bjam的時候再傳入參數來覆蓋。同時生成的b2是bjam的代理,運行哪個的效果都差不多。 
在終端下運行 
bjam --show-libraries 
會列出所有要編譯的庫。 
真正編譯時,可以傳入–with-xxx來選擇編譯哪些庫,或者傳入–without-xxx來選擇不編譯哪些庫。如果不傳則會讀取project-config.jam的設置,如果也沒有則是編譯全部的庫。 
更多的參數可以用 
bjam --help 
來查看。例如編譯成靜態庫還是動態庫,運行時庫是靜態的還是動態的,編譯完後要不要安裝等。

注意: 
舊版本的boost可能會存在編譯問題,儘量用新的就好。bjam在*nix和windows支持的參數有不同。


2. iOS平臺編譯

環境:

OS X Yosemite 10.10.3 
Xcode 6.3.1(6D1002)。如果用Xcode 7在模擬器版鏈接失敗,往 ${EXTRA_CPPFLAGS:= 添加-miphoneos-version-min=7參數 
boost 1.57/1.58

步驟:

把下面的腳本保存成build_boost.sh,直接運行即可:

#!/bin/bash# http://blog.csdn.net/hursing/article/details/45439087# 請自行修改路徑,cd到boost解壓後的目錄下dir=`dirname $0`cd "$dir/../../third_party/boost_1_57_0"# 如果庫文件已存在,直接退出if [ -e ./stage/lib/libboost_date_time.a ]; then
  echo "libraries exist. no need to build."
  exit 0fi# 以下代碼參考 https://gist.github.com/rsobik/7513324 ,原文使用的boost版本比較舊,不能使用。: ${COMPILER:="clang++"}: ${IPHONE_SDKVERSION:=`xcodebuild -showsdks | grep iphoneos | egrep "[[:digit:]]+\.[[:digit:]]+" -o | tail -1`}: ${XCODE_ROOT:=`xcode-select -print-path`}: ${EXTRA_CPPFLAGS:="-DBOOST_AC_USE_PTHREADS -DBOOST_SP_USE_PTHREADS -stdlib=libc++"}echo "IPHONE_SDKVERSION: $IPHONE_SDKVERSION"echo "XCODE_ROOT:        $XCODE_ROOT"echo "COMPILER:          $COMPILER"echo "bootstrap"# 此腳本如果是被Xcode調用的話,會因爲xcode export的某些變量導致失敗,所以加了env -i。直接在命令行運行此腳本可以把env -i 去掉env -i bash ./bootstrap.shecho "write project-config.jam"# 默認生存的project-config.jam是編譯Mac版的,這裏直接調換掉rm project-config.jam
cat >> project-config.jam <<EOF
using darwin : ${IPHONE_SDKVERSION}~iphone
: $XCODE_ROOT/Toolchains/XcodeDefault.xctoolchain/usr/bin/$COMPILER -arch armv7 -arch arm64 $EXTRA_CPPFLAGS: <striper> <root>$XCODE_ROOT/Platforms/iPhoneOS.platform/Developer
: <architecture>arm <target-os>iphone
;
using darwin : ${IPHONE_SDKVERSION}~iphonesim
: $XCODE_ROOT/Toolchains/XcodeDefault.xctoolchain/usr/bin/$COMPILER -arch i386 -arch x86_64 $EXTRA_CPPFLAGS: <striper> <root>$XCODE_ROOT/Platforms/iPhoneSimulator.platform/Developer
: <architecture>ia64 <target-os>iphone
;
EOF# 上面的代碼裏,兩個using darwin分別是編譯真機版和模擬器版的設置。每多一種CPU架構就要再加一個-arch xxx。echo "build boost iphone dev"./bjam -j16 --with-date_time --with-filesystem --with-system --with-thread --build-dir=iphone-build --stagedir=iphone-build/stage toolset=darwin architecture=arm target-os=iphone macosx-version=iphone-${IPHONE_SDKVERSION} define=_LITTLE_ENDIAN link=static stageecho "build boost iphone sim"./bjam -j16 --with-date_time --with-filesystem --with-system --with-thread --build-dir=iphonesim-build --stagedir=iphonesim-build/stage --toolset=darwin-${IPHONE_SDKVERSION}~iphonesim architecture=ia64 target-os=iphone macosx-version=iphonesim-${IPHONE_SDKVERSION} link=static stageecho "lipo"# 把各架構下的庫文件合一,以便在xcode裏可以少設置些搜索路徑。做得更徹底些是各個分庫合成一個大庫。不過除非是把靜態庫加入到代碼倉庫,否則是浪費時間了。要合成的大庫話請參考https://gist.github.com/rsobik/7513324原文。mkdir -p stage/lib
lipo -create iphone-build/stage/lib/libboost_date_time.a iphonesim-build/stage/lib/libboost_date_time.a -output stage/lib/libboost_date_time.a
lipo -create iphone-build/stage/lib/libboost_filesystem.a iphonesim-build/stage/lib/libboost_filesystem.a -output stage/lib/libboost_filesystem.a
lipo -create iphone-build/stage/lib/libboost_system.a iphonesim-build/stage/lib/libboost_system.a -output stage/lib/libboost_system.a
lipo -create iphone-build/stage/lib/libboost_thread.a iphonesim-build/stage/lib/libboost_thread.a -output stage/lib/libboost_thread.a# 庫文件最終放在./stage/lib/下echo "Completed successfully"1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859

集成到Xcode

做iOS的同學還是習慣完全用Xcode的吧。所以可以把上面的腳本集成到xcode裏。在某個工程中,Xcode菜單File->New->Target…->Other->Aggregate->取名boost,Finish->在這個target的屬性中選擇Build Phases->點擊左邊的+號->New Run Script Phase->填入bash ./build_boost.sh->自己再填好庫文件搜索路徑和鏈接各個boost庫。主target還要設置依賴boost target,免得boost編譯前就鏈接以致錯誤。 
xcode的target設置


3.Android平臺編譯

Android的編譯方法有兩種:一種是和iOS一樣,自己覆蓋project-config.jam引入NDK的編譯工具設置,然後用bjam編譯;另一種是自己寫Android.mk。自己寫project-config.jam因爲要兼顧很多種CPU架構而(無論是寫jam還是主工程的Android.mk都)較爲麻煩,所以本文用後者。

環境

Ubuntu 14.04 64bit / Linux Mint 17 64bit 
NDK r10c 
boost 1.57/1.58

步驟

想要哪個庫,自己把那個庫下的cpp文件加到mk裏,都在libs/xxxx/下。如果在libs找不到,說明這個庫是不需要額外編譯的。 
以下是編譯四個庫的Android.mk的內容:

include $(CLEAR_VARS)
LOCAL_PATH := $(ROOT_PATH)/third_party/boost_1_57_0
LOCAL_MODULE := boost# 需要編譯哪個庫,自行把libs目錄下的cpp加進來即可。
LOCAL_SRC_FILES += \  libs/filesystem/src/path.cpp \  libs/filesystem/src/path_traits.cpp \  libs/filesystem/src/operations.cpp \  libs/filesystem/src/codecvt_error_category.cpp \  libs/filesystem/src/portability.cpp \  libs/filesystem/src/utf8_codecvt_facet.cpp \  \  libs/date_time/src/gregorian/date_generators.cpp \  libs/date_time/src/gregorian/greg_month.cpp \  libs/date_time/src/gregorian/greg_weekday.cpp \  libs/date_time/src/gregorian/gregorian_types.cpp \  libs/date_time/src/posix_time/posix_time_types.cpp \  \  libs/system/src/error_code.cpp \  \  libs/thread/src/future.cpp \  libs/thread/src/pthread/once.cpp \  libs/thread/src/pthread/once_atomic.cpp \  libs/thread/src/pthread/thread.cpp# 如果要把boost集成到動態庫裏,-fPIC是必須的,不然會有鏈接錯誤。原因請自行Google
LOCAL_CFLAGS += -fPIC -frtti -fexceptions
include $(BUILD_STATIC_LIBRARY)

Application.mk的內容:

APP_PLATFORM := android-19
APP_OPTIM := release
APP_CFLAGS += -Wall
APP_STL := gnustl_static
APP_ABI := armeabi-v7a

這是最普通的做法,如果要加編譯參數,還得自己琢磨下。例如不要rtti,就得LOCAL_CFLAGS += -DBOOST_NO_RTTI

還是想用boost原生的編譯方法的話,可參考這裏 http://stackoverflow.com/questions/30491158/compile-and-use-boost-for-android-ndk-r10e


4.Windows平臺編譯

環境

Windows 7 旗艦版 64bit SP1 
Visual Studio Ultimate 2013 
boost 1.57/1.58

步驟

以下是build_boost.bat的內容,直接執行即可:

cd ..\..\third_party\boost_1_57_0if not exist .\b2.exe (
    call .\bootstrap.bat    .\b2.exe -j5 --with-date_time --with-filesystem --with-system --with-thread --with-regex link=static runtime-link=static
)

注意這裏生成的是MTd和MT。MD的話runtime-link=shared。

集成到VS

工程屬性->Configuration Properties->Build Events->Pre-Link Event->Command Line->填入build_boost.bat 
還有設置好庫搜索路徑和依賴的庫。 
Windows的boost有個特點,代碼裏有#pragma comment(lib, "xxxx"),所以可以不設置依賴的庫。但是如果工程設置不對而有link錯誤,那還是手動加進去吧。


5.Linux平臺編譯

環境

Ubuntu 14.04 64bit / Linux Mint 17 64bit 
gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1) 
boost 1.57/1.58

步驟

直接編譯。以下是終端命令

cd boost_1_57_0
bash bootstrap.sh
./b2

這樣就能在boost_1_57_0/stage/lib/下找到所有的庫文件。

如果用cmake來組織編譯,以下是主工程的CMakeLists.txt裏的部分內容:

include(ExternalProject)
ExternalProject_Add(boost
  SOURCE_DIR ${ROOT_DIR}/third_party/boost_1_57_0
  CONFIGURE_COMMAND bash ${ROOT_DIR}/third_party/boost_1_57_0/bootstrap.sh --with-libraries=date_time,thread,filesystem,system  BUILD_COMMAND ${ROOT_DIR}/third_party/boost_1_57_0/b2 -j10 cflags=-fPIC cxxflags=-fPIC cxxflags=-fvisibility=hidden cxxflags=-fvisibility-inlines-hidden cxxflags=-fexceptions cxxflags=-DBOOST_NO_RTTI
  BUILD_IN_SOURCE 1
  INSTALL_COMMAND "")set(
  BOOST_LIBRARIES  ${ROOT_DIR}/third_party/boost_1_57_0/stage/lib/libboost_date_time.a  ${ROOT_DIR}/third_party/boost_1_57_0/stage/lib/libboost_system.a  ${ROOT_DIR}/third_party/boost_1_57_0/stage/lib/libboost_thread.a  ${ROOT_DIR}/third_party/boost_1_57_0/stage/lib/libboost_filesystem.a
)# ...# 下面是設置鏈接和依賴target_link_libraries(your_target ${BOOST_LIBRARIES})add_dependencies(your_target boost)

可留意 
b2 -j10 cflags=-fPIC cxxflags=-fPIC cxxflags=-fvisibility=hidden cxxflags=-fvisibility-inlines-hidden cxxflags=-fexceptions cxxflags=-DBOOST_NO_RTTI 
如果要傳遞多個cflags,需要重複鍵名,而不是加雙引號把多個值賦給同一個。紅色的部分是隱藏符號。


6.Mac OS X編譯

環境

OS X Yosemite 10.10.3 
Xcode 6.3.1(6D1002) 
boost 1.57/1.58

步驟

和Linux相同。集成到Xcode的步驟和iOS類似。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章