我最近遇到了一个与cmake相关的非常有趣的问题。 问题如下:
我有一个CMakeLists.txt,它定义了一个相当简单的项目。我希望能够在构建项目时设置linux环境变量。为此,我想调用一个小脚本var_set.sh
来完成它。它看起来像这样:
#!/bin/bash
MY_VAR=$1
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
,脚本实际上会被执行,但当然,我无法获取我想要导出的变量。
有人知道这种行为的原因是什么?
UPD:
我明白,实现我原本想要的东西可能根本不可能。
最初的想法和动机如下。我们有一个使用ROS的相对较大的项目。它使用catkin_make来构建一切。它基本上做的是按照CMakeLists.txt和package.xml文件定义的顺序为子文件夹中找到的所有包调用cmake(这一点在这里看起来并不重要)。它还提供了一种使用find_package等的重写方式。
问题是代码的很大一部分是以我无法影响的方式编写的。这部分依赖于库G2O(图形优化),而G2O包不是" catkinized",即catkin无法知道提供了哪些库。
G2O本身定义了相当多的库,我们可以通过FindG2O.cmake文件找到它们(但是如果一个库是,"核心"我们知道它的名字和#34 ; G2O_CORE_LIBRARY"在FindG2O.cmake中设置)。我们还使用环境变量" G2O_ROOT"指向当前的g2o安装。
我的想法是在构建G2O时设置此环境变量(使用包裹它的catkin元数据包),并将此知识提供给之后构建的任何人,因为这样可以轻松使用FindG2O.cmake。
我理解这个解释非常混乱。如果不清楚,请询问。
似乎我想要实现的是不可能的,因为catkin_make可能在不同的子进程中调用不同的cmake然后,当然,我无法修改父进程。
答案 0 :(得分:2)
你做错了。即使source
可行(但它不能因为它是bash
内部命令而不是文件系统中存在的真正的二进制文件/可执行文件),它也不会影响任何事情!因为cmake
启动子进程(通过execute_process()
)并且它将被终止,w /执行结果在相应的变量中可用。 在子进程中设置任何环境变量不会影响父环境。
因此,您最好使用$ENV{blah}
来设置所需的变量。或者(更好)只使用CMake变量......有很多方法可以做到这一点。只需提供更多详细信息,您想要实施什么。
答案 1 :(得分:1)
使用execute_process
的OUTPUT_VARIABLE
选项。
让你的脚本看起来像这样:
#!/bin/bash
MY_VAR=$1
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并对文件进行后处理。