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

gav*_*aaa 32 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
Run Code Online (Sandbox Code Playgroud)

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

clang++ -std=c++11 -stdlib=libc++ -target i386-pc-win32 class1.cpp class2.cpp 
Run Code Online (Sandbox Code Playgroud)

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

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

我也试过了'-triple x86-pc-win32'旗帜,但是我得到了这个警告clang: warning: argument unused during compilation: '-triple x86-pc-win32'

Eri*_* MC 31

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

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

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

brew install llvm
Run Code Online (Sandbox Code Playgroud)

您需要访问Visual Studio C++库和标头,这些库和标头可通过Windows 10虚拟机(VM)或Windows 10计算机上的Visual Studio 2017获得.在Window上安装Visual Studio,并通过Visual Studio Installer包含以下"Individual Components":

  • Windows Universal CRT SDK
  • Windows Universal C运行时
  • 适用于UWP的Windows 10 SDK(XXXX):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
Run Code Online (Sandbox Code Playgroud)

创建Hello World src:

// hello.cc

#include <cstdio>

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

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

用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
Run Code Online (Sandbox Code Playgroud)

链接由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 
Run Code Online (Sandbox Code Playgroud)

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

.\hello.exe
Run Code Online (Sandbox Code Playgroud)

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


bam*_*s53 24

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

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

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

  • 在Windows上,许多C++功能(如名称修改和RTTI支持)都不完整.使用Clang在Windows上编译Windows时遇到同样的问题.如今,Windows C++支持已经相当完整.

  • LLVM项目包括lld链接器,它显然足够远,它可以在x86 Windows上自托管,因此可能作为跨平台链接器工作,但是lld还不是clang发行版的标准部分.ld默认情况下,OS X上的Clang仍然使用OS X平台链接器,就像Windows上的Clang一样link.exe.您需要获得lld并找出如何与其链接,或找到其他一些跨平台链接器.

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

  • Xcode不会帮助您解决任何问题.它可以配置clang为OS X或iOS构建,但您必须手动配置跨平台构建到Windows.

我相信有人可以拼凑一个基于LLVM的环境来在OS X或Linux上构建一个C"Hello,World"Windows exe,但它还没有准备好让Xcode将"Windows"项添加到可能的列表中目标平台.


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


我已经成功完成了相反的交叉编译:在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不支持相同的文件权限,因此构建时不会设置执行位)并运行结果.


Jas*_*son 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