MantisBT - CMake
View Issue Details
0014598CMakeCMakepublic2013-11-26 05:552013-11-28 06:34
Moshe Rubin 
Patrick R. Gansterer 
highmajoralways
closedduplicate 
MS WindowsMS Windows 8 Pro6.2.9200
CMake 2.8.12 
 
0014598: CMake 2.8.12 with "Visual Studio 11 ARM" generator fails to compile simple test program, 2.8.11 works
Running the following command using CMake 2.8.11:

"C:\Program Files (x86)\CMake 2.8.11\bin\cmake.exe" ..\ -G "Visual Studio 11 ARM" -T "v110_wp80"

successfully creates a Visual Studio solution file:

-- The C compiler identification is unknown
-- The CXX compiler identification is unknown
-- Configuring done
-- Generating done
-- Build files have been written to: C:/junk/TestProjects/CMakeArmRegression/Generated-2.8.11

Using CMake 2.8.12, however, fails to compile the simple test program:

"C:\Program Files (x86)\CMake 2.8.12\bin\cmake.exe" ..\ -G "Visual Studio 11 ARM" -T "v110_wp80"

-- The C compiler identification is MSVC 17.0.50727.1
-- The CXX compiler identification is MSVC 17.0.50727.1
-- Check for working C compiler using: Visual Studio 11 ARM
-- Check for working C compiler using: Visual Studio 11 ARM -- broken
CMake Error at C:/Program Files (x86)/CMake 2.8.12/share/cmake-2.8/Modules/CMakeTestCCompiler.cmake:61 (message):
  The C compiler "C:/Program Files (x86)/Microsoft Visual Studio
  11.0/VC/WPSDK/WP80/bin/x86_arm/cl.exe" is not able to compile a simple test program.

Because of this problem, I am forced to stay with 2.8.11 and cannot upgrade to 2.8.12.
I have attached a ZIP file (CMakeArmRegression.zip) with the following folders and files to reproduce the problem:

Folder CMakeArmRegression:

(*) An empty CMakeLists.txt file
(*) cmARM.bat batch file

Extract the ZIP file into any empty folder (in my case, CMakeArmRegression), 'cd' to that folder and run the command:

cmARM.bat 1> cmARM.out.txt 2>&1 cmARM.out.txt

This will create two sub-folders, Generated-2.8.11 and Generated-2.8.12, containing the output of running the two commands:

"C:\Program Files (x86)\CMake 2.8.11\bin\cmake.exe" ..\ -G "Visual Studio 11 ARM" -T "v110_wp80"
"C:\Program Files (x86)\CMake 2.8.12\bin\cmake.exe" ..\ -G "Visual Studio 11 ARM" -T "v110_wp80"

Open the output file cmARM.out.txt to see how 2.8.11 succeeds while 2.8.12 fails.
CMake 2.8.10 also fails, like 2.8.12, when the following command is run:

"C:\Program Files (x86)\CMake 2.8.10\bin\cmake.exe" ..\ -G "Visual Studio 11 ARM"

I assume the problem was fixed in 2.8.11 but the fix was regressed in 2.8.12.
No tags attached.
duplicate of 0013791closed Brad King CMake does not support generating projects for Windows Phone 8. 
zip CMakeArmRegression.zip (77,565) 2013-11-26 05:59
https://public.kitware.com/Bug/file/4968/CMakeArmRegression.zip
gif Win32-MinApp.PropertyPage.gif (33,030) 2013-11-27 06:08
https://public.kitware.com/Bug/file/4975/Win32-MinApp.PropertyPage.gif
gif

gif cmTryCompileExec.PropertyPage.gif (31,501) 2013-11-27 06:08
https://public.kitware.com/Bug/file/4976/cmTryCompileExec.PropertyPage.gif
gif

