简体   繁体   English

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

[英]Clang C++ Cross Compiler - Generating Windows Executable from Mac OS X

I have created a C++ application using Xcode on my Mac using the Clang compiler.我使用 Clang 编译器在我的 Mac 上使用 Xcode 创建了一个 C++ 应用程序。

I want to compile my source files to create an executable that can be ran on a windows machine however I cant get Clang to generate me an executable.我想编译我的源文件以创建一个可以在 Windows 机器上运行的可执行文件,但是我无法让 Clang 为我生成一个可执行文件。

Here is what I've tried:这是我尝试过的:

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

Here are step-by-step instructions for building a Hello World .exe using llvm/clang on Mac OS X.以下是在 Mac OS X 上使用 llvm/clang 构建 Hello World .exe 的分步说明。

Cross-compile Hello World for Windows using Clang/LLVM on Mac OS X在 Mac OS X 上使用 Clang/LLVM 为 Windows 交叉编译 Hello World

Install llvm with homebrew.使用自制软件安装 llvm。 This will include the clang and the llvm linker.这将包括 clang 和 llvm 链接器。

brew install llvm

You'll need access to Visual Studio C++ libraries and headers, which are available through Visual Studio 2017 on a Windows 10 Virtual Machine (VM) or on a Windows 10 Computer.您需要访问 Visual Studio C++ 库和标头,这些库和标头可通过 Windows 10 虚拟机 (VM) 或 Windows 10 计算机上的 Visual Studio 2017 获得。 Install Visual Studio on Window, and include the following 'Individual Components' through the Visual Studio Installer:在 Window 上安装 Visual Studio,并通过 Visual Studio 安装程序包含以下“独立组件”:

  • Windows Universal CRT SDK Windows 通用 CRT SDK
  • Windows Universal C Runtime Windows 通用 C 运行时
  • Windows 10 SDK (XXXX) for UWP: C++适用于 UWP 的 Windows 10 SDK (XXXX):C++
  • VC++ 2017 vXXX toolset (x86,x64) VC++ 2017 vXXX 工具集 (x86,x64)
  • Visual C++ 2017 Redistributable Update Visual C++ 2017 可再发行更新
  • C++/CLI support C++/CLI 支持

Get access to the MSVC libraries and headers from your Mac.从 Mac 访问 MSVC 库和标头。

  • (Option 1) Use your Windows VM and create a shared folder between host and guest. (选项 1)使用您的 Windows VM 并在主机和来宾之间创建一个共享文件夹。
  • (Option 2) Create a remote share on your Windows computer and connect to it from your Mac. (选项 2)在您的 Windows 计算机上创建一个远程共享并从您的 Mac 连接到它。
  • (Option 3) Copy the libraries and headers to your Mac, following any licensing terms. (选项 3)按照任何许可条款将库和标题复制到您的 Mac。

Find the specific directories on your llvm+MSVC install that correspond to the following:在 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

Create your Hello World src:创建你的 Hello World src:

// hello.cc

#include <cstdio>

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

  return 0;
}

Compile with clang:用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

Link with the lld linker, driven by clang:与 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 

Copy hello.exe to your Windows computer or Windows VM and run in PowerShell:将 hello.exe 复制到您的 Windows 计算机或 Windows VM 并在 PowerShell 中运行:

.\hello.exe

To build 64-bit versions, change to '-target x86_64-pc-win32', '-Wl,-machine:x64', and link to x64 libraries.要构建 64 位版本,请更改为“-target x86_64-pc-win32”、“-Wl,-machine:x64”,并链接到 x64 库。

Clang can in principle be used as a cross compiler: unlike most compilers clang/LLVM includes components (such as the codegen, assembler, and linker) for different platforms in the same binary. Clang 原则上可以用作交叉编译器:与大多数编译器不同,clang/LLVM 在同一个二进制文件中包含用于不同平台的组件(例如代码生成器、汇编器和链接器)。

