当前位置:网站首页>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可执行文件并验证它是否使用了表。
边栏推荐
- 阈值同态加密在隐私计算中的应用:解读
- EasyX second lesson
- 深潜Kotlin协程(二十一):Flow 生命周期函数
- Use byte stream to read Chinese from file to console display
- Embedded-c language-6
- Detailed explanation of use scenarios and functions of polar coordinate sector diagram
- 网站页面禁止复制内容 JS代码
- [wechat applet] read the life cycle and route jump of the applet
- High number | summary of calculation methods of volume of rotating body, double integral calculation of volume of rotating body
- Learnopongl notes (I)
猜你喜欢
Jarvis OJ shell traffic analysis
[team PK competition] the task of this week has been opened | question answering challenge to consolidate the knowledge of commodity details
PHP人才招聘系统开发 源代码 招聘网站源码二次开发
Basic introduction to the control of the row component displaying its children in the horizontal array (tutorial includes source code)
dried food! Semi supervised pre training dialogue model space
[61dctf]fm
【机器人坐标系第一讲】
Embedded UC (UNIX System Advanced Programming) -2
Get ready for the pre-season card game MotoGP ignition champions!
Browser rendering principle and rearrangement and redrawing
随机推荐
Solution of vant tabbar blocking content
2022 年 Q2 加密市场投融资报告:GameFi 成为投资关键词
Deep learning plus
Can you help me see what the problem is? [ERROR] Could not execute SQL stateme
PHP人才招聘系统开发 源代码 招聘网站源码二次开发
Embedded -arm (bare board development) -1
Error in composer installation: no composer lock file present.
Jarvis OJ simple network management protocol
Jarvis OJ shell流量分析
精准防疫有“利器”| 芯讯通助力数字哨兵护航复市
Android privacy sandbox developer preview 3: privacy, security and personalized experience
Combined use of vant popup+ other components and pit avoidance Guide
China Radio and television officially launched 5g services, and China Mobile quickly launched free services to retain users
张平安:加快云上数字创新,共建产业智慧生态
Learnopongl notes (II) - Lighting
The first lesson of EasyX learning
【剑指 Offer】61. 扑克牌中的顺子
[Jianzhi offer] 61 Shunzi in playing cards
Application of threshold homomorphic encryption in privacy Computing: Interpretation
Basic introduction to the control of the row component displaying its children in the horizontal array (tutorial includes source code)