我使用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'
答案 0 :(得分:24)
以下是在Mac OS X上使用llvm / clang构建Hello World .exe的分步说明。
使用自制软件安装llvm。这将包括clang和llvm链接器。
brew install llvm
您需要访问Visual Studio C ++库和标头,这些库和标头可通过Windows 10虚拟机(VM)或Windows 10计算机上的Visual Studio 2017获得。在Window上安装Visual Studio,并通过Visual Studio安装程序包含以下“单个组件”:
从Mac上访问MSVC库和标题。
在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。