我正在研究一个基本的makefile文件,以测试我们的替代Microsoft环境(如Windows Phone)的源代码。我打开了VS2012 ARM Developer命令提示符并在makefile上运行nmake
。结果是:
nmake /f makefile.namke
...
cl /c cryptlib.cpp cpu.cpp...
cryptlib.cpp
C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\crtdefs.h(338):
fatal error C1189: #error: Compiling Desktop applications for the ARM platform is not supported.
cpu.cpp
C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\crtdefs.h(338):
fatal error C1189: #error: Compiling Desktop applications for the ARM platform is not supported.
...
NMAKE : fatal error U1077: '"C:\Program Files (x86)\Microsoft Visual Studio 11.0
\VC\BIN\x86_ARM\cl.EXE"' : return code '0x2'
Stop.
“桌面应用程序” 有点含糊不清,所以我搜索了Microsoft这个术语的含义。看起来这意味着工具链正在构建基于x86或x64 Metro UI的应用程序。
我觉得我正在遭受脱节,或者微软正在遭受脱节,他们的工具也有问题。
为什么Microsoft的ARM版本的cl.exe试图构建x86或x64应用程序而不是为ARM编译?或者为什么VS2012 ARM Developer命令提示符设置为x86或x64应用程序?
我也尝试过修复问题,但建议的解决方案无效。所以现在我想了解最高层正在发生什么。
例如,one answer表示要将<WindowsSDKDesktopARMSupport>true</WindowsSDKDesktopARMSupport>
添加到ARM属性表中,但这不起作用。 Another answer说要添加CXXFLAGS = /D _ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE
,但这也不起作用。
makefile与在Microsoft的ARM工具链下测试编译一样简单。
LIB_SRCS = cryptlib.cpp cpu.cpp ...
LIB_OBJS = cryptlib.obj cpu.obj ...
TEST_SRCS = test.cpp bench1.cpp bench2.cpp ...
TEST_OBJS = test.obj bench1.obj bench2.obj ...
CXX = cl.exe /nologo
AR = lib.exe
CXXFLAGS =
all: cryptest.exe
cryptest.exe: $(TEST_OBJS) cryplib.lib
$(CXX) $(CXXFLAGS) /ref:cryplib.lib /out:$@ $(TEST_SRCS)
cryplib.lib : $(LIB_OBJS)
$(CXX) $(CXXFLAGS) $(LIB_SRCS)
$(AR) $(LIB_OBJS)
答案 0 :(得分:0)
正确的解决方案是添加类似于/D WINAPI_FAMILY=WINAPI_FAMILY_APP
或/D WINAPI_FAMILY=WINAPI_FAMILY_PHONE_APP
的内容。
Windows SDK标头有三个不同的API子集目标,“桌面”,“app”(Windows 8中引入的新“metro”风格应用程序)和“phone”。在Visual Studio中构建时,根据项目类型自动选择正确的子集,但是通过调用cl.exe手动构建时,需要手动指定目标。 (所选目标限制了标题中可见的声明,隐藏了那些在更有限的声明中不可用的声明。)
传统上,桌面是默认设置,但是在针对ARM时,您需要选择其中一个,因为ARM的桌面模式下没有公开支持的第三方代码目标。 (WinRT平板电脑确实有桌面模式,但不允许第三方为其构建应用程序。)
自Windows 10和MSVC 2015以来,您无需区分手机和应用,但应同时使用“app”。
建议的另一个标志_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE
,基本上告诉标头假装您可以为桌面API系列构建,即使对于ARM也是如此。要使用它,您似乎应该像这样定义它:/D _ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1
(即仅定义它是不够的,您应该将其定义为1
)。对于不使用大量Windows API的普通代码,这也应该同样有效,但更好的解决方案是声明真正的API目标,以便在尝试使用不可用的API时获得正确的警告。