當前位置:首頁 » 編程軟體 » clang交叉編譯

clang交叉編譯

發布時間: 2024-02-24 16:54:29

① 如何使用clang+llvm+binutils+newlib+gdb搭建交叉編譯環境

1,Build llvm/clang/lldb/lld 3.5.0等組件

1.0 准備:

至少需要從llvm.org下載llvm, cfe, lldb, compiler-rt,lld等3.5.0版本的代碼。

$tar xf llvm-3.5.0.src.tar.gz

$cd llvm-3.5.0.src

$mkdir -p tools/clang
$mkdir -p tools/clang/tools/extra
$mkdir -p tools/lld
$mkdir -p projects/compiler-rt

$tar xf cfe-3.5.0.src.tar.xz -C tools/clang --strip-components=1
$tar xf compiler-rt-3.5.0.src.tar.xz -C projects/compiler-rt --strip-components=1
$tar xf lldb-3.5.0.src.tar.xz -C tools/clang/tools/extra --strip-components=1
$tar xf lld-3.5.0.src.tar.xz -C tools/lld --strip-components=1
1.1 【可選】使用clang --stdlib=libc++時,自動添加-lc++abi。

libc++組件可以使用gcc libstdc++的supc++ ABI,也可以使用c++abi,cxxrt等,實際上自動添加-lc++abi是不必要的,這里這么處理,主要是為了方便起見。實際上完全可以在「clang++ -stdlib=libc++」時再手工添加-lc++abi給鏈接器。

這里涉及到鏈接時DSO隱式還是顯式的問題,早些時候ld在鏈接庫時會自動引入由庫引入的依賴動態庫,後來因為這個行為的不可控性,所以ld鏈接器的行為做了修改,需要顯式的寫明所有需要鏈接的動態庫,才會有手工添加-lc++abi這種情況出現。

--- llvm-3.0.src/tools/clang/lib/Driver/ToolChain.cpp 2012-03-26 18:49:06.663029075 +0800
+++ llvm-3.0.srcn/tools/clang/lib/Driver/ToolChain.cpp 2012-03-26 19:36:04.260071355 +0800
@@ -251,6 +251,7 @@
switch (Type) {
case ToolChain::CST_Libcxx:
CmdArgs.push_back("-lc++");
+ CmdArgs.push_back("-lc++abi");
break;

case ToolChain::CST_Libstdcxx:
1.2 【必要】給clang++添加-fnolibgcc開關。

這個開關主要用來控制是否連接到libgcc或者libunwind。

註:libgcc不等於libunwind。libgcc_eh以及supc++的一部分跟libunwind功能相當。

註:libgcc_s和compiler_rt的一部分相當。

這個補丁是必要的, 不會對clang的正常使用造成任何影響 ,只有在使用「-fnolibgcc"參數時才會起作用。

之所以進行了很多unwind的引入,主要是為了避免不必要的符號缺失麻煩,這里的處理相對來說是干凈的,通過as-needed規避了不必要的引入。

--- llvm-static-3.5.0.bak/tools/clang/lib/Driver/Tools.cpp 2014-09-10 13:46:02.581543888 +0800
+++ llvm-static-3.5.0/tools/clang/lib/Driver/Tools.cpp 2014-09-10 16:03:37.559019321 +0800
@@ -2060,9 +2060,15 @@
".a");

CmdArgs.push_back(Args.MakeArgString(LibClangRT));
- CmdArgs.push_back("-lgcc_s");
- if (TC.getDriver().CCCIsCXX())
- CmdArgs.push_back("-lgcc_eh");
+ if (Args.hasArg(options::OPT_fnolibgcc)) {
+ CmdArgs.push_back("--as-needed");
+ CmdArgs.push_back("-lunwind");
+ CmdArgs.push_back("--no-as-needed");
+ } else {
+ CmdArgs.push_back("-lgcc_s");
+ if (TC.getDriver().CCCIsCXX())
+ CmdArgs.push_back("-lgcc_eh");
+ }
}

