2017-09-19 122 views
0

我正在嘗試使用Swig爲大型C++項目生成接口文件。該項目的頭文件的基礎上,編譯器類型一些檢查,比如,爲Swig設置編譯器標誌

#if defined(__clang__) 
    ... 
#if defined(__llvm__) 

所以我必須通過編譯器標誌痛飲。具體而言,在我看來,我應該叫痛飲這樣的:

swig -D__clang__ ... 

然而,這似乎並沒有減輕我收到錯誤消息,因爲我仍然得到同樣的錯誤。

我不清楚,如果我設置錯誤的編譯器標誌,或者我沒有設置所有的編譯器標誌。所以,問題是雙重的:

  1. 我是否正確設置編譯器標誌通過調用

    痛飲-D__clang__ ...... xxx.i

,或者我應該以某種方式定義這些參數在xxx.i接口文件中?

  1. 如何捕獲所有的編譯器標誌?我當然可以在我的機器上編譯C++代碼,但我怎麼知道編譯器設置了哪些宏?有沒有一個通用的方法來做到這一點?
+0

取決於編譯器,哪個編譯器? –

+0

現在我正在嘗試爲Android編譯一些東西,所以它使用了一個鏗鏘的處理器。但我相信它設置了一些其他標誌,而我沒有看到它記錄了它正在使用的標誌 –

+0

我在想如果有一個簡單的10行C++文件,我可以編寫它將打印出所有編譯器宏。這個想法是,我將編譯這個簡單的測試文件與我想要使用的編譯器,然後檢索標誌,並將其傳入Swig –

回答

0

Richard是正確的。大多數編譯器似乎都支持-dM命令(至少clanggcc似乎)。在我的情況下,我想看看哪些預處理器宏由Android構建系統設置。這有點複雜,因爲Android NDK有許多編譯器,所有編譯器的構建都略有不同。因此,我創建了下面的Python腳本3保存所有的宏包括對文件:

import os, sys 

# Define the toolchain root 
root = "C:\\Android\\android-sdk\\ndk-bundle\\toolchains\\" 

# Define the directory where you want all of the macro definitions to go 
output = "output\\" 
os.makedirs(output, exist_ok=True) 

# Get a list of all of the files 
files = [ (os.path.join(dp, f), f) for dp, dn, fn in os.walk(os.path.expanduser(root)) for f in fn ] 

# We only want executables 
files = [ file for file in files if file[1].endswith("exe") ] 

# Now, let's limit that to executables that contain one of the following keys 
keys = [ "gcc", "g++", "clang", "c++", "cpp" ] 
files = [ file for file in files if any(key in file[1] for key in keys) ] 

# and that exclude the following keys 
keys = [ "-ar", "-nm", "-ranlib", "filt", "-format", "-tidy" ] 
files = [ file for file in files if all(key not in file[1] for key in keys) ] 

# Now, for each of these files, we want to see what preprocessor macros are being set. 
call = " -dM -E - <NUL> " 
for file in files: 
    command = file[0] + call + output + file[1].replace(".exe", ".txt").replace(root,"") 
    print(command) 
    os.system(command) 

如果你把這個文件「introspect.py」,然後使用很簡單

python introspect.py 

這是什麼腳本的作用是在root目錄(在我的系統C:\\Android\\android-sdk\\ndk-bundle\\toolchains\\)中查找所有應該包含編譯器的*.exe文件(對於Linux系統更改此文件)。具體而言,該腳本將查找所有可執行文件的條款之一

[ "gcc", "g++", "clang", "c++", "cpp" ] 
爲名

,排除與

[ "-ar", "-nm", "-ranlib", "filt", "-format", "-tidy" ] 
在名稱

文件。最後,每個找到的可執行文件格式

compiler.exe -dM -E - <NUL> output\compiler.txt 

其中compiler將會像clanggccg++然後運行。請注意,此腳本強制創建output目錄。我的系統上運行後,output目錄中包含的文件(警告:真的有可用的很多編譯器通過NDK):

aarch64-linux-android-c++.txt 
aarch64-linux-android-cpp.txt 
aarch64-linux-android-g++.txt 
aarch64-linux-android-gcc-4.9.txt 
aarch64-linux-android-gcc-4.9.x.txt 
aarch64-linux-android-gcc.txt 
arm-linux-androideabi-c++.txt 
arm-linux-androideabi-cpp.txt 
arm-linux-androideabi-g++.txt 
arm-linux-androideabi-gcc-4.9.txt 
arm-linux-androideabi-gcc-4.9.x.txt 
arm-linux-androideabi-gcc.txt 
clang++.txt 
clang.txt 
clang_32.txt 
i686-linux-android-c++.txt 
i686-linux-android-cpp.txt 
i686-linux-android-g++.txt 
i686-linux-android-gcc-4.9.txt 
i686-linux-android-gcc-4.9.x.txt 
i686-linux-android-gcc.txt 
mips64el-linux-android-c++.txt 
mips64el-linux-android-cpp.txt 
mips64el-linux-android-g++.txt 
mips64el-linux-android-gcc-4.9.txt 
mips64el-linux-android-gcc-4.9.x.txt 
mips64el-linux-android-gcc.txt 
mipsel-linux-android-c++.txt 
mipsel-linux-android-cpp.txt 
mipsel-linux-android-g++.txt 
mipsel-linux-android-gcc-4.9.txt 
mipsel-linux-android-gcc-4.9.x.txt 
mipsel-linux-android-gcc.txt 
x86_64-linux-android-c++.txt 
x86_64-linux-android-cpp.txt 
x86_64-linux-android-g++.txt 
x86_64-linux-android-gcc-4.9.txt 
x86_64-linux-android-gcc-4.9.x.txt 
x86_64-linux-android-gcc.txt 

其中這些文件的前幾行往往看起來象

#define __DBL_MIN_EXP__ (-1021) 
#define __UINT_LEAST16_MAX__ 65535 
#define __ATOMIC_ACQUIRE 2 
#define __FLT_MIN__ 1.17549435082228750796873653722224568e-38F 
#define __GCC_IEC_559_COMPLEX 2 
#define __UINT_LEAST8_TYPE__ unsigned char 
#define __INTMAX_C(c) C## L 
#define __CHAR_BIT__ 8 
#define __UINT8_MAX__ 255 
#define __ANDROID__ 1 
#define __WINT_MAX__ 4294967295U 
#define __ORDER_LITTLE_ENDIAN__ 1234 
#define __SIZE_MAX__ 18446744073709551615UL 
#define __WCHAR_MAX__ 4294967295U 
#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1 
#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1 
#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1 

事實證明,這些文件中的很多文件是相同的,但clanggcc文件之間存在顯着差異。

0

您應該有一個.i文件來定義您想要生成的接口。

在那裏你可以簡單地使用#define __clang__

例如,看看在swig.i文件礦庫https://bitbucket.org/binarno/imebra/src/db648a8b9c359524d40fd7d63c785b6269147010/wrappers/swig.i?at=default

還要注意,痛飲並不需要所有的編譯器標誌:它是不會編譯您的項目,但它只是生成額外的cxx文件。在.i文件中,只需聲明允許swig選擇正確的類和方法的標誌(如果需要)即可。