-
Bug
-
Resolution: Unresolved
-
Minor
-
None
-
Durable Task Plugin 1.14
Hello, I've ran into a weird parsing bug when using multi-line bat commands under Windows.
We use the VisualStudio compiler, which requires running `vcvarsall.bat` from the command line in order to setup our environment prior to build.
node('windows-vs2013') { bat """ vcvarsall.bat x86 echo "Made it!" nmake /? """ }
Unfortunately, it doesn't appear we actually execute the command successfully. We see:
[Pipeline] node
Running on dynamic-windows-vs2013-2934 in C:\jenkins\workspace\multiline-bat
[Pipeline] {
[Pipeline] bat
[multiline-bat] Running batch scriptC:\jenkins\workspace\multiline-bat>vcvarsall.bat x86;
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS
Note, the command appears to be executed, but we never see the expected "Made it" text or the help content from nmake.
To be clear, you cannot do this in two steps:
bat "vcvarsall x86" bat "nmake"
Because the second command will be executed in a different shell that does not contain the correct environment configuration.
Curiously, we can work around the issue by doing:
node('windows-vs2013') { bat """ call vcvarsall.bat x86 echo "Made it!" nmake /? """ }
Which produces the correct output:
Edit 9/5/17:
Which only sometimes produces the correct result:
Running on dynamic-windows-vs2013-6962 in C:\jenkins\workspace\multiline-bat
[Pipeline] {
[Pipeline] bat
[multiline-bat] Running batch scriptC:\jenkins\workspace\multiline-bat>call vcvarsall.bat x86
"Made it!"Microsoft (R) Program Maintenance Utility Version 12.00.21005.1
Copyright (C) Microsoft Corporation. All rights reserved.Usage: NMAKE @commandfile
NMAKE [options] [/f makefile] [/x stderrfile] [macrodefs] [targets]Options:
/A Build all evaluated targets
/B Build if time stamps are equal
/C Suppress output messages
/D Display build information
/E Override env-var macros
/ERRORREPORT:{NONE|PROMPT|QUEUE|SEND} Report errors to Microsoft
/G Display !include filenames
/HELP Display brief usage message
/I Ignore exit codes from commands
/K Build unrelated targets on error
/N Display commands but do not execute
/NOLOGO Suppress copyright message
/P Display NMAKE information
/Q Check time stamps but do not build
/R Ignore predefined rules/macros
/S Suppress executed-commands display
/T Change time stamps but do not build
/U Dump inline files
/Y Disable batch-mode
/? Display brief usage message
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS
I was a little surprised the first form didn't work and figured I'd create the ticket to raise awareness and share our workaround. Consider it a low priority.
Thanks for all your hard work.
Regards,
Ryan
Note, I actually discovered this very usable workaround while drafting the issue. This new workaround solves my original complaint about our previous workaround, which required chaining together multiple commands using
bat "vcvarsall x86 && cmake ... && nmake ..."
The "&&" chaining becomes pretty unusable if the arguments/command chain gets large. The "call" solution is much more succinct and allows us to still leverage a multi-line string to improve readability. Cheers!
Edit 9/5/17
The "call" workaround previously mentioned only partially works. It works in the simple case, like in the original sample, but extending it failed:
bat """ call vcvarsall.bat amd64 cmake -G Ninja -D SOME_VARIABLE=Something ^ -D CMAKE_INSTALL_PREFIX=${WORKSPACE}/install ^ -D CMAKE_BUILD_TYPE=RelWithDebInfo ^ -D VERSION_PRIVATEBUILD=true ^ -D VERSION_NUMBER=4.0.0.0 ^ -D VERSION_SPECIALBUILD=${BUILD_TAG} ^ -D SOME_CUSTOM_PARAM=http://someURL ^ -D SOME_CUSTOM_PARAM=${WORKSPACE}/build/folder ^ """
We're still back to the original solution, which works but seems a little tacky:
void multiline(List<String> commands) { command = commands.join(" && ") return command } bat multiline([ "vcvarsall.bat amd64", "cmake -G ..." ])
I had the same issue - and think it's not a Jenkins bug but an idiosyncrasy of windows batch files. I don't know what you mean about it only sometimes working but the correct answer here does seem to be to use call - annoyingly (for someone used to sh) the behaviour of directly naming the target depends on the target you are trying to run.
See:
Perhaps in your other cases when it didn't work you changed the echo to instead call another batch file? At the very least, understanding this has solved my indentical-looking problem.