虽然 fabian 的想法很棒,但它有一个 巨大 缺点 - 您必须运行可执行文件。 Not always can you run the executable。目标是获得alignof(std::max_align_t) 的值不运行任何东西,只需要编译。我们可以做到。
一如既往,向最优秀的人学习。来自CMake modules 检查文件:CMakeCompilerABI.hCMakeCCompilerABI.cCMakeDetermineCompilerABI.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];
}
请注意我们如何计算 alignof 并将其转换为字符串在编译时。
现在我们必须将它编译成一个目标文件——我们不需要运行任何可执行文件。所以我们看看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。