# VS2015 build script problem

#### martins

##### Orbiter Founder
Orbiter Founder
I am currently updating my Orbiter build toolset from VS2008 to VS2015.

While the transition worked surprisingly smoothly in terms of the actual code, I ran into a strange problem with a custom build step that has confounded me all day. I've run out of ideas, so here it is, in case somebody has a suggestion.

The custom build step compiles the LaTeX sources for the documents in the Doc\Technotes folder. It looks like this:

Code:
if not exist "$(ObjectDir)\latex" mkdir "$(ObjectDir)\latex"
if not exist "$(OrbiterDocDir)\Technotes" mkdir "$(OrbiterDocDir)\Technotes"
cd "%(RootDir)%(Directory)"

latex -aux-directory="$(ObjectDir)\latex" -output-directory="$(ObjectDir)\latex" "%(FullPath)"
bibtex "$(ObjectDir)\latex\%(Filename)" latex -aux-directory="$(ObjectDir)\latex" -output-directory="$(ObjectDir)\latex" "%(FullPath)" latex -aux-directory="$(ObjectDir)\latex" -output-directory="$(ObjectDir)\latex" "%(FullPath)" dvips "$(ObjectDir)\latex\%(Filename).dvi" -o "$(ObjectDir)\latex\%(Filename).ps" ps2pdf "$(ObjectDir)\latex\%(Filename).ps" "$(OrbiterDocDir)\Technotes\%(Filename).pdf" (Don't worry about the various path macros. They specify the source, build and deploy directories and I checked that they are expanded correctly.) This build script works ok in VS2008, and it works nearly in VS2015, except for the last command that converts the intermediate PS file to PDF. This just fails with a 255 error code and doesn't produce any output. If I execute the last line manually in a command shell (with expanded macros) it works ok. I even tried to pipe the entire script into a bat file on the fly and run that from the custom build step, with the same result. If I run the generated bat file manually outside the VS IDE, it works flawlessly. I checked that the ps2pdf executable is found within the custom build environment. I tried to combine the DVI -> PS -> PDF conversion into a single DVI -> PDF step using the dvipdf command, with the same result. What does work is using pdflatex to generate PDF output directly from the sources. Unfortunately this doesn't work if the LaTeX code includes EPS figures, which I have. So can anybody think of a reason why the ps2pdf utility doesn't work inside the VS2015 IDE? Are there particular restrictions on what can be used in the custom build step? I am using the MiKTeX 2.9 installation for my LaTeX compiler. Often ps2pdf is implemented as a batch file calling gs (ghostscript) with a predefined set of parameters, but in this case it's an exe (possibly a wrapper for another exe). I thought it might be running up against my virus scanner, but why would it then run without problems outside the IDE? #### Face ##### Addon Developer Addon Developer Beta Tester So can anybody think of a reason why the ps2pdf utility doesn't work inside the VS2015 IDE? Are there particular restrictions on what can be used in the custom build step? AFAIK, there are no restrictions, but I know that the shell of the pre/post-build events doesn't always have all the environment variables a user shell has. Perhaps ps2pdf needs some variables that were installed during setup, but only available in a user shell? #### martins ##### Orbiter Founder Orbiter Founder Good point. I think the VS2015 installation contains a "native tools" command shell that might mimic the environment present in the custom build step. I'll try to run ps2pdf in there to see if that turns up anything. Edit: Do you know if there is a way to invoke a "normal" user shell from within the custom build step? If I just call Code: cmd build.bat from the build step, would this run with the standard user environment, or would it still inherit the VS2015 environment? #### Face ##### Addon Developer Addon Developer Beta Tester Good point. I think the VS2015 installation contains a "native tools" command shell that might mimic the environment present in the custom build step. I'll try to run ps2pdf in there to see if that turns up anything. Edit: Do you know if there is a way to invoke a "normal" user shell from within the custom build step? If I just call Code: cmd build.bat from the build step, would this run with the standard user environment, or would it still inherit the VS2015 environment? On my Win7, the above call did not work at all. I had to put it like so to have the batch file executed: Code: cmd.exe /C build.bat However, a simple test with a script piping "SET" into text files showed that the environment is modified by Visual Studio, and the "cmd" call did not refresh it for the batch file. Particularly interesting: the INCLUDE and LIB variables get overwritten. I think ps2pdf needs some specific "LIB" IIRC, so I guess that might be the culprit. Seems like it is not so trivial to reset the environment: https://stackoverflow.com/questions/8261156/start-new-cmd-exe-and-not-inherit-environment #### kuddel ##### Donator Donator I once had an issue when the last command (-line) in a post- or pre-build step did not contain a newline. Maybe it's just that, adding a trailing newline... #### martins ##### Orbiter Founder Orbiter Founder I once had an issue when the last command (-line) in a post- or pre-build step did not contain a newline. Maybe it's just that, adding a trailing newline... Good idea, but unfortunately it wasn't that. I did now run the script in the VS2015-specific command prompt, and it works there. The environment in the VS2015 shell also modifies the environment, but with some subtle differences to the custom build step in the IDE. None of the differences look significant to me. This is getting annoying. I feel I have already spent more time on this than it's worth. Maybe as a last attempt I am going to try to bypass the ps2pdf tool by invoking gs directly, if I can figure out the required parameters. Failing that, I may stick with VS2008 for the time being. If it ain't broke ... #### Face ##### Addon Developer Addon Developer Beta Tester Maybe as a last attempt I am going to try to bypass the ps2pdf tool by invoking gs directly, if I can figure out the required parameters. What about file locks hold by VS while ps2pdf is running? I sometimes have troubles with this while building more complex solutions. #### martins ##### Orbiter Founder Orbiter Founder What about file locks hold by VS while ps2pdf is running? I sometimes have troubles with this while building more complex solutions. Quite possible, but I wouldn't really know how to check for this. Anyway, I seem to have found a solution. Replacing the last line with Code: gswin32c -sDEVICE=pdfwrite -sOutputFile="$(OrbiterDocDir)\Technotes\%(Filename).pdf" -dNOPROMPT -dNOPAUSE -dBATCH "\$(ObjectDir)\latex\%(Filename).ps"
appears to do the trick. It's a bit clumsy, but it's good enough for me. Sorry for sending you on a wild goose chase ...

#### n122vu

Donator
Could it have been an authorization/privileges issue with the VS shell related to Windows UAC? When working with VS2015 here at work, I would sometimes have issues on Windows 7 if I didn't run Visual Studio as Administrator, so I just set my shortcut/taskbar icon to always run it as Administrator and avoid errors related to filesystem security.

#### martins

##### Orbiter Founder
Orbiter Founder
Could it have been an authorization/privileges issue with the VS shell related to Windows UAC? When working with VS2015 here at work, I would sometimes have issues on Windows 7 if I didn't run Visual Studio as Administrator, so I just set my shortcut/taskbar icon to always run it as Administrator and avoid errors related to filesystem security.
Maybe, although it seems a bit worrying if you need admin privileges just to compile a latex document.

I dived a bit deeper into the ps2pdf mystery and the implementation looks quite messy. In addition to the ps2pdf.exe, there is also a ps2pdf.bat in the MiKTeX installation (not on the search path) which seems to be doing essentially the same thing. Possibly ps2pdf.exe is a wrapper for ps2pdf.bat, although I can't imagine why they would arrange it like this. In addition, ps2pdf.bat is the entry point for a whole cascade of bat files, some of which write out parameters into a temporary file to be picked up by a script later on in the sequence. Maybe it's not too surprising that this falls over when the environment isn't fully compliant.

Anyway, let's not dwell on this unedifying issue longer than necessary. I've got a working solution, and I hope I won't have to touch it again.