gif PhoneDirect3DApp1.PropertyPage.gif (32,161) 2013-11-27 06:09
https://public.kitware.com/Bug/file/4977/PhoneDirect3DApp1.PropertyPage.gif
gif
Issue History
2013-11-26 05:55Moshe RubinNew Issue
2013-11-26 05:59Moshe RubinFile Added: CMakeArmRegression.zip
2013-11-26 09:18Brad KingAssigned To => Patrick R. Gansterer
2013-11-26 09:18Brad KingStatusnew => assigned
2013-11-26 09:23Brad KingNote Added: 0034565
2013-11-26 14:31Moshe RubinNote Added: 0034574
2013-11-26 14:51Brad KingNote Added: 0034575
2013-11-27 03:36Patrick R. GanstererNote Added: 0034582
2013-11-27 06:07Moshe RubinNote Added: 0034585
2013-11-27 06:08Moshe RubinFile Added: Win32-MinApp.PropertyPage.gif
2013-11-27 06:08Moshe RubinFile Added: cmTryCompileExec.PropertyPage.gif
2013-11-27 06:09Moshe RubinFile Added: PhoneDirect3DApp1.PropertyPage.gif
2013-11-27 07:46Moshe RubinNote Added: 0034586
2013-11-27 19:29Brad KingNote Added: 0034604
2013-11-28 03:23Patrick R. GanstererNote Added: 0034606
2013-11-28 05:43Moshe RubinNote Added: 0034608
2013-11-28 06:33Patrick R. GanstererRelationship addedduplicate of 0013791
2013-11-28 06:34Patrick R. GanstererNote Added: 0034609
2013-11-28 06:34Patrick R. GanstererStatusassigned => closed
2013-11-28 06:34Patrick R. GanstererResolutionopen => duplicate

Notes
(0034565)
Brad King   
2013-11-26 09:23   
From the reported output it looks like 2.8.11 never even tried to run the test for a working compiler. Now that 2.8.12 (correctly) tries to run the test it exposes this failure.

For reference, the provided Generated-2.8.12/CMakeFiles/CMakeError.log contains:

 LINK : fatal error LNK1104: cannot open file 'kernel32.lib'
(0034574)
Moshe Rubin   
2013-11-26 14:31   
Investigating further shows the following:

(*) Compiling the "Generated-2.8.11\CMakeFiles\2.8.11\CompilerIdC\CompilerIdC.vcxproj" project fails to compile with the following output:

<snippet>
1>------ Build started: Project: CompilerIdC, Configuration: Debug ARM ------
1>Debug\CMakeCCompilerId.obj : fatal error LNK1112: module machine type 'ARM' conflicts with target machine type 'X86'
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

</snippet>

The reason is clear from the linker command line:

<snippet>
/OUT:".\CompilerIdC.exe" /MANIFEST /NXCOMPAT /PDB:".\CompilerIdC.pdb" /DYNAMICBASE "WindowsPhoneCore.lib" "RuntimeObject.lib" "PhoneAppModelHost.lib" /MACHINE:X86 /INCREMENTAL:NO /PGD:".\CompilerIdC.pgd" /SUBSYSTEM:CONSOLE /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /ManifestFile:"Debug\CompilerIdC.exe.intermediate.manifest" /ERRORREPORT:PROMPT /NOLOGO /TLBID:1
</snippet>

Although the platform is ARM, the "/MACHINE:X86" is in conflict. The /MACHINE: value should have been "/MACHINE:ARM" rather than "/MACHINE:X86".

(*) Compiling the "Generated-2.8.12\CMakeFiles\2.8.12\CompilerIdC\CompilerIdC.vcxproj" project succeeds because the "/MACHINE:ARM" is correct:

<snippet>
/OUT:".\CompilerIdC.exe" /MANIFEST /NXCOMPAT /PDB:".\CompilerIdC.pdb" /DYNAMICBASE "WindowsPhoneCore.lib" "RuntimeObject.lib" "PhoneAppModelHost.lib" /MACHINE:ARM /INCREMENTAL:NO /PGD:".\CompilerIdC.pgd" /SUBSYSTEM:CONSOLE /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /ManifestFile:"Debug\CompilerIdC.exe.intermediate.manifest" /ERRORREPORT:PROMPT /NOLOGO /TLBID:1
</snippet>