However you'll run into a number of problems trying to use it as such in a production capacity:但是,尝试在生产能力中使用它时会遇到许多问题:

  • You need platform libraries and headers.您需要平台库和头文件。 To generate an executable that will work on Windows you need Windows headers and Windows libraries you want to link to, either import libs if you're dynamically linking or static libs for static linking.要生成可在 Windows 上运行的可执行文件,您需要要链接到的 Windows 标头和 Windows 库,如果您是动态链接,则导入库或用于静态链接的静态库。 You should be able to get these from an installation of Visual Studio.您应该能够从 Visual Studio 的安装中获得这些。

  • Many C++ features such as name mangling and RTTI support are not complete on Windows. 许多 C++ 功能(如名称修改和 RTTI 支持)在 Windows 上并不完整。 You'd have these same problems compiling for Windows on Windows with Clang. 在使用 Clang 在 Windows 上编译 Windows 时,您会遇到同样的问题。 Windows C++ support is pretty much complete these days.这些天来,Windows C++ 支持几乎是完整的

  • The LLVM project includes the lld linker, which is apparently far enough along that it can self host on x86 Windows and so might work for you as a cross-platform linker, however lld is not yet a standard part of clang distributions. LLVM 项目包括 lld 链接器,它显然足够远,它可以在 x86 Windows 上自托管,因此可以作为跨平台链接器为您工作,但是 lld 还不是 clang 发行版的标准部分。 Clang on OS X still uses the OS X platform linker ld by default as does Clang on Windows ( link.exe ).默认情况下,OS X 上的 Clang 仍然使用 OS X 平台链接器ld ,就像 Windows 上的 Clang ( link.exe ) 一样。 You'll need to get lld and figure out how to link with it, or find some other cross-platform linker.您需要获取 lld 并弄清楚如何与之链接,或者找到其他一些跨平台链接器。

  • The clang driver isn't written as a cross-platform compiler driver. clang 驱动程序不是作为跨平台编译器驱动程序编写的。 You'll likely have to do a lot more hands-on work to run a cross-platform compilation.您可能需要做更多的动手工作来运行跨平台编译。 Take a look at the output of clang -### : the clang driver constructs that command for you, but you may have to do much of the same work as the clang driver by hand.看一下clang -###的输出:clang 驱动程序为您构造了该命令,但您可能需要手动完成与 clang 驱动程序相同的大部分工作。 And since clang gets much less testing at cross-platform compilation you're likely to run into more bugs.而且由于 clang 在跨平台编译时得到的测试要少得多,因此您可能会遇到更多错误。

  • Xcode is not going to help you with any of this. Xcode 不会帮助您解决任何这些问题。 It can configure clang to build for OS X or iOS, but you'll have to manually configure cross-platform builds to Windows.它可以配置 clang 为 OS X 或 iOS 构建,但您必须手动配置跨平台构建到 Windows。

I'm relatively confident that one could cobble together an LLVM based environment to build a C "Hello, World" Windows exe on OS X or Linux, but it's not quite ready for Xcode to add a "Windows" item to the list of possible target platforms.我相对有信心,可以拼凑出一个基于 LLVM 的环境,在 OS X 或 Linux 上构建一个 C“Hello, World”Windows exe,但是 Xcode 还没有准备好将“Windows”项目添加到可能的列表中目标平台。


If you're not a compiler developer you're probably best off just copying your source code to a Windows machine and building with Visual Studio.如果您不是编译器开发人员,您最好将源代码复制到 Windows 机器并使用 Visual Studio 构建。 If you are, or want to be, a compiler developer then by all means, help push Clang's cross-compilation abilities forward.如果您是或想成为编译器开发人员,那么请务必帮助推动 Clang 的交叉编译能力向前发展。 I think the Clang universal driver project is exciting and I would really like to see progress continue.我认为 Clang通用驱动程序项目令人兴奋,我真的希望看到进展继续。


I've successfully done the opposite cross-compilation: compiling a Mac OS X executable on Windows.我已经成功地完成了相反的交叉编译:在 Windows 上编译 Mac OS X 可执行文件。 This turned out to be quite easy to do manually on a small program, ie directly compiling a .cpp file.事实证明,在一个小程序上手动完成非常容易,即直接编译一个 .cpp 文件。

First, Mac OS X development tools come with "SDKs" which contain all the system libraries and headers for a particular OS.首先,Mac OS X 开发工具带有“SDK”,其中包含特定操作系统的所有系统库和头文件。 The largest challenge here was figuring out how to transfer the SDK to Windows while preserving all the symbolic links in the SDK.这里最大的挑战是弄清楚如何将 SDK 传输到 Windows,同时保留 SDK 中的所有符号链接。 (For some reason creating symbolic links on Windows requires elevated privileges, so after producing a tar.gz on OS X with the symbolic links I had to run 7zip on Windows as an administrator to correctly expand the archive.) (出于某种原因,在 Windows 上创建符号链接需要提升权限,因此在使用符号链接在 OS X 上生成 tar.gz 后,我必须以管理员身份在 Windows 上运行 7zip 以正确扩展存档。)

Once the SDK is available on Windows there's a single flag to tell clang where to get all the system dependencies: -isysroot .一旦 SDK 在 Windows 上可用,就会有一个标志告诉 clang 从哪里获取所有系统依赖项: -isysroot This combined with the -target flag were all that I needed to tell clang how to produce complete object files for OS X.结合-target标志,我需要告诉 clang 如何为 OS X 生成完整的目标文件。

For linking I manually used lld, as the compiler driver didn't seem support using cross linking with lld.对于链接,我手动使用了 lld,因为编译器驱动程序似乎不支持使用与 lld 的交叉链接。 lld supports similar flags for determining the target system libraries. lld 支持用于确定目标系统库的类似标志。

The final step was simply copying the produced executable to an OS X machine, enabling the execute permission (Windows doesn't support the same file permissions so the execute bit doesn't get set when building) and running the result.最后一步是简单地将生成的可执行文件复制到 OS X 机器,启用执行权限(Windows 不支持相同的文件权限,因此在构建时不会设置执行位)并运行结果。

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

You'll have to adapt them for Mac OS X and you may have to compile MinGW yourself.您必须针对 Mac OS X 调整它们,并且您可能必须自己编译 MinGW。

http://www.mingw.org http://www.mingw.org

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM