1

I've following commands in a powershell script:

$boostPath = "D:/lib/boost/1.62.0-vs2013-x64"
cmake -S $cmakeRootPath -B $buildPath -G $cmakeGenerator -DBOOST_ROOT=$boostPath

With this the variable $boostPath is not expanded. I can see in FindBoost log

-- [ C:/Program Files/CMake/share/cmake-3.18/Modules/FindBoost.cmake:1528 ] BOOST_ROOT = "$boostPath"

Instead, if in the script I write

cmake -S $cmakeRootPath -B $buildPath -G $cmakeGenerator -DBOOST_ROOT="D:/lib/boost/1.62.0-vs2013-x64"

The variable is set correctly and cmake works. How can I give correctly the argument using a variable?

Jepessen
  • 11,744
  • 14
  • 82
  • 149
  • 3
    The PowerShell parser interprets the entire string `-DBOOST_ROOT=$boostPath` as a switch parameter. Use `-DBOOST_ROOT="$boostPath"` and it should work – Mathias R. Jessen Jul 07 '20 at 13:51

1 Answers1

4

Mathias R. Jessen has provided the crucial pointer in comment:

A token such as -DBOOST_ROOT=$boostPath is parsed as a literal by PowerShell - the $boostPath variable reference is not recognized and therefore not expanded (replaced by its value).

PowerShell's sometimes surprising behavior with unquoted compound token is summarized in this GitHub issue.

The following should generally work and definitely works if $boostPath contains no spaces:

cmake -S $cmakeRootPath -B $buildPath -G $cmakeGenerator -DBOOST_ROOT="$boostPath"

Double-quoting of the variable reference forces its expansion.

Note:

  • Since PowerShell performs re-quoting behind the scenes that preserves double quotes (potentially converted from single quotes) only if needed (see this answer) and your path contains no spaces, what cmake will see on the command line is verbatim
    -DBOOST_ROOT=D:/lib/boost/1.62.0-vs2013-x64 - no quotes.

  • If $boostPath did contain spaces, say $boostPath = "D:/lib 1/boost/1.62.0-vs2013-x64", PowerShell would double-quote the argument as a whole, so that what cmake will see on the command line is verbatim
    "-DBOOST_ROOT=D:/lib 1/boost/1.62.0-vs2013-x64"

    • If cmake on Windows[1] truly requires the "..." to be around the $boostPath value only (which some CLIs, notably msiexec, unfortunately require), use this workaround (one argument omitted for brevity):
cmake -S $cmakeRootPath -B $buildPath -DBOOST_ROOT="`"$boostPath`""

Caveat: If PowerShell's broken (re)quoting of arguments passed to external programs (see this answer) should ever get fixed (see this GitHub issue), this workaround will break.


[1] Only on Windows do (console) programs need to do their own parsing of a whole command line into individual arguments; on Unix-like platforms, they sensibly receive an array of verbatim tokens.

mklement0
  • 382,024
  • 64
  • 607
  • 775