lukka / run-cmake

GitHub Action to build C++ applications with CMake (CMakePresets.json), Ninja and vcpkg on GitHub.
MIT License
173 stars 19 forks source link

Semicolons in cmakeAppendedArgs #55

Closed garethsb closed 2 years ago

garethsb commented 2 years ago

The following does not work as I expected on Linux and macOS runners.

- name: test
  uses: lukka/run-cmake@v3.4
  with:
    cmakeListsOrSettingsJson: CMakeListsTxtAdvanced
    ...
    cmakeAppendedArgs: '-GNinja -DFOO_BAR="foo meow;bar hiss"'

It appears argStringToArray strips off double quotes, and I suspect the cmake command line ends up with an unquoted semicolon which acts as a command terminator and therefore in the log:

  CMake Warning:
    No source or binary directory provided.  Both will be assumed to be the
    same as the current working directory, but note that this warning will
    become a fatal error in future CMake releases.

The hint was that on Windows runners this works fine, because ; isn't special.

I've attempted to work around it for now by:

    cmakeAppendedArgs: '-GNinja "-DFOO_BAR=\"foo meow;bar hiss\""'

But that doesn't feel right to me, and doesn't work on Windows runners (I haven't worked out why yet...).

lukka commented 2 years ago

@garethsb this is an interesting problem indeed and the problem is that the shell the action uses to launch command on Windows is the cmd.exe one. You may escape using the ^ character, but it would work only on cmd.exe....

You may try setting bash on Windows by using the useShell input, which I really never really tested thoroughly, be warned.

I think the solution would be to just use bash on any platform, which means entirely removing support from cmd.exe (so removing any horrible code dealing with quotes and spaces like the mentioned argStringToArray) and modifying all the code to work on Windows using the bash shell.

garethsb commented 2 years ago

Thanks for quick response. I've ultimately found a way to work around it in my case by passing two different variables rather than one with a semicolon-separated list value. I didn't find one way of passing a list value successfully on all platforms.

To confirm, the naive attempt currently fails on Linux and macOS...

cmakeAppendedArgs: '-GNinja -DFOO_BAR="foo meow;bar hiss"'
garethsb commented 2 years ago

You may try setting bash on Windows by using the useShell input, which I really never really tested thoroughly, be warned.

Hmm, what would useShell: false do?

lukka commented 2 years ago

The useShell input is passed as-is to the standard child_process.spawn API.

Unfortunately nodejs is not really helping in providing completely OS independent APIs, there are specific cases for Windows and Unix.

lukka commented 2 years ago

Hopefully this is possible with CMakePreset.json. Please take a look to run-cmake@v10 and see if CMakePreset.json suites your needs.