3

When using CMake to generate a Visual Studio 15 Solution for the 64 bit architecture one has to first call vcvarsall.bat amd64 and then call cmake with the generator option cmake . -Bbuild -G"Visual Studio 14 2015 Win64". CMake will then determine the value of a couple of variables when executing the project() function.

CMAKE_GENERATOR: Visual Studio 14 2015 Win64
CMAKE_BUILD_TOOL: C:/Program Files (x86)/MSBuild/14.0/bin/MSBuild.exe
CMAKE_CXX_COMPILER: C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/x86_amd64/cl.exe
CMAKE_C_COMPILER: C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/x86_amd64/cl.exe
CMAKE_LINKER: C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/x86_amd64/link.exe
CMAKE_CXX_COMPILER_ID: MSVC
CMAKE_CXX_COMPILER_VERSION: 19.0.24215.1
CMAKE_VS_PLATFORM_NAME: x64

I would like to get rid of the call to vcvarsall.bat and the -G"generator" option by setting the values of the variables in a toolchain file like this:

# VisualStudio2015.cmake

set(CMAKE_GENERATOR "Visual Studio 14 2015 Win64" CACHE STRING "The CMake generator" FORCE )

set(CMAKE_BUILD_TOOL "C:/Program Files (x86)/MSBuild/14.0/bin/MSBuild.exe" CACHE FILEPATH "The visual studio build-system" FORCE)
set(CMAKE_CXX_COMPILER "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/x86_amd64/cl.exe" CACHE FILEPATH "Microsoft compiler" FORCE)
set(CMAKE_C_COMPILER "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/x86_amd64/cl.exe" CACHE FILEPATH "Microsoft compiler" FORCE)
set(CMAKE_LINKER "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/x86_amd64/link.exe" CACHE FILEPATH "Microsoft linker" FORCE)

set(CMAKE_CXX_COMPILER_ID MSCV CACHE STRING "The Id string of the compiler" FORCE)
set(CMAKE_CXX_COMPILER_VERSION 19.0.24215.1 CACHE STRING "The version of the compiler" FORCE)
set(CMAKE_VS_PLATFORM_NAME x64 CACHE STRING "Target processor architecture" FORCE)

and then call cmake with the CMAKE_TOOLCHAIN_FILE option:

cmake . -Bbuild -DCMAKE_TOOLCHAIN_FILE=VisualStudio2015.cmake

The problem is that this does not seem to work. When cmake executes the project() function it overrides the values for the compiler that I have set. So do I just forget to set some variables that are required or is this simply not possible?

Thank you for your time.

Knitschi
  • 2,822
  • 3
  • 32
  • 51
  • I've once done something like this in `PreLoad.cmake` (see [here](https://stackoverflow.com/questions/33917454/cmake-how-to-specify-the-version-of-visual-c-to-work-with)). But I don't understand why you need to set all the other variables once you have defined the generator? Those are normally detected/evaluated by CMake itself. Or is the question more about how to suppress those CMake mechanisms and overwrite/preset everything in a toolchain file? – Florian Jun 25 '17 at 20:19
  • I do not know if I have to set them. I just thought that cmake uses the environment which is set by calling ````vcvarsall.bat```` to determine the compiler and build tool pathes. So I assumed I have to set those manually when I do not call ````vcvarsall.bat````. – Knitschi Jun 26 '17 at 06:34

1 Answers1

2

Turning my comment into an answer

I think what your are looking for is not a toolchain file (since you can't change the CMAKE_GENERATOR there), but the -C <initial-cache> option to "Pre-load a script to populate the cache".

And you shouldn't put too many of the values CMake normally detects/evaluates into the script.

So I've successfully tested the following:

VS2015InitialCache.cmake

set(CMAKE_GENERATOR "Visual Studio 14 2015 Win64" CACHE STRING "The CMake generator" FORCE)

set(CMAKE_CACHE_INIT_FILE "${CMAKE_CURRENT_LIST_FILE}" CACHE STRING "The CMake cache init file used" FORCE)

set(CMAKE_MAKE_PROGRAM "C:/Program Files (x86)/Microsoft Visual Studio 14.0/Common7/IDE/devenv.com" CACHE FILEPATH "Microsoft compiler" FORCE)
set(CMAKE_CXX_COMPILER "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/x86_amd64/cl.exe" CACHE FILEPATH "Microsoft CXX compiler" FORCE)
set(CMAKE_C_COMPILER "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/x86_amd64/cl.exe" CACHE FILEPATH "Microsoft C compiler" FORCE)

And then you call:

> cmake -CVS2015InitialCache.cmake -H. -Bbuild
loading initial cache file VS2015InitialCache.cmake
-- The C compiler identification is MSVC 19.0.24215.1
-- The CXX compiler identification is MSVC 19.0.24215.1
-- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/x86_amd64/cl.exe
...

References

Florian
  • 39,996
  • 9
  • 133
  • 149
  • Thank you for your answer. I will try that out as soon as I can and mark it as a valid answer then. – Knitschi Jun 27 '17 at 10:57
  • Setting the generator in a config file which is set with the ````-C```` option seems to work. However, I still would expect the generator and compiler definitions to be in the toolchain file. – Knitschi Jul 05 '17 at 10:57
  • I also tried to set ````CMAKE_BINARY_DIR```` in the config file, but I got errors. Do you know if this is not possible or did I just make some mistake? – Knitschi Jul 05 '17 at 11:02
  • Do you know if there is a variable that holds the value of the ````-C```` option at cmake time? – Knitschi Jul 05 '17 at 15:07
  • @Knitschi If I look at [`cmake::ReadListFile()`](https://github.com/Kitware/CMake/blob/master/Source/cmake.cxx#L465) the "home output directory" is restored after reading the file. So no, I'm pretty sure you can't change the binary output directory from inside any CMake scripts. But the second part is possible: since there is no variable holding the cache init file path, I added a new `CMAKE_CACHE_INIT_FILE` to store it and make it available. – Florian Jul 05 '17 at 20:20
  • Ok thank you. Could have thought about that myself ;-) – Knitschi Jul 06 '17 at 15:38
  • I tried the same using ````Ninja```` as the generator. It does not work without calling ````vcvarsall.bat```` before. When using the Visual Studio generator that call is not needed ... strange. – Knitschi Jul 20 '17 at 07:29