CMake生成VS2012 ARM project遇到的问题

VS2012 目前比较新,最新版本的cmake 2.8.10.1)目前还不支持wp8的SDK,我在win8 中生成arm 项目后cmake就过不去了。具体操作如下:
在调用命令生成vs11的project

cmake -G"Visual Studio 11 ARM" .

出现如下问题:

1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V110\Platforms\ARM\PlatformToolsets\v110\Microsoft.Cpp.ARM.v110.targets(36,5): error MSB8022: Compiling Desktop applications for the ARM platform is not supported.========== 生成: 成功 0 个,失败 1 个,最新 0 个,跳过 0 个 ==========


主要问题出现在检测编译器并运行trycompile。接下来打开trycompile调试开关,来看看究竟是怎么回事。运行完成后去build目录下的CMakeFiles\CMakeTmp目录打开CMAKE_TRY_COMPILE.sln工程文件手工编译一把看看。出现的问题果然和命令行下的一样。问题终于找到了。 原来在vsproject里有一个项设置(PlatformToolset)估计和编译器有关系。cmake默认生成的指向是v110。需要改成v110_wp80 才能编译ARM版本。
另外在改成wp8后编译还是不通过提示不能连接kernel32.lib(这不明摆的事么。wp8肯定连接不了,一定是cmake在创建项目的时候没有考虑wp的问题)

1>LINK : fatal error LNK1104: cannot open file 'kernel32.lib'


接下来就是改正这两个问题,拔一下cmake源代码。
具体改动如下:
cmGlobalVisualStudio10Generator.cxx是生成platform toolset主要类,修改后的代码如下
void cmVisualStudio10TargetGenerator::WriteProjectConfigurationValues() { ... if(const char* toolset = gg->GetPlatformToolset()) //通过GetPlatformToolset设置project属性 { //get arch info if ( strstr(this->Platform.c_str(), "ARM") ) { toolset = "v110_wp80"; // 如果是ARM架构就设置v110_wp8,这里用的hardcode,如果要制定SDK应该在添加一些针对winphone sdk的变量, // 通过cmake变量来设置这个值。大致方法是 this->Makefile->AddDefinition(); this->Makefile->GetDefinition(); } std::string pts = ""; pts += toolset; pts += "\n"; this->WriteString(pts.c_str(), 2); } }


修改link flags 去掉相关的kernel32.lib
这个link flags在哪里加的呢?
cmake-2.8.10.1\Modules\Platform\Windows-MSVC.cmake

cmake-2.8.10.1\Modules\Platform\Windows-Intel.cmake

这两个module里面添加了
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")

CMAKE_C_STANDARD_LIBRARIES会在代码中调用并作为标准链接库,添加到每个项目的AdditionalDependencies
对应的代码如下

void cmVisualStudio10TargetGenerator::WriteLinkOptions(std::string const& config) {... std::string standardLibsVar = "CMAKE_"; standardLibsVar += linkLanguage; standardLibsVar += "_STANDARD_LIBRARIES"; std::string libs = this->Makefile->GetSafeDefinition(standardLibsVar.c_str()); //这里获取CMAKE_C_STANDARD_LIBRARIES // Remove trailing spaces from libs std::string::size_type pos = libs.size()-1; if(libs.size() != 0) { while(libs[pos] == ' ') { pos--; } } if(pos != libs.size()-1) { libs = libs.substr(0, pos+1); } // Replace spaces in libs with ; cmSystemTools::ReplaceString(libs, " ", "; "); cmComputeLinkInformation* pcli = this->GeneratorTarget->GetLinkInformation(config.c_str()); if(!pcli) { cmSystemTools::Error ("CMake can not compute cmComputeLinkInformation for target:", this->Name.c_str()); return; } // add the libraries for the target to libs string cmComputeLinkInformation& cli = *pcli; if ( strstr(this->Platform.c_str(), "ARM") == 0 ) //这里是添加的代码,如果是ARM架构就不link了 { this->AddLibraries(cli, libs); linkOptions.AddFlag("AdditionalDependencies", libs.c_str()); } ... }




【CMake生成VS2012 ARM project遇到的问题】修改后重新编译cmake 再生成 Visual Studio 11 ARM的工程文件就顺利完成了。我相信随着windowRT的普及,很快CMake 开发人员就会注意到这个问题,慢慢改正过来。



    推荐阅读