So I imagine this was one of the fixes that went into 2.8.12.

(*) So what does 2.8.12 fail on? It fails on linking testCCompiler.c:

<snippet>
Determining if the C compiler works failed with the following output:
Change Dir: C:/junk/TestProjects/CMakeArmRegression/Generated-2.8.12/CMakeFiles/CMakeTmp

Run Build Command:C:\PROGRA~2\MICROS~3.0\Common7\IDE\devenv.com CMAKE_TRY_COMPILE.sln /build Debug /project cmTryCompileExec2727613988

Microsoft (R) Microsoft Visual Studio 2012 Version 11.0.51106.1.
Copyright (C) Microsoft Corp. All rights reserved.
1>------ Build started: Project: cmTryCompileExec2727613988, Configuration: Debug ARM ------
1> Microsoft (R) C/C++ Optimizing Compiler Version 17.00.50727.1 for ARM
1> Copyright (C) Microsoft Corporation. All rights reserved.
1>
1> cl /c /Zi /W3 /WX- /Od /Ob0 /Oy- /D WIN32 /D _WINDOWS /D _DEBUG /D "CMAKE_INTDIR=\"Debug\"" /D _MBCS /D WINAPI_FAMILY=WINAPI_FAMILY_PHONE_APP /Gm- /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Fo"cmTryCompileExec2727613988.dir\Debug\\" /Fd"cmTryCompileExec2727613988.dir\Debug\vc110.pdb" /Gd /TC /analyze- /errorReport:prompt testCCompiler.c
1>
1> testCCompiler.c
1>LINK : fatal error LNK1104: cannot open file 'kernel32.lib'
</snippet>

Adding "--debug-trycompile" to the command ""C:\Program Files (x86)\CMake 2.8.12\bin\cmake.exe" ..\ -G "Visual Studio 11 ARM" -T "v110_wp80" --debug-trycompile" enables us to determine the problem: the cmTryCompileExec2727613988.vcxproj project file has linker dependencies that should not be there:

<snippet>
<Link>
  . . .
  <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;comdlg32.lib;advapi32.lib</AdditionalDependencies>
</snippet>

When these WIN32-related dependencies are removed from the project, the build succeeds.

So the solution is that, when using an ARM-related generator, CMake should not add WIN32-based linker dependencies (e.g., WIN32 DLLs).
(0034575)
Brad King   
2013-11-26 14:51   
For reference, the Win32 libraries like kernel32 are chosen here:

 http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/Platform/Windows-MSVC.cmake;hb=v2.8.12.1#l157 [^]

