web-dev-qa-db-fra.com

Clang C ++ Cross Compiler - Génération d'un exécutable Windows à partir de Mac OS X

J'ai créé une application C++ en utilisant Xcode sur mon Mac en utilisant le compilateur Clang.

Je veux compiler mes fichiers source pour créer un exécutable qui peut être exécuté sur une machine Windows, mais je ne peux pas obtenir Clang pour me générer un exécutable.

Voici ce que j'ai essayé:

clang++ -std=c++11 -stdlib=libc++ -Arch x86_64 class1.cpp class2.cpp... -o executable.exe

Cela crée un exécutable mais cela ne fonctionne pas (Windows me donne une erreur à faire avec l'application étant 16 bits - ne comprends pas cela - qui ne peut pas fonctionner sur 64 bits)

clang++ -std=c++11 -stdlib=libc++ -target i386-pc-win32 class1.cpp class2.cpp 

Pour une raison quelconque, chaque fois que j'utilise le -target flag J'obtiens une erreur indiquant que le compilateur ne peut pas trouver le <iostream> header mais à tout autre moment, il ne gémit jamais.
J'ai essayé d'utiliser -Ipath/to/iostreamfolder/ mais cela ne donne pas de meilleurs résultats

Toute suggestion sera appréciée! Merci!

J'ai aussi essayé le '-triple x86-pc-win32' flag mais je reçois cet avertissement clang: warning: argument unused during compilation: '-triple x86-pc-win32'

29
gavlaaaaaaaa

Clang peut en principe être utilisé comme compilateur croisé: contrairement à la plupart des compilateurs, clang/LLVM inclut des composants (tels que le codegen, l'assembleur et l'éditeur de liens) pour différentes plates-formes dans le même binaire.

Cependant, vous rencontrerez un certain nombre de problèmes en essayant de l'utiliser en tant que tel dans une capacité de production:

  • Vous avez besoin de bibliothèques de plates-formes et d'en-têtes. Pour générer un exécutable qui fonctionnera sous Windows, vous avez besoin des en-têtes Windows et des bibliothèques Windows que vous souhaitez lier, importez des bibliothèques si vous liez dynamiquement ou des bibliothèques statiques pour la liaison statique. Vous devriez pouvoir les obtenir à partir d'une installation de Visual Studio.

  • De nombreuses fonctionnalités C++ telles que le changement de nom et la prise en charge RTTI ne sont pas complètes sous Windows. Vous auriez ces mêmes problèmes de compilation pour Windows sur Windows avec Clang. Le support de Windows C++ est à peu près complet de nos jours.

  • Le projet LLVM inclut l'éditeur de liens lld, qui est apparemment suffisamment avancé pour pouvoir s'auto-héberger sur Windows x86 et pourrait donc fonctionner pour vous en tant qu'éditeur de liens multiplateforme, mais lld n'est pas encore une partie standard des distributions de clang. Clang sous OS X utilise toujours l'éditeur de liens de la plate-forme OS X ld par défaut, tout comme Clang sous Windows (link.exe). Vous devrez obtenir lld et comprendre comment vous connecter avec lui, ou trouver un autre éditeur de liens multiplateforme.

  • Le pilote clang n'est pas écrit en tant que pilote de compilateur multiplateforme. Vous devrez probablement faire beaucoup plus de travaux pratiques pour exécuter une compilation multiplateforme. Jetez un œil à la sortie de clang -###: le pilote clang construit cette commande pour vous, mais vous devrez peut-être faire à peu près le même travail que le pilote clang à la main. Et puisque clang obtient beaucoup moins de tests lors de la compilation multiplateforme, vous risquez de rencontrer plus de bogues.

  • Xcode ne va pas vous aider avec tout cela. Il peut configurer clang pour construire pour OS X ou iOS, mais vous devrez configurer manuellement les builds multiplateformes sur Windows.

Je suis relativement confiant que l'on pourrait bricoler un environnement basé sur LLVM pour construire un exe Windows C "Hello, World" sur OS X ou Linux, mais il n'est pas tout à fait prêt pour Xcode d'ajouter un élément "Windows" à la liste des possibles plates-formes cibles.


Si vous n'êtes pas un développeur de compilateur, il vaut probablement mieux copier votre code source sur une machine Windows et créer avec Visual Studio. Si vous êtes ou souhaitez être un développeur de compilateur, aidez par tous les moyens à pousser les capacités de compilation croisée de Clang vers l'avant. Je pense que le projet Clang pilote universel est passionnant et j'aimerais vraiment que les progrès continuent.


J'ai réussi la compilation croisée inverse: compiler un exécutable Mac OS X sous Windows. Cela s'est avéré assez facile à faire manuellement sur un petit programme, c'est-à-dire à compiler directement un fichier .cpp.

Premièrement, les outils de développement Mac OS X sont livrés avec des "SDK" qui contiennent toutes les bibliothèques système et les en-têtes pour un système d'exploitation particulier. Le plus grand défi ici était de savoir comment transférer le SDK vers Windows tout en préservant tous les liens symboliques dans le SDK. (Pour une raison quelconque, la création de liens symboliques sous Windows nécessite des privilèges élevés, donc après avoir produit un tar.gz sur OS X avec les liens symboliques, j'ai dû exécuter 7Zip sous Windows en tant qu'administrateur pour développer correctement l'archive.)

