我正在编写一个通用的CMake脚本,该脚本提供了一个感谢的后备策略,用于在编译一个带有特征的项目时激活向量化功能。
使用C++17标准的特征3.4,并使用更新的编译器编译(例如。gcc > 7),在静态对象对齐方面,开发人员没有遵守任何代码要求。在STL容器中不再有EIGEN_MAKE_ALIGNED_OPERATOR_NEW宏和显式对齐(而且我们在实验室里为此辛勤地欢呼!)
但是,我们有各种各样的项目和不同的编译设置。我们希望在编写代码时不必担心对齐问题,而CMake脚本则检测到architecture+compilation功能,并为体系结构禁用本征的不安全矢量化特性(即使这意味着破坏abi兼容性)。
是否有一种方法在CMake级别检索体系结构最大对齐大小,以正确设置EIGEN_MAX_STATIC_ALIGN_BYTES指令?
可能是检索max_align_t?T的bash脚本。
发布于 2021-11-13 08:34:52
虽然fabian的想法很棒,但它有一个巨大的缺点--您必须运行可执行文件。并不总是可以运行可执行文件。。目标是在不运行任何东西的情况下获得alignof(std::max_align_t)的值,只需要编译。我们就能做到。
像往常一样,向最好的人学习。来自CMake模块检查文件:CMakeCompilerABI.h CMakeCCompilerABI.c CMakeDetermineCompilerABI.cmake。注意CMakeCompilerABI.h如何将信息嵌入到可执行文件中,而不实际打印它。用同样的名字。源文件如下所示:
// determineAlingofMax.cpp
#include <cstddef>
#define VAL alignof(std::max_align_t)
const char info_alingof_max_align_t[] = {
'I', 'N', 'F', 'O', ':', 'a', 'l', 'i', 'n', 'g', 'o', 'f', 'm', 'a', 'x'
'[', '0' + ((VAL / 10) % 10), '0' + (VAL % 10), ']', '\0',
};
int main(int argc, char *argv[]) {
return info_alingof_max_align_t[argc];
}请注意我们是如何计算对齐的,并在编译时将其转换为字符串。
现在我们必须将它编译成一个对象文件--我们不需要运行任何可执行文件。因此,我们来看看CMakeDetermineCompilerABI.cmake并编写类似的文章:
set(BIN "${CMAKE_BINARY_DIR}/determineAlingofMax.bin"
try_compile(ALIGNMAX_COMPILED
${CMAKE_BINARY_DIR}
SOURCES /path/to/the/determineAlingofMax.cpp
CMAKE_FLAGS ${CMAKE_FLAGS}
# Ignore unused flags
"--no-warn-unused-cli"
COMPILE_DEFINITIONS ${COMPILE_DEFINITIONS}
COPY_FILE "${BIN}"
COPY_FILE_ERROR copy_error
OUTPUT_VARIABLE OUTPUT
)
if (ALIGNMAX_COMPILED AND not copy_error)
file(STRINGS "${BIN}" data REGEX "INFO:alingofmax\\[[^]]*\\]")
if (data MATCHES "INFO:alingofmax\\[0*([^]]*)\\]")
set(ALINGOFMAX "${CMAKE_MATCH_1}" CACHE INTERNAL "")
endif()
endif()
if (NOT ALINGOFMAX)
message(FATAL_ERROR some error here)
endif()
# and finally, maybe option()
set(EIGEN_MAX_STATIC_ALIGN_BYTES ${ALINGOFMAX})注意二进制文件不是只执行编译的。字符串INFO:alignofmax只需要足够的惟一性,所以它不会出现在可执行文件中--我更喜欢最近使用UUID。
发布于 2021-11-13 07:54:11
您可以将来自T的源代码与try_run一起使用。注意,交叉编译需要额外的注意事项;有关这方面的更多信息,请参阅try_run文档。
cmake_tests/alignment_check.cpp:
这是来自T的源
#include <iostream>
#include <cstddef>
int main()
{
std::cout << alignof(std::max_align_t) << '\n';
}CMakeLists.txt
...
try_run(MY_MAXALIGN_RUN_RESULT MY_MAXALIGN_COMPILE_SUCCESS
${CMAKE_CURRENT_BINARY_DIR} "${CMAKE_CURRENT_SOURCE_DIR}/cmake_tests/alignment_check.cpp"
COMPILE_OUTPUT_VARIABLE MY_MAXALIGN_COMPILE_OUTPUT
RUN_OUTPUT_VARIABLE MY_MAXALIGN_RUN_OUTPUT)
if (NOT MY_MAXALIGN_COMPILE_SUCCESS)
message(FATAL_ERROR "Error during compilation of ${CMAKE_CURRENT_SOURCE_DIR}/cmake_tests/alignment_check.cpp :\n\n${MY_MAXALIGN_COMPILE_OUTPUT}")
endif()
if (MY_MAXALIGN_RUN_RESULT)
message(FATAL_ERROR "Error running logic in ${CMAKE_CURRENT_SOURCE_DIR}/cmake_tests/alignment_check.cpp :\n\n${MY_MAXALIGN_RUN_OUTPUT}")
endif()
string(STRIP ${MY_MAXALIGN_RUN_OUTPUT} MY_MAXALIGN)
message(STATUS "MY_MAXALIGN = \"${MY_MAXALIGN}\"")
...可以使用MY_MAXALIGN cmake变量的内容来指定编译定义。
CMake输出
...
MY_MAXALIGN = "8"
...https://stackoverflow.com/questions/69950658
复制相似问题