「バッチTclスクリプトを使用したVivadoツールの起動」で丸括弧を含むパスの処理にハマった件

# 概要
Vivadoというソフトウェアが世の中にはあります。
AMDっていうIntelとタメを張るCPUの会社さんが、2025年現在から見て少し昔に買収したXilinxという会社さんのツールなんですけどご存じでしょうか？

Xilinxという会社さんは、FPGAと呼ばれる「論理回路をプログラミングの要領で構築するIC」を製造している会社さんで、VivadoというツールはFPGAに書き込むコードをコンパイルするためのソフトウェアになります。

「Xilinxという会社さんが作ったFPGA」に書き込むデータを作成するには、このVivadoと呼ばれる複雑で使いにくいソフトウェアを使わなければならず、いちいちGUIをマウスでポチポチしなければならないため、「同じ作業を機械的に繰り返したいだけなんだけど！！」というときには正直面倒くさいです。

そんな作業を自動化できる仕組みが「バッチTclスクリプトを使用したVivadoツールの起動」となります。
Vivadoは、GUIの裏でバッチファイルやTclスクリプトを動かしているだけなので、「そもそもGUIなんか立ち上げなくても動かせるじゃん！」ってことになるわけです。

なので、必要な動作をバッチファイルやTclスクリプトからVivadoに投げて裏で動かしつつ、作業が完了したら「start_GUI」(GUIを立ち上げるコマンド)を送ることで、結果だけ表示させることができるわけですね。
いやそれだけではなく、GUIを立ち上げることなく作業を完了することもできます。

そんなわけで面倒くさがりな自分は、自動化を目論んで2025年現在AMDから提示されている資料の「UG910」「UG908」「UG894」「UG835」に記載されている該当部分を読んで自動化を進めていたのですが…。

**変　な　挙　動　に　ハ　マ　り　ま　し　た　ｗ**

そんなわけで、備忘録を記載していきたいと思います。

・
・
・

というか、なんでハマったのかまだよくわかっていないので、だれか教えていただけないでしょうか…？

# 「バッチTclスクリプトを使用したVivadoツールの起動」とはなんぞや
そもそも、「『バッチTclスクリプトを使用したVivadoツールの起動』とはなんぞや」、となるので解説します。
「[UG910 Vivado Design Suite ユーザーガイド 入門](https://docs.amd.com/viewer/book-attachment/7YwEXvzS7QYjBX8byJxJdQ/6CWWgcnYNlLbPwb9ogKLVQ-7YwEXvzS7QYjBX8byJxJdQ)」によると、以下のような記載があります。

> **Vivado Design Suite Tcl シェルの起動**
> Vivado Design Suite Tcl シェルを起動するには、Linux コマンド プロンプトまたは Windows コマンド プロンプトに次のように入力します。
> 
> ```batch
> vivado -mode tcl
> ```
> 
> 注記: Windows で、[Start] → [All Programs] → [Xilinx Design Tools] → [Vivado <version>] → [Vivado <version> Tcl Shell]をクリックします。
> 
> **バッチ Tcl スクリプトを使用した Vivado ツールの起動**
> Vivado ツールを起動するときに Tcl スクリプトを指定すると、Vivado ツールをバッチ モードで使用できます。Linuxコマンド プロンプトまたは Windows コマンド プロンプトに次のように入力します。
> 
> ```batch
> vivado -mode batch -source <your_Tcl_script>
> ```
> 
> 注記: バッチ モードの場合、指定したスクリプトが実行された後Vivadoツールが終了します。

つまり、コマンドプロンプトで以下のコマンドを実行すれば、バッチモードでVivadoを動かせそうです。

```batch
vivado -mode batch -source <your_Tcl_script>
```

このコマンドの先頭にある「vivado」というコマンドは、Vivadoのインストール後に、スタートメニューに生えてくる「Xilinx Design Tools」というフォルダから開ける「`Vivado <version> Tcl Shell`」というコマンドプロンプトの画面に打ち込んだときのみ有効なコマンドなので、**通常のコマンドプロンプトからは実行することができません。**

「え？じゃあどうやってVivadoを起動するんだ？」

って話になるんですけど、これは簡単で、「vivado」というコマンドの代わりになるものを実行すれば良いわけです。
それが、Vivadoをインストールした際に、デスクトップに作成した「`Vivado <version>`」という形式のアイコンのプロパティを開いて、リンク先を見るとわかります。
ここのリンク先に「[User_DIR]\Vivado\2024.1\bin\vivado.bat」ってな感じでバッチファイルが指定されているので、「vivado」というコマンドの代わりにこいつを呼び出すと動作します。

```batch
[User_DIR]\Vivado\2024.1\bin\vivado.bat -mode batch -source <your_Tcl_script>
```

このコマンドを自分の環境のディレクトリに整理して、Windowsに標準で搭載されているコマンドプロンプトで実行すれば、Vivadoが動作するわけですね。

ということで実行しましょう！
例えば「start_tcl_settings.tcl」というファイルを作成して、「[User_DIR]\Write(test1.0.1)\TCL」というディレクトリに突っ込んでおきます！
そのあとに、Vivadoのバッチモードを起動するコマンドを実行します！
実行結果を下にドーン！！

```batch
[User_DIR]\Write(test1.0.1)\TCL>[User_DIR]\Vivado\2024.1\bin\vivado.bat -mode batch -source "[User_DIR]\Write(test1.0.1)\TCL\start_tcl_settings.tcl"
\TCL:<PC名>-<年月日>_<時刻> の使い方が誤っています。

[User_DIR]\Write(test1.0.1)\TCL>
```
あ、あれ？

# 考察パート
「`\TCL`」と表示されているので、パスに含まれる「)」より前の部分がマルッと無視されたと考えられます。
丸括弧がある場合、バッチファイルがおかしな挙動をすることがあると認識していたため、
```batch
[User_DIR]\Vivado\2024.1\bin\vivado.bat -mode batch -source
```
とりあえず前半のこの部分には問題ないものだと仮定しました。
(ここを疑うとVivadoのデバッグになりかねないので後回し…)

