2016-03-18 2 views
2

Je change de base de code en utilisant msvc pour clanger un produit Windows. Si je construis un petit programme de test en utilisant clang sur windows, il construit, relie et fonctionne très bien, mais si je construis une librairie à partir de notre produit qui utilise un intrinsèque, apparaît comme un symbole manquant.Problèmes liant les intrinsèques de msvc en utilisant clang sur les fenêtres

J'ai essayé de compiler à la fois le code de test et notre produit en utilisant l'option --verbose et je ne peux rien voir de différent entre les deux. La seule différence dans la façon dont ils sont appelés est que le grand produit est construit en utilisant fastbuild ce qui nécessite l'utilisation de -c pour empêcher le compilateur d'appeler aussi le linker. Clang ajoute évidemment dans certaines bibliothèques qui manquent quand j'appelle l'éditeur de liens manuellement moi-même, donc quelqu'un peut-il me dire ce qu'ils pourraient être? (Je suis déjà en train de créer un lien dans la librairie crt (libcmt, msvcrt) donc ce n'est pas ça

J'ai commencé à écrire ma propre bibliothèque d'intrinsèques en assemblage, ce qui est amusant, mais ne devrait pas être nécessaire.

Selon la demande, la compilation du code ci-dessous avec clang fonctionne en utilisant directement, c.-à-clang IntrinsicsTest.cpp produit un exe

IntrinsicsTest.cpp 
#include "stdio.h" 
#include "intrin.h" 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    unsigned long long r = __rdtsc(); 
    printf("Intrinsic: %llu\n", r); 
} 

échoue pourtant à relier un appel par FastBuild:. FBuild.exe -showcmds -clean IntrinsicsTest_debug_x86

clang.exe "\ IntrinsicsTest.cpp" -D_WINDOWS -c -m32 -mfpmath = sse -D_UNICODE -DUNICODE -fno-RTTI -fexceptions -E ... \ IntrinsicsTest.debug.Win32.lib

lib .exe/NOLOGO /OUT:"...IntrinsicsTest.debug.Win32.lib "" ... \ IntrinsicsTest.obj "... \ IntrinsicsTest.debug.Win32.exe

link.exe/NOLOGO/INCREMENTAL: NON /OUT:"...IntrinsicsTest.debug.Win32.exe "" ... \ IntrinsicsTest.obj "-defaultlib: libcmt.lib -INCREMENTAL -MANIFEST/MACHINE: X86/SUBSYSTEM: CONSOLE/OPT: NOICF/OPT: NOREF

IntrinsicsTest.obj: erreur LNK2019: symbole externe non résolu ___rdtsc référencé dans la fonction _wmain ... \ IntrinsicsTest.debug.Win32.exe

LNK1120 erreur fatale: 1 unresolved externals

+2

Les variables intrinsèques sont généralement des extensions de compilateur, et non standard, elles dépendent donc du compilateur. –

+0

Utilisez-vous clang-cl? mingw-w64 clang? MS clang/C2? – melak47

+0

"Clang --version" me donne: 'clang la version 3.8.0 (branches/release_38) Cible: x86_64-pc-windows-msvc modèle Discussion: posix InstalledDir: C: \ Program Files \ LLVM \ bin' – Teknogrebo

Répondre

3

J'ai résolu le problème.Il y avait plusieurs facteurs qui contribuaient à la façon dont fastbuild, clang et msvc interagissaient. A/Avec Clang sous Windows, il n'est pas nécessaire de spécifier "système" inclut. Dans notre projet, nous avons eu les chemins d'exemple:

-I"C:/Program Files/LLVM/lib/clang/3.8.0/include" 
-I"C:/Program Files (x86)/Microsoft Visual Studio 12.0/VC/include/" 
-I"C:/Program Files (x86)/Microsoft Visual Studio 12.0/VC/atlmfc/include" 
-I"C:/Program Files (x86)/Windows Kits/8.1/include/um" 
-I"C:/Program Files (x86)/Windows Kits/8.1/include/shared" 
-I"C:/Program Files (x86)/Windows Kits/8.1/include/winrt" 

