You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在GitLab CI中通过MSVC2017_x64生成带自定义宏的多版本C++应用

解决GitLab CI下Windows+MSVC生成多版本C++应用的问题

你的核心问题在于给nmake加-D参数是错误的——nmake的-D选项是用来启用调试输出的,不是传递预定义宏给MSVC编译器的。下面提供两种可靠的解决方案,完全不依赖用户环境配置,只通过GitLab CI脚本实现:


方案1:通过qmake的DEFINES传递预定义宏(推荐)

qmake会自动将DEFINES变量中的内容转换为MSVC的/D编译参数,这是Qt项目传递预定义宏的标准方式。同时可以直接把GitLab流水线ID作为宏嵌入代码:

修改后的.gitlab-ci.yml示例:

stages:
- build
- test
variables:
  GIT_SUBMODULE_STRATEGY: recursive
build:
  stage: build
  only:
    - master
  tags:
    - windows
    - qt
  script:
    - call "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvars64.bat"
    - call "C:\Qt\5.9.1\msvc2017_64\bin\qtenv2.bat"
    - set CL=/MP16
    - set PATH="C:\Program Files (x86)\Inno Setup 5";%PATH%
    
    # 定义路径变量简化后续命令
    - set APP_SRC_DIR=%CI_PROJECT_DIR%\(...)\Application
    - set OUTPUT_DIR=%CI_PROJECT_DIR%\(...)\3rdParty\Windows

    # 编译生产版本(prod)
    - cd %APP_SRC_DIR%
    - qmake CONFIG+=release DEFINES+=MODE_PROD DEFINES+=BUILD_ID=%CI_PIPELINE_ID%
    - nmake clean  # 清理上次编译残留,避免版本冲突
    - nmake
    - copy Application.exe %OUTPUT_DIR%\Application_prod.exe  # 重命名避免覆盖

    # 编译预发布版本(stage)
    - cd %APP_SRC_DIR%
    - qmake CONFIG+=release DEFINES+=MODE_STAGE DEFINES+=BUILD_ID=%CI_PIPELINE_ID%
    - nmake clean
    - nmake
    - copy Application.exe %OUTPUT_DIR%\Application_stage.exe

    # 部署依赖并打包
    - cd %OUTPUT_DIR%
    - copy %APP_SRC_DIR%\Application.ico .
    - windeployqt Application_prod.exe
    - windeployqt Application_stage.exe
    - iscc InnoScript.iss  # 需修改iss文件适配双版本打包,或生成两个独立安装包
  artifacts:
    name: "%CI_COMMIT_REF_NAME%"
    expire_in: 1 month
    paths:
      - (...)\3rdParty\Windows\Application_prod.exe
      - (...)\3rdParty\Windows\Application_stage.exe

代码中如何使用宏:

#include <iostream>

int main() {
#ifdef MODE_PROD
    std::cout << "Production Build | Pipeline ID: " << BUILD_ID << std::endl;
#elif defined(MODE_STAGE)
    std::cout << "Staging Build | Pipeline ID: " << BUILD_ID << std::endl;
#endif
    return 0;
}

方案2:动态生成配置头文件(更灵活)

如果不想修改qmake参数,可以直接在CI脚本中生成一个临时头文件,定义所需宏,代码中只需包含这个头文件即可:

CI脚本修改部分:

# 生成生产版本配置头文件
- echo #define MODE_PROD > %APP_SRC_DIR%\build_config.h
- echo #define BUILD_ID %CI_PIPELINE_ID% >> %APP_SRC_DIR%\build_config.h
- cd %APP_SRC_DIR%
- qmake CONFIG+=release
- nmake clean
- nmake
- copy Application.exe %OUTPUT_DIR%\Application_prod.exe

# 生成预发布版本配置头文件
- echo #define MODE_STAGE > %APP_SRC_DIR%\build_config.h
- echo #define BUILD_ID %CI_PIPELINE_ID% >> %APP_SRC_DIR%\build_config.h
- cd %APP_SRC_DIR%
- qmake CONFIG+=release
- nmake clean
- nmake
- copy Application.exe %OUTPUT_DIR%\Application_stage.exe

代码中引入头文件:

#include "build_config.h"
// 后续宏判断逻辑和方案1一致

关键注意事项

  1. 必须执行nmake clean:每次编译不同版本前清理构建目录,防止旧的目标文件、中间文件干扰新编译。
  2. 重命名输出文件:两个版本的exe必须改名,否则后编译的版本会覆盖前一个。
  3. Inno Setup适配:如果需要打包两个版本,需要修改.iss脚本,要么将两个exe都包含进去,要么生成两个独立的安装包。

内容的提问来源于stack exchange,提问作者Sv443

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:49:58