that block is the else() of if(WINCE) and assumes Windows is the target platform.
(0034582)
Patrick R. Gansterer   
2013-11-27 03:36   
Where are the functions of X86-kernel32.lib defined for ARM? Usually they need to be specified explicit, because the other generators (NMake, Ninja) will fail otherwise.
(0034585)
Moshe Rubin   
2013-11-27 06:07   
Compiling with the ARM configuration means that WIN32 system DLLs (e.g., kernel32.dll, shell32.dll) are not supported. See "Are kernel32.dll and shell32.dll supported in ARM?" on StackOverflow (http://stackoverflow.com/questions/13797883/are-kernel32-dll-and-shell32-dll-supported-in-arm [^]). Metro (or Windows Store) apps use a totally different API, unrelated to the Win32 API we've come to know and love <g>.

I generated a default Windows Phone 8 app using the Project Wizard. When I checked the Properties>Linker>Input, it is basically empty, i.e., no kernel32.dll etc. are present.

I'm uploading screen captures of the Linker>Input property pages for three types of apps:

(1) Win32 minimal app, generated by the Project Wizard
(2) CMake's own cmTryCompileExec
(3) Windows ARM default PhoneDirect3DApp application, generated by the Project Wizard

Case (1) is a normal Win32 app, therefore Linker>Input shows "kernel32.dll" et al.
Case (3) is an ARM app, not Win32, therefore Linker>Input shows no system DLLs
Case (2) should have been an ARM app, with no Linker>Input DLLs. The problem is that it is showing Win32 system DLLs.

Last night I attempted to build CMake with the following fix to Windows-MSVC.cmake:

<quote>
  if(MSVC_VERSION GREATER 1310)
    set(_RTC1 "/RTC1")
    set(_FLAGS_CXX " /GR /EHsc")
    if(arch_hint STREQUAL "ARM")
        MESSAGE(STATUS, "arch_hint == ARM (1)")
    else()
        # MosheRubin (26 Nov 2013)
        # Do NOT add WIN32 dependencies if using an ARM generator
        set(CMAKE_C_STANDARD_LIBRARIES_INIT "kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib")
    endif()
  else()
    set(_RTC1 "/GZ")
    set(_FLAGS_CXX " /GR /GX")
    if(arch_hint STREQUAL "ARM")
        MESSAGE(STATUS, "arch_hint == ARM (2)")
    else()
        # MosheRubin (26 Nov 2013)
        # Do NOT add WIN32 dependencies if using an ARM generator
        set(CMAKE_C_STANDARD_LIBRARIES_INIT "kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib")
    endif()
  endif()
</quote>

This still failed when I ran my test batch file using the new CMake binary, but I may have done something incorrectly. In any case I think the fix is basically correct: if the configuration is ARM based, do not include the Win32 system DLLs. What do you think?
(0034586)
Moshe Rubin   
2013-11-27 07:46   
A useful CMake command line option would be to ignore the results of the try_compile step. A developer would use this when the try_compile fails but the developer is convinced the generated solution file will work. This is what happened for me in 2.8.11: although the try_compile failed, 2.8.11 ignored the failure and the generated solution file worked perfectly.
(0034604)
Brad King   
2013-11-27 19:29   
Re 0014598:0034586: The fact that the try_compile fails is telling you that CMake is not generating working project files. If the test were skipped the 2.8.12-generated solution would not work either. It would also have the Windows system libraries in each project.

It looks like the ARM generator has never worked properly. In 2.8.11 it appeared to work by accident because the linker error due to machine type mismatch that occurred during the compiler identification prevented it from loading the platform information file Windows-MSVC.cmake which sets all the system libraries. In other words, one bug in ARM support suppressed other bugs in ARM support to make things work by accident. Now that the compiler id runs correctly it identifies the platform as Windows and loads the information for it including the system library settings.

Never having worked with the (contributed) ARM generator I was always a bit surprised it worked because it is actually a cross-compiling case. CMake cross-compiling support normally requires a toolchain file to set the target platform information as described here:

 http://www.cmake.org/Wiki/CMake_Cross_Compiling [^]

For ARM such a file could set the CMAKE_SYSTEM_NAME to something other than "Windows" to prevent the windows system libraries from being used. In fact when using a toolchain file one can "force" the compiler settings and bypass the test for working compiler exactly as you request.

Having not worked with the ARM tools myself I have no recommendation on the proper path forward for this issue.
(0034606)
Patrick R. Gansterer   
2013-11-28 03:23   
What system API do you want to use? Win32 or WinRT or <whatever>? Windows CE for example uses Win32 API for ARM too (only the libraries which provide the functions have different names). If you want to use WinRT this bug is duplicate of bug 13511. If you want to compile a Phone application bug 13791 might be the better duplicate.
(0034608)
Moshe Rubin   
2013-11-28 05:43   
I believe bug 13791 is what I'm reporting -- good catch! jjujyl, the reporter, did comprehensive research into the .vcxproj file differences and mentioned my comment about the link files (kernel32.dll etc.). So I guess you could mark this entry (14598) as a duplicate of 13791.

Do we know if Paul Annetts (reporter in 13791) is currently working on a fix?
(0034609)
Patrick R. Gansterer   
2013-11-28 06:34   
I have no more information as write in the bug.