Mam dużą, mieszaną C/Fortran, bazę kodu, aktualnie kompilowaną przy użyciu narzędzi Intel w systemie Windows. Zostałem poproszony o przeniesienie go na narzędzia GNU, w systemie Linux. Mniej więcej losowo wybrałem wersję 4.8.Współdziałanie GNU Fortran i C
Jeżeli funkcja C jest wywoływana z Fortran, interoperacyjność często wygląda tak:
// C code:
void PRINTSTR(char *str, size_t len) {
for(int ii = 0; ii < len; ii++) {
putchar(str[ii]);
}
putchar('\n');
}
!Fortran code:
program test
implicit none
call printstr("Hello, world.")
end
Intel Fortran kompilator zawsze generuje symbole wielkich liter, tak to działa prawidłowo. Ale kompilator GNU Fortran zawsze generuje małe litery, a więc występuje błąd linkera.
Kompilator GNU Fortran miał opcję o nazwie -fcase-upper
, która powodowała generowanie wielkich liter, ale wydaje się, że była ona zbyt konfigurowalna dla dobra wszystkich osób i została usunięta (nie jestem dokładnie pewien kiedy).
Jest możliwe, aby skorzystać z możliwości ISO_C_BINDING
zmusić kompilator do wygenerowania wielkości liter nazwy:
program test
interface
subroutine printstr(str) bind(C, name='PRINTSTR')
character :: str(*)
end subroutine
end interface
call printstr("Hello, world.")
end
to rozwiąże błąd linkera ale zmienia jak parametry łańcuchowe są obsługiwane; parametr długości nie jest już dostępny. Aby użyć tej metody, nie musiałbym tylko dodawać definicji interfejsu dla każdej funkcji, która obecnie działa w ten sposób, ale musiałbym również zmienić sposób obsługi ciągów w każdym wywołaniu takiej funkcji, upewniając się, że wszystkie ciągi są zakończone znakiem NUL.
Mógłbym przejść przez wszystkie takie funkcje małymi literami, ale oczywiście kompilator Intela nadal generuje wielkie litery, aby złamać istniejącą kompilację.
Ponieważ istnieje ~ 2000 takich funkcji, wydaje się, że niewykonalna ilość pracy. Tak, moje pytanie jest następujące: Jak mogę rozwiązać błędy łącza bez zmiany semantyki funkcji połączenia i bez łamania istniejącej kompilacji przy użyciu kompilatorów Intel?
Obawiam się, że raczej większy problem będzie polegał na tym, że Intel podaje długość jako 'size_t', podczas gdy GFortran używa' int'. To jest w porządku na 32-bitowych, ale strasznie się psuje 64-bitowych systemów przechodzących więcej niż jeden ciąg na raz, a nawet nie zostanie złapany przez linker. –
Myślę, że, szczęśliwie, ucieknę z tym. Kompilacja Intela jest 32-bitowa. – Tom
Myślę (prawdopodobnie) kompilator, który miał '-fcase-upper' był g95, a nie GFortran (który jest teraz oficjalnym kompilatorem GNU Fortran). AFAIK g95 jest nadal rozwijany, choć w wolniejszym tempie niż GFortran, ale jeśli twoja baza kodów jest czysta F77/F95 i nie używa najnowocześniejszych funkcji F2003/F2008, może warto się przyjrzeć? –