简体   繁体   中英

Setting compiler flags for Swig

I am trying to generate the interface files for a large C++ project using Swig. The header files for the project do some checking based on the compiler type, for instance,

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

So I have to pass the compiler flags to Swig. Specifically, it seems to me that I should call swig like this:

swig -D__clang__ ... 

However, this does not seem to alleviate the error messages I am getting, since I still get the same errors.

It is not clear to me if I am setting the compiler flags incorrectly, or whether I am not setting all of the compiler flags. So the question is twofold:

  1. Am I setting the compiler flag correctly by calling

    swig -D__clang__ ...... xxx.i

or should I somehow define these parameters in the xxx.i interface file?

  1. How does one go about capturing all of the compiler flags? I can certainly compile the C++ code on my machine, but how do I know which macros are getting set by the compiler? Is there a general way to do this?

Richard is correct. Most compilers seem to support the -dM command (at least clang and gcc seem to). In my case, I wanted to see which preprocessor macros were set by the Android build system. This is a little bit complicated since the Android NDK has many compilers, all built slightly differently. Therefore, I created the following python 3 script to save all of the macro includes to file:

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 )

If you call this file "introspect.py", then usage is simply

python introspect.py

What this script does is to look for all of the *.exe files (change this for linux systems) in the root directory (on my system C:\\\\Android\\\\android-sdk\\\\ndk-bundle\\\\toolchains\\\\ ) which should contain the compiler somewhere. Specifically, this script will look for all executables with one of the terms

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

in the name, excluding files with

[ "-ar", "-nm", "-ranlib", "filt", "-format", "-tidy" ] 

in the name. Finally, each of the found executables is then run in the format

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

where compiler will be something like clang or gcc or g++ . Note that this script forces the creation of the output directory. After running on my system, the output directory contains the files (warning: there really are a lot of compilers available through the 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

where the first few lines of those files tend to look like

#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

It turns out that many of these files are identical, but there are significant differences between the clang and gcc files.

You should have a .i file that defines the interface that you want to generate.

There you can simply use #define __clang__ .

For instance, take a look at a swig.i file for a library of mine https://bitbucket.org/binarno/imebra/src/db648a8b9c359524d40fd7d63c785b6269147010/wrappers/swig.i?at=default

Also note that swig does not need all the compiler flags: it is not going to compile your project but it will just generate the additional cxx files. In the .i file just declare the flag (if needed) that allows swig to select the correct classes and method.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM