如何解决将 CMake 选项转换为预处理器定义的更简单/更简洁的机制?
我发现自己在 CMakeLists.txt
中重复了以下代码段:
option(SOME_OPT "Some option" ON)
if (SOME_OPT)
target_compile_deFinitions(my_app SOME_IDENTIFIER_HERE_RELATED_TO_OPT)
endif()
(偶尔也有类似的东西,但 -D
带有字符串值)。
CMake 中是否有一种机制(不要介意版本)使这更容易或更简洁?
解决方法
选项 1:使用生成器表达式
这是使用目标属性和生成器表达式的一种选择:
"name": "aws-cdk-library","version": "0.0.0","description": "company's AWS CDK Library.","author": {
"name": "company","url": "https://www.company.com","organization": true
},"scripts": {
"build": "lerna run build --stream --sort --concurrency=1","clean": "lerna clean","deploy": "lerna publish --no-push --no-git-tag-version --force-publish --yes","eslint": "eslint . --ext=.js,.ts --format=node_modules/eslint-formatter-pretty","install": "lerna bootstrap","lint": "eslint . --ext .js,.ts --ignore-path=.gitignore","package": "lerna run package --stream --sort --concurrency=1","publish-mvn": "lerna run publish-mvn --stream --sort --concurrency=1","test": "jest","test:ci": "jest --ci --runInBand","setVersion": "lerna version --no-push --no-git-tag-version --force-publish --yes","watch": "lerna run watch --parallel"
},"devDependencies": {
"@aws-cdk/assert": "1.106.0","@aws-cdk/aws-certificatemanager": "1.106.0","@aws-cdk/aws-cloudfront": "1.106.0","@aws-cdk/aws-cloudwatch": "1.106.0","@aws-cdk/aws-cloudwatch-actions": "1.106.0","@aws-cdk/aws-lambda": "1.106.0","@aws-cdk/aws-route53": "1.106.0","@aws-cdk/aws-route53-targets": "1.106.0","@aws-cdk/aws-s3": "1.106.0","@aws-cdk/aws-s3-deployment": "1.106.0","@aws-cdk/aws-sns": "1.106.0","@aws-cdk/aws-sns-subscriptions": "1.106.0","@aws-cdk/aws-synthetics": "1.106.0","@aws-cdk/core": "1.106.0","@aws-solutions-constructs/aws-cloudfront-s3": "1.106.0","@aws-solutions-constructs/core": "1.106.0","@types/jest": "^26.0.23","@types/node": "^15.0.0","@typescript-eslint/eslint-plugin": "^4.22.0","@typescript-eslint/parser": "^4.22.0","constructs": "^3.3.75","eslint": "^7.25.0","eslint-config-tc": "^19.0.0","eslint-config-typescript-tc": "^3.0.0","eslint-formatter-pretty": "^4.0.0","eslint-plugin-eslint-comments": "^3.2.0","eslint-plugin-import": "^2.22.1","eslint-plugin-jest": "^24.3.6","eslint-plugin-prettier": "^3.4.0","eslint-plugin-unicorn": "^33.0.0","jest": "^26.6.3","jsii": "^1.30.0","jsii-pacmak": "^1.30.0","jsii-release": "^0.2.9","lerna": "^4.0.0","prettier": "^2.2.1","ts-jest": "^26.5.5","ts-node": "^10.0.0","typescript": "^4.2.4"
},"dependencies": {
"@company/cdk-route53-cloudfront-s3": "file:packages/route53-cloudfront-s3","@company/cdk-cloudwatch": "file:packages/cloudwatch","@company/cdk-nodejs-canary": "file:packages/nodejs-canary","@company/cdk-pagerduty-alarm-action": "file:packages/pagerduty-alarm-action","@company/cdk-tags": "file:packages/tags"
},"engines": {
"node": ">=14.0.0","npm": ">=6.0.0"
},"private": true,"license": "UNLICENSED"
}```
** module-package.json **
{
"name": "@company/cdk-tags","description": "A helper library for setting required AWS Tags.","keywords": [
"aws","cdk"
],"repository": {
"type": "git","url": "git+................"
},"url": "..........","license": "UNLICENSED","bugs": {
"url": "..............."
},"homepage": ".......................","main": "lib/index.js","types": "lib/index.d.ts","scripts": {
"build": "jsii","watch": "jsii -w","package": "jsii-pacmak","publish-mvn": "jsii-release-maven"
},"jsii": {
"outdir": "dist","targets": {
"java": {
"package": "com.company.common.aws.cdk","maven": {
"groupId": "com.company.common.aws.cdk","artifactId": "tags"
}
}
}
},"@aws-cdk/aws-sns": "1.106.0"
},"peerDependencies": {
"@aws-cdk/core": "1.106.0","constructs": "^3.2.84"
}
}
如生成器表达式迷你语言所期望的那样,option(SOME_OPT1 "Some option 1" ON)
option(SOME_OPT2 "Some option 2" OFF)
option(SOME_OPT3 "Some option 3" ON)
target_compile_definitions(my_app PRIVATE
$<$<BOOL:${SOME_OPT1}>:SOME_IDENTIFIER_HERE_RELATED_TO_OPT1>
$<$<BOOL:${SOME_OPT2}>:SOME_IDENTIFIER_HERE_RELATED_TO_OPT2>
$<$<BOOL:${SOME_OPT3}>:SOME_IDENTIFIER_HERE_RELATED_TO_OPT3>
)
舞蹈对于将真实/虚假 CMake 值转换为 $<BOOL:${var}>
或 1
是必要的。
选项 2:生成的“配置文件”
如果您有很多这样的选项,另一个选择是使用 0
命令创建包含相关信息的标题。创建一个名为 configure_file
的标题(作为示例),内容如下:
config.h.in
#ifndef MYPROJ_CONFIG_H
#define MYPROJ_CONFIG_H
#cmakedefine SOME_IDENTIFIER_HERE_RELATED_TO_OPT1
#cmakedefine SOME_IDENTIFIER_HERE_RELATED_TO_OPT2
#cmakedefine01 SOME_IDENTIFIER_HERE_RELATED_TO_OPT3
#endif
指令由 #cmakedefine VAR
处理以设置 configure_file
,如果 VAR
在 CMakeLists.txt 中定义为真实的东西,如果不是,则注释掉该行。 VAR
变体始终定义 01
,但将其设置为 VAR
或 0
。
然后在你的 CMakeLists.txt 你可以写:
1
然后您的源文件可以option(SOME_OPT1 "Some option 1" ON)
option(SOME_OPT2 "Some option 2" OFF)
option(SOME_OPT3 "Some option 3" ON)
# Setting these variables exposes them to configure_file below
set(SOME_IDENTIFIER_HERE_RELATED_TO_OPT1 "${SOME_OPT1}")
set(SOME_IDENTIFIER_HERE_RELATED_TO_OPT2 "${SOME_OPT2}")
set(SOME_IDENTIFIER_HERE_RELATED_TO_OPT3 "${SOME_OPT3}")
configure_file(config.h.in config.h)
target_include_directories(my_app PRIVATE "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>")
,默认情况下:
#include <config.h>
这两个选项每个选项都需要一行开销,尽管第一种方法有点嘈杂,第二种方法需要一个文件。但是,第二种方法还允许您添加额外的预处理器代码,这些代码可能更好地放在配置文件中。它还可以通过 #ifndef MYPROJ_CONFIG_H
#define MYPROJ_CONFIG_H
#define SOME_IDENTIFIER_HERE_RELATED_TO_OPT1
/* #undef SOME_IDENTIFIER_HERE_RELATED_TO_OPT2 */
#define SOME_IDENTIFIER_HERE_RELATED_TO_OPT3 1
#endif
语法替换 CMake 变量 values。有关更多详细信息,请参阅文档:https://cmake.org/cmake/help/latest/command/configure_file.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。