Une fois que le SDK est disponible sur Windows, un seul indicateur indique à clang où trouver toutes les dépendances du système: -isysroot. Ceci combiné avec le -target flag était tout ce dont j'avais besoin pour dire à clang comment produire des fichiers objets complets pour OS X.

Pour la liaison, j'ai utilisé manuellement lld, car le pilote du compilateur ne semblait pas prendre en charge l'utilisation de la liaison croisée avec lld. lld prend en charge des indicateurs similaires pour déterminer les bibliothèques du système cible.

La dernière étape consistait simplement à copier l'exécutable produit sur une machine OS X, à activer l'autorisation d'exécution (Windows ne prend pas en charge les mêmes autorisations de fichier, donc le bit d'exécution n'est pas défini lors de la construction) et à exécuter le résultat.

23
bames53

Voici des instructions étape par étape pour créer un fichier Hello World .exe à l'aide de llvm/clang sur Mac OS X.

Compilation croisée de Hello World pour Windows à l'aide de Clang/LLVM sur Mac OS X

Installez llvm avec homebrew. Cela comprendra le clang et l'éditeur de liens llvm.

brew install llvm

Vous aurez besoin d'accéder aux bibliothèques et en-têtes Visual Studio C++, qui sont disponibles via Visual Studio 2017 sur une machine virtuelle (VM) Windows 10 ou sur un ordinateur Windows 10. Installez Visual Studio sur Windows et incluez les "composants individuels" suivants via le programme d'installation de Visual Studio:

  • SDK CRT universel Windows
  • Windows Universal C Runtime
  • SDK Windows 10 (X.X.X.X) pour UWP: C++
  • VC++ 2017 vXXX toolset (x86, x64)
  • Mise à jour redistribuable Visual C++ 2017
  • Prise en charge C++/CLI

Accédez aux bibliothèques et aux en-têtes MSVC depuis votre Mac.

  • (Option 1) Utilisez votre Windows VM et créez un dossier partagé entre l'hôte et l'invité.
  • (Option 2) Créez un partage distant sur votre ordinateur Windows et connectez-vous à celui-ci depuis votre Mac.
  • (Option 3) Copiez les bibliothèques et les en-têtes sur votre Mac, conformément aux conditions de licence.

Recherchez les répertoires spécifiques de votre installation llvm + MSVC qui correspondent aux éléments suivants:

// LLVM:
INCLUDES: /usr/local/Cellar/llvm/5.0.0/include

// MSVC:
INCLUDES: "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.11.25503\include"
LIBS: "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.11.25503\lib\x86"