そうなると、
```batch
"[User_DIR]\Write(test1.0.1)\TCL\start_tcl_settings.tcl"
```
後半のこの部分がおかしな挙動を引き起こしていると考えられます。
その場合、ダブルクォーテーションを無視しておかしくなっていることになるので、エスケープ不可能だと思いました。
すると、Tclファイルが入っているフォルダの名前から丸括弧を消さなければならないので、面倒だなと思い、いったん保留にしました。
他にやりようがなければ変える、くらいの気持ちです。
(ファイルの詳細を相手に知られたくないものの、バージョン情報だけは知っていてほしいため、フォルダにバージョン情報を書き込むことで確認が容易になるようにしています。そこに丸括弧を入れてしまっているので、今さらフォーマットを変えるのは面倒、というお話です。)

また、「`:<PC名>-<年月日>_<時刻> の使い方が誤っています。`」というエラーの意味がよくわかりません。。。
これは試行錯誤した後の自分の憶測になってしまうのですが、このエラーは「`(サブスクリプトの):<PC名>-<年月日>_<時刻> の使い方が誤っています。`」という意味だと思います。
つまり、

```batch
[User_DIR]\Vivado\2024.1\bin\vivado.bat -mode batch -source "[User_DIR]\Write(test1.0.1)\TCL\start_tcl_settings.tcl"
```

の前と後のパスのどちらかが、サブスクリプトとして認識されてしまったことで、エラーが発生したんじゃないかな、と感じました。
こちらを突き詰めてみたいのですが、自分の理解の浅さと、調査をするための手の付け方がわからなかったため、コマンドの書き方を変更して試すことにしました。

# 対処方法は突然に
色々試行錯誤していると、同じコマンドをコピペして実行しているのに、成功する場合と失敗する場合があることに気が付きました。

以下に成功する場合と失敗する場合を示します。

### 成功した場合
```batch
[User_DIR]>[User_DIR]\Vivado\2024.1\bin\vivado.bat -mode batch -source "[User_DIR]\Write(test1.0.1)\TCL\start_tcl_settings.tcl"
```

### 失敗した場合
```batch
[User_DIR]\Write(test1.0.1)\TCL>[User_DIR]\Vivado\2024.1\bin\vivado.bat -mode batch -source "[User_DIR]\Write(test1.0.1)\TCL\start_tcl_settings.tcl"
\TCL:<PC名>-<年月日>_<時刻> の使い方が誤っています。

[User_DIR]\Write(test1.0.1)\TCL>
```

お気づきになられましたか？

```batch
[User_DIR]>
[User_DIR]\Write(test1.0.1)\TCL>
```

