2、MPC配置开发案例
约 3434 字大约 11 分钟
2026-03-26
下面以LiquiBook项目为案例,研究下MPCb不同配置文件开发方式;
LiquiBook项目工作区文件
liquibook.mwc文件内容如下:
// 声明一个名为 liquibook 的工作区
// 工作区是 MPC 中的顶层组织单元,可以包含多个项目(.mpc 文件)
workspace(liquibook) {
// ========== 全局命令行选项 ==========
// 这些 cmdline 选项会应用到工作区内所有项目的生成过程中
// 添加 MPC 基础文件的搜索路径
// -include 选项告诉 MPC 在生成项目时,去 mpc 目录下查找基础项目文件(.mpb)
// 这些基础文件通常包含公共的编译配置(如头文件路径、宏定义等)
cmdline += -include mpc
// 添加 QUICKFAST_ROOT 环境变量指定的路径到基础文件搜索路径
// $QUICKFAST_ROOT 是一个环境变量,指向 QuickFIX 引擎的安装根目录
// 这样工作区内的项目就可以继承 QuickFIX 提供的基础配置
cmdline += -include $QUICKFAST_ROOT
// 指定特性配置文件
// -feature_file 选项告诉 MPC 读取 liquibook.features 文件
// 该文件定义了项目的可选特性(features),例如:
// - 是否启用 SSL 支持
// - 是否使用调试模式
// - 是否包含测试代码
// 特性可以通过 requires/avoids 关键字在 .mpc 文件中使用
cmdline += -feature_file liquibook.features
// 展开所有变量引用
// -expand_vars 选项让 MPC 在生成项目文件时,直接替换所有 $() 变量
// 例如:$(QUICKFAST_ROOT) 会被替换为实际路径
// 否则某些项目类型(如 Visual Studio)会保留变量形式
cmdline += -expand_vars
// 使用环境变量
// -use_env 选项允许在配置文件中使用环境变量
// 配合 -expand_vars 使用,可以在生成时动态替换环境变量值
cmdline += -use_env
// ========== 特定平台/构建工具的配置 ==========
// specific(make) 块内的配置只对 make 类型的项目生成器生效
// 这里的 "make" 通常指的是 GNU Make 或 NMake
specific(make) {
// -value_template 用于定义项目文件中某个字段的模板值
// 这里配置 make 生成器生成的 Makefile 中包含 "Release" 和 "Debug"
// 两种构建配置
//
// 等价于告诉 MPC:当生成 Makefile 时,为每个项目创建 Release 和
// Debug 两个构建目标,这样在执行 make 时可以指定:
// make # 默认配置(通常是 Release)
// make DEBUG=1 # Debug 构建
//
// 注意:对于 Visual Studio 项目,配置会自动包含 Release/Debug,
// 无需特别指定;但对于 Makefile 需要显式声明
cmdline += -value_template "configurations=Release Debug"
}
}| 配置项 | 作用 | 适用场景 |
|---|---|---|
-include mpc | 添加基础项目搜索路径 | 让项目可以继承 MPC 目录下的 .mpb 基础文件 |
-include $QUICKFAST_ROOT | 添加 QuickFIX 基础配置路径 | 集成 QuickFIX 金融协议库的编译配置 |
-feature_file liquibook.features | 指定特性配置文件 | 定义可选的编译特性,支持条件编译 |
-expand_vars | 展开变量 | 生成完整的、不依赖环境变量的项目文件 |
-use_env | 启用环境变量 | 允许在配置中使用 $变量名 引用环境变量 |
specific(make) 块 | make 专用配置 | 为 Makefile 生成器指定 Release/Debug 配置 |
WMC配置文件中有多重配置指令,详细指令使用方法可以参考: WMC配置指令
MPC配置文件
头文件mpc配置
// ============================================================================
// 项目声明
// ============================================================================
// project(项目名称) : 继承的基础项目列表
//
// 这里声明了一个名为 "liquibook" 的项目
// 它继承自 "liquibook_exe" 基础项目(通常定义在 .mpb 文件中)
// 这意味着 liquibook_exe 中定义的所有配置(如 includes、libs、macros 等)
// 都会被这个项目自动继承
project (liquibook): liquibook_exe {
// ==========================================================================
// 目标类型配置
// ==========================================================================
// exename = * 是一个特殊的语法
//
// 通常 exename 应该指定具体的可执行文件名,例如:
// exename = myapp
//
// 但这里使用了通配符 "*",它的含义是:
// "自动生成可执行文件名,使用项目名称作为基础"
// 实际上等价于 exename = liquibook
//
// 这种写法通常用于简化配置,避免重复输入项目名称
// 当项目名称和可执行文件名相同时特别有用
exename = *
// ==========================================================================
// 头文件列表
// ==========================================================================
// Header_files 组件:列出项目需要的头文件
// 这些文件通常用于 IDE 的项目文件中显示,方便开发时查看
// 也会影响依赖关系分析和预编译头处理
Header_files {
// *.h - 使用通配符匹配当前目录下所有 .h 文件
// 这会自动包含当前目录中的所有 C/C++ 头文件
// 注意:默认情况下不会递归搜索子目录
*.h
}
// ==========================================================================
// 源文件列表
// ==========================================================================
// Source_files 组件:列出需要编译的源文件
// 这些文件会被添加到编译命令中,生成目标文件(.o 或 .obj)
Source_files {
// *.cpp - 使用通配符匹配当前目录下所有 .cpp 文件
// 这会自动包含当前目录中的所有 C++ 源文件
// 注意:不包含子目录中的文件
*.cpp
}
}关键配置如下:
1、项目声明部分
| 元素 | 值 | 说明 |
|---|---|---|
| 项目名称 | liquibook | 项目的唯一标识符,用于在工作区中引用 |
| 继承基础项目 | liquibook_exe | 从 liquibook_exe 基础项目中继承所有配置 |
| 目标类型 | exename = * | 生成可执行文件,文件名自动使用项目名称 |
2、通配符 * 的使用
在 MPC 中,通配符 * 有两种使用场景:
| 场景 | 含义 | 示例 |
|---|---|---|
在 exename 中 | 使用项目名称作为可执行文件名 | exename = * → 生成 liquibook |
| 在文件列表中 | 匹配当前目录下所有符合模式的文件 | *.cpp → 所有 .cpp 文件 |
3、文件匹配规则
MPC 中文件列表的通配符匹配规则:
// 当前目录下的所有 .cpp 文件
Source_files {
*.cpp // 匹配:main.cpp, util.cpp 等
}
// 更复杂的匹配模式
Source_files {
src/*.cpp // 匹配 src 目录下的所有 .cpp 文件
**/*.cpp // 递归匹配所有子目录下的 .cpp 文件(需要 recurse=1)
}mpc配置文件,更多指令详解请参考: MPC 配置指令
MPB基础配置文件
liquibook_exe.mpb 文件配置内容:
// ============================================================================
// MPC 基础项目文件 (.mpb)
// ============================================================================
// 这是一个没有名称的项目声明(匿名项目)
// 这种匿名项目通常用作"配置片段",可以被其他项目继承
// 或者作为一个独立的配置块,影响后续的项目定义
project {
// ==========================================================================
// specific(prop:microsoft) 作用域
// ==========================================================================
// specific() 是 MPC 中的条件配置指令
// 语法: specific(类型:子类型) { ... }
//
// "prop:microsoft" 的含义:
// - "prop" 是项目属性(property)类型
// - "microsoft" 表示这是针对微软编译器/工具链的配置
//
// 这个条件块内的配置只在以下情况生效:
// 1. 使用微软的编译工具链(Visual Studio、MSVC 等)
// 2. 并且项目类型支持属性配置
// 3. 或者通过 MPC 的 -features 或特定配置启用
specific(prop:microsoft) {
// ------------------------------------------------------------------------
// Release 配置的可执行文件输出路径
// ------------------------------------------------------------------------
// "Release::exeout" 语法:配置名::配置项
//
// 含义:
// - Release: 指定这是 Release 构建配置下的设置
// - exeout: 可执行文件输出路径(exe output)
// - $(LIQUIBOOK_ROOT): 环境变量,指向 liquibook 项目的根目录
//
// 这个设置告诉 MPC:当生成 Release 配置的项目时,
// 将可执行文件输出到 $(LIQUIBOOK_ROOT)/Output/Release 目录
Release::exeout = $(LIQUIBOOK_ROOT)/Output/Release
// ------------------------------------------------------------------------
// Debug 配置的可执行文件输出路径
// ------------------------------------------------------------------------
// 类似 Release 配置,这是 Debug 构建配置下的设置
// 将可执行文件输出到 $(LIQUIBOOK_ROOT)/Output/Debug 目录
Debug::exeout = $(LIQUIBOOK_ROOT)/Output/Debug
// 注意:这里没有指定其他配置(如 Release_Debug、MinSizeRel 等)
// 其他配置会使用默认值或继承其他地方的设置
}
// ==========================================================================
// else 子句:非微软工具链的配置
// ==========================================================================
// else 块对应上面的 specific(prop:microsoft)
// 当 specific 条件不满足时(即不使用微软编译工具链),执行这个 else 块
//
// 常见场景:
// - 使用 GCC/Clang 编译器(Linux/macOS)
// - 使用 MinGW(Windows 上的 GCC)
// - 使用其他非微软的构建工具
else {
// ------------------------------------------------------------------------
// 通用可执行文件输出路径
// ------------------------------------------------------------------------
// exeout: 可执行文件输出路径(不区分构建配置)
//
// 对于非微软工具链(如 GNU Make),通常不需要区分 Release/Debug
// 输出目录,或者通过其他方式(如 make 参数)控制
//
// 这里将所有可执行文件输出到 $(LIQUIBOOK_ROOT)/bin 目录
// 这是 Linux/Unix 环境下常见的做法
exeout = $(LIQUIBOOK_ROOT)/bin
}
}1、匿名项目(Anonymous Project)
project { ... }| 特点 | 说明 |
|---|---|
| 无名 | 没有指定项目名称,不能被其他项目直接通过名称继承 |
| 作用 | 作为配置块,影响后续定义的项目,或作为条件配置容器 |
| 使用场景 | 常用于 .mpb 文件中定义公共配置,或作为条件配置模板 |
2、specific(prop:microsoft) 条件指令
这是 MPC 中最强大的条件配置机制之一:
| 组成部分 | 说明 |
|---|---|
specific | MPC 的关键字,表示条件配置块 |
prop | 配置类型,表示这是项目属性(property)相关的条件 |
microsoft | 子类型,表示微软工具链(Visual Studio、MSVC) |
{ } | 条件满足时执行的配置块 |
常见的 specific 类型:
| 类型 | 说明 | 示例 |
|---|---|---|
prop:microsoft | 微软工具链 | specific(prop:microsoft) { ... } |
prop:gnu | GNU 工具链 | specific(prop:gnu) { ... } |
prop:borland | Borland 工具链 | specific(prop:borland) { ... } |
make | Make 构建系统 | specific(make) { ... } |
vc10 | Visual Studio 2010 | specific(vc10) { ... } |
3、配置名称和作用域
Release::exeout = $(LIQUIBOOK_ROOT)/Output/Release这个语法的完整解析:
| 语法部分 | 说明 |
|---|---|
Release | 构建配置名称(Build Configuration) |
:: | 作用域解析符,表示配置特定于该构建配置 |
exeout | 配置项名称,表示可执行文件输出路径 |
= | 赋值操作符 |
$(LIQUIBOOK_ROOT)/Output/Release | 赋值内容,使用了环境变量 |
常见的构建配置名称:
| 配置名 | 说明 |
|---|---|
Release | 发布版本(优化、无调试信息) |
Debug | 调试版本(无优化、包含调试信息) |
RelWithDebInfo | 带调试信息的发布版本 |
MinSizeRel | 最小体积发布版本 |
4、环境变量使用
$(LIQUIBOOK_ROOT)/Output/Release| 语法 | 说明 |
|---|---|
$(变量名) | MPC 中引用变量的标准语法 |
LIQUIBOOK_ROOT | 环境变量名称,需要提前在 shell 中设置 |
| 路径拼接 | MPC 会自动处理路径分隔符(Windows 用 \,Unix 用 /) |
设置环境变量示例:
# Linux/macOS
export LIQUIBOOK_ROOT=/home/user/liquibook
# Windows (CMD)
set LIQUIBOOK_ROOT=C:\liquibook
# Windows (PowerShell)
$env:LIQUIBOOK_ROOT = "C:\liquibook"5、条件执行逻辑
这段代码的执行逻辑如下:
┌─────────────────────────────────────┐
│ 检查是否使用微软编译工具链 │
│ (specific(prop:microsoft) 条件) │
└──────────────┬──────────────────────┘
│
┌──────┴──────┐
▼ ▼
条件为真 条件为假
(使用 MSVC) (使用 GCC/Clang)
│ │
▼ ▼
┌───────────────┐ ┌───────────────┐
│ Release 配置 │ │ else 块 │
│ 输出到: │ │ 输出到: │
│ Output/Release │ │ bin/ │
├───────────────┤ ├───────────────┤
│ Debug 配置 │ │ 不区分配置 │
│ 输出到: │ │ 统一输出 │
│ Output/Debug │ │ │
└───────────────┘ └───────────────┘liquibook_simple.mpb
liquibook_simple.mpb配置文件内容如下:
// ============================================================================
// MPC 项目配置示例
// ============================================================================
// 项目声明:定义一个名为 "liquibook" 的项目
// 语法:project : 项目名称 { ... }
//
// 注意:这里使用的是冒号 ":" 而不是圆括号 "()"
// 这种写法是 MPC 项目声明的另一种形式:
// project : liquibook // 项目名为 liquibook
// project(liquibook) // 与上一行等价
//
// 这种写法通常用于项目名称不需要指定继承关系时
project : liquibook {
// ==========================================================================
// 库依赖配置
// ==========================================================================
// libs += 指令:添加需要链接的库
//
// "liquibook_simple" 是一个库的名称
// MPC 会自动根据平台添加前缀(lib)和后缀(.a、.lib、.so、.dll 等)
//
// 这个配置告诉链接器:在链接时需要链接 liquibook_simple 库
// 相当于在命令行中添加:-lliquibook_simple (Linux) 或 liquibook_simple.lib (Windows)
libs += liquibook_simple
// ==========================================================================
// 项目依赖顺序配置
// ==========================================================================
// after += 指令:指定项目构建依赖顺序
//
// 这个配置告诉 MPC:在构建当前项目(liquibook)之前,
// 必须先构建完 "liquibook_simple" 项目
//
// 这种依赖关系确保:
// 1. 编译顺序正确(依赖的项目先编译)
// 2. 链接时能找到依赖的库文件
// 3. 在 IDE(如 Visual Studio)中正确设置项目依赖关系
after += liquibook_simple
}1、项目声明语法对比
MPC 中项目声明的两种等价形式:
| 语法形式 | 示例 | 说明 |
|---|---|---|
| 圆括号形式 | project(liquibook) : base { ... } | 明确指定项目名和继承关系 |
| 冒号形式 | project : liquibook { ... } | 项目名放在冒号后,不能指定继承 |
// 这两种写法完全等价
project(liquibook) {
libs += liquibook_simple
}
project : liquibook {
libs += liquibook_simple
}
// 如果需要继承基础项目,必须使用圆括号形式
project(liquibook) : common_base {
libs += liquibook_simple
}2、libs += 指令详解
libs 指令用于指定需要链接的库:
| 方面 | 说明 |
|---|---|
| 作用 | 添加链接时需要的库文件 |
| 操作符 | += 追加库到列表 |
| 值 | liquibook_simple 库名(不含前缀和后缀) |
| 平台处理 | MPC 自动处理平台差异 |
不同平台的实际效果:
| 平台 | 生成的链接参数 |
|---|---|
| Linux/Unix (GCC) | -lliquibook_simple |
| Windows (MSVC) | liquibook_simple.lib |
| Windows (MinGW) | -lliquibook_simple |
| macOS (Clang) | -lliquibook_simple |
3、after += 指令详解
after 指令用于指定项目构建顺序:
| 方面 | 说明 |
|---|---|
| 作用 | 定义项目之间的构建依赖关系 |
| 操作符 | += 追加依赖项目 |
| 值 | liquibook_simple 被依赖的项目名 |
| 效果 | 确保 liquibook_simple 在 liquibook 之前构建 |
在 Visual Studio 中的效果:
项目依赖关系设置:
liquibook 依赖于 liquibook_simple
→ 构建 liquibook 前会先构建 liquibook_simple在 Makefile 中的效果:
# 生成类似这样的依赖关系
liquibook: liquibook_simple
$(CXX) -o liquibook liquibook.o -lliquibook_simple