2015-10-23 16 views
26

Moduły są alternatywą dla #includes. Clang has a complete implementation for C++. W jaki sposób chciałbym przejść, jeśli chcę teraz używać modułów przy użyciu Clanga?Jak używać modułów C++ w Clang?


Stosując

import std.io; 

w C++ pliku źródłowego nie działa (kompilacji), jednak, jak w opisie dla modułów (który zawiera składni) nie jest ostateczny.


W Clang documentation stwierdza, że ​​przy przejściu flagę -fmodules, właczoną zostaną przepisane do ich odpowiednich importu. Jednak sprawdzanie preprocesor sugeruje inaczej (test.cpp zawiera tylko #include <stdio.h> i pusty główny):

$ clang++-3.5 -fmodules -E test.cpp -o test 
$ grep " printf " test 
extern int printf (const char *__restrict __format, ...); 

Ponadto kompilacji tego pliku testowego z -fmodules vs flagi w ogóle nie produkuje ten sam plik obiektowy.

Co robię źle?

Odpowiedz

11

Jak wspomniałeś, dzyń nie ma jeszcze C++ składni dla importu, więc wątpię, że #include dyrektyw będą dosłownie przepisany jako import gdy przerób plik, tak że nie może być najlepszym sposobem na sprawdzić, czy moduły działają zgodnie z przeznaczeniem.

Jeśli jednak ustawisz jawnie -fmodules-cache-path=<path>, możesz obserwować, jak clang wypełnia go skompilowanymi plikami modułów (* .pcm) podczas kompilacji - jeśli są jakieś moduły.

Musisz użyć biblioteki libC++ (która wydaje się pochodzić z module.modulemap od wersji 3.7.0), jeśli chcesz korzystać teraz z biblioteki standardowej z włączoną obsługą modułów - choć z mojego doświadczenia to nie działa całkowicie jeszcze. (Kompilator C++ programu Visual Studio 2015 ma również otrzymać wsparcie modułu z aktualizacją 1 w listopadzie)

Niezależnie od stdlib, nadal można używać modułów we własnym kodzie. Dokumenty docs zawierają szczegółowy opis Module Map Language, ale także utworzyłem mały przykładowy projekt here (przy użyciu cmake), który powinien wygenerować katalog cache z niektórymi modułami, gdy jest zbudowany.

14

Od this commit, Clang ma eksperymentalne wsparcie dla Modules TS.

Weźmy te same przykładowe pliki (z małą zmianą), jak w przypadku VS blog post o obsłudze modułów eksperymentalnych.

Najpierw zdefiniuj plik interfejsu modułu. Domyślnie Clang rozpoznaje pliki z rozszerzeniem cppm (i niektórymi innymi) jako pliki interfejsu modułu C++.

// file: foo.cppm 
export module M; 

export int f(int x) 
{ 
    return 2 + x; 
} 
export double g(double y, int z) 
{ 
    return y * z; 
} 

Zauważ, że deklaracja interfejs modułu musi być export module M; a nie tylko module M; jak w blogu VS.

Następnie zużywają moduł następująco:

// file: bar.cpp 
import M; 

int main() 
{ 
    f(5); 
    g(0.0, 1); 
    return 0; 
} 

Teraz precompile moduł foo.cppm z

clang++ -fmodules-ts --precompile foo.cppm -o M.pcm 

lub, jeśli rozszerzenie interfejsu moduł jest inny niż cppm (powiedzmy ixx, ponieważ jest z VS), możesz użyć:

clang++ -fmodules-ts --precompile -x c++-module foo.ixx -o M.pcm 

Następnie zbudować program z

clang++ -fmodules-ts -fprebuilt-module-path=. bar.cpp 

lub, jeśli nazwa pliku PCM nie jest taka sama jak nazwa modułu, trzeba by użyć:

clang++ -fmodules-ts -fmodule-file=M.pcm bar.cpp 

Przetestowałem te polecenia na Windows używający r303050 build (15 maja 2017 r.).

Uwaga: W przypadku korzystania z opcji -fprebuilt-module-path=., pojawia się ostrzeżenie:

szczęk ++. Exe ostrzegawczy: argumentu niewykorzystane podczas kompilacji: '-fprebuilt-module-path ='. [-Wunused-argument-wiersza polecenia]

, który wydaje się niepoprawny, ponieważ bez tej opcji nie można znaleźć modułu M.

+2

Działa to również z Xcode 9. –