static void addProfileRT(
@@ -7150,24 +7156,50 @@
bool isAndroid = Triple.getEnvironment() == llvm::Triple::Android;
bool StaticLibgcc = Args.hasArg(options::OPT_static_libgcc) ||
Args.hasArg(options::OPT_static);
+
+
+
if (!D.CCCIsCXX())
- CmdArgs.push_back("-lgcc");
+ if (Args.hasArg(options::OPT_fnolibgcc)) {
+ CmdArgs.push_back("--as-needed");
+ CmdArgs.push_back("-lunwind");
+ CmdArgs.push_back("--no-as-needed");
+ } else
+ CmdArgs.push_back("-lgcc");

if (StaticLibgcc || isAndroid) {
if (D.CCCIsCXX())
- CmdArgs.push_back("-lgcc");
+ if (Args.hasArg(options::OPT_fnolibgcc)) {
+ CmdArgs.push_back("--as-needed");
+ CmdArgs.push_back("-lunwind");
+ CmdArgs.push_back("--no-as-needed");
+ } else
+ CmdArgs.push_back("-lgcc");
} else {
if (!D.CCCIsCXX())
CmdArgs.push_back("--as-needed");
- CmdArgs.push_back("-lgcc_s");
+ if (Args.hasArg(options::OPT_fnolibgcc))
+ CmdArgs.push_back("-lunwind");
+ else
+ CmdArgs.push_back("-lgcc_s");
if (!D.CCCIsCXX())
CmdArgs.push_back("--no-as-needed");
}

if (StaticLibgcc && !isAndroid)
- CmdArgs.push_back("-lgcc_eh");
+ if (Args.hasArg(options::OPT_fnolibgcc)) {
+ CmdArgs.push_back("--as-needed");
+ CmdArgs.push_back("-lunwind");
+ CmdArgs.push_back("--no-as-needed");
+ } else
+ CmdArgs.push_back("-lgcc_eh");
else if (!Args.hasArg(options::OPT_shared) && D.CCCIsCXX())
- CmdArgs.push_back("-lgcc");
+ if (Args.hasArg(options::OPT_fnolibgcc)) {
+ CmdArgs.push_back("--as-needed");
+ CmdArgs.push_back("-lunwind");
+ CmdArgs.push_back("--no-as-needed");
+ } else
+ CmdArgs.push_back("-lgcc");

// According to Android ABI, we have to link with libdl if we are
// linking with non-static libgcc.
--- llvm-static-3.5.0.bak/tools/clang/include/clang/Driver/Options.td 2014-08-07 12:51:51.000000000 +0800
+++ llvm-static-3.5.0/tools/clang/include/clang/Driver/Options.td 2014-09-10 13:36:34.598511176 +0800
@@ -788,6 +788,7 @@
def fomit_frame_pointer : Flag<["-"], "fomit-frame-pointer">, Group<f_Group>;
def fopenmp : Flag<["-"], "fopenmp">, Group<f_Group>, Flags<[CC1Option, NoArgumentUnused]>;
def fopenmp_EQ : Joined<["-"], "fopenmp=">, Group<f_Group>, Flags<[CC1Option]>;
+def fnolibgcc : Flag<["-"], "fnolibgcc">, Group<f_Group>, Flags<[CC1Option, NoArgumentUnused]>;
def fno_optimize_sibling_calls : Flag<["-"], "fno-optimize-sibling-calls">, Group<f_Group>;
def foptimize_sibling_calls : Flag<["-"], "foptimize-sibling-calls">, Group<f_Group>;
def force__cpusubtype__ALL : Flag<["-"], "force_cpusubtype_ALL">;
1.3 llvm的其他補丁。

llvm/clang將gcc toolchain的路徑hard code在代碼中,請查閱tools/clang/lib/Driver/ToolChains.cpp。

找到x86_64-redhat-linux之類的字元串。

如果沒有你系統特有的gcc tripple string,請自行添加。

這個tripple string主要是給llvm/clang搜索gcc頭文件等使用的,不影響本文要構建的toolchain

1.4 構建clang/llvm/lldb

本文使用ninja。順便說一下,llvm支持configure和cmake兩種構建方式。可能是因為工程太大,這兩種構建方式的工程文件都有各種缺陷(主要表現在開關選項上,比如configure有,但是cmake卻沒有等)。llvm-3.4.1就是因為cmake工程文件的錯誤而導致了3.4.2版本的發布。

綜合而言,cmake+ninja的方式是目前最快的構建方式之一,可以將構建時間縮短一半以上。

mkdir build
cd build

cmake \
-G Ninja \
-DCMAKE_INSTALL_PREFIX=/usr \
-DCMAKE_BUILD_TYPE="Release" \
-DCMAKE_CXX_FLAGS="-std=c++11" \
-DBUILD_SHARED_LIBS=OFF \
-DLLVM_ENABLE_PIC=ON \
-DLLVM_TARGETS_TO_BUILD="all" \
-DCLANG_VENDOR="MyOS" ..

ninja

ninja install
如果系統原來就有clang/clang++的可用版本,可以添加:

-DCMAKE_C_COMPILER=clang \
-DCMAKE_CXX_COMPILER=clang++ \
這樣就會使用系統的clang++來構建llvm/clang

2,測試clang/clang++。

自己找幾個簡單的c/cpp/objc等編譯測試一下即可。完整測試可以在構建時作ninja check-all

3,libunwind/libc++/libc++abi,一套不依賴libgcc, libstdc++的c++運行庫。

3.1 從https://github.com/pathscale/libunwind 獲取代碼。

libunwind有很多個實現,比如gnu的libunwind, path64的libunwind,還有libcxxabi自帶的Unwinder.

這里作下說明:

1),gnu的libunwind會有符號缺失和沖突。

