Mój projekt używa SCons do zarządzania procesem kompilacji. Chcę obsługiwać wiele kompilatorów, dlatego postanowiłem użyć AddOption
, aby użytkownik mógł określić, który kompilator ma być używany w wierszu poleceń (domyślnie jest to, co jest ich aktualnym kompilatorem).Jak ustalić, który kompilator był wymagany?
AddOption('--compiler', dest = 'compiler', type = 'string', action = 'store', default = DefaultEnvironment()['CXX'], help = 'Name of the compiler to use.')
Chcę móc mieć wbudowane ustawienia kompilatora dla różnych kompilatorów (w tym takie rzeczy jak najwyższych dopuszczalnych poziomów ostrzegawczych dla tego konkretnego kompilatora). To właśnie moja pierwsza próba rozwiązania obecnie wygląda następująco:
if is_compiler('g++'):
from build_scripts.gcc.std import cxx_std
from build_scripts.gcc.warnings import warnings, warnings_debug, warnings_optimized
from build_scripts.gcc.optimizations import optimizations, preprocessor_optimizations, linker_optimizations
elif is_compiler('clang++'):
from build_scripts.clang.std import cxx_std
from build_scripts.clang.warnings import warnings, warnings_debug, warnings_optimized
from build_scripts.clang.optimizations import optimizations, preprocessor_optimizations, linker_optimizations
Jednak nie jestem pewien, co do wyglądu is_compiler()
działają jak. Moja pierwsza myśl polegała na bezpośrednim porównywaniu nazwy kompilatora (na przykład "clang ++") z tym, co podaje użytkownik. Jednak natychmiast to się nie powiodło, gdy próbowałem użyć scons --compiler=~/data/llvm-3.1-obj/Release+Asserts/bin/clang++
.
Więc pomyślałem, że trochę mądrzejszy i używać tej funkcji
cxx = GetOption('compiler')
def is_compiler (compiler):
return cxx[-len(compiler):] == compiler
To tylko wygląda na końcu łańcucha kompilatora, tak że ignoruje katalogów. Niestety "clang ++" kończy się na 'g ++', więc mój kompilator był postrzegany jako g ++ zamiast clang ++.
Moja następna myśl polegała na wyszukiwaniu wstecznym i wyszukaniu pierwszego wystąpienia separatora ścieżek ("\" lub "/"), ale wtedy zdałem sobie sprawę, że to nie zadziała dla osób, które mają wiele wersji kompilatora . Ktoś kompilujący się z "g ++ - 4.7" nie zarejestruje się jako g ++.
Czy istnieje prosty sposób ustalenia, który kompilator został zamówiony?
Obecnie tylko g ++ i clang ++ są obsługiwane (i tylko ich ostatnio wydane wersje) ze względu na obsługę C++ 11, więc rozwiązanie, które działa tylko dla tych dwóch, byłoby na razie wystarczająco dobre. Jednak moim ostatecznym celem jest wspieranie co najmniej g ++, clang ++, icc i msvC++ (gdy obsługują wymagane funkcje C++ 11), dlatego preferowane są bardziej ogólne rozwiązania.
Oddzielę te dwa problemy tutaj. problem # 1) * który * kompilator jest żądany i # 2) * gdzie * znajduje się żądany kompilator (domyślnie możesz używać rozsądnych wartości domyślnych i pozwolić im je określić, jeśli nie chcą domyślnego języka/gcc/cokolwiek). Te dwie rzeczy nie mają ze sobą wiele wspólnego, w końcu mogę z łatwością utworzyć miękki link do dzwonka, który nazywa się 'msvc', jeśli chcę (właściwie nigdy nie próbował, ale dlaczego nie?) – Voo
Zgadzam się z sugestią @Voo . Edytuj, aby zawęzić do jednego pytania, a następnie utwórz nowe pytanie. Masz dwa dobre pytania, dlatego też przegłosowałem ten, który stworzyłeś (do tej pory). – octopusgrabbus
@Voo, jeśli napiszesz to jako odpowiedź, przyjmuję to, ponieważ to był kluczowy wgląd, którego użyłem do rozwiązania problemu. –