在Travis CI Windows环境下用CMake配置MSVC编译遇问题
The core issue here is that even though you've installed the Visual Studio 2019 Build Tools, the necessary environment variables for the MSVC toolchain aren't loaded in your Travis CI PowerShell session. When you manually point CMake to cl.exe, it can run the compiler, but lacks the required INCLUDE, LIB, and path configurations to find headers, libraries, and supporting tools—hence the failed test program compilation.
Here's a step-by-step solution to get this working:
1. Update Your Build Tools Installation Command
First, ensure you're installing all required components for a functional MSVC toolchain. The Windows SDK is often missing in minimal installs, which is needed to compile even simple test programs:
choco install visualstudio2019buildtools --package-parameters "--add Microsoft.VisualStudio.Component.VC.Tools.x86.x64 --add Microsoft.VisualStudio.Component.Windows10SDK.19041 --quiet --norestart"
--quiet --norestartprevents interactive prompts and restarts, which are critical for CI environments.- The Windows SDK version (19041) can be adjusted to match your project's needs, but 19041 is a widely compatible LTS release.
2. Load MSVC Environment Variables
After installation, you need to inject the VC toolchain's environment variables into your PowerShell session. Directly running vcvarsall.bat in PowerShell won't persist variables, so use this script to capture and apply them:
# Refresh environment variables after Chocolatey installs refreshenv # Load x64 MSVC toolchain environment into PowerShell cmd /c "`"C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Auxiliary\Build\vcvarsall.bat`" x64 && set" | ForEach-Object { if ($_ -match '^([^=]+)=(.*)') { [Environment]::SetEnvironmentVariable($matches[1], $matches[2], 'Process') } }
- This runs
vcvarsall.bat(which configures the toolchain) in a cmd shell, captures the resulting environment variables, and applies them to your current PowerShell process. - Use
x86instead ofx64if you need a 32-bit toolchain.
3. Simplify Your CMake Invocation
With the environment properly configured, you no longer need to manually specify CMAKE_CXX_COMPILER. Use the official Visual Studio generator for CMake to ensure full compatibility:
mkdir build cd build cmake .. -G "Visual Studio 16 2019" -A x64 cmake --build . --config Release
- The
-Gflag tells CMake to generate Visual Studio 2019 project files, and-A x64targets 64-bit architecture. - CMake will automatically detect
cl.exeand all required dependencies thanks to the loaded environment variables.
Full Travis CI Configuration Example
Putting it all together, here's a complete .travis.yml for your project:
os: windows language: cpp before_install: # Install CMake and add it to system PATH - choco install cmake --installargs 'ADD_CMAKE_TO_PATH=System' # Install VS 2019 Build Tools with required components - choco install visualstudio2019buildtools --package-parameters "--add Microsoft.VisualStudio.Component.VC.Tools.x86.x64 --add Microsoft.VisualStudio.Component.Windows10SDK.19041 --quiet --norestart" # Refresh and load MSVC environment variables - refreshenv - cmd /c "`"C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Auxiliary\Build\vcvarsall.bat`" x64 && set" | ForEach-Object { if ($_ -match '^([^=]+)=(.*)') { [Environment]::SetEnvironmentVariable($matches[1], $matches[2], 'Process') } } script: - mkdir -p build - cd build - cmake .. -G "Visual Studio 16 2019" -A x64 - cmake --build . --config Release # Optional: Run tests if you have them - ctest -C Release
Why Your Original Approach Failed
When you specified CMAKE_CXX_COMPILER directly, CMake could locate cl.exe, but the compiler couldn't find:
- Standard library headers (like
<iostream>) because theINCLUDEenvironment variable wasn't set to the MSVC include directories. - Linker libraries because the
LIBenvironment variable wasn't configured. - Supporting tools (like
link.exe) because they weren't added to thePATH.
Loading vcvarsall.bat fixes all these issues in one go, ensuring the entire toolchain works as expected.
内容的提问来源于stack exchange,提问作者nickelpro