2),libcxxabi自帶的Unwinder是給mac和ios用的,也就是只能在darwin體系構建。目前Linux的實現仍然不全,等linux實現完整了或許就不再需要path64的unwind實現了。

暫時建議使用pathscale的unwind實現。

mkdir -p build
cd build
cmake -G Ninja -DCMAKE_C_COMPILER=clang -DCMAKE_C_FLAGS="-m64" ..
ninja

mkdir -p /usr/lib
cp src/libunwind.so /usr/lib
cp src/libunwind.a /usr/lib
3.2 第一次構建libcxx.

必須先構建一次libcxx,以便後面構建libcxxabi。這里構建的libcxx實際上是使用gcc的libgcc/stdc++/supc++的。

打上這個補丁來禁止libgcc的引入:

diff -Nur libcxx/cmake/config-ix.cmake libcxxn/cmake/config-ix.cmake
--- libcxx/cmake/config-ix.cmake 2014-06-25 06:57:50.000000000 +0800
+++ libcxxn/cmake/config-ix.cmake 2014-06-25 09:05:24.980350544 +0800
@@ -28,5 +28,4 @@
check_library_exists(c printf "" LIBCXX_HAS_C_LIB)
check_library_exists(m ccos "" LIBCXX_HAS_M_LIB)
check_library_exists(rt clock_gettime "" LIBCXX_HAS_RT_LIB)
-check_library_exists(gcc_s __gcc_personality_v0 "" LIBCXX_HAS_GCC_S_LIB)
編譯安裝:

mkdir build
cd build
cmake \
-G Ninja \
-DCMAKE_INSTALL_PREFIX=/usr \
-DCMAKE_C_COMPILER=clang \
-DCMAKE_CXX_COMPILER=clang++ \
..
ninja
ninja install
3.3,測試第一次構建的libcxx。

使用"clang++ -stdlib=libc++ -o test test.cpp -lstdc++"編譯簡單c++代碼,檢查是否出錯。(如果前面構建clang是已經apply了c++abi的鏈接補丁,這里會出現找不到c++abi的情況,跳過即可)

使用"ldd test"查看test二進制動態庫使用情況。可以發現,test依賴於libgcc_s/libc++/libstdc++。(多少有些不爽了吧?使用了libc++居然還要依賴libstdc++?)

② gdal for android 如何支持 gpkg

編譯環境如下:

ubuntu 16.04 LTS

android-ndk-r18b

GNU Make 4.1

代碼版本如下:

gdal-2.2.3

curl-7.59.0

按照網上的辦法順利對GDAL進行了交叉編譯,坑來了。

利用GDAL的CPLHTTPFetch測試網路抓取功能的時候,沒抓取到文件。測試函數如下:

bool SaveUrl2File(const char* pszUrl, const char* pszFileName)
{
if (CPLHTTPEnabled() != TRUE)
return false;

CPLHTTPResult *pRest = CPLHTTPFetch(pszUrl, NULL);
if (pRest == NULL)
return false;

FILE *pFile = fopen(pszFileName, "wb");
if (pFile == NULL)
return false;

fwrite(pRest->pabyData, sizeof(GByte), pRest->nDataLen, pFile);
fclose(pFile);

CPLHTTPDestroyResult(pRest);
CPLHTTPCleanup();
return true;
}
查看錯誤信息,大概的意思是需要HTTPS支持,查資料得知,需要在編譯curl的時候指定--with-ssl 才能支持HTTPS,然後就開始編譯openssl庫,本來應該是比較容易的一件事,結果整了足足一天,糟糕的是還沒把ssl編譯出來。我用的NDK版本比較高,編譯器是clang,真是沒搞出來,原因是和NDK版本有密切關系,貌似GCC比較容易,clang是google推薦編譯器。之後就從網上找ssl庫,arm64-v8a的ssl不太好找,還好在GITHUB上找到了。

這是成功在curl中集成ssl後的configure輸出,注意最後一行Protocols 中要出現HTTPS,另外在編譯curl的時候要指定ssl的庫目錄,和庫名字,否則鏈接的時候可能會找不到庫。

export LDFLAGS="-L/xxx/xxx/build64dr/openssl/lib" ,指定ssl庫的搜索目錄

export LIBS="-lssl -lcrypto -lz",指定ssl庫名字

GDAL編譯好後,開始測試 SaveUrl2File 函數,測試失敗,提示SSL certificate problem: unable to get local issuer certificate,調用CPLSetConfigOption("GDAL_HTTP_UNSAFESSL", "YES");即可解決,原理就不說了。OK,GDAL在android下可以抓取網路數據了。

③ [openharmony]liteos-a系統編譯之GN

在 文章 中已經分析openharmony的小型系統(liteos-a)編譯過程,最主要的就是調用gn/ninja/makefs三個命令最終生成可燒錄的鏡像文件
從前面文件可以看到hb build調用的gn命令參數如下

這里詳細分析一下gn工具在編譯過程中的使用

這里簡單介紹下GN工具的使用方法,gn語法可以參考 http://weharmonyos.com/openharmony/compile/gn/docs/
,已經熟悉的可以跳過

從上面圖中可以看到使用的命令類型為 gn gen <output_dir> [options] ,此命令就是為了將所有需要的BUILD.gn文件生成為*.ninja文件供ninja進行編譯; 可以通過 gn help gen 命令查看詳細的用法說明, 如下

下面重點說一下gn_cmd中的 [options]

liteos-a編譯系統的dotfile內容如下:

liteos-a是嵌入式系統,而編譯環境是linux系統,這就需要用到交叉編譯方式,這個就可以在環境配置中指定 target_os 、 target_cpu 、 board_cpu 等等信息
這些信息就是 buildconfig 參數指定的 BUILDCONFIG.gn 文件中配置的
除了以上信息,還配置了以下幾個重要信息

詳細信息可以查看 //build/lite/config/BUILDCONFIG.gn 文件內容

toolchain定義源碼編譯需要的工具,像編譯器、匯編器、連接器等等,一般在.gn所在目錄下有一個 toolchain 目錄,裡面的 BUILD.gn 定義詳細的編譯工具鏈信息
這里目錄結構如下:

從結構信息中可以看到定義了clang和gcc兩種工具鏈,通過變數 board_toolchain_type 來區分(此變數也是buildconfig中定義的),具體信息參見BUILD.gn文件內容,如下

在.gn文件所在目錄下的BUILD.gn就是入口,此文件做了以下幾個事情

這里重點說一下target為 ohos 的 group 如下:

這里也比較好理解,裡面就是讀取一個配置文件,幾級循環來處理配置文件中配置的內容。流程如下

到此就將此board下各模塊的依賴關系添加好了,然後 GN 會將依賴樹中所有的BUILD.gn生成對應的.ninja文件,並且在out的根目錄下生成下面幾個ninja的入口文件以及配置文件

④ 怎麼樣才能提高python程序的網路吞吐速率

Python是一個很酷的語言,因為你可以在很短的時間內利用很少的代碼做很多事情。不僅如此,它還能輕松地支持多任務,比如多進程等。Python批評者有時會說Python執行緩慢。本文將嘗試介紹6個技巧,可加速你的Python應用程序。
1.讓關鍵代碼依賴於外部包

