Clang C++ 交叉编译器 - 从 Mac OS X 生成 Windows 可执行文件
我使用 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: 警告:编译期间未使用的参数:'-triple x86-pc-win32'
Clang 原则上可以用作交叉编译器:与大多数编译器不同,clang/LLVM 包含针对不同平台的组件(例如代码生成器、汇编器和链接器)在同一个二进制文件中.
但是,尝试在生产能力中使用它时会遇到许多问题:
您需要平台库和头文件.要生成可在 Windows 上运行的可执行文件,您需要要链接到的 Windows 标头和 Windows 库,如果您是动态链接,则导入库或用于静态链接的静态库.您应该可以通过安装 Visual Studio 获得这些.
许多 C++ 功能(例如名称修改和 RTTI 支持)在 Windows 上并不完整.使用 Clang 在 Windows 上编译 Windows 时也会遇到同样的问题.Windows C++ 支持是 这些天已经基本完成了.LLVM 项目包括 lld 链接器,它显然已经足够远,它可以在 x86 Windows 上自托管,因此可能适合您作为跨平台链接器,但是 lld 还不是标准的一部分叮当分布.默认情况下,OS X 上的 Clang 仍然使用 OS X 平台链接器
ld
,就像 Windows 上的 Clang (link.exe
).您需要获取 lld 并弄清楚如何与之链接,或者找到其他一些跨平台链接器.clang 驱动程序不是作为跨平台编译器驱动程序编写的.您可能需要做更多的实践工作才能运行跨平台编译.看看
clang -###
的输出:clang 驱动程序为您构造了该命令,但您可能需要手动完成与 clang 驱动程序相同的大部分工作.而且由于 clang 在跨平台编译时得到的测试要少得多,因此您很可能会遇到更多错误.Xcode 不会帮助您解决这些问题.它可以配置 clang 以针对 OS X 或 iOS 进行构建,但您必须手动将跨平台构建配置到 Windows.
我相对有信心,可以拼凑出一个基于 LLVM 的环境,在 OS X 或 Linux 上构建一个 CHello, 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 不支持相同的文件权限,因此在构建时不会设置执行位)并运行结果.
I have created a C++ application using Xcode on my Mac using the Clang compiler.
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.
Here is what I've tried:
clang++ -std=c++11 -stdlib=libc++ -arch x86_64 class1.cpp class2.cpp... -o executable.exe
This creates an executable however this does not run (Windows gives me an error to do with the application being 16 bit -dont understand this- that cant run on 64 bit)
clang++ -std=c++11 -stdlib=libc++ -target i386-pc-win32 class1.cpp class2.cpp
For some reason whenever I use the -target
flag I get an error stating that the compiler cannot find the <iostream>
header however any other time it never moans.
I have tried using -Ipath/to/iostreamfolder/
however this doesnt produce any better results
Any suggestions would be great! Thanks!
I have also tried the '-triple x86-pc-win32'
flag however I get this warning clang: warning: argument unused during compilation: '-triple x86-pc-win32'
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.
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. You should be able to get these from an installation of Visual Studio.
Many C++ features such as name mangling and RTTI support are not complete on Windows. You'd have these same problems compiling for Windows on Windows with Clang.Windows C++ support is pretty much complete these days.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. Clang on OS X still uses the OS X platform linker
ld
by default as does Clang on Windows (link.exe
). You'll need to get lld and figure out how to link with it, or find some other cross-platform linker.The clang driver isn't written as a cross-platform compiler driver. 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. And since clang gets much less testing at cross-platform compilation you're likely to run into more bugs.Xcode is not going to help you with any of this. It can configure clang to build for OS X or iOS, but you'll have to manually configure cross-platform builds to 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.
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. If you are, or want to be, a compiler developer then by all means, help push Clang's cross-compilation abilities forward. I think the Clang universal driver project is exciting and I would really like to see progress continue.
I've successfully done the opposite cross-compilation: compiling a Mac OS X executable on Windows. This turned out to be quite easy to do manually on a small program, i.e. directly compiling a .cpp file.
First, Mac OS X development tools come with "SDKs" which contain all the system libraries and headers for a particular OS. The largest challenge here was figuring out how to transfer the SDK to Windows while preserving all the symbolic links in the 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.)
Once the SDK is available on Windows there's a single flag to tell clang where to get all the system dependencies: -isysroot
. This combined with the -target
flag were all that I needed to tell clang how to produce complete object files for OS X.
For linking I manually used lld, as the compiler driver didn't seem support using cross linking with lld. lld supports similar flags for determining the target system libraries.
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.
相关文章