web-dev-qa-db-fra.com

Comment utiliser les modules C ++ dans Clang?

Les modules sont une alternative à #includes. Clang a une implémentation complète pour C++ . Comment pourrais-je faire si je voulais utiliser des modules en utilisant Clang maintenant?


En utilisant

import std.io;

dans un fichier source C++ ne fonctionne pas encore (compilation), car la spécification pour les modules (qui inclut la syntaxe) n'est pas définitive.


Le documentation de Clang indique que, lors du passage du -fmodules flag, #includes sera réécrit dans leurs importations appropriées. Cependant, la vérification du préprocesseur suggère le contraire (test.cpp contient uniquement #include <stdio.h> et un principal vide):

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

De plus, la compilation de ce fichier de test avec -fmodules vs aucun indicateur ne produit le même fichier objet.

Qu'est-ce que je fais mal?

30
xjcl

Comme vous l'avez mentionné, clang n'a pas encore de syntaxe C++ pour les importations, donc je doute que #include les directives vont être littéralement réécrites en tant qu'importations lors du prétraitement d'un fichier, ce qui n'est peut-être pas le meilleur moyen de tester si les modules fonctionnent comme prévu .

Cependant, si vous définissez -fmodules-cache-path=<path> explicitement, vous pouvez observer le clang le remplir avec des fichiers de module précompilés (* .pcm) pendant une construction - s'il y a des modules impliqués.

Vous devrez utiliser libc ++ (qui semble venir avec un module.modulemap à partir de la version 3.7.0) si vous souhaitez utiliser une bibliothèque standard activée par modules en ce moment - bien que d'après mon expérience, cela ne fonctionne pas entièrement pour l'instant. (Le compilateur C++ de Visual Studio 2015 est également censé obtenir une forme de prise en charge de module avec la mise à jour 1 en novembre)

Indépendamment de stdlib, vous pouvez toujours utiliser des modules dans votre propre code. Les docs contiennent une description détaillée du Module Map Language , mais j'ai également mis en place un petit exemple de projet ici (en utilisant cmake) qui devrait générer un cache répertoire avec certains modules lors de la construction.

12
melak47

Depuis ce commit , Clang a un support expérimental pour Modules TS .

Prenons les mêmes fichiers d'exemple (avec une petite modification) que dans le VS blog post sur le support du module expérimental.

Tout d'abord, définissez le fichier d'interface du module. Par défaut, Clang reconnaît les fichiers avec l'extension cppm (et quelques autres) en tant que fichiers d'interface du module 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;
} 

Notez que la déclaration d'interface du module doit être export module M; et pas seulement module M; comme dans le blog VS.

Consommez ensuite le module comme suit:

// file: bar.cpp
import M;

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

Maintenant, précompilez le module foo.cppm avec

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

ou, si l'extension de l'interface du module est autre que cppm (disons ixx, comme c'est le cas avec VS), vous pouvez utiliser:

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

Ensuite, créez le programme avec

clang++ -fmodules-ts -c M.pcm -o M.o
clang++ -fmodules-ts -fprebuilt-module-path=. M.o bar.cpp

ou, si le nom du fichier pcm n'est pas le même que le nom du module, vous devrez utiliser:

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

J'ai testé ces commandes sur Windows en utilisant build r30305 (15 mai 2017).

Remarque: lorsque vous utilisez le -fprebuilt-module-path=. option, je reçois un avertissement:

clang ++. exe: avertissement: argument non utilisé lors de la compilation: '-fprebuilt-module-path =.' [-Wunused-command-line-argument]

ce qui semble être incorrect car sans cette option, le module M est introuvable.

25
Smi