当前位置:网站首页>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可执行文件并验证它是否使用了表。
边栏推荐
- C how TCP restricts the access traffic of a single client
- WSL2.0安装
- [61dctf]fm
- 飞桨EasyDL实操范例:工业零件划痕自动识别
- Do sqlserver have any requirements for database performance when doing CDC
- China Radio and television officially launched 5g services, and China Mobile quickly launched free services to retain users
- SQL injection of cisp-pte (Application of secondary injection)
- Sentinel-流量防卫兵
- [wechat applet] read the life cycle and route jump of the applet
- Iphone14 with pill screen may trigger a rush for Chinese consumers
猜你喜欢
Flet tutorial 12 stack overlapping to build a basic introduction to graphic and text mixing (tutorial includes source code)
Jarvis OJ Webshell分析
Copy mode DMA
npm安装
浏览器渲染原理以及重排与重绘
The survey shows that the failure rate of traditional data security tools in the face of blackmail software attacks is as high as 60%
国产芯片产业链两条路齐头并进,ASML真慌了而大举加大合作力度
If you can't afford a real cat, you can use code to suck cats -unity particles to draw cats
Embedded-c Language-1
Jarvis OJ 远程登录协议
随机推荐
调查显示传统数据安全工具面对勒索软件攻击的失败率高达 60%
7.Scala类
帮忙看看是什么问题可以吗?[ERROR] Could not execute SQL stateme
How to install MySQL
easyNmon使用汇总
Learnopongl notes (II) - Lighting
Raspberry pie 4B installation pytorch1.11
[61dctf]fm
Is it safe to open an account for digging wealth stocks? How is it safe to open a stock account?
[team PK competition] the task of this week has been opened | question answering challenge to consolidate the knowledge of commodity details
Can you help me see what the problem is? [ERROR] Could not execute SQL stateme
兰空图床苹果快捷指令
[729. My schedule I]
NPM installation
中国广电正式推出5G服务,中国移动赶紧推出免费服务挽留用户
SQL injection of cisp-pte (Application of secondary injection)
Wechat official account web page authorization login is so simple
Jarvis OJ Webshell分析
Jarvis OJ webshell analysis
PHP strict mode