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 = "<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 开发人员就会注意到这个问题,慢慢改正过来。