为 Swig 设置编译器标志
Setting compiler flags for Swig
我正在尝试使用 Swig 为大型 C++ 项目生成接口文件。项目的头文件根据编译器类型做一些检查,例如,
#if defined(__clang__)
...
#if defined(__llvm__)
所以我必须将编译器标志传递给 Swig。具体来说,我觉得应该这样调用swig:
swig -D__clang__ ...
但是,这似乎并没有减轻我收到的错误消息,因为我仍然收到相同的错误。
我不清楚我是否错误地设置了编译器标志,或者我是否没有设置所有编译器标志。所以问题是双重的:
我是否通过调用
正确设置了编译器标志
痛饮-D__clang__ ...... xxx.i
或者我是否应该以某种方式在 xxx.i 接口文件中定义这些参数?
- 如何捕获所有编译器标志?我当然可以在我的机器上编译 C++ 代码,但是我怎么知道编译器设置了哪些宏?有没有通用的方法来做到这一点?
理查德是正确的。大多数编译器似乎都支持 -dM
命令(至少 clang
和 gcc
似乎支持)。就我而言,我想查看 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\
) 应该在某处包含编译器。具体来说,此脚本将查找所有具有术语
之一的可执行文件
[ "gcc", "g++", "clang", "c++", "cpp" ]
在名称中,排除带有
的文件
[ "-ar", "-nm", "-ranlib", "filt", "-format", "-tidy" ]
在名字里。最后,每个找到的可执行文件都是 运行 格式
compiler.exe -dM -E - < NUL > output\compiler.txt
其中 compiler
类似于 clang
或 gcc
或 g++
。请注意,此脚本会强制创建 output
目录。在我的系统上 运行ning 之后,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
事实证明,这些文件中有许多是相同的,但 clang
和 gcc
文件之间存在显着差异。
您应该有一个 .i 文件来定义您要生成的界面。
在那里你可以简单地使用#define __clang__
。
例如,查看我的库的 swig.i 文件 https://bitbucket.org/binarno/imebra/src/db648a8b9c359524d40fd7d63c785b6269147010/wrappers/swig.i?at=default
另请注意,swig 不需要所有编译器标志:它不会编译您的项目,而只会生成额外的 cxx 文件。在 .i 文件中,只需声明允许 swig select 正确 类 和方法的标志(如果需要)。
我正在尝试使用 Swig 为大型 C++ 项目生成接口文件。项目的头文件根据编译器类型做一些检查,例如,
#if defined(__clang__)
...
#if defined(__llvm__)
所以我必须将编译器标志传递给 Swig。具体来说,我觉得应该这样调用swig:
swig -D__clang__ ...
但是,这似乎并没有减轻我收到的错误消息,因为我仍然收到相同的错误。
我不清楚我是否错误地设置了编译器标志,或者我是否没有设置所有编译器标志。所以问题是双重的:
我是否通过调用
正确设置了编译器标志痛饮-D__clang__ ...... xxx.i
或者我是否应该以某种方式在 xxx.i 接口文件中定义这些参数?
- 如何捕获所有编译器标志?我当然可以在我的机器上编译 C++ 代码,但是我怎么知道编译器设置了哪些宏?有没有通用的方法来做到这一点?
理查德是正确的。大多数编译器似乎都支持 -dM
命令(至少 clang
和 gcc
似乎支持)。就我而言,我想查看 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\
) 应该在某处包含编译器。具体来说,此脚本将查找所有具有术语
[ "gcc", "g++", "clang", "c++", "cpp" ]
在名称中,排除带有
的文件[ "-ar", "-nm", "-ranlib", "filt", "-format", "-tidy" ]
在名字里。最后,每个找到的可执行文件都是 运行 格式
compiler.exe -dM -E - < NUL > output\compiler.txt
其中 compiler
类似于 clang
或 gcc
或 g++
。请注意,此脚本会强制创建 output
目录。在我的系统上 运行ning 之后,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
事实证明,这些文件中有许多是相同的,但 clang
和 gcc
文件之间存在显着差异。
您应该有一个 .i 文件来定义您要生成的界面。
在那里你可以简单地使用#define __clang__
。
例如,查看我的库的 swig.i 文件 https://bitbucket.org/binarno/imebra/src/db648a8b9c359524d40fd7d63c785b6269147010/wrappers/swig.i?at=default
另请注意,swig 不需要所有编译器标志:它不会编译您的项目,而只会生成额外的 cxx 文件。在 .i 文件中,只需声明允许 swig select 正确 类 和方法的标志(如果需要)。