4.2 C/C++开发环境:VSCode+CMake+MSYS2

注意 :默认已安装好VSCode、CMake和MSYS2环境,其中MSYS2是解压安装的且没有设置环境变量。

基本流程:创建目录结构、配置CMake项目、使用Ninja或make构建项目。

一、VSCode终端是powershell

1.1 项目初始化

项目的目录结构:

powershell 复制代码
./
├── 3rd              # 第三方库的目录
├── build            # 编译目录
│   └── deps         # 如果程序使用动态库,要拷贝到这个目录
├── src              # 存储源码的目录
|    └── main.cpp   
├── CMakeLists.txt   # CMake配置文件
├── init_project.ps1 # 脚本1:生成项目的基本目录结构
├── set_env.ps1      # 脚本2:设置msys2 MinGW的环境变量,这样vscode的powershell终端能使用msys2
└── build.ps1        # 脚本2:编译脚本

初始化脚本init_project.ps1

powershell 复制代码
# 设置UTF-8编码
$OutputEncoding = [System.Text.Encoding]::UTF8
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8

# 创建项目目录结构
New-Item -ItemType Directory -Force -Path "3rd" | Out-Null
New-Item -ItemType Directory -Force -Path "src" | Out-Null
New-Item -ItemType Directory -Force -Path "build" | Out-Null

# 创建main.cpp文件
@"
#include <iostream>

int main() {
    std::cout << "Hello, World!" << std::endl;
    return 0;
}
"@ | Out-File -FilePath "src\main.cpp" -Encoding UTF8

# 创建CMakeLists.txt文件
@"
cmake_minimum_required(VERSION 3.10)
project(demo1)

# set(FFMPEG_DIR `${CMAKE_CURRENT_SOURCE_DIR}/3rd/ffmpeg)
# include_directories(`${FFMPEG_DIR}/include)
# link_directories(`${FFMPEG_DIR}/lib)
# set(FFMPEG_LIBS avformat avcodec avdevice avfilter avutil swresample swscale fdk-aac x264 z c m dl)
# add_executable(`${PROJECT_NAME} src/main.cpp `${FFMPEG_LIBS})

