2017-02-13 27 views
1

Я передал переменную CC, которая содержит исполняемый файл, который ссылается на компилятор в системе. Мне нужно взять этот исполняемый файл и в конечном итоге вызвать его с некоторыми аргументами ссылки на компилятор.Определить компилятор и использовать флаги, специфичные для компилятора, при вызове

Мой текущий подход кажется очень хрупким:

def guess_compiler(cc): 
    out = subprocess.check_output((cc, '--version')) 
    for possible in (b'clang', b'gcc'): 
     if possible in out: 
      return possible.decode() 
    else: 
     # Fall back to gcc 
     return 'gcc' 

Из этого я использую отображение конкретных аргументов компоновщика я забочусь о:

return { 
    'clang': '-Wl,-undefined,dynamic_lookup', 
    'gcc': '-Wl,--unresolved-symbols=ignore-all', 
}[cc] 

Короче говоря, я надеюсь, что есть лучший (менее хрупкий) способ сделать то, что я сделал.

Для тех, кто ищет, почему я хочу что-то вроде этого, в основном для переносимости в a project I'm implementing.

ответ

1

Я бы скорее позвонил компилятору с каким-то фиктивным кодом, и эти флаги прошли. Это также инструменты, такие как Autotools и CMake.

Проблема с вашим текущим подходом заключается в том, что текстовая строка, которую вы видите в --version, может фактически быть произвольной. Например, когда лязг не был так популярен, FreeBSD-х cc --version давали

GCC 4.2.1 -Совместим Clang бла бла

Так, просто вызовите компилятор с каждым флагом вы заинтересованы в а затем посмотрите на код выхода.

Пример того, как сделать это:

for flag in FLAGS: 
    try: 
     subprocess.check_call((cc, 'test.c', flag), cwd=tmpdir) 
     return flag 
    except subprocess.CalledProcessError: 
     pass 
else: 
    # wellp, none of them worked, fall back to gcc and they'll get a 
    # hopefully reasonable error message 
    return FLAG_GCC 
+0

Отредактировано с тем, что я попытался пойти с :) –