そう、成功する場合と失敗する場合の違いは、**コマンドを実行したときにいるカレントディレクトリ**だったんです！！
どうして…。

# 原因はわからないけどこうするとうまくいく…(2025/06/07現在)
もう少し調べていくと、**コマンドを実行した時にいるカレントディレクトリに丸括弧が含まれているとコケること**がわかりました。
なので、コマンド実行前に、パスに丸括弧の含まれないディレクトリに移動することで、バッチファイルの処理が途中で終了することなく完了する、ということです。

ということで、以下のようなコマンドを実行することにします。

```batch
cd /d <丸括弧の含まれない適当なフォルダに移動>
[User_DIR]\Vivado\2024.1\bin\vivado.bat -mode batch -source "[User_DIR]\Write(test1.0.1)\TCL\start_tcl_settings.tcl"
```

「一件落着！！」と気持ちよくなることはできませんでしたが、回避方法を編み出すことができました。。。
同じことに困っている方がいらっしゃれば、参考になれば幸いです。。。

あっ、ちなみにこの現象、「2023.2」と「2024.1」で確認しています。
少なくとも「この2つのバージョンでは発生する現象である」という認識があるだけでも、やりようがあると思うので、バージョン情報を共有いたします

# 追記1(2025/06/10現在)
気が向いたのでVivadoの中身を見てみました。
`echoした後、pauseする`コマンドを上と下に付けて、プログラムを挟み込むことで、エラーで停止する位置を割り出しました。

そのコマンドがこちらです。

```batch
@REM setupEnv.batの中身です。
if not defined RDI_SESSION_INFO (
  set RDI_SESSION_INFO=%session_string%
)
```

ここで判定を行うと、

```batch
\TCL:<PC名>-<年月日>_<時刻> の使い方が誤っています。
```

のエラーが出るようです。
この前には`RDI_SESSION_INFO`の変数設定はないので、おかしくなりようがないのですが、誤動作します。
そこで、カレントディレクトリを確認するためにechoで表示することにしました。

```batch
@REM setupEnv.batの中身です。
@REM カレントディレクトリを表示するプログラムを追記しました。
echo %cd%

if not defined RDI_SESSION_INFO (
  set "RDI_SESSION_INFO=%session_string%"
)
```

**な　ぜ　か　動　い　た　ｗ**

えぇ…
エラーが出ずに動いてしまいました…。

# 追記2(2025/06/10現在)
~~追記1のプログラムですが、試行錯誤の跡が残っていたため修正しました。~~

```batch
@REM 試行錯誤の跡が残っていた修正前
  set "RDI_SESSION_INFO=%session_string%"
@REM 元に戻した修正後
  set RDI_SESSION_INFO=%session_string%
```

⇒この修正を行うと、「%cd%」があっても動かないことがわかりました。。。ダブルクォーテーションを付けるのが肝だったようです。。。

プログラム編集中に気になったことがあったので、以下のように変更してみました。

```batch
if not defined "%RDI_SESSION_INFO%" (
  set "RDI_SESSION_INFO=%session_string%"
)
```

このプログラムで動かしたところ、カレントディレクトリの表示なしに起動させることができました。
…で、何が原因だったのでしょうか？

# 追記3(2025/06/10現在)

```batch
if not defined RDI_SESSION_INFO (
  set "RDI_SESSION_INFO=%session_string%"
)
```

これで動きました。
このプログラムの前に、

```batch
set session_string=%cd%:%COMPUTERNAME%-%DATE:/=-%_%TIME::=-%
set session_string=%session_string: =%
```

とあったので、ダブルクォーテーションの囲い漏れだと思われます。
パスはダブルクォーテーションを付けておくと安心ですね。。。

「2023.2」と「2024.1」で動作することを確認しました。

## 追記3からわかること
1. なるべくパスに「丸括弧」を含まないようにしましょう
1. 変更が難しいのであれば、「setupEnv.bat」でダブルクォーテーションを追加すれば丸括弧を使っていても動作するようになります

```batch
if not defined RDI_SESSION_INFO (
  set "RDI_SESSION_INFO=%session_string%"
)
```

これでカレントディレクトリを、わざわざ丸括弧の含まれていないところに移動させることなくVivadoを動かすことができるので、「どうしても丸括弧を使わなければいけないんだ！！」という人は、Vivadoのバッチファイルを**自己責任**で編集してみると良いと思います。