add_executable(`${PROJECT_NAME} src/main.cpp)
"@ | Out-File -FilePath "CMakeLists.txt" -Encoding UTF8

# 创建.gitignore文件
@"
.vscode/
build/
"@ | Out-File -FilePath ".gitignore" -Encoding UTF8

# 创建空的set_env.ps1和build.ps1文件
New-Item -ItemType File -Force -Path "set_env.ps1" | Out-Null
New-Item -ItemType File -Force -Path "build.ps1" | Out-Null

Write-Host "项目结构已创建完成!"

1.2 VSCode配置msys2

为了可以在VSCode终端里面使用MSYS2,这里设置一些环境变量。

配置msys2脚本 set_env.ps1

powershell 复制代码
# =============================================================================
#                          MSYS2 配置参数(可修改)
# =============================================================================
# MSYS2安装路径
$MSYS2_DIR = "D:\Program\msys64"

# 选择MSYS2子系统: MINGW64, MINGW32, MSYS, CLANG64
$MSYSTEM = "MINGW64"

# 是否继承当前环境变量PATH (yes=继承, no=不继承)
$MSYS2_PATH_TYPE = "inherit"
# =============================================================================
#                          以下内容请勿修改
# =============================================================================
# 设置输出编码为 UTF-8
$OutputEncoding = [System.Text.Encoding]::UTF8
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8

# 检查 MSYS2 目录是否存在
if (-not (Test-Path $MSYS2_DIR)) {
    Write-Error "Error: MSYS2 directory not found at $MSYS2_DIR"
    Write-Error "Please update MSYS2_DIR in this script to your MSYS2 installation path."
    exit 1
}

# 设置基本环境变量
$env:MSYS = "winsymlinks:nativestrict"
$env:MSYS2_ARG_CONV_EXCL = "*"
$env:MSYSTEM = $MSYSTEM
$env:MSYS2_PATH_TYPE = $MSYS2_PATH_TYPE

# 更新 PATH 环境变量
$env:Path = "$MSYS2_DIR\$MSYSTEM\bin;$MSYS2_DIR\usr\bin;$env:Path"

# 创建 PowerShell 配置
$profileContent = @"
`$env:MSYS = 'winsymlinks:nativestrict'
`$env:MSYSTEM = '$MSYSTEM'
`$env:MSYS2_PATH_TYPE = '$MSYS2_PATH_TYPE'
`$env:MSYS2_ARG_CONV_EXCL = '*'
`$env:Path = '$MSYS2_DIR\$MSYSTEM\bin;$MSYS2_DIR\usr\bin;' + `$env:Path
"@

# 确保配置文件目录存在
$profileDir = Split-Path $PROFILE
if (-not (Test-Path $profileDir)) {
    New-Item -ItemType Directory -Path $profileDir -Force | Out-Null
}

# 添加配置到 PowerShell 配置文件
$profileContent | Add-Content $PROFILE

Write-Host "MSYS2 $MSYSTEM environment loaded successfully."
Write-Host ""
Write-Host "Please restart your PowerShell terminal for the changes to take effect."

# 验证环境
$bashPath = "$MSYS2_DIR\usr\bin\bash.exe"
if (Test-Path $bashPath) {
    Write-Host ""
    Write-Host "MSYS2 Environment Information:"
    Write-Host "----------------------------"
    try {
        $unameOutput = & $bashPath -c "uname -a"
        if ($LASTEXITCODE -eq 0) {
            Write-Host $unameOutput
        } else {
            Write-Warning "Failed to execute uname command"
            exit 1
        }
    } catch {
        Write-Warning "Failed to execute uname command"
        exit 1
    }
    Write-Host "----------------------------"
    Write-Host "MSYS2 environment loaded successfully."
    Write-Host ""
} else {
    Write-Error "Error: bash.exe not found at $bashPath"
    exit 1
}

1.3 编译项目

(1) 手动编译

powershell 复制代码
# niaja 编译
cmake ..
ninja

# make编译 (使用mingw环境的make,而不是系统自带的)
cmake .. -G "MinGW Makefiles"
make  # mingw32-make 默认是这个名称

(2) 自动编译

编译脚本build.ps1

powershell 复制代码
# =============================================================================
#                          构建配置参数(可修改)
# =============================================================================
# 选择构建工具: NINJA 或 MINGW
$BUILD_TOOL = "NINJA"

# 程序名称
$PROGRAM_NAME = "demo1"

# 是否在构建完成后运行程序 (yes=运行, no=不运行)
$RUN_AFTER_BUILD = "yes"

# 是否清理并重新配置 (yes=重新配置, no=使用现有配置)
$RECONFIGURE = "no"

# =============================================================================
#                          以下内容请勿修改
# =============================================================================
# 设置输出编码为 UTF-8
$OutputEncoding = [System.Text.Encoding]::UTF8
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8

# 检查并创建build目录
if (-not (Test-Path "build")) {
    New-Item -ItemType Directory -Path "build" | Out-Null
}
Set-Location "build"

# 创建deps目录(在build目录下)
if (-not (Test-Path "deps")) {
    New-Item -ItemType Directory -Path "deps" | Out-Null
}

# 根据参数决定是否重新配置
if ($RECONFIGURE -eq "yes") {
    if (Test-Path "CMakeCache.txt") { Remove-Item "CMakeCache.txt" -Force }
    if (Test-Path "CMakeFiles") { Remove-Item "CMakeFiles" -Recurse -Force }
}

Write-Host "正在配置 CMake 项目..."
if ($BUILD_TOOL -eq "NINJA") {
    cmake -G "Ninja" ..
} elseif ($BUILD_TOOL -eq "MINGW") {
    cmake -G "MinGW Makefiles" ..
} else {
    Write-Error "错误:无效的构建工具选项 $BUILD_TOOL!"
    Write-Error "请将 BUILD_TOOL 设置为 NINJA 或 MINGW。"
    Set-Location ..
    exit 1
}

if ($LASTEXITCODE -ne 0) {
    Write-Error "CMake 配置失败!"
    Set-Location ..
    exit 1
}

Write-Host ""
Write-Host "正在构建项目..."
if ($BUILD_TOOL -eq "NINJA") {
    ninja
} else {
    mingw32-make
}

if ($LASTEXITCODE -ne 0) {
    Write-Error "构建失败!"
    Set-Location ..
    exit 1
}

Write-Host ""
Write-Host "正在检查依赖目录..."

# 检查依赖目录是否存在
if (-not (Test-Path "deps")) {
    Write-Error "错误:依赖目录不存在!"
    Write-Error "请在 build\deps 目录中放入所需的依赖库文件。"
    exit 1
}

# 设置依赖库路径和环境变量
$LIB_PATH = Join-Path $PWD "deps"
if (-not (Test-Path $LIB_PATH)) {
    Write-Error "错误:缺少依赖库目录 $LIB_PATH"
    exit 1
}

# 设置运行时环境变量
$env:Path = "$LIB_PATH;$env:Path"
if ($env:LD_LIBRARY_PATH) {
    $env:LD_LIBRARY_PATH = "$LIB_PATH;$env:LD_LIBRARY_PATH"
} else {
    $env:LD_LIBRARY_PATH = $LIB_PATH
}

Write-Host ""
Write-Host "正在运行程序..."
if ($RUN_AFTER_BUILD -eq "yes") {
    try {
        & ".\$PROGRAM_NAME.exe"
        if ($LASTEXITCODE -ne 0) {
            Write-Error "程序执行失败"
            exit 1
        }
    } catch {
        Write-Error "程序执行失败: $_"
        exit 1
    }
}

Write-Host ""
Set-Location ..

1.4 脚本使用顺序

init_project.ps1创建基本的目录结构(只需执行一次):

set_env.ps1设置msys2环境变量(只需执行一次):

build.bat编译运行程序(如有需要将依赖库拷贝到build/deps目录):

二、VSCode终端是cmd

2.1 项目初始化

目录结构:

bash 复制代码
./
├── 3rd              # 第三方库的目录
├── build            # 编译目录
│   └── deps         # 如果程序使用动态库,要拷贝到这个目录
├── src              # 存储源码的目录
|    └── main.cpp   
├── CMakeLists.txt   # CMake配置文件
├── init_project.bat # 脚本1:生成项目的基本目录结构
├── set_env.bat      # 脚本2:设置msys2 MinGW的环境变量,这样vscode的powershell终端能使用msys2
└── build.bat        # 脚本2:编译脚本

初始化脚本 init_project.bat

bash 复制代码
@echo off
chcp 65001 >nul

REM 创建项目目录结构
mkdir 3rd 2>nul
mkdir src 2>nul
mkdir build 2>nul

REM 创建main.cpp文件
echo #include ^<iostream^> > src\main.cpp
echo. >> src\main.cpp
echo int main() { >> src\main.cpp
echo     std::cout ^<^< "Hello, World!" ^<^< std::endl; >> src\main.cpp
echo     return 0; >> src\main.cpp
echo } >> src\main.cpp

REM 创建CMakeLists.txt
echo cmake_minimum_required(VERSION 3.10) > CMakeLists.txt
echo project(demo1) >> CMakeLists.txt
echo. >> CMakeLists.txt
echo # set(FFMPEG_DIR ${CMAKE_CURRENT_SOURCE_DIR}/3rd/ffmpeg) >> CMakeLists.txt
echo # include_directories(${FFMPEG_DIR}/include) >> CMakeLists.txt
echo # link_directories(${FFMPEG_DIR}/lib) >> CMakeLists.txt
echo # set(FFMPEG_LIBS avformat avcodec avdevice avfilter avutil swresample swscale fdk-aac x264 z c m dl) >> CMakeLists.txt
echo # add_executable(${PROJECT_NAME} src/main.cpp ${FFMPEG_LIBS}) >> CMakeLists.txt
echo. >> CMakeLists.txt
echo add_executable(${PROJECT_NAME} src/main.cpp) >> CMakeLists.txt

REM 创建.gitignore文件
echo .vscode/ > .gitignore
echo build/ >> .gitignore

REM 创建set_env.bat
echo. >> set_env.bat

REM 创建build.bat
echo. >> build.bat

echo 项目结构已创建完成!

2.2 VSCode配置MSYS2

设置mys2脚本 set_env.bat

powershell 复制代码
@echo off
rem =============================================================================
rem                          MSYS2 配置参数(可修改)
rem =============================================================================
rem MSYS2安装路径
set "MSYS2_DIR=D:\Program\msys64"

rem 选择MSYS2子系统: MINGW64, MINGW32, MSYS, CLANG64
set "MSYSTEM=MINGW64"

rem 是否继承当前环境变量PATH (yes=继承, no=不继承)
set "MSYS2_PATH_TYPE=inherit"

rem 是否启用Cygwin转换路径 (yes=启用, no=禁用)
set "MSYS2_CYGWIN_CONV=no"

rem =============================================================================
rem                          以下内容请勿修改
rem =============================================================================
rem 设置代码页为 UTF-8
chcp 65001 >nul

rem 检查 MSYS2 目录是否存在
if not exist "%MSYS2_DIR%" (
    echo Error: MSYS2 directory not found at %MSYS2_DIR%
    echo Please update MSYS2_DIR in this script to your MSYS2 installation path.
    exit /b 1
)

rem 设置基本环境变量
set "MSYS=winsymlinks:nativestrict"
set "MSYS2_ARG_CONV_EXCL=*"

rem 更新 PATH 环境变量
set "PATH=%MSYS2_DIR%\%MSYSTEM%\bin;%MSYS2_DIR%\usr\bin;%PATH%"

rem 创建一个临时的 PowerShell 配置文件
(
echo $env:MSYS = 'winsymlinks:nativestrict'
echo $env:MSYSTEM = '%MSYSTEM%'
echo $env:MSYS2_PATH_TYPE = '%MSYS2_PATH_TYPE%'
echo $env:MSYS2_ARG_CONV_EXCL = '*'
echo $env:Path = '%MSYS2_DIR%\%MSYSTEM%\bin;%MSYS2_DIR%\usr\bin;' + $env:Path
) > "%TEMP%\msys2_profile.ps1"

rem 将配置添加到 PowerShell 配置文件
powershell -NoProfile -Command "$profileDir = Split-Path $PROFILE; if (-not (Test-Path $profileDir)) { New-Item -ItemType Directory -Path $profileDir -Force }; Get-Content '%TEMP%\msys2_profile.ps1' | Add-Content $PROFILE"

rem 在当前会话中应用配置
powershell -NoProfile -ExecutionPolicy Bypass -File "%TEMP%\msys2_profile.ps1"

rem 清理临时文件
del "%TEMP%\msys2_profile.ps1" 2>nul

echo MSYS2 %MSYSTEM% environment loaded successfully.
echo.
echo Please restart your PowerShell terminal for the changes to take effect.

rem 验证环境
if exist "%MSYS2_DIR%\usr\bin\bash.exe" (
    echo.
    echo MSYS2 Environment Information:
    echo ----------------------------
    powershell -NoProfile -Command "& '%MSYS2_DIR%\usr\bin\bash.exe' -c 'uname -a'" 2>nul || (
        echo Warning: Failed to execute uname command
        exit /b 1
    )
    echo ----------------------------
    echo MSYS2 environment loaded successfully.
    echo.
) else (
    echo Error: bash.exe not found at %MSYS2_DIR%\usr\bin\bash.exe
    exit /b 1
)

2.2 编译

编译脚本 build.bat

powershell 复制代码
@echo off
setlocal EnableDelayedExpansion

rem =============================================================================
rem                          构建配置参数(可修改)
rem =============================================================================
rem 选择构建工具: NINJA 或 MINGW
set "BUILD_TOOL=NINJA"

rem 程序名称
set "PROGRAM_NAME=demo1"

rem 是否在构建完成后运行程序 (yes=运行, no=不运行)
set "RUN_AFTER_BUILD=yes"

rem 是否清理并重新配置 (yes=重新配置, no=使用现有配置)
set "RECONFIGURE=no"

rem =============================================================================
rem                          以下内容请勿修改
rem =============================================================================
rem 设置代码页为 UTF-8
chcp 65001 >nul

rem 检查并创建build目录
if not exist build mkdir build
cd build

rem 创建deps目录(在build目录下)
if not exist deps mkdir deps

rem 根据参数决定是否重新配置
if /i "%RECONFIGURE%"=="yes" (
    if exist CMakeCache.txt del /f /q CMakeCache.txt
    if exist CMakeFiles rmdir /s /q CMakeFiles
)

echo 正在配置 CMake 项目...
if /i "%BUILD_TOOL%"=="NINJA" (
    cmake -G "Ninja" ..
) else if /i "%BUILD_TOOL%"=="MINGW" (
    cmake -G "MinGW Makefiles" ..
) else (
    echo 错误:无效的构建工具选项 %BUILD_TOOL%!
    echo 请将 BUILD_TOOL 设置为 NINJA 或 MINGW。
    cd ..
    exit /b 1
)

if %ERRORLEVEL% neq 0 (
    echo CMake 配置失败!
    cd ..
    exit /b 1
)

echo.
echo 正在构建项目...
if /i "%BUILD_TOOL%"=="NINJA" (
    ninja
) else (
    mingw32-make
)

if %ERRORLEVEL% neq 0 (
    echo 构建失败!
    cd ..
    exit /b 1
)

echo.
echo 正在检查依赖目录...

rem 检查依赖目录是否存在
if not exist deps (
    echo 错误:依赖目录不存在!
    echo 请在 build\deps 目录中放入所需的依赖库文件。
    exit /b 1
)

rem 设置依赖库路径和环境变量
set "LIB_PATH=%CD%\deps"
if not exist "%LIB_PATH%" (
    echo 错误:缺少依赖库目录 %LIB_PATH%
    exit /b 1
)

rem 设置运行时环境变量
set "PATH=%LIB_PATH%;%PATH%"
if defined LD_LIBRARY_PATH (
    set "LD_LIBRARY_PATH=%LIB_PATH%;!LD_LIBRARY_PATH!"
) else (
    set "LD_LIBRARY_PATH=%LIB_PATH%"
)

if /i "%RUN_AFTER_BUILD%"=="yes" (
    %PROGRAM_NAME%.exe || (
        echo 程序执行失败
        exit /b 1
    )
)

echo.
endlocal
相关推荐
机器视觉知识推荐、就业指导2 小时前
C++/Qt 联合编程中的定时器使用陷阱:QObject::startTimer 报错详解
c++·qt
慢半拍iii2 小时前
数据结构——D/串
c语言·开发语言·数据结构·c++
邪恶的贝利亚2 小时前
从基础到实战-rmpt to webrtc
c++·webrtc·rtmp·流媒体
whoarethenext3 小时前
使用 C/C++ 和 OpenCV 提取图像的感兴趣区域 (ROI)
c语言·c++·opencv
小玺玺3 小时前
[RDK X5] MJPG编解码开发实战:从官方API到OpenWanderary库的C++/Python实现
c++·python·opencv·rdk x5
凌肖战3 小时前
力扣上C语言编程题:最大子数组和(涉及数组)
c语言·算法·leetcode
德先生&赛先生4 小时前
深入理解c语言中的static
c++
景彡先生4 小时前
C++ 中的 iostream 库:cin/cout 基本用法
开发语言·c++
逝缘~6 小时前
小白学Pinia状态管理
前端·javascript·vue.js·vscode·es6·pinia
SY师弟7 小时前
台湾TEMI协会竞赛——1、龙舟机器人组装教学
c语言·单片机·嵌入式硬件·机器人·嵌入式·台湾temi协会