autotools,stdc++fs,误报
autotools, stdc++fs, false positive
我正在尝试有条件地使用 std::filesystem(如果可用)。
检查 header 文件是否有效,首先通过 AM_CHECK_HEADERS,然后是 AC_TRY_COMPILE(后者是由于 Xcode/OSX 的某些组合具有 header,但触发静态断言实际编译)。如果所有这些检查都通过,则设置 HAVE_FILESYSTEM。
然而,代码还需要与 gcc 7.5.0 兼容,这需要链接到 libstdc++fs。
因此,我添加了额外的检查:
AC_MSG_CHECKING([if std::filesystem requires linking stdc++fs])
AC_TRY_LINK([
#if HAVE_FILESYSTEM
#include <filesystem>
#endif
],
[
std::filesystem::directory_iterator {};
],
ac_cv_link_fs_stdlib=no,
ac_cv_link_fs_stdlib=yes)
if test "x$ac_cv_fs_stdlib" = xyes -a "x$ac_cv_class_fs_path" = xyes; then
AC_MSG_RESULT(yes)
SYSLIBS="$SYSLIBS -lstdc++fs"
else
AC_MSG_RESULT(no)
fi
但它一直给我 false-positives,即在 GCC 7.5.0 上给出的答案是“否”。然而构建本身给出了这种错误:
utils.cc:(.text+0x2c9b): undefined reference to std::filesystem::create_directory(std::filesystem::__cxx11::path const&, std::error_code&)
。
显然,这对我来说看起来像是链接器错误。我的configure.ac怎么会fixed/what错了?
编辑:也尝试使用 std::filesystem::path
、std::filesystem::access
并根据下面的答案 std::filesystem::create_directory
。到目前为止,其中 None 已经提供了帮助。是否可以实际看到编译器调用? set -x
里面的configure脚本可以吗?
您的测试只声明了一个未被使用的变量。因此,测试程序不会从 std::filesystem
调用任何函数,因此它总是会通过链接阶段。您还使用了 AC_TRY_LINK
,这是一个过时的宏,更喜欢使用 AC_LINK_IFELSE
。最后,您在 AC_TRY_LINK
语句中设置的变量似乎与您检查的变量不同:ac_cv_link_fs_stdlib
与 ac_cv_fs_stdlib
不同。
它应该是这样的:
AC_LINK_IFELSE(
[AC_LANG_SOURCE([
#if HAVE_FILESYSTEM
#include <filesystem>
#endif
int main() {
std::error_code ec;
std::filesystem::create_directory("/dev/null", &ec);
}
])],
[ac_cv_fs_stdlib=no],
[ac_cv_fs_stdlib=yes]
)
另外请确保在 运行 此测试之前使用 AC_PROG_CXX
并设置 AC_LANG(C++)
,如果您还没有设置的话。
我正在尝试有条件地使用 std::filesystem(如果可用)。 检查 header 文件是否有效,首先通过 AM_CHECK_HEADERS,然后是 AC_TRY_COMPILE(后者是由于 Xcode/OSX 的某些组合具有 header,但触发静态断言实际编译)。如果所有这些检查都通过,则设置 HAVE_FILESYSTEM。 然而,代码还需要与 gcc 7.5.0 兼容,这需要链接到 libstdc++fs。 因此,我添加了额外的检查:
AC_MSG_CHECKING([if std::filesystem requires linking stdc++fs])
AC_TRY_LINK([
#if HAVE_FILESYSTEM
#include <filesystem>
#endif
],
[
std::filesystem::directory_iterator {};
],
ac_cv_link_fs_stdlib=no,
ac_cv_link_fs_stdlib=yes)
if test "x$ac_cv_fs_stdlib" = xyes -a "x$ac_cv_class_fs_path" = xyes; then
AC_MSG_RESULT(yes)
SYSLIBS="$SYSLIBS -lstdc++fs"
else
AC_MSG_RESULT(no)
fi
但它一直给我 false-positives,即在 GCC 7.5.0 上给出的答案是“否”。然而构建本身给出了这种错误:
utils.cc:(.text+0x2c9b): undefined reference to std::filesystem::create_directory(std::filesystem::__cxx11::path const&, std::error_code&)
。
显然,这对我来说看起来像是链接器错误。我的configure.ac怎么会fixed/what错了?
编辑:也尝试使用 std::filesystem::path
、std::filesystem::access
并根据下面的答案 std::filesystem::create_directory
。到目前为止,其中 None 已经提供了帮助。是否可以实际看到编译器调用? set -x
里面的configure脚本可以吗?
您的测试只声明了一个未被使用的变量。因此,测试程序不会从 std::filesystem
调用任何函数,因此它总是会通过链接阶段。您还使用了 AC_TRY_LINK
,这是一个过时的宏,更喜欢使用 AC_LINK_IFELSE
。最后,您在 AC_TRY_LINK
语句中设置的变量似乎与您检查的变量不同:ac_cv_link_fs_stdlib
与 ac_cv_fs_stdlib
不同。
它应该是这样的:
AC_LINK_IFELSE(
[AC_LANG_SOURCE([
#if HAVE_FILESYSTEM
#include <filesystem>
#endif
int main() {
std::error_code ec;
std::filesystem::create_directory("/dev/null", &ec);
}
])],
[ac_cv_fs_stdlib=no],
[ac_cv_fs_stdlib=yes]
)
另外请确保在 运行 此测试之前使用 AC_PROG_CXX
并设置 AC_LANG(C++)
,如果您还没有设置的话。