雖然Python讓許多編程任務變得容易,但它可能並不總能為緊急的任務提供最佳性能。你可以為緊急的任務使用C、C++或機器語言編寫的外部包,這樣可以提高應用程序的性能。這些包都是不能跨平台的,這意味著你需要根據你正在使用的平台,尋找合適的包。簡而言之,這個方案放棄了一些應用程序的可移植性,以換取只有在特定主機上直接編程才能獲得的程序性能。這里有一些你應該考慮加入到你的「性能兵工廠」的包:

  • Cython

  • PyInlne

  • PyPy

  • Pyrex

  • 這些包以不同的方式提高性能。例如,Pyrex能夠擴展Python所能做的事情,例如使用C的數據類型來讓內存任務更加有效或直接。PyInIne讓你在Python應用程序中直接使用C代碼。程序中的內聯代碼單獨編譯,但它在利用C語言所能提供的效率的同時,也讓所有的代碼都在同一個地方。
    2.排序時使用鍵(key)

    有很多老的Python排序代碼,它們在你創建一個自定義的排序時花費你的時間,但在運行時確實能加速執行排序過程。元素排序的最好方法是盡可能使用鍵(key)和默認的sort()排序方法。例如,考慮下面的代碼:

  • import operatorsomelist = [(1, 5, 8), (6, 2, 4), (9, 7, 5)]somelist.sort(key=operator.itemgetter(0))somelist#Output = [(1, 5, 8), (6, 2, 4), (9, 7, 5)]somelist.sort(key=operator.itemgetter(1))somelist#Output = [(6, 2, 4), (1, 5, 8), (9, 7, 5)]somelist.sort(key=operator.itemgetter(2))somelist#Output = [(6, 2, 4), (9, 7, 5), (1, 5, 8)],
  • 每一個實例中,根據你選擇的作為key參數部分的索引,數組進行了排序。類似於利用數字進行排序,這種方法同樣適用於利用字元串排序。
    3.優化循環

    每種編程語言都會強調需要優化循環。當使用Python的時候,你可以依靠大量的技巧使得循環運行得更快。然而,開發者經常漏掉的一個方法是:避免在一個循環中使用點操作。例如,考慮下面的代碼:

  • lowerlist = ['this', 'is', 'lowercase']upper = str.upperupperlist = []append = upperlist.appendfor word in lowerlist:append(upper(word))print(upperlist)#Output = ['THIS', 'IS', 'LOWERCASE']
  • 每一次你調用方法str.upper,Python都會求該方法的值。然而,如果你用一個變數代替求得的值,值就變成了已知的,Python就可以更快地執行任務。優化循環的關鍵,是要減少Python在循環內部執行的工作量,因為Python原生的解釋器在那種情況下,真的會減緩執行的速度。

    (注意:優化循環的方法有很多,這只是其中的一個。例如,許多程序員都會說,列表推導是在循環中提高執行速度的最好方式。這里的關鍵是,優化循環是程序取得更高的執行速度的更好方式之一。)
    4.使用較新版本的Python

    在網上搜索Python信息,都會發現無數人在問,從Python一個版本遷移到另一個版本的問題的信息。一般來說,Python的每一個版本都包含了能讓其比上個版本運行更快的優化。版本遷移的限制因素是,你喜歡的那些庫是否已經遷移到Python的較新版本。相比於詢問是否應該進行版本遷移,關鍵問題是確定一個新版本什麼時候有足夠的支持,以保證遷移的可行性。

    你需要驗證你的代碼仍然運行。你需要在Python的新版本下使用你獲得的新庫,然後檢查你的應用程序是否需要重大改變。只有在你作出必要的更正之後,你才會注意到版本之間的差別。然而,如果你正好確保你的應用程序能在新版本下運行,而不需要任何改變,你可能會錯過那些版本升級帶來的新特性。一旦你進行了遷移,你應該為你的新版本下的應用程序寫一個說明,檢查有問題的地方,並且優先考慮利用新版本的特性去更新那些地方。這樣用戶將會在升級的過程中更早的看到一個更大的性能提升。
    5.嘗試多種編碼方法

    如果每次你創建一個應用程序都是用相同的編碼方法,幾乎肯定會導致一些你的應用程序比它能夠達到的運行效率慢的情況。作為分析過程的一部分,你可以嘗試一些實驗。例如,在一個字典中管理一些元素,你可以採用安全的方法確定元素是否已經存在並更新,或者你可以直接添加元素,然後作為異常處理該元素不存在情況。考慮第一個編碼的例子:

  • n = 16myDict = {}for i in range(0, n):char = 'abcd'[i%4]if char not in myDict:myDict[char] = 0myDict[char] += 1print(myDict)
  • 這段代碼通常會在myDict開始為空時運行得更快。然而,當mydict通常被數據填充(或者至少大部分被充填)時,另一種方法效果更好。

  • n = 16myDict = {}for i in range(0, n):char = 'abcd'[i%4]try:myDict[char] += 1except KeyError:myDict[char] = 1print(myDict)
  • 兩種情況下具有相同的輸出:{『d': 4, 『c': 4, 『b': 4, 『a': 4}。唯一的不同是這個輸出是如何得到的。跳出固定的思維模式,創造新的編碼技巧,能夠幫助你利用你的應用程序獲得更快的結果。
    6.交叉編譯應用程序

    開發者有時會忘記,電腦實際上是不懂任何用於創建現代應用程序的語言,電腦所能懂得是機器代碼。為了能在電腦上運行應用程序,你使用一個應用將人類可讀的代碼你轉換成計算機能理解的。有時候用一種語言,比如Python,寫一個應用,並用另一種語言,比如C++,運行它,從性能的角度來看是有意義的。這取決於你想要應用程序去做什麼,以及主機系統可以提供的資源。

    一個有趣的交叉編譯器,Nuitka,可以將你的Python代碼轉換為C++代碼。這么做的結果是,你可以在原生模式下執行應用程序,而不是依靠解釋器。根據平台和任務,你可以看到一個顯著的性能提升。

    (注意:Nuitka目前還處於測試階段,所以用它來產品程序時需要小心。實際上,目前最好將其用於實驗。現在也有一些關於交叉編譯是否是得到更好性能的最佳方式的討論。開發者已經利用交叉編譯好幾年了,目的是實現特定的目標,比如更好的應用程序的速度。記住,每一個解決方案都會有得有失,你應該在將一個解決方案用於生產環境之前就好好考慮一下得失情況。)

    在使用一個交叉編譯器時,要確保它支持你使用的Python的版本。Nuitka支持Python2.6、2.7、3.2和3.3。想讓這個方案發揮作用,你需要一個Python解釋器和一個C++編譯器。Nuitka支持多種C++編譯器,包括Microsoft Visual Studio、MinGW 和 Clang/LLVM。

    交叉編譯也可能帶來一些嚴重的負面影響。例如,當利用Nuitka工作時,你會發現即使一個小程序也能消耗很大的硬碟空間,這是因為Nuitka使用大量的動態鏈接庫(DLLs)實現Python的功能。所以當你面對一個資源有限的系統時,這個方案可能不會很好的起作用。
    總結

    這六個技巧中的任意一個,都可以幫助你創造更快的Python程序。但任何技巧都不是萬能的,不能每次都起作用。有些技巧在Python的特定版本下比其他技巧的更有效——甚至系統平台也能影響它們的效果。你需要配置你的應用,確定哪個地方讓其運行緩慢,然後嘗試似乎能最好的解決這些問題的一些技巧。

