简体   繁体   English

cmake execute_process找不到源命令

[英]cmake execute_process cannot find source command

I have recently bumped into quite an interesting issue with cmake. 我最近碰到了一个与cmake相当有趣的问题。 The problem is the following: 问题如下:

I have a CMakeLists.txt that defines a fairly simple project. 我有一个CMakeLists.txt,它定义了一个相当简单的项目。 I want to be able to set a linux environment variable while building the project. 我希望能够在构建项目时设置linux环境变量。 For this I want to call a tiny script var_set.sh that does it. 为此,我想调用一个微型脚本var_set.sh It looks like this: 看起来像这样:

#!/bin/bash
MY_VAR=$1
export MY_VAR

In the CMakeLists.txt I run it as follows: 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})

the output of this is 这个的输出是

-- No such file or directory

I believe the problem is the source command. 我相信问题是source命令。 If I use ./var_set.sh instead of source var_set.sh the script actually gets executed, but then, of course, I am unable to get the variable I want exported. 如果我使用./var_set.sh而不是source var_set.sh则实际上会执行脚本,但是,当然,我无法获取要导出的变量。

Does anybody know what can be the reason for this behavior? 有人知道这种行为的原因是什么吗?

UPD: UPD:

I come to an understanding that it is probably not at all possible to achieve what I originally want. 我了解到,要实现我最初想要的目标可能根本不可能。

The original idea and motivation are the following. 最初的想法和动机如下。 We have a relatively big project using ROS. 我们有一个使用ROS的相对较大的项目。 It uses catkin_make to build everything. 它使用catkin_make来构建所有内容。 What it basically does is calles a cmake for all packages it finds in the subfolders in an order defined by CMakeLists.txt and a package.xml file (it is not important how this one looks like here). 它的基本作用是按照在CMakeLists.txt和package.xml文件中定义的顺序,对在子文件夹中找到的所有软件包进行cmake(这在这里看起来并不重要)。 It also provides an overridden way to use find_package etc. 它还提供了一种使用find_package等的替代方法。

The problem is that there is a significant part of the code that is written in the way I have no means of influencing. 问题在于,有很大一部分代码是以我无法影响的方式编写的。 This part relies on a library G2O (graph optimization) and the G2O package is not "catkinized", ie catkin has no means of knowing what libraries are provided. 这部分依赖于库G2O(图形优化),并且G2O包未“分类”,即catkin无法得知所提供的库。

G2O by itself defines quite some number of libraries and we are able to find them through FindG2O.cmake files (but if a library is, say, "core" we know it by the name "G2O_CORE_LIBRARY" set in FindG2O.cmake). G2O本身定义了很多库,我们可以通过FindG2O.cmake文件找到它们(但是,如果一个库是“核心”,我们就可以通过在FindG2O.cmake中设置的名称“ G2O_CORE_LIBRARY”来了解它)。 We also use an environmental variable "G2O_ROOT" to point to the current g2o installation. 我们还使用环境变量“ G2O_ROOT”指向当前的g2o安装。

My idea was to set this environment variable while building the G2O (using a catkin meta package wrapped around it) and make this knowledge available to whoever gets built afterwards because this would enable an easy usage of FindG2O.cmake. 我的想法是在构建G2O时设置此环境变量(使用包裹在其中的catkin元数据包),并让以后构建的任何人都可以使用此知识,因为这样可以轻松使用FindG2O.cmake。

I understand this explanation is quite messy. 我知道这个解释很乱。 Please ask if something is not clear. 请询问是否不清楚。

It seems like what I am trying to achieve is not possible as catkin_make probably calls different cmake in a different subprocess and then, of course, I can do nothing to modify the parent process. 似乎我要实现的目标是不可能的,因为catkin_make可能在不同的子进程中调用了不同的cmake,然后,我当然不能做任何修改父进程的操作。

You just do it wrong. 你做错了。 Even if source would work (but it can't because it is bash internal command and not a real binary/executable present in your filesystem), it wouldn't affect anything! 即使source可以工作(但是它不能执行,因为它是bash内部命令,而不是文件系统中存在的实际二进制/可执行文件),也不会影响任何内容! Because cmake starts a child process (by means of execute_process() ) and it will be terminated, w/ execution results available in corresponding variables. 由于cmake启动子进程(通过execute_process() )并将终止,因此执行结果可在相应变量中使用。 Setting any environment variables in a child process will not affect the parent environment . 在子进程中设置任何环境变量都不会影响父环境

So, you'd better to use $ENV{blah} to set desired variables. 因此,最好使用$ENV{blah}设置所需的变量。 Or (better) just use CMake variables... there is a lot of ways to do that. 或者(更好)只是使用CMake变量...有很多方法可以做到这一点。 Just give more details what do you want to implement. 只需提供更多详细信息,您想实现什么。

Use the OUTPUT_VARIABLE option of execute_process . 使用execute_processOUTPUT_VARIABLE选项。

Make your script look like this: 使您的脚本如下所示:

#!/bin/bash
MY_VAR=$1
echo "$MY_VAR"

And use it in your CMakeLists.txt as follows: 并在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})

The output of the CMake configuration step is then: 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

A drawback to this approach is that you will have to suppress all unwanted output in your script. 这种方法的一个缺点是您将不得不禁止脚本中所有不需要的输出。 Alternatively, use OUTPUT_FILE and post-process the file. 或者,使用OUTPUT_FILE并对文件进行后处理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM