使用vscode搭建cmake工程

一、什么是cmake?

Cmake是一个跨平台的构建系统生成工具,它生成的是编译后的工程代码吗?不,它生成的是构建脚本,举个例子,编写好CMakefileLists.txt,CMake工具会为你生成晦涩难懂的makefile文件,然后再通过make构建工具进行代码编译、链接等操作。

那有人就要问了,既然我还得编写CMakefileLists.txt文件,那为什么不直接编写makefile文件呢?答案是CMakefileLists.txt的可读性非常强,需要写的代码量也比较少,就可以自动生成makefile文件了。

这里引入一个简单的CMake工程,main.c中main函数调用hello.c文件中的函数,二者位于不同文件夹目录下。

main.c

cpp 复制代码
#include <stdio.h>
#include "hello.h"

void main(void)
{
    HelloTypedef_t myHello;
    
    helloInit(&myHello, "crkylin", 22);
    helloPrint(&myHello);
}

hello.c

cpp 复制代码
#include "hello.h"

HelloTypedef_t myHello;

void helloInit(HelloTypedef_t* hello, const char* name, unsigned char age)
{
    strcpy(hello->name, name);
    hello->age = age;
}

void helloPrint(HelloTypedef_t* hello)
{
    printf("hello, my name is %s, age %d\r\n", hello->name, hello->age);
}

hello.o

cpp 复制代码
#ifndef __HELLO_H
#define __HELLO_H

#include <string.h>

typedef struct hello_s
{
    /* data */
    const char name[12];
    unsigned char age;
} HelloTypedef_t;


void helloInit(HelloTypedef_t* hello, const char* name, unsigned char age);
void helloPrint(HelloTypedef_t* hello);

#endif

CMakeLists.txt

cpp 复制代码
cmake_minimum_required(VERSION 3.10)

project(Hello)

file(GLOB SRC_FILES
    "${PROJECT_SOURCE_DIR}/drivers/Src/**"
    "${PROJECT_SOURCE_DIR}/**")

include_directories(
    ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Inc
)

add_executable(${CMAKE_PROJECT_NAME} ${SRC_FILES})

Makefile文件

Go 复制代码
# CMAKE generated file: DO NOT EDIT!
# Generated by "Unix Makefiles" Generator, CMake Version 3.22

# Default target executed when no arguments are given to make.
default_target: all
.PHONY : default_target

# Allow only one "make -f Makefile2" at a time, but pass parallelism.
.NOTPARALLEL:

#=============================================================================
# Special targets provided by cmake.

# Disable implicit rules so canonical targets will work.
.SUFFIXES:

# Disable VCS-based implicit rules.
% : %,v

# Disable VCS-based implicit rules.
% : RCS/%

# Disable VCS-based implicit rules.
% : RCS/%,v

# Disable VCS-based implicit rules.
% : SCCS/s.%

# Disable VCS-based implicit rules.
% : s.%

.SUFFIXES: .hpux_make_needs_suffix_list

# Command-line flag to silence nested $(MAKE).
$(VERBOSE)MAKESILENT = -s

#Suppress display of executed commands.
$(VERBOSE).SILENT:

# A target that is always out of date.
cmake_force:
.PHONY : cmake_force

#=============================================================================
# Set environment variables for the build.

# The shell in which to execute make rules.
SHELL = /bin/sh

# The CMake executable.
CMAKE_COMMAND = /usr/bin/cmake

# The command to remove a file.
RM = /usr/bin/cmake -E rm -f

# Escaping for special characters.
EQUALS = =

# The top-level source directory on which CMake was run.
CMAKE_SOURCE_DIR = /home/crkylin/linux/cmake

# The top-level build directory on which CMake was run.
CMAKE_BINARY_DIR = /home/crkylin/linux/cmake/build

#=============================================================================
# Targets provided globally by CMake.

# Special rule for the target edit_cache
edit_cache:
	@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "No interactive CMake dialog available..."
	/usr/bin/cmake -E echo No\ interactive\ CMake\ dialog\ available.
.PHONY : edit_cache

# Special rule for the target edit_cache
edit_cache/fast: edit_cache
.PHONY : edit_cache/fast

# Special rule for the target rebuild_cache
rebuild_cache:
	@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake to regenerate build system..."
	/usr/bin/cmake --regenerate-during-build -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)
.PHONY : rebuild_cache

# Special rule for the target rebuild_cache
rebuild_cache/fast: rebuild_cache
.PHONY : rebuild_cache/fast

# The main all target
all: cmake_check_build_system
	$(CMAKE_COMMAND) -E cmake_progress_start /home/crkylin/linux/cmake/build/CMakeFiles /home/crkylin/linux/cmake/build//CMakeFiles/progress.marks
	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 all
	$(CMAKE_COMMAND) -E cmake_progress_start /home/crkylin/linux/cmake/build/CMakeFiles 0
.PHONY : all

# The main clean target
clean:
	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 clean
.PHONY : clean

# The main clean target
clean/fast: clean
.PHONY : clean/fast

# Prepare targets for installation.
preinstall: all
	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 preinstall
.PHONY : preinstall

# Prepare targets for installation.
preinstall/fast:
	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 preinstall
.PHONY : preinstall/fast