⑤ SE是什麼編譯器

Clang交叉編譯器。

_lang具有更現代的設計茄渣,並且通常被認為比GCC更先進。除此之外,Clang還獲得了更為寬松的許可,該許可允許製造可商購的衍生物。ARM / Keil從Clang派生了一個編譯器,從而停止了其先前專有編譯器的開發。考慮到所有這些,我們決定更深入地研究Clang,以使用它創建我們自己的編譯器為目標。

_EGGER將所有內容打包到一個易於下載的「軟體包」中,完全集成並且可以立即使用。Clang和GCC都有非常先進的前端,可以將源代碼轉換為中間表示(IR),並且都可以生成出色的代碼。到目前為止,SEGGER一直專注於針對基於Cortex-M微控制器的ARM Thumb-2代碼的銀吵代碼生成器的更改。下一步將包括改善與其他編譯器的兼容性,而不僅僅是GCC和Clang(針對實用程序和其他專顫搏悄業),以使其易於切換。

⑥ 關於Mac上交叉編譯幾個小問題,求解答

我是打算編譯給模擬器脊喊悔用的庫喔。sysroot設置成simulator.platform相應的目錄了。但是還滲大是出櫻正現clang: warning: using sysroot for 'iPhoneSimulator' but targeting 'MacOSX'。雖然是warning但是不知道有沒影響。

