cmake-多模块工程的编译

本文详细介绍了如何使用CMake进行子模块的编译,包括动态库和可执行文件的生成。通过一个包含多个子模块(苹果、梨、橙子)的示例工程,演示了如何设置目录结构,配置CMakeLists.txt文件,以及如何使用add_subdirectory和add_library等命令。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

承接上文 cmake-外部库的导入引出的问题:假设有这样一个需求,一个大型工程的编译中,不仅要有可执行程序生成,而且还有动态库的生成,或者说构建一个sdk。显然就会涉及子模块的编译问题,接下来我们将要解决这个问题。

目录结构

|-- bin
|-- build
|-- CMakeLists.txt
|-- inc
|   |-- apple.h
|   |-- orange.h
|   `-- pear.h
|-- lib
`-- src
    |-- apple
    |   |-- apple.c
    |   `-- CMakeLists.txt
    |-- CMakeLists.txt
    |-- main.c
    |-- orange
    |   |-- CMakeLists.txt
    |   `-- orange.c
    `-- pear
        |-- CMakeLists.txt
        `-- pear.c

目录结构说明

bin目录用来存放生成的可执行文件

lib目录用来存放生成的动态库文件

src目录下有三个子目录 apple、pear、orange,本文中假设这三个水果子模块即为三个对应的so库;同时main.c将调用每个子模块中的函数生成一个可执行文件fruit。

功能说明

apple.c

#include <stdio.h>

void apple()
{
    printf("I'm an Apple\n");
}

pear.c

#include <stdio.h>

void pear()
{
    printf("I'm a pear\n");
}

orange.c

#include <stdio.h>

void orange()
{
    printf("I'm an Orange\n");
}

main.c

#include <stdio.h>
#include <stdlib.h>
#include "apple.h"
#include "pear.h"
#include "orange.h"

int main(int argc, char** argv)
{
    apple();
    pear();
    orange();

    return 0;
}

从上面的源码可以知道,apple、pear、orange三个库非常简单,就只有一个函数,函数的实现为简单的一句打印。main.c分别调用一次三个库中的函数。由于本文的重点在于cmake的子模块的编译,所以模拟的代码都非常简单。

需要说明的是,除了在顶层目录下有一个CMakeLists.txt外,src目录下也有一个CMakeLists.txt,apple、pear、orange三个子目录下也分别有一个CMakeLists.txt。如果你对这些CMakeLists.txt的作用感到迷惑,接下来就为你揭开这层面纱。

CMakeLists.txt

顶层CMakeLists.txt

CMAKE_MINIMUM_REQUIRED(VERSION 3.12)
cmake_policy(SET CMP0048 NEW)
project(test06 VERSION "1.0.0.0")

include_directories(${PROJECT_SOURCE_DIR}/inc) # 指定头文件搜索路径

aux_source_directory(${PROJECT_SOURCE_DIR}/src src_dirs) # 指定源码目录

link_directories(${PROJECT_SOURCE_DIR}/lib) # 指定库搜索路径

add_subdirectory(src) # 指定 编译子目录

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin) # 指定可执行文件输出目录
add_executable(fruit ${src_dirs}) # 指定可执行文件名及源码

target_link_libraries(fruit apple pear orange) # 链接外部库

要想进入子目录进行编译,首先得在父目录的CMakeLists.txt中使用add_subdirectory命令,参数为子目录名。如上所示。

add_subdirectory()

add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])

src/CMakeLists.txt

add_subdirectory(./apple)
add_subdirectory(./pear)
add_subdirectory(./orange)

要想将编译传递到apple、pear、orange目录,src目录中也要有CMakeLists.txt并使用add_subdirectory命令进行传递。

src/apple/CMakeLists.txt

message("apple---${PROJECT_SOURCE_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib) # 指定动态库输出目录
add_library(apple SHARED ./apple.c) # 生成动态库 libapple.so

src/orange/CMakeLists.txt

message("orange---${PROJECT_SOURCE_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib) # 指定动态库输出目录
add_library(orange SHARED ./orange.c) # 生成动态库 liborange.so

src/pear/CMakeLists.txt

message("pear---${PROJECT_SOURCE_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib) # 指定动态库输出目录
add_library(pear SHARED ./pear.c) # 生成动态库 libpear.so

编译

cd build
cmake ..
make

将会在lib目录下生成libapple.so,liborange.so,libpear.so。

在bin目录下生成fruit。

### 使用 CMake-GUI 编译 OpenCV 4.5.4 为了成功使用CMake-GUI编译OpenCV 4.5.4版本,需遵循一系列配置步骤来确保环境设置正确无误。 #### 准备工作 首先确认已安装适当版本的CMake工具。对于此过程而言,推荐至少3.x以上的版本[^3]。接着,从GitHub仓库获取OpenCV及其贡献模块(opencv_contrib),这些资源构成了完整的功能集用于开发计算机视觉应用。 #### 配置CMake-GUI 启动CMake-GUI应用程序之后,指定源代码路径指向解压后的OpenCV根目录以及构建输出的目标位置。在高级模式下开启更多选项以便自定义编译参数。针对特定需求调整诸如`WITH_OPENGL`这样的开关状态;如果遇到与OpenGL兼容性的挑战,则可能暂时关闭该特性以顺利完成初次编译测试[^2]。 #### 设置编译器及其他依赖项 依据目标平台选取合适的编译器套件,比如MinGW或者MSVC,并通过环境变量或其他方式告知CMake其确切的位置。此外还需引入必要的第三方库支持,像IPP、TBB等优化组件可选加入以提升性能表现[^4]。 #### 执行生成命令并处理潜在错误 点击“Configure”按钮让CMake读取项目结构并解析所需的信息。期间可能会弹出提示框询问关于某些缺失包的选择,请按照实际情况作出回应。一旦完成上述操作,“Generate”按键会激活,按下它即开始创建适用于所选IDE或构建系统的工程文件集合。 最后,在终端中可以利用如下指令验证编译成果: ```bash g++ test_opencv.cpp -o test_opencv `pkg-config --cflags --libs opencv4` ``` 这条语句展示了如何借助于`pkg-config`工具自动检索到正确的头文件包含路径和链接标志位从而简化最终二进制文件的制作流程[^1]。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sif_666

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值