4

问题描述

我在设置执行 MSYS2 bash 命令的 CMake external_process() 命令时遇到问题。当我在 MSYS2 shell 中运行该命令时$ bash -v ./bootstrap.sh,该命令可以正常工作。但是,如果我在 MSYS2 shell 中运行 CMake 脚本,则在整个过程中使用$ cmake -P Run_bash_command.cmake命令错误。我在CMake 文档中找到的一条重要信息让我认为我没有正确调用 bash 或缺少环境变量:

CMake 直接使用操作系统 API 执行子进程。所有参数都逐字传递给子进程。不使用中间 shell,因此诸如 > 之类的 shell 运算符被视为普通参数。

如果可能,我希望能够使用 CMake 执行此命令,因为此问题是更大的 CMake 超级构建项目的一部分。如果有另一种解决问题的方法,我愿意接受建议,只要我可以将它包含到超级构建项目的自动化中。任何帮助将不胜感激。

Run_bash_command.cmake 内容:

SET( ENV{MSYSTEM} MINGW64 )
SET( DIR_CONTAINING_BOOTSTRAP_SH C:/bash_test )
SET( BASH_COMMAND_TO_RUN bash -v ./bootstrap.sh )

EXECUTE_PROCESS( COMMAND ${BASH_COMMAND_TO_RUN}
          WORKING_DIRECTORY ${DIR_CONTAINING_BOOTSTRAP_SH} RESULT_VARIABLE command_result )

IF( NOT "${command_result}" STREQUAL "0" )
    MESSAGE( FATAL_ERROR "Error: command_result='${command_result}'" )
ENDIF()

环境设置

  • 我按照说明设置 MSYS2 64bit 并使用命令添加了 mingw-w64 工具链以及 cmakepacman -S base-devel git mingw-w64-x86_64-cmake mingw-w64-x86_64-toolchain
  • 要运行命令,我使用与 MSYS2 一起安装的MinGW-w64 Win64 Shell
  • 文件bootstrap.sh来自libusb github 存储库,文件夹c:/bash_test包含 master 分支的克隆

输出

$ bash -v ./bootstrap.sh输出:

$ bash -v ./bootstrap.sh
#!/bin/sh

if ! test -d m4 ; then
    mkdir m4
fi
autoreconf -ivf || exit 1
autoreconf: Entering directory `.'
autoreconf: configure.ac: not using Gettext
autoreconf: running: aclocal --force -I m4
autoreconf: configure.ac: tracing
autoreconf: running: libtoolize --copy --force
libtoolize: putting auxiliary files in '.'.
libtoolize: copying file './ltmain.sh''
...<clipped output due to length>...
configure.ac:29: installing './install-sh'
configure.ac:29: installing './missing'
examples/Makefile.am: installing './depcomp'
autoreconf: Leaving directory `.'

$ cmake -P Run_bash_command.cmake输出:

$ cmake -P Run_bash_command.cmake
#!/bin/sh

if ! test -d m4 ; then
    mkdir m4
fi
autoreconf -ivf || exit 1
autoreconf: Entering directory `.'
autoreconf: configure.ac: not using Gettext
autoreconf: running: aclocal --force -I m4
aclocal-1.15: error: aclocal: file '/msys64/usr/share/aclocal/xsize.m4' does not exist
autoreconf: aclocal failed with exit status: 1
CMake Error at Run_bash_command.cmake:10 (MESSAGE):
  Error: command_result='1'

我尝试过的事情:

  • 替换bash -l -c,但这会导致 shell 默认为主目录,然后找不到文件 bootstrap.sh
  • 通过检查我的环境 PATH 变量验证了正确版本的 bash
  • 已验证的 MSYS2 及其软件包是最新的
  • 使用sh代替bash
  • 直接调用autoreconf -ivf,但出现同样的问题
  • 使用 Unix 风格的路径而不是 Windows 风格
4

1 回答 1

1

我能够使用下面的代码解决问题。

Run_bash_command.cmake 内容:

SET( DIR_CONTAINING_BOOTSTRAP_SH /C/bash_test )
SET( BASH_COMMAND_TO_RUN bash -l -c "cd ${DIR_CONTAINING_BOOTSTRAP_SH} && sh ./bootstrap.sh" )

EXECUTE_PROCESS( COMMAND ${BASH_COMMAND_TO_RUN}
                WORKING_DIRECTORY ${DIR_CONTAINING_BOOTSTRAP_SH} RESULT_VARIABLE command_result )

IF( NOT "${command_result}" STREQUAL "0" )
    MESSAGE( FATAL_ERROR "Error: command_result='${command_result}'" )
ENDIF()

重要笔记:

  • Usingbash -l导致 shell 默认到主目录,为了解决这个问题,我添加了一个更改目录cd <path>命令,让我们回到我们想要发出 bash 命令的目录。
  • Using-c导致 bash 从字符串中读取命令。由于我们要发出两个命令,一个用于更改目录,一个用于运行 shell 脚本,我们需要使用&&将命令链接在一起并使用“引号”来确保整个命令作为字符串被正确读取。
于 2016-04-01T04:06:04.310 回答