// C Runtime Library (CRT):
INCLUDES: "C:\Program Files (x86)\Windows Kits\10\Include\10.0.15063.0\ucrt"
LIBS: "C:\Program Files (x86)\Windows Kits\10\Include\10.0.15063.0\ucrt"

// User-Mode Library (UM):
INCLUDES: "C:\Program Files (x86)\Windows Kits\10\Include\10.0.15063.0\um"
LIBS: "C:\Program Files (x86)\Windows Kits\10\Lib\10.0.15063.0\um\x86"

// 'Shared' includes:
INCLUDES: "C:\Program Files (x86)\Windows Kits\10\Include\10.0.15063.0\shared"

// WinRT includes:
INCLUDES: "C:\Program Files (x86)\Windows Kits\10\Include\10.0.15063.0\winrt"

// Figure out your MSC 'version', e.g.
Visual C++ 2012 (11.0)   -->     MSC_VER=1700
Visual C++ 2013 (12.0)   -->     MSC_VER=1800
Visual C++ 2015 (14.0)   -->     MSC_VER=1900
Visual C++ 2017 (15.0)   -->     MSC_VER=1910

Créez votre Hello World src:

// hello.cc

#include <cstdio>

int main(int argc, char* argv[]) {
  printf("Hello, World!\n");

  return 0;
}

Compiler avec clang:

clang -target i686-pc-win32 \
  -fms-compatibility-version=19 \
  -fms-extensions \
  -fdelayed-template-parsing \ 
  -fexceptions \
  -mthread-model posix \
  -fno-threadsafe-statics \
  -Wno-msvc-not-found \
  -DWIN32 \
  -D_WIN32 \
  -D_MT \
  -D_DLL \
  -Xclang -disable-llvm-verifier \
  -Xclang '--dependent-lib=msvcrt' \
  -Xclang '--dependent-lib=ucrt' \
  -Xclang '--dependent-lib=oldnames' \
  -Xclang '--dependent-lib=vcruntime' \
  -D_CRT_SECURE_NO_WARNINGS \
  -D_CRT_NONSTDC_NO_DEPRECATE \
  -U__GNUC__ \
  -U__gnu_linux__ \
  -U__GNUC_MINOR__ \
  -U__GNUC_PATCHLEVEL__ \
  -U__GNUC_STDC_INLINE__  \
  -I/usr/local/Cellar/llvm/5.0.0/include \
  -I/c/Program\ Files\ (x86)/Microsoft\ Visual\ Studio/2017/Community/VC/Tools/MSVC/14.11.25503/include \
  -I/c/Program\ Files\ (x86)/Windows\ Kits/10/Include/10.0.15063.0/ucrt \
  -I/c/Program\ Files\ (x86)/Windows\ Kits/10/Include/10.0.15063.0/shared \
  -I/c/Program\ Files\ (x86)/Windows\ Kits/10/Include/10.0.15063.0/winrt \
  -c hello.cc -o hello.o

Lien avec l'éditeur de liens lld, piloté par clang:

clang -Fuse-ld=lld -target i686-pc-win32 -Wl,-machine:x86 -fmsc-version=1900 \
  -o hello.exe hello.o \
  -L/external/code8-cc/cc/msvctoolchain/x86/lib/msvc \
  -L/external/code8-cc/cc/msvctoolchain/x86/lib/um \
  -L/code8-cc/cc/msvctoolchain/x86/lib/ucrt
  -nostdlib -lmsvcrt -Wno-msvc-not-found 

Copiez hello.exe sur votre ordinateur Windows ou Windows VM et exécutez dans PowerShell:

.\hello.exe

Pour créer des versions 64 bits, passez à "-target x86_64-pc-win32", "-Wl, -machine: x64" et liez-vous aux bibliothèques x64.

28
Erik MC

Pensez à utiliser MinGW sur Mac OS X pour compiler les binaires Windows. Voici les instructions pour le faire sous Linux: http://www.blogcompiler.com/2010/07/11/compile-for-windows-on-linux/

Vous devrez les adapter pour Mac OS X et vous devrez peut-être compiler MinGW vous-même.

http://www.mingw.org

8
Jason