⑦ OpenSSL的編譯和使用

個人博客地址: https://blog.yookingh.cn
該文章地址: https://blog.yookingh.cn/dev/201215-openssl.html

從NDK r19開滑知始,由於gcc兼容clang的編譯方式有問題,該版本乎高已經移除了相關gcc文件,所以用老方法交叉編譯Openssl的時候,會提示找不到gcc文件。

參考: https://blog.csdn.net/zoujin6649

build-android-single.sh 腳本文件及注釋如下歲讓尺

執行腳本

修改腳本為 循環編譯 ,編譯所有需要的文件

build-android-all.sh 腳本文件內容如下

執行腳本方法同上,如為第一次執行(即沒有Makefile文件),仍需要執行 ./config 循環編譯無需執行 make clean

參考: https://blog.csdn.net/iamadk

Python 腳本內容

創建編譯執行腳本

執行編譯腳本同r15,第一次需要執行 ./config 生成Makefile,第二次或以上需要清除make記錄即 make clean ,接下來依舊是創建 循環編譯 腳本

⑧ 如何提高python的運行效率

竅門一:關鍵代碼使用外部功能包

Python簡化了許多編程任務,但是對於一些時間敏感的任務,它的表現經常不盡人意。使用C/C++或機器語言的外部功能包處理時間敏感任務,可以有效提高應用的運行效率。這些功能包往往依附於特定的平台,因此你要根據自己所用的平台選擇合適的功能包。簡而言之,這個竅門要你犧牲應用的可移植性以換取只有通過對底層主機的直接編程才能獲得的運行效率。以下是一些你可以選擇用來提升效率的功能包:

Cython
Pylnlne
PyPy
Pyrex

這些功能包的用處各有不同。比如說,使用C語言的數據類型,可以使涉及內存操作的任務更高效或者更直觀。Pyrex就能幫助Python延展出這樣的功能。Pylnline能使你在Python應用中直接使用C代碼。內聯代碼是獨立編譯的,但是它把所有編譯文件都保存在某處,並能充分利用C語言提供的高效率。

竅門二:在排序時使用鍵

Python含有許多古老的排序規則,這些規則在你創建定製的排序方法時會佔用很多時間,而這些排序方法運行時也會拖延程序實際的運行速度。最佳的排序方法其實是盡可能多地使用鍵和內置的sort()方法。譬如,拿下面的代碼來說:

