cmake execute_process 找不到源命令
cmake execute_process cannot find source command
我最近在使用 cmake 时遇到了一个非常有趣的问题。
问题如下:
我有一个 CMakeLists.txt 定义了一个相当简单的项目。我希望能够在构建项目时设置一个 linux 环境变量。为此,我想调用一个小脚本 var_set.sh
来完成它。它看起来像这样:
#!/bin/bash
MY_VAR=
export MY_VAR
在CMakeLists.txt
我运行它如下:
execute_process(COMMAND source var_set.sh VALUE
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
RESULT_VARIABLE variable_RESULT)
message(STATUS ${variable_RESULT})
message(STATUS $ENV{MY_VAR})
这个输出是
-- No such file or directory
我认为问题出在 source
命令上。如果我使用 ./var_set.sh
而不是 source var_set.sh
脚本实际上会被执行,但是,当然,我无法获得我想要导出的变量。
有人知道这种行为的原因吗?
更新:
我明白了,可能根本不可能达到我最初想要的。
最初的想法和动机如下。我们有一个使用 ROS 的比较大的项目。它使用 catkin_make 来构建所有内容。它基本上所做的是按照 CMakeLists.txt 和 package.xml 文件定义的顺序为它在子文件夹中找到的所有包调用一个 cmake(这个文件在这里看起来如何并不重要)。它还提供了一种重写的方式来使用 find_package 等
问题是有很大一部分代码是以我无法影响的方式编写的。这部分依赖于一个库G2O(图形优化),而G2O包不是"catkinized",即catkin无法知道提供了哪些库。
G2O 本身定义了相当多的库,我们可以通过 FindG2O.cmake 文件找到它们(但是如果一个库是 "core" 我们知道它的名字是 "G2O_CORE_LIBRARY" 在 FindG2O.cmake 中设置)。我们还使用环境变量 "G2O_ROOT" 指向当前的 g2o 安装。
我的想法是在构建 G2O 时设置这个环境变量(使用围绕它的 catkin 元包),并让之后构建的任何人都可以使用这些知识,因为这样可以轻松使用 FindG2O.cmake .
我明白这个解释很乱。有什么不明白的请追问。
似乎我想要实现的目标是不可能的,因为 catkin_make 可能会在不同的子进程中调用不同的 cmake,然后,当然,我无法修改父进程。
你只是做错了。即使 source
可以工作(但它不能,因为它是 bash
内部命令而不是文件系统中存在的真正 binary/executable),它不会影响任何东西!因为 cmake
启动了一个子进程(通过 execute_process()
)并且它将被终止,w/执行结果在相应的变量中可用。 在子进程中设置任何环境变量都不会影响父环境。
因此,您最好使用$ENV{blah}
来设置所需的变量。或者(更好)只使用 CMake 变量......有很多方法可以做到这一点。只需详细说明您要实现的内容即可。
使用 execute_process
的 OUTPUT_VARIABLE
选项。
让你的脚本看起来像这样:
#!/bin/bash
MY_VAR=
echo "$MY_VAR"
并在您的 CMakeLists.txt
中使用它,如下所示:
cmake_minimum_required(VERSION 2.6)
execute_process(COMMAND sh "var_set.sh" "VALUE" "VALUE2"
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
RESULT_VARIABLE variable_RESULT
OUTPUT_VARIABLE variable_OUTPUT
)
message(STATUS ${variable_RESULT})
message(STATUS ${variable_OUTPUT})
CMake 配置步骤的输出是:
-- The C compiler identification is GNU 5.1.1
-- The CXX compiler identification is GNU 5.1.1
-- Check for working C compiler: /usr/lib64/ccache/cc
-- Check for working C compiler: /usr/lib64/ccache/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/lib64/ccache/c++
-- Check for working CXX compiler: /usr/lib64/ccache/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- 0
-- VALUE
-- Configuring done
-- Generating done
-- Build files have been written to: /tmp/out
这种方法的一个缺点是您必须在脚本中禁止所有不需要的输出。或者,使用 OUTPUT_FILE 和 post 处理文件。
我最近在使用 cmake 时遇到了一个非常有趣的问题。 问题如下:
我有一个 CMakeLists.txt 定义了一个相当简单的项目。我希望能够在构建项目时设置一个 linux 环境变量。为此,我想调用一个小脚本 var_set.sh
来完成它。它看起来像这样:
#!/bin/bash
MY_VAR=
export MY_VAR
在CMakeLists.txt
我运行它如下:
execute_process(COMMAND source var_set.sh VALUE
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
RESULT_VARIABLE variable_RESULT)
message(STATUS ${variable_RESULT})
message(STATUS $ENV{MY_VAR})
这个输出是
-- No such file or directory
我认为问题出在 source
命令上。如果我使用 ./var_set.sh
而不是 source var_set.sh
脚本实际上会被执行,但是,当然,我无法获得我想要导出的变量。
有人知道这种行为的原因吗?
更新:
我明白了,可能根本不可能达到我最初想要的。
最初的想法和动机如下。我们有一个使用 ROS 的比较大的项目。它使用 catkin_make 来构建所有内容。它基本上所做的是按照 CMakeLists.txt 和 package.xml 文件定义的顺序为它在子文件夹中找到的所有包调用一个 cmake(这个文件在这里看起来如何并不重要)。它还提供了一种重写的方式来使用 find_package 等
问题是有很大一部分代码是以我无法影响的方式编写的。这部分依赖于一个库G2O(图形优化),而G2O包不是"catkinized",即catkin无法知道提供了哪些库。
G2O 本身定义了相当多的库,我们可以通过 FindG2O.cmake 文件找到它们(但是如果一个库是 "core" 我们知道它的名字是 "G2O_CORE_LIBRARY" 在 FindG2O.cmake 中设置)。我们还使用环境变量 "G2O_ROOT" 指向当前的 g2o 安装。
我的想法是在构建 G2O 时设置这个环境变量(使用围绕它的 catkin 元包),并让之后构建的任何人都可以使用这些知识,因为这样可以轻松使用 FindG2O.cmake .
我明白这个解释很乱。有什么不明白的请追问。
似乎我想要实现的目标是不可能的,因为 catkin_make 可能会在不同的子进程中调用不同的 cmake,然后,当然,我无法修改父进程。
你只是做错了。即使 source
可以工作(但它不能,因为它是 bash
内部命令而不是文件系统中存在的真正 binary/executable),它不会影响任何东西!因为 cmake
启动了一个子进程(通过 execute_process()
)并且它将被终止,w/执行结果在相应的变量中可用。 在子进程中设置任何环境变量都不会影响父环境。
因此,您最好使用$ENV{blah}
来设置所需的变量。或者(更好)只使用 CMake 变量......有很多方法可以做到这一点。只需详细说明您要实现的内容即可。
使用 execute_process
的 OUTPUT_VARIABLE
选项。
让你的脚本看起来像这样:
#!/bin/bash
MY_VAR=
echo "$MY_VAR"
并在您的 CMakeLists.txt
中使用它,如下所示:
cmake_minimum_required(VERSION 2.6)
execute_process(COMMAND sh "var_set.sh" "VALUE" "VALUE2"
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
RESULT_VARIABLE variable_RESULT
OUTPUT_VARIABLE variable_OUTPUT
)
message(STATUS ${variable_RESULT})
message(STATUS ${variable_OUTPUT})
CMake 配置步骤的输出是:
-- The C compiler identification is GNU 5.1.1
-- The CXX compiler identification is GNU 5.1.1
-- Check for working C compiler: /usr/lib64/ccache/cc
-- Check for working C compiler: /usr/lib64/ccache/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/lib64/ccache/c++
-- Check for working CXX compiler: /usr/lib64/ccache/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- 0
-- VALUE
-- Configuring done
-- Generating done
-- Build files have been written to: /tmp/out
这种方法的一个缺点是您必须在脚本中禁止所有不需要的输出。或者,使用 OUTPUT_FILE 和 post 处理文件。