首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从CMake设置本征最大静态对准

从CMake设置本征最大静态对准
EN

Stack Overflow用户
提问于 2021-11-13 01:09:53
回答 2查看 178关注 0票数 0

我正在编写一个通用的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脚本。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-11-13 08:34:52

虽然fabian的想法很棒,但它有一个巨大的缺点--您必须运行可执行文件。并不总是可以运行可执行文件。。目标是在不运行任何东西的情况下获得alignof(std::max_align_t)的值,只需要编译。我们就能做到。

像往常一样,向最好的人学习。来自CMake模块检查文件:CMakeCompilerABI.h CMakeCCompilerABI.c CMakeDetermineCompilerABI.cmake。注意CMakeCompilerABI.h如何将信息嵌入到可执行文件中,而不实际打印它。用同样的名字。源文件如下所示:

代码语言:javascript
复制
// 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并编写类似的文章:

代码语言:javascript
复制
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。

票数 1
EN

Stack Overflow用户

发布于 2021-11-13 07:54:11

您可以将来自T的源代码与try_run一起使用。注意,交叉编译需要额外的注意事项;有关这方面的更多信息,请参阅try_run文档。

cmake_tests/alignment_check.cpp:

这是来自T的源

代码语言:javascript
复制
#include <iostream>
#include <cstddef>
int main()
{
    std::cout << alignof(std::max_align_t) << '\n';
}

CMakeLists.txt

代码语言:javascript
复制
...

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输出

代码语言:javascript
复制
...
MY_MAXALIGN = "8"
...
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69950658

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档