2

I'm working on a basic makefile file to test compiling our sources for alternate Microsoft environments, like Windows Phone. I opened an VS2012 ARM Developer Command Prompt and ran nmake on the makefile. It resulted in:

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.

"Desktop applications" is kind of ambiguous, so I searched Microsoft for the meaning of the term. It appears that means the toolchain is building x86 or x64 Metro UI-based application.

I feel like I'm suffering a disconnect, or Microsoft is suffering a disconnect and their tools are buggy.

Why is Microsoft's ARM version of cl.exe trying to build an x86 or x64 application instead of compiling for ARM? Or why is the VS2012 ARM Developer Command Prompt setting up for a x86 or x64 application?


I also tried remediating the problem, but the proposed solutions are not working. So now I am trying to understand what's going on at the highest levels.

For example, one answer says to add <WindowsSDKDesktopARMSupport>true</WindowsSDKDesktopARMSupport> to an ARM property sheet, but that did not work. Another answer says to add CXXFLAGS = /D _ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE, but that did not work either.


The makefile is about as simple as it gets to test the compile under Microsoft's ARM toolchain.

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)
Community
  • 1
  • 1
jww
  • 97,681
  • 90
  • 411
  • 885
  • _"...add `CXXFLAGS = /D _ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE`, but that did not work either."_ - do you mean literally that, or defining it to something nonzero? Line 337 of that header is checking its value, not merely its existence. Presumably those cpp files are using some of the Win32 APIs which are arbitrarily disallowed on ARM? In every instance I've come across, "Desktop" always refers to legacy Win32, i.e. not WinRT or UWP. – Notlikethat Apr 25 '16 at 20:28

1 Answers1

0

The correct solution would be to add something similar to /D WINAPI_FAMILY=WINAPI_FAMILY_APP or /D WINAPI_FAMILY=WINAPI_FAMILY_PHONE_APP.

The Windows SDK headers have three different API subset targets, "desktop", "app" (the new "metro" style app introduced in windows 8) and "phone". When building from within Visual Studio, the right subset is chosen automatically depending on the project type, but when building manually by invoking cl.exe, you need to manually specify the target. (The chosen target limits what declarations are visible in the headers, hiding the ones that are unavailable in the more limited ones.)

Out of tradition, desktop is the default, but when targeting ARM, you need to choose one of the other ones, since there's no publicly supported target for third party code in desktop mode for ARM. (The WinRT tablets did have a desktop mode, but third parties weren't allowed to build apps for it.)

Since Windows 10 and MSVC 2015, you don't need to distinguish between phone and app, but should use "app" for both.

The other flag that was suggested, _ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE, basically tells the headers to pretend like you are allowed to build for the desktop API family even for ARM. To use it, it seems like you should define it like this: /D _ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1 (i.e. just defining it isn't enough, you should define it to 1). For plain code that doesn't use much of the windows API, this should also work equally well, but the better solution is to declare the real API target, to get proper warnings when trying to use APIs that aren't available.

mstorsjo
  • 12,983
  • 2
  • 39
  • 62