在windows平台上,由于平台API差异过大,一般为linux设计的项目(POSIX兼容)无法通过MSVC的编译,而是会报非常多的头文件错误。如果要修改,工程量将巨大。Windows平台上,主要有两个类POSIX兼容平台,可以在Windows系统上编译运行为Linux编写的程序(功能支持不完整)。
cmake是一个跨平台项目编译工具,通过CMakeLists.txt
文件,可以方便地管理项目文件,并灵活地组织编译。根据工具链的不同,编译结果可以应用于各个平台上。例如,Linux系统中,cmake可以编译出Makefile
,并交给linux平台的make程序进行编译。
一个项目需要在Windows平台上编译,但是是面向linux编写的(Makefile
),这时候就需要使用Windows平台上的工具链进行编译。但是,多文件项目管理复杂,一个一个文件进行编译较为繁琐,这时候,就可以使用cmake工具辅助进行编译。
笔者是VS Code重度依赖用户,所以在VS Code上利用cmake tools进行配置。当然也可以使用命令行或是cmake-gui进行配置,只不过cmake tools更加集成和方便。
Clang-CL for MSVC
可以在Visual Studio的组件中找到
CMake
可以在官网下载,安装后注意检查PATH,是否添加cmake
我们应当明确几个编译概念:
Make
构建系统(即Linux中使用Makefile
进行构建的系统),以及Ninja
(一套更轻量的命令行构建系统,是CMake Tools 的默认构建系统)MingGW
编译系统使用编译工具链,按照开发者指定的编译规则进行程序的编译链接。那么,CMake属于哪里?CMake 属于更上一层的编译工具,使用CMake,可以生成任何一种适配的Build System所需要的规则,然后再调用这些Build System进行程序编译。
在VS Code中,安装插件CMake Tools
,并在项目目录中创建CMakeLists.txt
文件,插件被激活后,状态栏会显示CMake Toolkits, Build Variant, Build Target等信息。如果是第一次在项目中使用插件,Toolkits工具链会显示No Kit Selected
,单击该按钮,出现选择框。
初次配置,点击Scan for kits
,工具会自动扫描电脑上安装的工具链。
Clang for MSVC 对应有四条(名称已经被我修改,正常情况下还有版本信息),Build Target有x86和x64,命令行接口有GNU CLI和MSVC CLI。
接下来,检查工具链配置参数,Ctrl+Shift+P
,打开Command Palette,输入cmake kits
-> 编辑用户本地CMake 工具包,这会打开一个json文件。
部分配置如下:
{
"name": "Clang 14.0.5 (GNU CLI) for MSVC (VS Community 2022 Release - x86)",
"visualStudio": "8b689476",
"visualStudioArchitecture": "x86",
"compilers": {
"C": "C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Tools\\Llvm\\bin\\clang.exe",
"CXX": "C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Tools\\Llvm\\bin\\clang.exe"
}
},
{
"name": "Clang 14.0.5 (MSVC CLI) for MSVC (VS Community 2022 Release - x64)",
"visualStudio": "8b689476",
"visualStudioArchitecture": "x64",
"preferredGenerator": {
"name": "Visual Studio 17 2022",
"platform": "x64",
"toolset": "ClangCL"
},
"compilers": {
"C": "C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Tools\\Llvm\\x64\\bin\\clang-cl.exe",
"CXX": "C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Tools\\Llvm\\x64\\bin\\clang-cl.exe"
}
},
ClangCL
,若为host=xxx
,则仍将通过传统MSVC工具链编译,仍会遇到API不适配问题preferredGenerator
为MSVC工具链Debug
调试模式(包含调试信息)、Release
发布模式(去除调试信息,增加优化)[all]
全部编译,但是速度很慢,注意更换使用命令选项卡可以进行更加完整的配置,常用的有两个:
CMakeLists.txt
指定的安装配置进行生成工具的安装IDE中显示这个错误,通常有两种来源:
cmake configure
,在command palette 进行cmake: Configure
即可修复。file not found
而没有其他提示,这是C/C++ Clang adapter 的报错,这个插件功能完全冗余,而且配置未知,直接卸载即可。在一个目录下,创建如下文件
G:.
│ CMakeLists.txt
├─include
│ hello_lib.h
├─lib
│ │ CMakeLists.txt
│ ├─include
│ │ hello_lib.h
│ └─src
│ hello_lib.c
└─src
hello.c
// hello.c
#include
#include
#include "hello_lib.h"
int main() {
printf("Hello World!\n");
DbgPrint("%s\n", "Hello World"); // defined in hello_lib
return 0;
}
// hello_lib.h
#include
#include
#include
#include
void DbgPrint(char* FormatStr, ...);
// hello_lib.c
#include "hello_lib.h"
void DbgPrint(char* FormatStr, ...)
{
char dbgout[1000];
va_list vaList;
va_start(vaList, FormatStr);
sprintf(dbgout, FormatStr, vaList);
OutputDebugStringA(dbgout);
va_end(vaList);
}
然后配置CMakeLists:
root
cmake_minimum_required(VERSION 3.0)
project(HELLO)
add_subdirectory(lib)
aux_source_directory(src src_dir)
add_executable(hello ${src_dir})
target_include_directories(hello PUBLIC ${PROJECT_SOURCE_DIR}/include)
target_link_libraries(hello PUBLIC hello_lib)
add_subdirectory
增加子项目target_link_libraries
链接库,hello_lib
在子项目中定义lib
cmake_minimum_required(VERSION 3.0)
project(HELLO_LIB)
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/src src_dir)
add_library(hello_lib STATIC ${src_dir})
target_include_directories(hello_lib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
add_library(STATIC)
添加静态库最后,build,输出结果:
[build] hello_lib.vcxproj -> G:\C\Cmake Test\build\lib\Debug\hello_lib.lib
[build] hello.c
[build] hello.vcxproj -> G:\C\Cmake Test\build\Debug\hello.exe
[build] Build finished with exit code 0