65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 pkg-config 实用程序修复 CMake 构建问题

emptyStarIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

0/5 (0投票)

2024 年 7 月 17 日

CPOL

3分钟阅读

viewsIcon

250377

引言

最近,CMake 3.30.0 发布,修复了使用 SQLite3 库构建的问题。修复方式引起了我的兴趣。他们只添加了一个使用 `pkg-config` 的小脚本。我对该实用程序的潜力产生了好奇。我将研究它的用法。

背景

三周前,当我在我的 CMake 脚本中运行 `find_package( SQLite3 REQUIRED )` 时,它失败了并输出了一个错误。`find_package` 总是对解决依赖关系和编写可移植构建脚本有很大帮助,这要归功于抽象和自动化配置和版本控制的贡献者。虽然熟悉这种情况,但我一直有点懒,并且对在实用程序失败时需要编写手动配置感到恼火。

在寻找解决这个使用 SQLite3 的 find_package 问题的方案时,我在互联网上找到了许多人建议的不同方法,但其中大多数对我来说都不起作用。然后,我对这种困惑的根源产生了兴趣。

当我到达 GitHub 存储库 `Kitware/CMake` 下的脚本 `FindSQLite3.cmake` 时,我注意到它看起来与我在我的环境中看到的不同,我使用的是 CMake 3.29.6。幸运或不幸的是,它自 2024 年 3 月就已经修复了,但仍在等待下一个版本。现在,3.30.0 上周发布了此修复程序。让我们升级 CMake 并享受使用 SQLite3 构建 C++ 代码的便利。

CMake 脚本中的 pkg-config

脚本中的修复非常简单:使用 `PkgConfig` 包中的 `pkg_check_modules` 命令。它调用 `pkg-config` 工具来获取编译器所需的信息,并在 CMake 脚本的变量中提供这些信息。在此处CMake 文档中查看您可以使用它获取哪些变量。

即使您现在无法升级 CMake,但拥有或可以安装 pkg-config,也可以通过在您的 CMake 构建脚本中包含以下小脚本来解决 SQLite3 的问题。这个解决方案是我暂时使用的。

find_package(PkgConfig)
pkg_check_modules(PC_SQLite3 sqlite3)
set( SQLite3_ROOT "${PC_SQLite3_PREFIX}" )

带有 `_PREFIX` 后缀的变量是 `pkg_check_modules` 提供的变量之一,并且上面的脚本将其设置为 `SQLite3_ROOT`。 默认情况下,`find_path` 和 `find_library` 命令从带有后缀 `_ROOT` 的变量中搜索路径,因此拥有 `SQLite3_ROOT` 允许旧的 `FindSQLite3.cmake` 脚本找到所需的文件。

命令行中的 pkg-config

由于 `pkg-config` 是一个命令行工具,我开始对它如何改变命令行上的 C++ 代码编译感兴趣。 所以,我用来自我的上一篇文章的代码试了一下。

# install pkg-config
apt-get install pkg-config
# install sqlite3 libraries
apt-get install libsqlite3-dev
# compile the code setting up compile options by pkg-config
g++ --std=c++14 -I./include ./main-2.cpp ./src/SmartDbConnFactory.cpp $(pkg-config --libs --cflags sqlite3)

编译成功,生成的可执行文件可以运行!

但是,执行 `pkg-config --libs --cflags sqlite3`,我只得到 `-lsqlite3`。 我无法从中感受到这个工具的力量。

所以,我也用 `opencv` 试了一下。 这一次,该命令返回了一个很长的命令。 这会很有趣。

pkg-config --libs --cflags opencv

-I/usr/include/opencv4 -lopencv_stitching -lopencv_alphamat -lopencv_aruco -lopencv_barcode -lopencv_bgsegm -lopencv_bioinspired -lopencv_ccalib -lopencv_cvv -lopencv_dnn_objdetect -lopencv_dnn_superres -lopencv_dpm -lopencv_face -lopencv_freetype -lopencv_fuzzy -lopencv_hdf -lopencv_hfs -lopencv_img_hash -lopencv_intensity_transform -lopencv_line_descriptor -lopencv_mcc -lopencv_quality -lopencv_rapid -lopencv_reg -lopencv_rgbd -lopencv_saliency -lopencv_shape -lopencv_stereo -lopencv_structured_light -lopencv_phase_unwrapping -lopencv_superres -lopencv_optflow -lopencv_surface_matching -lopencv_tracking -lopencv_highgui -lopencv_datasets -lopencv_text -lopencv_plot -lopencv_ml -lopencv_videostab -lopencv_videoio -lopencv_viz -lopencv_wechat_qrcode -lopencv_ximgproc -lopencv_video -lopencv_xobjdetect -lopencv_objdetect -lopencv_calib3d -lopencv_imgcodecs -lopencv_features2d -lopencv_dnn -lopencv_flann -lopencv_xphoto -lopencv_photo -lopencv_imgproc -lopencv_core

让我们用 OpenCV 写一个简单的代码。 这个程序将把一个图像文件转换成灰度图像。

// main.cpp
#include <iostream>
#include <opencv2/opencv.hpp>

int main() {
	cv::Mat image = cv::imread("example.jpg");
	cv::Mat grayImage;
	cv::cvtColor(image, grayImage, cv::COLOR_BGR2GRAY);
	cv::imwrite("example_gray.jpg", grayImage);
	return 0;
}

现在,使用 pkg-config 实用程序编译它。

# install OpenCV libraries and dependencies
apt-get install libopencv-dev
# compile the code setting up compile options by pkg-config
g++ --std=c++14 main.cpp $(pkg-config --libs --cflags opencv4)

编译成功,图像文件转换工作正常! 我对这个结果感到兴奋。 这将使我的编码生活更轻松。

© . All rights reserved.