如何在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一致
关键注意事项
- 必须执行
nmake clean:每次编译不同版本前清理构建目录,防止旧的目标文件、中间文件干扰新编译。 - 重命名输出文件:两个版本的exe必须改名,否则后编译的版本会覆盖前一个。
- Inno Setup适配:如果需要打包两个版本,需要修改
.iss脚本,要么将两个exe都包含进去,要么生成两个独立的安装包。
内容的提问来源于stack exchange,提问作者Sv443
相关产品推荐
相关产品推荐

