CMake构建Visual Studio中MFC项目的Unicode问题
最近在学习使用CMake来构建项目,想用来建几个MFC的项目练习一下。其实,在Windows平台上,MSBuild也是个蛮好的选择,管理项目很方面(很多时候虽然喜欢IDE,但有时候IDE操作的步骤让我感觉罗嗦)。
之前还是很认真地学习了一下《CMake实践》,一本不痛不痒地介绍CMake的pdf文档,很有价值。不过,关于MFC项目的问题没有提供。于是bing了一下,发现有如下原文。
How to use MFC with CMake
To use MFC, the CMAKE_MFC_FLAG variable must be set as follows:
0: Use Standard Windows Libraries
1: Use MFC in a Static Library
2: Use MFC in a Shared DLL
This can be set in a CMakeLists.txt file and will enable MFC in the application. It should be set to 1 or 2. This is used in visual studio 6 and 7 project files. The CMakeSetup dialog uses MFC and the CMakeLists.txt looks like this:
ADD_DEFINITIONS(-D_AFXDLL)
SET(CMAKE_MFC_FLAG 2)
ADD_EXECUTABLE(CMakeSetup WIN32 ${SRCS})
Note that visual studio 9 project files do not appear to work with CMAKE_MFC_FLAG 1; this may be related to bug 7056.
In order to use MFC with UNICODE, you must also specify the entry point wWinMainCRTStartup. For example:
set(CMAKE_MFC_FLAG 2)
set_target_properties(MyApp PROPERTIES
COMPILE_DEFINITIONS _AFXDLL,_UNICODE,UNICODE,_BIND_TO_CURRENT_CRT_VERSION,_BIND_TO_CURRENT_MFC_VERSION
LINK_FLAGS "/ENTRY:\"wWinMainCRTStartup\"")
照做不误,本以为万事大吉,但发现生成的项目有个问题比较麻烦,在项目属性中,Character Set的值却是MBCS。显然,我并不希望如此。于是,继续bing,无果。
无奈,把cmake-2.8.1.zip下了下来,检索CharacterSet,发现如下内容。
cmLocalVisualStudio7Generator.cxx
// If unicode is enabled change the character set to unicode, if not
// then default to MBCS.
if(targetOptions.UsingUnicode())
{
fout << "\t\t\tCharacterSet=\"1\">\n";
}
else
{
fout << "\t\t\tCharacterSet=\"2\">\n";
}
是不是缺少了定义,继续定位。
cmVisualStudioGeneratorOptions.cxx
// Look for the a _UNICODE definition.
for(std::vector<std::string>::const_iterator di = this->Defines.begin();
di != this->Defines.end(); ++di)
{
//std::cout << *di << std::endl;
if(*di == "_UNICODE")
{
return true;
}
}
return false;
到这,立马明白,很有可能出在判断上。于是修改
if((*di).find("_UNICODE"))
编译,重新运行,一切正常。
通过,继续定位代码,问题来自cmSystemTools::ExpandListArgument的解析过程,对于如COMPILE_DEFINITIONS _AFXDLL;_UNICODE的解析不是预期的那样分解为多个串。