Mi proyecto utiliza SCons para gestionar el proceso de construcción. Quiero admitir múltiples compiladores, así que decidí usar AddOption
para que el usuario pueda especificar qué compilador usar en la línea de comandos (siendo el valor predeterminado el compilador actual).Cómo determinar qué compilador se solicitó
AddOption('--compiler', dest = 'compiler', type = 'string', action = 'store', default = DefaultEnvironment()['CXX'], help = 'Name of the compiler to use.')
Quiero ser capaz de tener configuración del compilador incorporados para varios compiladores (incluyendo cosas tales como niveles máximos de advertencia para que el compilador particular). Esto es lo que mi primer intento de solución se ve actualmente como:
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
Sin embargo, no estoy seguro de qué hacer con el aspecto is_compiler()
función similar. Lo primero que pensé fue comparar directamente el nombre del compilador (como 'clang ++') con lo que pasa el usuario. Sin embargo, esto falló inmediatamente cuando traté de usar scons --compiler=~/data/llvm-3.1-obj/Release+Asserts/bin/clang++
.
Así que pensé que tendría un poco más inteligente y el uso de esta función
cxx = GetOption('compiler')
def is_compiler (compiler):
return cxx[-len(compiler):] == compiler
Esto sólo se ve al final de la cadena del compilador, por lo que ignora los directorios. Desafortunadamente, 'clang ++' termina en 'g ++', por lo que se vio que mi compilador era g ++ en lugar de clang ++.
Mi siguiente pensamiento fue hacer una búsqueda hacia atrás y buscar la primera aparición de un separador de ruta ('\' o '/'), pero luego me di cuenta de que esto no funcionaría para las personas que tienen múltiples versiones de compilación . Alguien que compila con 'g ++ - 4.7' no se registrará como g ++.
Entonces, ¿hay alguna forma sencilla de determinar qué compilador fue solicitado?
Actualmente, solo se admiten g ++ y clang ++ (y solo sus versiones más recientes) debido a su compatibilidad con C++ 11, por lo que una solución que solo funcione para esos dos sería lo suficientemente buena por ahora. Sin embargo, mi objetivo final es soportar al menos g ++, clang ++, icc y msvC++ (una vez que admiten las características requeridas de C++ 11), por lo que se prefieren soluciones más generales.
Yo separaría los dos problemas aquí. problema # 1) * qué * compilador se solicita y # 2) * donde * está localizado el compilador solicitado (para eso puede usar valores predeterminados razonables la mayor parte del tiempo y solo dejar que lo especifiquen si no quieren el clang predeterminado gcc/lo que sea). Las dos cosas no tienen mucho en común, después de todo, puedo crear fácilmente un enlace suave para clang que se llama 'msvc' si quisiera (en realidad nunca lo intenté, pero ¿por qué no?) – Voo
Estoy de acuerdo con la sugerencia que @Voo te dio . Edítalo para limitar a una pregunta y luego crea una nueva pregunta. Tienes dos buenas preguntas, por lo que subí la que creaste (hasta ahora). – octopusgrabbus
@Voo si lo escribe como una respuesta, lo aceptaré, ya que esa fue la idea clave que utilicé para resolver el problema. –