import operator
somelist = [(1, 5,]
在每段例子里,list都是根據你選擇的用作關鍵參數的索引進行排序的。這個方法不僅對數值類型有效,還同樣適用於字元串類型。

竅門三:針對循環的優化

每一種編程語言都強調最優化的循環方案。當使用Python時,你可以藉助豐富的技巧讓循環程序跑得更快。然而,開發者們經常遺忘的一個技巧是:盡量避免在循環中訪問變數的屬性。譬如,拿下面的代碼來說:

lowerlist = ['this', 'is', 'lowercase']
upper = str.upper
upperlist = []
append = upperlist.append
for word in lowerlist:
append(upper(word))
print(upperlist)
#Output = ['THIS', 'IS', 'LOWERCASE']
每次你調用str.upper, Python都會計算這個式子的值。然而,如果你把這個求值賦值給一個變數,那麼求值的結果就能提前知道,Python程序就能運行得更快。因此,關鍵就是盡可能減小Python在循環中的工作量。因為Python解釋執行的特性,在上面的例子中會大大減慢它的速度。

(注意:優化循環的方法還有很多,這只是其中之一。比如,很多程序員會認為,列表推導式是提高循環速度的最佳方法。關鍵在於,優化循環方案是提高應用程序運行速度的上佳選擇。)

竅門四:使用較新的Python版本

如果你在網上搜索Python,你會發現數不盡的信息都是關於如何升級Python版本。通常,每個版本的Python都會包含優化內容,使其運行速度優於之前的版本。但是,限制因素在於,你最喜歡的函數庫有沒有同步更新支持新的Python版本。與其爭論函數庫是否應該更新,關鍵在於新的Python版本是否足夠高效來支持這一更新。

你要保證自己的代碼在新版本里還能運行。你需要使用新的函數庫才能體驗新的Python版本,然後你需要在做出關鍵性的改動時檢查自己的應用。只有當你完成必要的修正之後,你才能體會新版本的不同。

然而,如果你只是確保自己的應用在新版本中可以運行,你很可能會錯過新版本提供的新特性。一旦你決定更新,請分析你的應用在新版本下的表現,並檢查可能出問題的部分,然後優先針對這些部分應用新版本的特性。只有這樣,用戶才能在更新之初就覺察到應用性能的改觀。

竅門五:嘗試多種編碼方法

每次創建應用時都使用同一種編碼方法幾乎無一例外會導致應用的運行效率不盡人意。可以在程序分析時嘗試一些試驗性的辦法。譬如說,在處理字典中的數據項時,你既可以使用安全的方法,先確保數據項已經存在再進行更新,也可以直接對數據項進行更新,把不存在的數據項作為特例分開處理。請看下面第一段代碼:

n = 16
myDict = {}
for i in range(0, n):
char = 'abcd'[i%4]
if char not in myDict:
myDict[char] = 0
myDict[char] += 1
print(myDict)
當一開始myDict為空時,這段代碼會跑得比較快。然而,通常情況下,myDict填滿了數據,至少填有大部分數據,這時換另一種方法會更有效率。

n = 16
myDict = {}
for i in range(0, n):
char = 'abcd'[i%4]
try:
myDict[char] += 1
except KeyError:
myDict[char] = 1
print(myDict)
在兩種方法中輸出結果都是一樣的。區別在於輸出是如何獲得的。跳出常規的思維模式,創建新的編程技巧能使你的應用更有效率。

竅門六:交叉編譯你的應用

開發者有時會忘記計算機其實並不理解用來創建現代應用程序的編程語言。計算機理解的是機器語言。為了運行你的應用,你藉助一個應用將你所編的人類可讀的代碼轉換成機器可讀的代碼。有時,你用一種諸如Python這樣的語言編寫應用,再以C++這樣的語言運行你的應用,這在運行的角度來說,是可行的。關鍵在於,你想你的應用完成什麼事情,而你的主機系統能提供什麼樣的資源。

Nuitka是一款有趣的交叉編譯器,能將你的Python代碼轉化成C++代碼。這樣,你就可以在native模式下執行自己的應用,而無需依賴於解釋器程序。你會發現自己的應用運行效率有了較大的提高,但是這會因平台和任務的差異而有所不同。

(注意:Nuitka現在還處在測試階段,所以在實際應用中請多加註意。實際上,當下最好還是把它用於實驗。此外,關於交叉編譯是否為提高運行效率的最佳方法還存在討論的空間。開發者已經使用交叉編譯多年,用來提高應用的速度。記住,每一種解決辦法都有利有弊,在把它用於生產環境之前請仔細權衡。)

在使用交叉編譯器時,記得確保它支持你所用的Python版本。Nuitka支持Python2.6, 2.7, 3.2和3.3。為了讓解決方案生效,你需要一個Python解釋器和一個C++編譯器。Nuitka支持許多C++編譯器,其中包括Microsoft Visual Studio,MinGW 和 Clang/LLVM。

交叉編譯可能造成一些嚴重問題。比如,在使用Nuitka時,你會發現即便是一個小程序也會消耗巨大的驅動空間。因為Nuitka藉助一系列的動態鏈接庫(DDLs)來執行Python的功能。因此,如果你用的是一個資源很有限的系統,這種方法或許不太可行。

熱點內容
安卓機怎麼關閉主題 發布:2024-12-26 21:55:57 瀏覽:915
javafor線程 發布:2024-12-26 21:54:35 瀏覽:744
python自定義模塊 發布:2024-12-26 21:41:37 瀏覽:57
linux安裝mysqltar 發布:2024-12-26 21:18:02 瀏覽:315
瀏覽器的java支持 發布:2024-12-26 21:15:45 瀏覽:655
電商高管如何配置 發布:2024-12-26 21:13:48 瀏覽:709
批發的演算法 發布:2024-12-26 21:13:46 瀏覽:208
安卓手機在日本下載哪個導航 發布:2024-12-26 21:09:32 瀏覽:560
白雜訊加密 發布:2024-12-26 20:31:02 瀏覽:641
怎麼防止電腦刪除腳本 發布:2024-12-26 20:19:19 瀏覽:153