How to C++ in Windows

build-env
#1

The Windows docs page states that C++ is supported.
The CPP docs page falsely states that it covers Windows, but it doesn’t.

Currently there is no example out there on how to build a C++ project in Travis on Windows.

There are numerous issues out there reported of users trying to figure it out, and complaining that various things are not available nor working.

Some of the main issues are:

  • Developer console is not activated by default
  • Developer console is difficult to activate due to running Bash by default
  • Because of ^ we are missing: msbuild, nmake, cl, and many other established Windows build tools, even though they are installed.
  • Missing Qt installation - The chocolatey packages are out of date and broken & official installer only supports 5.12.x and installing takes a lot of time
  • Missing Boost - The chocolatey package is for MSVC 12, we only have 14 available in Travis

Some examples would solve at least the first 3 issues, which are not related to missing dependencies, but documentation bugs.

1 Like
#2

Attempting to load the Developer Console via

    script:
      - /c/Program\ Files\ \(x86\)/Microsoft\ Visual\ Studio/2017/BuildTools/Common7/Tools/VsDevCmd.bat
      - qmake -o Makefile phoenix.pro 64
      - nmake release

does not put the compiler, linker into PATH, nor does it set the paths to the Windows SDK.
The script finishes with success, but the tools are not available in the PATH.

Setting the paths manually is possible:

env:
      - NMAKE_PATH="/c/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/amd64/"
      # - NMAKE_PATH="/c/Program Files (x86)/Microsoft Visual Studio/2017/BuildTools/VC/Tools/MSVC/14.16.27023/bin/Hostx86/x86/"
      - RC_PATH="/c/Program Files (x86)/Windows Kits/10/bin/x64/"
      # -RC_PATH="/c/Program Files (x86)/Windows Kits/10/bin/x86/"
script:
      - export PATH="$NMAKE_PATH:$RC_PATH:$PATH"
      - qmake -o Makefile phoenix.pro 64
      - nmake release

but that is not enough for a proper build, since the Windows SDK headers are still not available.

Note: When using CMake, because CMake is smart and it finds the tools and set’s the paths itself, the compilation works.

#3

Hey @ovidiub13, sorry for the troubles you are having trying to setup your C++ builds.

I’ll be honest, C++ support isn’t the same as on our Linux build environment but the tools are there for you to try. We unfortunately also don’t have examples at this time.

Sorry for the inconvenience and hopefully someone with a working example will reply here.

#4

Here’s what I have succeded so far:

First of all, according to this we should set VsDevCmd.bat and not vcvars64.bat, since VS 2017 comes with VsDevCmd.bat and apparently it’s better suited to set up the environment.

Second, when calling VsDevCmd.bat from git-bash (the default shell in windows on travis CI), the environment is not passed, and get’s lost.

As a solution I’ve created a .bat script that has these lines at the beginning:

echo off
call "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\Common7\Tools\VsDevCmd.bat" -host_arch=amd64 -arch=amd64
call "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\Common7\Tools\VsDevCmd.bat" -test

They set-up the environment and test it. After these I add what ever commands I need to compile my code in this script, and it works.

I still have issues about missing some windows libraries, but I’m still investigating on that.

#5

I have also been looking into the C++ support for Windows recently.

Your idea of doing all the building from a single batch or Powershell script, and setting up environment variables at the start of the script, sounds like a perfectly reasonable way to go. To be honest, there are so many problems related to quoting, escaping, and path translation on Travis+Windows that I try to move as much logic as possible out of the YAML file and into dedicated bash/Powershell scripts.

Another option - which is a lot more work - is to identify which environment changes that the vcvars*.bat / VsDevCmd.bat script is making, and apply those to the Git Bash environment. This makes cl.exe, link.exe etc available directly within Git Bash. Here is an example implementation: Invocation in .travis.yml, script for analyzing environment changes & applying them to the Git Bash environment, script for initializing VS2017 x64 native tools.

The last script above should probably be rewritten to call out to VsDevCmd.bat sometime.

I have used the above tooling to compile regular C code into a static library.

By leveraging the glue code above, it should be possible to add an extra setting for the Windows environment, like so: “compiler: gcc” / “compiler: vs2017-32” / “compiler: vs2017-64” which will affect which set of tools is available on the Git Bash command line.

#6

FWIW, Python has logic in distutils to extract envvars from VS build prompt scripts that it uses to build extensions in Windows. So you can set the envvars necessary for building (namely, INCLUDE, LIB, LIBPATH and PATH) with the following code:

eval "$(python2 -c '
import sys, os, subprocess
import distutils.msvc9compiler as msvc
msvc.find_vcvarsall=lambda _: sys.argv[1]
envs=msvc.query_vcvarsall(sys.argv[2])
for k,v in envs.items():
    k = k.upper()
    v = ":".join(subprocess.check_output(["cygpath","-u",p]).rstrip() for p in v.split(";"))
    v = v.replace("'\''",r"'\'\\\'\''")
    print "export %(k)s='\''%(v)s'\''" % locals()
' 'c:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\Common7\Tools\VsDevCmd.bat' '-arch=amd64'
)"
1 Like