# clear depends
depend:
	$(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 1
.PHONY : depend

#=============================================================================
# Target rules for targets named Hello

# Build rule for target.
Hello: cmake_check_build_system
	$(MAKE) $(MAKESILENT) -f CMakeFiles/Makefile2 Hello
.PHONY : Hello

# fast build rule for target.
Hello/fast:
	$(MAKE) $(MAKESILENT) -f CMakeFiles/Hello.dir/build.make CMakeFiles/Hello.dir/build
.PHONY : Hello/fast

drivers/Src/hello.o: drivers/Src/hello.c.o
.PHONY : drivers/Src/hello.o

# target to build an object file
drivers/Src/hello.c.o:
	$(MAKE) $(MAKESILENT) -f CMakeFiles/Hello.dir/build.make CMakeFiles/Hello.dir/drivers/Src/hello.c.o
.PHONY : drivers/Src/hello.c.o

drivers/Src/hello.i: drivers/Src/hello.c.i
.PHONY : drivers/Src/hello.i

# target to preprocess a source file
drivers/Src/hello.c.i:
	$(MAKE) $(MAKESILENT) -f CMakeFiles/Hello.dir/build.make CMakeFiles/Hello.dir/drivers/Src/hello.c.i
.PHONY : drivers/Src/hello.c.i

drivers/Src/hello.s: drivers/Src/hello.c.s
.PHONY : drivers/Src/hello.s

# target to generate assembly for a file
drivers/Src/hello.c.s:
	$(MAKE) $(MAKESILENT) -f CMakeFiles/Hello.dir/build.make CMakeFiles/Hello.dir/drivers/Src/hello.c.s
.PHONY : drivers/Src/hello.c.s

main.o: main.c.o
.PHONY : main.o

# target to build an object file
main.c.o:
	$(MAKE) $(MAKESILENT) -f CMakeFiles/Hello.dir/build.make CMakeFiles/Hello.dir/main.c.o
.PHONY : main.c.o

main.i: main.c.i
.PHONY : main.i

# target to preprocess a source file
main.c.i:
	$(MAKE) $(MAKESILENT) -f CMakeFiles/Hello.dir/build.make CMakeFiles/Hello.dir/main.c.i
.PHONY : main.c.i

main.s: main.c.s
.PHONY : main.s

# target to generate assembly for a file
main.c.s:
	$(MAKE) $(MAKESILENT) -f CMakeFiles/Hello.dir/build.make CMakeFiles/Hello.dir/main.c.s
.PHONY : main.c.s

# Help Target
help:
	@echo "The following are some of the valid targets for this Makefile:"
	@echo "... all (the default if no target is provided)"
	@echo "... clean"
	@echo "... depend"
	@echo "... edit_cache"
	@echo "... rebuild_cache"
	@echo "... Hello"
	@echo "... drivers/Src/hello.o"
	@echo "... drivers/Src/hello.i"
	@echo "... drivers/Src/hello.s"
	@echo "... main.o"
	@echo "... main.i"
	@echo "... main.s"
.PHONY : help



#=============================================================================
# Special targets to cleanup operation of make.

# Special rule to run CMake to check the build system integrity.
# No rule that depends on this can have commands that come from listfiles
# because they might be regenerated.
cmake_check_build_system:
	$(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 0
.PHONY : cmake_check_build_system

十行左右的CMakeLists.txt文件生成了两百行CMakefile文件,帮助我们来构建项目代码。

极大提高了开发者构建工程的效率。

二、如何搭建CMake工程?

安装插件`C/C++`,`C/C++ Extension Pack`,`CMake Language Support`,`CMake Tools`,`Makefile Tools`

  1. 编写项目文件,如上述的main.c, hello.c, hello.h。为模拟实际项目,可以将源文件放在不同目录下。

  2. 编写CMakeLists.txt文件

    cmake_minimum_required(VERSION 3.10) # 要求使用3.10版本以上CMake工具

    project(Hello) # 项目名称为Hello

    file(GLOB SRC_FILES # 添加全局源文件
    "{PROJECT_SOURCE_DIR}/drivers/Src/**" # hello.c所在目录 "{PROJECT_SOURCE_DIR}/**") # main.c所在目录

    include_directories(
    ${CMAKE_CURRENT_SOURCE_DIR}/drivers/Inc # 添加头文件目录
    )

    添加可执行文件,第一个参数是输出文件名,第二个参数是源文件

    add_executable({CMAKE_PROJECT_NAME} {SRC_FILES})

  3. 使用CMake工具生成构建脚本

在vscode中按下F7,CMake工具会让我们选择使用的编译器,这里我们选GCC 11.4.0 x86_64-linux-gnu

三、编译运行

相关推荐
Mr.zwX2 小时前
如何用vscode/cursor快速绑定并操作远程Github仓库
ide·vscode·github
MounRiver_Studio2 小时前
RISC-V IDE MRS2使用笔记(九):静态代码分析
ide·mcu·risc-v·嵌入式开发
凯小默2 小时前
cursor 跟 vscode 编辑器里面怎么打开绘制 drawio 的文件?
vscode·draw.io·cursor
万能的小裴同学2 小时前
Android Studio 2025版JNI配置
android·ide·android studio
MounRiver_Studio2 小时前
RISC-V IDE MRS2使用笔记(八):手动切换文件编码
ide·mcu·嵌入式·risc-v
Lovely Ruby2 小时前
Cursor 迁移到 Zed 编辑器
java·缓存·编辑器
Gu_yyqx2 小时前
IDEA中debug的使用
java·ide·intellij-idea
云声风语2 小时前
buuCTF练习题misc大白记一次vim配合xxd使用
linux·编辑器·vim
Lv117700818 小时前
Visual Studio中的多态
ide·笔记·c#·visual studio