Clang C ++交叉编译器 - 从Mac OS X生成Windows可执行文件

时间:2014-04-23 15:32:40

标签: c++ windows macos clang llvm-clang

我使用Clang编译器在Mac上使用Xcode创建了一个C ++应用程序。

我想编译我的源文件来创建一个可以在Windows机器上运行的可执行文件但是我不能让Clang生成一个可执行文件。

这是我尝试过的:

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

这会创建一个可执行文件,但这不会运行(Windows给我一个错误,该应用程序是16位 - 不明白这一点 - 不能在64位上运行)

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

出于某种原因,每当我使用-target标志时,我都会收到一条错误,指出编译器无法找到<iostream>标头,但是任何其他时间都不会发出声音。
 我尝试过使用-Ipath/to/iostreamfolder/,但这并没有产生更好的结果

任何建议都会很棒!谢谢!

我也尝试了'-triple x86-pc-win32'标志但是我收到了此警告clang: warning: argument unused during compilation: '-triple x86-pc-win32'

3 个答案:

答案 0 :(得分:24)

以下是在Mac OS X上使用llvm / clang构建Hello World .exe的分步说明。

使用Mac OS X上的Clang / LLVM交叉编译Hello World for Windows

使用自制软件安装llvm。这将包括clang和llvm链接器。

brew install llvm

您需要访问Visual Studio C ++库和标头,这些库和标头可通过Windows 10虚拟机(VM)或Windows 10计算机上的Visual Studio 2017获得。在Window上安装Visual Studio,并通过Visual Studio安装程序包含以下“单个组件”:

  • Windows Universal CRT SDK
  • Windows Universal C Runtime
  • 适用于UWP的Windows 10 SDK(X.X.X.X):C ++
  • VC ++ 2017 vXXX工具集(x86,x64)
  • Visual C ++ 2017可再发行更新
  • C ++ / CLI支持

从Mac上访问MSVC库和标题。

  • (选项1)使用Windows VM并在主机和来宾之间创建共享文件夹。
  • (选项2)在Windows计算机上创建远程共享并从Mac连接到它。
  • (选项3)按照任何许可条款将库和标题复制到Mac。

在llvm + MSVC安装中找到与以下内容对应的特定目录:

// 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

创建Hello World src:

// hello.cc

#include <cstdio>

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

  return 0;
}

与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

链接lld链接器,由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 

将hello.exe复制到Windows计算机或Windows VM并在PowerShell中运行:

.\hello.exe

要构建64位版本,请更改为“-target x86_64-pc-win32”,“ - WI,-machine:x64”,并链接到x64库。

答案 1 :(得分:22)

Clang原则上可以用作交叉编译器:与大多数编译器不同,clang / LLVM包含同一二进制文件中不同平台的组件(如codegen,汇编器和链接器)。

但是,在生产能力中尝试使用它时会遇到许多问题:

  • 您需要平台库和标头。要生成可在Windows上运行的可执行文件,您需要要链接到的Windows标头和Windows库,如果是动态链接则导入库,或者静态链接用于静态链接。您应该可以从Visual Studio的安装中获取这些内容。

  • 在Windows上,许多C ++功能(如名称修改和RTTI支持)都不完整。你在使用Clang在Windows上编译Windows时会遇到同样的问题。最近Windows C ++支持为pretty much complete

  • LLVM项目包括lld链接器,它显然足够远,它可以在x86 Windows上自行托管,因此可能适合作为跨平台链接器,但是lld还不是标准的一部分clang发行。 OS X上的Clang仍然默认使用OS X平台链接器ld和Windows上的Clang(link.exe)。你需要得到lld并弄清楚如何与它链接,或找到一些其他的跨平台链接器。

  • clang驱动程序不是作为跨平台编译器驱动程序编写的。您可能需要做更多实际工作才能运行跨平台编译。看看clang -###的输出:clang驱动程序为您构造该命令,但您可能需要手动完成与clang驱动程序相同的工作。而且由于clang在跨平台编译方面的测试要少得多,你可能会遇到更多错误。

  • Xcode不会为您提供任何帮助。它可以为OS X或iOS配置clang以构建,但您必须手动将跨平台构建配置为Windows。

我相对有信心可以拼凑一个基于LLVM的环境来在OS X或Linux上构建一个C“Hello,World”Windows exe,但是它还没有为Xcode添加“Windows”项目做好准备。可能的目标平台列表。


如果您不是编译器开发人员,那么最好只将源代码复制到Windows机器并使用Visual Studio构建。如果您是或希望成为编译器开发人员,那么请帮助推动Clang的交叉编译能力。我认为Clang universal driver项目很令人兴奋,我真的希望看到进展继续。


我已经成功完成了相反的交叉编译:在Windows上编译Mac OS X可执行文件。事实证明,在一个小程序上手动操作非常容易,即直接编译.cpp文件。

首先,Mac OS X开发工具附带“SDK”,其中包含特定操作系统的所有系统库和标头。这里最大的挑战是弄清楚如何将SDK转移到Windows,同时保留SDK中的所有符号链接。 (由于某些原因,在Windows上创建符号链接需要提升权限,因此在使用符号链接在OS X上生成tar.gz之后,我必须在Windows上以管理员身份运行7zip才能正确扩展存档。)

一旦SDK在Windows上可用,就会有一个标志告诉clang从哪里获取所有系统依赖项:-isysroot。结合-target标志就是我需要告诉clang如何为OS X生成完整的目标文件。

对于链接我手动使用lld,因为编译器驱动程序似乎不支持使用与lld的交叉链接。 lld支持类似的标志来确定目标系统库。

最后一步是将生成的可执行文件复制到OS X计算机,启用执行权限(Windows不支持相同的文件权限,因此构建时不会设置执行位)并运行结果。 / p>

答案 2 :(得分:8)

考虑在Mac OS X上使用MinGW来编译Windows二进制文件。以下是有关如何在Linux上执行此操作的说明:http://www.blogcompiler.com/2010/07/11/compile-for-windows-on-linux/

您必须为Mac OS X调整它们,您可能需要自己编译MinGW。

http://www.mingw.org