2012-08-14 12 views
5

W kontekście mieszanej aplikacji C/Fortran, czy istnieje sposób sprawdzenia, czy kompilator zna "iso_c_binding" (na przykład GCC 4.1.2 tego nie zna, podczas gdy 4.3.4), podobnie jak dyrektywa w sprawie wstępnego przetwarzania czy coś takiego? Nie mogę sobie pozwolić na proste sprawdzenie wersji GCC, ponieważ mogę używać innych kompilatorów.Sprawdź, czy iso_c_binding jest dostępne w czasie kompilacji

Dzięki

+0

Sprawdź, czy '#ifdef iso_c_binding' itp działa ... –

+3

kompilacji prostego programu, który używa rzeczy, które trzeba od' ISO_C_BINDING'. Jeśli kompiluje się i działa, możesz dołączyć definicję symbolu preprocesora do pliku nagłówkowego konfiguracji. Wykonaj tę część procedury budowania kodu. W ten sposób GNU 'autoconf' robi to w skryptach' configure'. –

+0

Czy można zrobić coś takiego z CMake? – sunmat

Odpowiedz

2

Twoim jedynym dwóch opcji, że mogę myśleć, mają toczyć własną wersję iso_c_binding dla systemów, które nie mają tego modułu (as suggested by @HighPerformanceMark) lub do wykorzystania preprocesory warunkowo skompilować fragmenty kodu w zależności od wersji kompilatora. W obu przypadkach będziesz musiał pracować, aby twój kod był przenośny w różnych systemach. Zgodnie z sugestią @HighPerformanceMark możesz skopiować i wkleić implementację open source o numerze iso_c_binding, ale w przypadku każdego nowego systemu, do którego należy twój kod, musisz sprawdzić, czy ta implementacja jest poprawna.

W zależności od tego, jak chcesz zachować kod, jeśli iso_c_binding jest nie dostępny, zalecam użycie metody preprocesora. Twierdzisz, że "nie mogę sobie pozwolić na proste sprawdzenie wersji GCC, ponieważ mogę używać innych kompilatorów". Jednak wszystkie twoje opcje będą wymagały pracy z twojej strony, aby utrzymać twój kod do użytku w różnych systemach, metoda preprocesora wymaga, moim zdaniem, najmniejszej ilości pracy.

Poniższy kod określa wersję kompilatora za pomocą preprocesora i może być używany do warunkowego kompilowania kodu w zależności od tego, czy wersje kompilatora spełniają pewną minimalną wersję. Dla gfortran:

Jeśli GNU Fortran wywołuje preprocesor, __GFORTRAN__ jest zdefiniowany i __GNUC__, __GNUC_MINOR__ i __GNUC_PATCHLEVEL__ mogą być wykorzystane do ustalenia wersji kompilatora.

W pliku, na przykład precomp.inc, powinienem dołączyć wiele sprawdzeń prekompilatora, które określają, które funkcje mają zawierać kod. Na przykład sprawdziłbym wersję kompilatora i, jeśli obsługuje on moduł iso_c_binding, zdefiniowałbym makro preprocesora HAS_ISO_C_BINDING (lub podobnego). Plik precomp.inc można następnie dołączyć do innych części kodu. Ten plik może wyglądać następująco:

!> \file precomp.inc 
!! Preprocessor feature detection. 

#if defined(__GFORTRAN__) 

#if __GNUC__ >= 4 && __GNUC_MINOR__ >= 3 
#define HAS_ISO_C_BINDING 1 
#else 
#define HAS_ISO_C_BINDING 0 
#endif 

#elif defined(__INTEL_COMPILER) 
#error "I haven't implemented this yet..." 

#else 
#error "Compiler not yet supported." 

#endif 

błąd w końcowej #else klauzuli można zastąpić HAS_ISO_C_BINDING=0, jeśli chcesz być w stanie skompilować bez wsparcia dla modułu iso_c_binding.

Twoje źródło Fortran będzie wyglądać

program main 

#include 'precomp.h' 
#if HAS_ISO_C_BINDING 
use iso_c_binding 
#endif 

implicit none 

! Some code... 

#if HAS_ISO_C_BINDING 
! Code which depends on iso_c_binding 
#else 
! Fallback code 
#end if 

! Some more code... 

end program main 

Ponownie, prawo metoda, zależy od tego jak chcesz kod do kompilowania jeśli iso_c_binding nie jest dostarczony. Jeśli Twój kod wymaga kompilacji w systemach bez tego modułu, to odpowiedź @ HighPerformanceMark jest prawdopodobnie lepsza. Jeśli możesz po prostu zwiększyć błąd w czasie kompilacji lub jeśli masz kod zastępczy, jeśli nie jest dostępny iso_c_binding, użyłbym tej metody preprocesora, ponieważ wymaga to tylko jednego dodatkowego sprawdzenia, aby dodać każdy nowy kompilator, którego potrzebujesz.

+0

Whoa there matey. konkretnie NIE sugerowało to kopiowania źródeł Intel Fortran dla "iso_c_binding", ponieważ mogłoby to stanowić naruszenie praw własności intelektualnej Intela, co może być niezgodne z prawem lub niezgodne z warunkami umowy, którą moi pracodawcy mają z firmą Intel w zakresie dostarczania oprogramowania. Wdrożenie open-source tego modułu. Zmieniłem twoje pytanie, by usunąć twoje oszczercze stwierdzenie. –

+0

Wystarczająco sprawiedliwe - przepraszam s za to. – Chris

0

Pytanie jest błędne. Praktycznie pytasz, czy towarzysz procesor Fortran (zakładając, że istnieje) obsługuje niezbędne aspekty interoperacyjności C, której twój program C tego wymaga.Interoperacyjność C ma o wiele więcej niż tylko obecność wewnętrznego modułu.

Na przykład, całkiem uzasadnione jest, aby procesor F2003 dostarczał ISO_C_BINDING, który następnie mówi, że prawie wszystkie aspekty interoperacyjności C nie są obsługiwane (stałe takie jak C_FLOAT, C_REAL, itd., Mogą mieć wartość ujemną, co oznacza "nie utrzymany").

Więc chyba że użycie C interoperacyjności jest bardzo podstawowe (istnieją pewne aspekty, które muszą być obsługiwane przez procesor F2003 - takie jak C_INT, C_LOC, C_F_POINTER, etc) Jedynym praktycznych sposobów dla stwierdzenia możliwości są:

  • Aby skompilować mały program, który Fortran jawnie użyć jest wymagane podmioty i testuje ich wartości (różne liczby ujemne wyjaśnić dlaczego procesor Fortran nie zapewnia wsparcia). Jak napisali inni, sukces lub niepowodzenie kompilacji, a być może i kolejne wyniki programu, jeśli kompilacja się powiedzie, mogą być następnie użyte do skonfigurowania innych aspektów twojej kompilacji.

  • Aby przeczytać Podręcznik procesora Fortran.

Powiązane problemy