当前位置:网站首页>CMake教程Step6(添加自定义命令和生成文件)
CMake教程Step6(添加自定义命令和生成文件)
2022-07-05 16:36:00 【开始沸腾了】
CMake官方文档
参考官方cmake3.24教程翻译。我这里使用cmake 3.16来演示例子。
https://cmake.org/cmake/help/v3.24/guide/tutorial/index.html
https://gitlab.kitware.com/cmake/cmake/-/tree/master/Help/guide/tutorial
step6
https://cmake.org/cmake/help/v3.24/guide/tutorial/Adding%20a%20Custom%20Command%20and%20Generated%20File.html
我的仓库 :
https://github.com/FRBoiling/cmake-tutorial.git
假设,出于本教程的目的,我们决定永远不要使用平台log和exp函数,而是要生成一个预先计算值的表,用于mysqrt函数。
在本节中,我们将创建表作为构建过程的一部分,然后将该表编译到我们的应用程序中。
初始化
首先,让我们删除MathFunctions/CMakeLists.txt中log和exp函数的检查。
add_library(MathFunctions mysqrt.cxx)
# state that anybody linking to us needs to include the current source dir to find MathFunctions.h, while we don't.
target_include_directories(MathFunctions
INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
)
# install rules
install(TARGETS MathFunctions DESTINATION lib)
install(FILES MathFunctions.h DESTINATION include)
然后,从mysqrt.cxx中删除对HAVE_LOG和HAVE_EXP的检查。同时,我们可以删除#include 。
double mysqrt(double x)
{
if (x <= 0)
{
return 0;
}
// #if defined(HAVE_LOG) && defined(HAVE_EXP)
// double result = std::exp(std::log(x) * 0.5);
// std::cout << "Computing sqrt of " << x << " to be " << result
// << " using log and exp" << std::endl;
// #else
double result = x;
// do ten iterations
for (int i = 0; i < 10; ++i)
{
if (result <= 0)
{
result = 0.1;
}
double delta = x - (result * result);
result = result + 0.5 * delta / result;
std::cout << "Computing sqrt of " << x << " to be " << result << std::endl;
}
// #endif
return result;
}
在MathFunctions目录中,新增MakeTable.cxx的源文件,用来生成table。我们可以看到table是作为有效的c++代码生成的,并且输出文件名作为参数传入。
// A simple program that builds a sqrt table
#include <cmath>
#include <fstream>
#include <iostream>
int main(int argc, char* argv[])
{
// make sure we have enough arguments
if (argc < 2) {
return 1;
}
std::ofstream fout(argv[1], std::ios_base::out);
const bool fileOpen = fout.is_open();
if (fileOpen) {
fout << "double sqrtTable[] = {" << std::endl;
for (int i = 0; i < 10; ++i) {
fout << sqrt(static_cast<double>(i)) << "," << std::endl;
}
// close the table with a zero
fout << "0};" << std::endl;
fout.close();
}
return fileOpen ? 0 : 1; // return 0 if wrote the file
}
自定义的命令生成
下一步是向MathFunctions/CMakeLists.txt文件添加适当的命令,以构建MakeTable可执行文件,然后作为构建过程的一部分运行它。需要几个命令来完成此操作。
首先,在MathFunctions/CMakeLists.txt的顶部,添加MakeTable的可执行文件
add_executable(MakeTable MakeTalbe.cxx)
然后添加一个自定义命令,指定如何通过运行MakeTable生成table.h
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h
COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h
DEPENDS MakeTable
)
接下来我们要让CMake知道mysqrt。cxx依赖于生成的文件table.h。这是通过将生成的table.h添加到标准库MathFunctions的源列表来实现的。
add_library(MathFunctions
mysqrt.cxx
${CMAKE_CURRENT_BINARY_DIR}/Table.h
)
我们还必须将当前的二进制目录添加到include目录列表中,以便mysqrt.cxx能够找到并包含table.h。
target_include_directories(MathFunctions
INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
)
使用生成的表
首先,修改mysqrt.cxx包含table.h。接下来,我们可以重写mysqrt函数来使用这个表:
double mysqrt(double x)
{
if (x <= 0) {
return 0;
}
// use the table to help find an initial value
double result = x;
if (x >= 1 && x < 10) {
std::cout << "Use the table to help find an initial value " << std::endl;
result = sqrtTable[static_cast<int>(x)];
}
// do ten iterations
for (int i = 0; i < 10; ++i) {
if (result <= 0) {
result = 0.1;
}
double delta = x - (result * result);
result = result + 0.5 * delta / result;
std::cout << "Computing sqrt of " << x << " to be " << result << std::endl;
}
return result;
}
测试练习
运行cmake可执行文件或cmake-gui来配置项目,然后使用您选择的构建工具构建它。
当这个项目被构建时,它将首先构建MakeTable可执行文件。然后运行MakeTable生成table.h。最后,它将编译mysqrt.cxx,其中包括table.h来生成MathFunctions库。
运行Tutorial可执行文件并验证它是否使用了表。
边栏推荐
- 国产芯片产业链两条路齐头并进,ASML真慌了而大举加大合作力度
- Summary of PHP pseudo protocol of cisp-pte
- The first lesson of EasyX learning
- ECU introduction
- 手机开证券账户安全吗?怎么买股票详细步骤
- PHP strict mode
- Is it safe for qiniu business school to open a stock account? Is it reliable?
- tf. sequence_ Mask function explanation case
- Jarvis OJ Flag
- 深潜Kotlin协程(二十一):Flow 生命周期函数
猜你喜欢
[first lecture on robot coordinate system]
Use JDBC technology and MySQL database management system to realize the function of course management, including adding, modifying, querying and deleting course information.
[Web attack and Defense] WAF detection technology map
浏览器渲染原理以及重排与重绘
thinkphp模板的使用
Games101 notes (II)
Solution of vant tabbar blocking content
项目引入jar从私服Nexus 拉去遇到的一个问题
【729. 我的日程安排表 I】
Precision epidemic prevention has a "sharp weapon" | smart core helps digital sentinels escort the resumption of the city
随机推荐
Explain in detail the functions and underlying implementation logic of the groups sets statement in SQL
[Jianzhi offer] 66 Build product array
Embedded UC (UNIX System Advanced Programming) -3
Embedded -arm (bare board development) -2
网上办理期货开户安全吗?网上会不会骗子比较多?感觉不太靠谱?
深潜Kotlin协程(二十一):Flow 生命周期函数
easyNmon使用汇总
If you can't afford a real cat, you can use code to suck cats -unity particles to draw cats
手机开证券账户安全吗?怎么买股票详细步骤
Embedded UC (UNIX System Advanced Programming) -2
Games101 notes (I)
【剑指 Offer】63. 股票的最大利润
[729. My schedule I]
【7.7直播预告】《SaaS云原生应用典型架构》大咖讲师教你轻松构建云原生SaaS化应用,难题一一击破,更有华为周边好礼等你领!
[Jianzhi offer] 63 Maximum profit of stock
Embedded -arm (bare board development) -1
[61dctf]fm
【性能测试】全链路压测
C how TCP restricts the access traffic of a single client
项目引入jar从私服Nexus 拉去遇到的一个问题