boost全平台编译方法
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 ]; thenecho "libraries exist. no need to build."exit 0 fi# 以下代碼參考 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"集成到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編譯前就鏈接以致錯誤。?
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_0 if 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(boostSOURCE_DIR ${ROOT_DIR}/third_party/boost_1_57_0CONFIGURE_COMMAND bash ${ROOT_DIR}/third_party/boost_1_57_0/bootstrap.sh --with-libraries=date_time,thread,filesystem,systemBUILD_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_RTTIBUILD_IN_SOURCE 1INSTALL_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類似。
轉載請注明出處:http://blog.csdn.net/hursing
總結
以上是生活随笔為你收集整理的boost全平台编译方法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 软件工程:软件工程过程与方法
- 下一篇: 从u盘到计算机内存的过程,U盘装系统步骤