2017-09-19 3 views
0

Ich versuche, die Interface-Dateien für ein großes C++ - Projekt mit Swig zu generieren. Die Header-Dateien für das Projekt tun einige Kontrollen auf der Grundlage der Compiler-Typ, zum BeispielSetzen von Compiler-Flags für Swig

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

Also muss ich die Compiler-Flags übergeben Swig. Insbesondere scheint es mir, dass ich so swig nennen sollte:

swig -D__clang__ ... 

Dies ist jedoch nicht die Fehlermeldungen zu lindern scheint erhalte ich, da ich immer noch die gleichen Fehler bekommen.

Es ist mir nicht klar, wenn ich die Compiler-Flags falsch einstelle, oder ob ich nicht alle Compiler-Flags setze. Die Frage ist also eine doppelte:

  1. Bin ich die Compiler-Flags korrekt

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

oder sollte ich irgendwie definieren diese Parameter in der Schnittstellendatei xxx.i?

  1. Wie kann man alle Compiler-Flags erfassen? Ich kann sicherlich den C++ - Code auf meinem Rechner kompilieren, aber woher weiß ich, welche Makros vom Compiler gesetzt werden? Gibt es einen allgemeinen Weg, dies zu tun?
+0

Hängt der Compiler ab, welcher Compiler? –

+0

Im Moment versuche ich etwas für Android zu kompilieren, also benutze ich einen clang Prozessor. Aber ich glaube, dass es einige andere Flags setzt, und ich sehe es nicht dokumentiert, welche Flags es verwendet –

+0

Ich frage mich, ob es eine einfache 10-Zeilen-C++ - Datei gibt, die ich schreibe, die alle Compiler-Makros ausdrucken wird. Die Idee ist, dass ich diese einfache Testdatei mit dem Compiler kompilieren würde, den ich verwenden möchte, dann die Flags abholen und diese in Swig –

Antwort

0

Richard hat Recht. Die meisten Compiler scheinen den -dM Befehl zu unterstützen (mindestens clang und gcc scheinen). In meinem Fall wollte ich sehen, welche Preprozessor-Makros vom Android-Build-System festgelegt wurden. Dies ist ein wenig kompliziert, da das Android NDK viele Compiler hat, die alle etwas anders aufgebaut sind. Deshalb habe ich die folgende Python 3 Skript erstellt das gesamte Makro zu speichern Datei beinhaltet:

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) 

Wenn Sie diese Datei „introspect.py“ nennen, dann ist die Nutzung einfach

python introspect.py 

Was Skript ist für alle *.exe Dateien (ändern Sie dies für Linux-Systeme) im root Verzeichnis (auf meinem System C:\\Android\\android-sdk\\ndk-bundle\\toolchains\\), die den Compiler irgendwo enthalten sollte. Insbesondere wird dieses Skript sucht alle ausführbaren Dateien mit einem der Begriffe

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

im Namen, Dateien ohne mit

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

im Namen. Schließlich wird jede der gefundenen ausführbaren Dateien dann im Format läuft

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

wo compiler etwas sein wird, wie clang oder gcc oder g++. Beachten Sie, dass dieses Skript die Erstellung des Verzeichnisses output erzwingt.Nach dem Ausführen auf meinem System enthält das output Verzeichnis der Dateien (Warnung: Es gibt wirklich eine Menge Compiler durch die NDK verfügbar):

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 

wo die ersten Zeilen dieser Dateien wie

aussehen neigen
#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 

Es stellt sich heraus, dass viele dieser Dateien identisch sind, aber es gibt signifikante Unterschiede zwischen den clang und gcc Dateien.

0

Sie sollten eine .i-Datei haben, die die Schnittstelle definiert, die Sie generieren möchten.

Dort können Sie einfach #define __clang__ verwenden.

Nehmen Sie zum Beispiel einen Blick auf eine swig.i Datei für eine Bibliothek von mir https://bitbucket.org/binarno/imebra/src/db648a8b9c359524d40fd7d63c785b6269147010/wrappers/swig.i?at=default

auch, dass die swig beachten nicht alle Compiler-Flags müssen: es wird nicht Ihr Projekt kompilieren, aber es wird nur erzeuge die zusätzlichen cxx-Dateien. In der .i-Datei deklarieren Sie einfach das Flag (falls erforderlich), das es swig ermöglicht, die richtigen Klassen und Methoden auszuwählen.