gpt4 book ai didi

linux - cmake 下 readlink 的奇怪行为

转载 作者:太空宇宙 更新时间:2023-11-04 10:40:44 24 4
gpt4 key购买 nike

我正在尝试使用 readlink -f 获取所有符号链接(symbolic link)后的共享库的绝对路径。

>readlink -f /opt/gcc4.9.3/lib64/libstdc++.so.6/opt/gcc4.9.3/lib64/libstdc++.so.6.0.20

但是当我在 cmake 中执行此操作时,它不会展开完整路径例如。
set(CPP11_PATH ${CMAKE_CURRENT_BINARY_DIR}/)
execute_process(COMMAND ldd ${CPP11_PATH} COMMAND grep libstdc++ COMMAND awk "{ print $3; }" OUTPUT_VARIABLE LIBSTDCPP_PATH)
message("LIBSTDCPP_PATH=${LIBSTDCPP_PATH}")
execute_process(COMMAND readlink -f ${LIBSTDCPP_PATH} OUTPUT_VARIABLE LIBSTDCPP_ABSPATH)
message("LIBSTDCPP_ABSPATH=${LIBSTDCPP_ABSPATH}")

打印:

LIBSTDCPP_PATH=/opt/gcc4.9.3/lib64/libstdc++.so.6LIBSTDCPP_ABSPATH=/opt/gcc4.9.3/lib64/libstdc++.so.6

如果我将其包装在 shell 脚本中,也会发生这种情况:
execute_process(COMMAND doreadlink.sh ${LIBSTDCPP_PATH} OUTPUT_VARIABLE LIBSTDCPP_ABSPATH2)
message("LIBSTDCPP_ABSPATH2=${LIBSTDCPP_ABSPATH2}")

>LIBSTDCPP_ABSPATH2=/opt/gcc4.9.3/lib64/libstdc++.so.6

它也发生在使用带有 REALPATH 的 get_filename_component() 时,这应该是执行此操作的规范 cmake 方法。
get_filename_component(LIBSTDCPP_PATH ${LIBSTDCPP_PATH} REALPATH)
message("LIBSTDCPP_PATH2=${LIBSTDCPP_PATH}")

谁能解释一下?

我已经尝试了 cmake rebuild_cache 和删除 CMakeCache.txt 并使用 --trace 运行以确保我认为正在运行的东西确实在运行。我还确认它发生在 rhel5 rhel6 和 rhel7 以及 cmake 2.8 和 3.4 上。

有一个工作正常的解决方法:
execute_process(COMMAND ldd ${CPP11_PATH} COMMAND grep libstdc++ COMMAND awk "{ print $3; COMMAND xargs readlink -f }" OUTPUT_VARIABLE LIBSTDCPP_PATH)

cmake 在幕后会做什么?

我尝试运行:
strace -f cmake <code>pwd</code>

一些输出是:

[pid 23195] execve("/usr/lib64/qt-3.3/bin/readlink", ["readlink", "-f", "/lib64/libstdc++.so.6\n"], [/* 53 vars */]) = -1 ENOENT (No such file or directory)[pid 23195] execve("/usr/local/bin/readlink", ["readlink", "-f", "/lib64/libstdc++.so.6\n"], [/* 53 vars */]) = -1 ENOENT (No such file or directory)[pid 23195] execve("/usr/bin/readlink", ["readlink", "-f", "/lib64/libstdc++.so.6\n"], [/* 53 vars */] [pid 23174]  "", 1)   = 0[pid 23195]  )      = 0[pid 23174] close(11)                   = 0[pid 23174] rt_sigprocmask(SIG_SETMASK, [],  [pid 23195] brk(0 [pid 23174]  NULL, 8) = 0[pid 23195]  )         = 0x12e5000[pid 23174] read(9, "", 1024)           = 0[pid 23174] close(9)                    = 0[pid 23195] mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0 [pid 23174] close(6)                    = 0[pid 23195]  )        = 0x7ff41654f000[pid 23174] close(8)                    = 0[pid 23195] access("/etc/ld.so.preload", R_OK [pid 23174] select(8, [3 5 7], NULL, NULL, NULL [pid 23195]  )      = -1 ENOENT (No such file or directory)[pid 23195] open("tls/x86_64/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)[pid 23195] open("tls/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)[pid 23195] open("x86_64/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)[pid 23195] open("libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)[pid 23195] open("/usr/local/lib/tls/x86_64/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)[pid 23195] stat("/usr/local/lib/tls/x86_64", 0x7fff36038350) = -1 ENOENT (No such file or directory)[pid 23195] open("/usr/local/lib/tls/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)[pid 23195] stat("/usr/local/lib/tls", 0x7fff36038350) = -1 ENOENT (No such file or directory)[pid 23195] open("/usr/local/lib/x86_64/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)

截图

O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)[pid 23195] stat("/usr/lib/oracle/10.2.0.4/client/lib/tls", 0x7fff36038350) = -1 ENOENT (No such file or directory)[pid 23195] open("/usr/lib/oracle/10.2.0.4/client/lib/x86_64/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)[pid 23195] stat("/usr/lib/oracle/10.2.0.4/client/lib/x86_64", 0x7fff36038350) = -1 ENOENT (No such file or directory)[pid 23195] open("/usr/lib/oracle/10.2.0.4/client/lib/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)rt_sigprocmask(SIG_BLOCK, [INT TERM CHLD], [], 8) = 0rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0ioctl(0, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B38400 opost isig icanon echo ...}) = 0ioctl(0, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B38400 opost isig icanon echo ...}) = 0write(2, "LIBSTDCPP_ABSPATH=/usr/lib64/lib"..., 45LIBSTDCPP_ABSPATH=/usr/lib64/libstdc++.so.6) = 45

所以它甚至看起来像是在执行正确的系统命令。

这是重现问题的 CMakeLists.txt:

cmake_minimum_required(VERSION 2.8)project(TEST CXX) set(CPP11_PATH ${CMAKE_CURRENT_BINARY_DIR}/cpp11)execute_process(COMMAND g++ ${CMAKE_CURRENT_SOURCE_DIR}/cpp11.cpp -o${CPP11_PATH})#execute_process(COMMAND ldd ${CPP11_PATH} COMMAND grep libstdc++ COMMAND awk "{ print $3; }" COMMAND xargs readlink -f OUTPUT_VARIABLE LIBSTDCPP_PATH)execute_process(COMMAND ldd ${CPP11_PATH} COMMAND grep libstdc++ COMMAND awk "{ print $3; }" OUTPUT_VARIABLE LIBSTDCPP_PATH)message("LIBSTDCPP_PATH=${LIBSTDCPP_PATH}")execute_process(COMMAND readlink -f ${LIBSTDCPP_PATH} OUTPUT_VARIABLE LIBSTDCPP_ABSPATH)message("LIBSTDCPP_ABSPATH=${LIBSTDCPP_ABSPATH}")

最佳答案

许多输出单行 的 shell 实用程序以换行符 (\n) 终止。这样做是为了在终端中获得漂亮的输出。

与 Linux shell 中的backtricks 运算符(`exec-some-command`)不同,它会自动去除尾随换行符,execute_process 默认情况下不会执行此操作。

execute_process 输出中去除尾随换行符的最简单方法是为其使用 OUTPUT_STRIP_TRAILING_WHITESPACE 选项:

execute_process(COMMAND <...>
OUTPUT_VARIABLE LIBSTDCPP_PATH
OUTPUT_STRIP_TRAILING_WHITESPACE
)

关于linux - cmake 下 readlink 的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35299970/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com