La version clang de la ligne xmmintrin déclare de intrinsics et donc si cet en-tête est utilisé, alors le programme de test compile très bien. Le Windows xmmintrin déclare les intrinsèques comme des fonctions externes, d'où le programme compile, mais ne lie pas - où une construction msvc obtient ces symboles à partir de maintenant n'est plus pertinent.

Cependant, même avec le chemin d'inclusion clang en premier, lorsque <intrin.h> est inclus par quelque chose, il tire dans l'en-tête de la fenêtre. B/Fastbuild vous permet de configurer des variables d'environnement pour l'environnement de construction. Nos scripts ont INCLUDE et PATH définis avec les chemins msvc. Enlever ceux-ci a aidé.

c/En plus de clang, j'ai plusieurs versions de msvc installées sur ma machine. Clang prenait MSVC14 alors que fastbuild essayait d'obtenir clang pour utiliser MSVC 12. En changeant fastbuild pour utiliser MSVC14 j'ai finalement réussi à surmonter le problème avec les intrinsèques.

+0

Ah, ça explique en partie pourquoi des en-têtes avec juste des prototypes peuvent exister pour des choses qui sont supposées être intrinsèques. Les prototypes peuvent aider les IDEs et d'autres choses, mais probablement le compilateur MSVC lui-même a déjà des définitions intégrées internes de la façon dont gcc/clang a prédéfini '__builtin_XYZ'. –

1

Intrinsics ne sont pas censés être des appels de fonction, ils sont censés inline à un ou instructions de couple. Ou dans certains cas, aucune instruction (par exemple une barrière de mémoire du compilateur, comme std::atomic_signal_fence de C++).

MSVC et GNU C sont des arômes distincts de C. clang implémente GNU C, et AFAIK ne prend pas en charge les intrinsèques MSVC.

Lorsqu'il existe un GNU C __builtin_something équivalent à un MSVC intrinsèque, utilisez-le via une fonction wrapper. Mingw-w64 prend apparemment en charge _Interlocked???, via <winnt.h>

This mailing list post est un correctif qui est passé de l'implémentation en ligne aux fonctions GNU C __sync_fetch_and_???. IDK si c'est livré avec MINGW actuel, ou s'il y a une version MINGW de clang. Mais c'est ce que vous devriez rechercher. Je suis sûr que vous n'êtes pas la première personne à vouloir compiler une base de code MSVC en utilisant un compilateur différent.

+3

Clang sur Windows expédie son propre '' avec beaucoup de intrinsèques MSVC. Certains sont implémentés directement, d'autres sont mappés sur les intrinsèques LLVM (y compris la famille '_Interlocked ???'), et d'autres sont juste déclarés (pas sûr que les définitions de ces bibliothèques soient dans une bibliothèque ou non). – melak47

+0

Merci pour vos réponses, mais cela ne tient pas compte de l'essentiel de ma question. Clang sur Windows compile les intrinsèques msvc très bien car ils sont inclus dans son intrin.h. Cependant, si je les relie manuellement, ils apparaissent comme des symboles manquants. @ melak47 C'est aussi mon hypothèse que la définition est dans une bibliothèque, mais je ne peux pas trouver le nom de cette bibliothèque. – Teknogrebo

+0

@Teknogrebo: Avec quels problèmes avez-vous un problème? Comme je l'ai dit au premier paragraphe, la plupart devraient être en ligne au moment de la compilation, de sorte que l'éditeur de liens ne fait pas partie de l'image. S'il y a un problème de temps de liaison, cela signifie que vous n'obtenez pas de définitions intégrées intégrées/intégrées pour elles. Peut-être éditer votre question avec un exemple minimal d'une fonction qui se construit bien dans un exécutable autonome mais pas comme une bibliothèque? Cela semble être ce que vous voulez dire. –