CMake生成VS2012 ARM project遇到的问题

来源:互联网 发布:雪豹特种部队 知乎 编辑:程序博客网 时间:2024/04/30 16:33

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 notsupported.========== 生成: 成功 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 infoif ( 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 = "<PlatformToolset>";pts += toolset;pts += "</PlatformToolset>\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 再生成 Visual Studio 11 ARM的工程文件就顺利完成了。我相信随着windowRT的普及,很快CMake 开发人员就会注意到这个问题,慢慢改正过来。



原创粉丝点击