4

問題の説明

MSYS2 bash コマンドを実行する CMake external_process() コマンドの設定に問題があります。MSYS2 シェルでコマンドを実行すると、コマンド$ bash -v ./bootstrap.shは正しく機能します。しかし、コマンドを使用して MSYS2 シェルで CMake スクリプトを実行すると$ cmake -P Run_bash_command.cmake、プロセスの途中でエラーが発生します。CMake ドキュメントで見つけた重要な情報により、bash を正しく呼び出していないか、環境変数が欠落していると思われます。

CMake は、オペレーティング システム API を直接使用して子プロセスを実行します。すべての引数は VERBATIM で子プロセスに渡されます。中間シェルは使用されないため、> などのシェル演算子は通常の引数として扱われます。

この問題ははるかに大きな 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 64ビットをセットアップし、コマンドを使用してmingw-w64ツールチェーンとcmakeを追加しましたpacman -S base-devel git mingw-w64-x86_64-cmake mingw-w64-x86_64-toolchain
  • コマンドを実行するには、MSYS2 と共にインストールされるMinGW-w64 Win64 シェルを使用します。
  • ファイルbootstrap.shlibusb 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すると、シェルがデフォルトでホーム ディレクトリになり、bootstrap.sh ファイルを見つけることができなくなります。
  • 環境の PATH 変数を調べて、正しいバージョンの bash が見つかることを確認しました
  • MSYS2 とそのパッケージが最新であることを確認
  • shの代わりに使用bash
  • 直接呼び出しautoreconf -ivfますが、同じ問題が発生します
  • Windows スタイルの代わりに Unix スタイルのパスを使用する
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()

重要事項:

  • を使用するbash -lと、シェルはデフォルトでホーム ディレクトリになります。これを回避するためにcd <path>、bash コマンドを発行するディレクトリに戻すためのディレクトリ変更コマンドを追加しました。
  • を使用する-cと、bash は文字列からコマンドを読み取ります。1 つはディレクトリの変更用、もう 1 つはシェル スクリプトの実行用の 2 つのコマンドを発行する必要があるため&&、コマンドを連結し、「引用符」を使用してコマンド全体が文字列として適切に読み取られるようにする必要があります。
于 2016-04-01T04:06:04.310 に答える