vscode-cmake-tools: A Kit with toolchainFile fails to determine CMAKE_(C|CXX)_COMPILER without the user adding both variables to the cache file

Brief Issue Summary

A local user CMake kit using a toolchainFile will make cmake-tools fail at determining the C/C++ compiler path.

Then IntelliSense setup is done wrong:

  1. Architecture/Pltform/CompilerFlavor dependent codepaths highlighting is wrong (eg: __amd64__ or __arm__, _WIN32 or __linux__, __MINGW32__ or __MINGW64__)
  2. Code completion is made difficult or incorrect (because of 1., symbols may be missing etc…)

Expected:

CMake toolchain file documentation doesn’t mandate that CMAKE_C_COMPILER and CMAKE_CXX_COMPILER variables be placed in the cache.

CMAKE_C_COMPILER and CMAKE_CXX_COMPILER should be figured out automatically by the extension w/o adding a cache entry for them both.

Note that the cache workaround is mentioned in:

  • #602 where writing the CXX/C compiler settings forces them on the command line and thus in the cache
  • #500 where a specific pair of set(... CACHE ...) calls are inserted in the toolchain file

Reproduction steps:

  1. Setup a local CMake build kit using a toolchain file documented as per CMake guidelines. (eg: a buildroot generated toolchain file will do just fine)
  2. Import a C++ project for which code blocks vary depending on the architecture (eg: __amd64__ or __arm__) or on the platform (eg: _WIN32 or __linux__) or the compiler flavor (eg: __MINGW32__ or __MINGW64__)
  3. Ctrl+Shift+P Cmake: Configure
  4. Observe the codepaths highlighting mismatches and the code completion problems

Apparent Behavior:

CMake Tools expects CMAKE_C_COMPILER and CMAKE_CXX_COMPILER in the cache to setup the CPP project correctly.

CMake Tools Log

No relevant logs to copy/paste.

Developer Tools Log

No relevant logs to copy/paste.

Platform and Versions

  • Operating System: Debian GNU/Linux SID
  • CMake Version: 3.16.3
  • VSCode Version: Version: 1.44.2 Commit: ff915844119ce9485abfe8aa9076ec76b5300ddd
  • CMake Tools Extension Version: 1.3.1
  • Compiler/Toolchain: any cross toolchain would exhibit the problem as long as it’s setup only through a toolchain file. (tested with a GCC 7.3 generated by a ARM based buildroot build, or Debian’s (g++|gcc)-arm-linux-gnueabi packages, or Debian’s gcc-mingw-w64-(x86-64|i686))

Other Notes/Information

Here is a failing toolchain file example. It targets mingw32 builds using mingw32 debian packages.

set(CMAKE_SYSTEM_NAME Windows)
set(CMAKE_SYSTEM_PROCESSOR x86)

set(toolchain_dir "/usr/bin")
set(toolchain_triplet "i686-w64-mingw32")
set(toolchain_prefix "${toolchain_triplet}-")
set(toolchain_suffix "-posix")

set(CMAKE_SYSROOT "/usr/${toolchain_triplet}")

set(CMAKE_C_COMPILER   "${toolchain_dir}/${toolchain_prefix}gcc${toolchain_suffix}")
set(CMAKE_CXX_COMPILER "${toolchain_dir}/${toolchain_prefix}g++${toolchain_suffix}")
set(CMAKE_RC_COMPILER "${toolchain_dir}/${toolchain_prefix}windres" CACHE FILEPATH "" FORCE)

set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE BOTH)

Appending these two lines are the current workaround for hand made toolchain files

set(CMAKE_C_COMPILER "${CMAKE_C_COMPILER}" CACHE FILEPATH "C Compiler path")
set(CMAKE_CXX_COMPILER "${CMAKE_CXX_COMPILER}" CACHE FILEPATH "C++ Compiler path")

The problem can’t be workaround easily when using generated toolchain files (eg: buildroot ./host/usr/share/buildroot/toolchainfile.cmake) or external toolchain files provided by third parties.

About this issue

  • Original URL
  • State: open
  • Created 4 years ago
  • Reactions: 15
  • Comments: 27 (10 by maintainers)

Most upvoted comments

@andreeis, indeed this actually works.

But, IMHO this still qualifies as a workaround because vscode-cmake-tools need those variables cached to configure correctly the CPP backend.

Here is my reasoning:

  1. According to cmake-toolchains(7) documentation, having the C/CXX compiler defined as simple variables in the toolchain file should suffice. And all toolchain files I came across and those I write myself do use regular set(CMAKE_C|CXX_COMPILER value), no CACHE involved.
  2. cmake-toolchains(7) command line examples tend to suggest that one can complement some toolchain files w/ additional variables directly defined on the command line, this is for example mentioned for Android or iOS support. But no mention of the necessity to define CMAKE_C|CXX_compiler using -D options on top of the toolchain file itself.
  3. vscode-cmake-tools documentation tells configuring a local kit is as simple as filling in the C/CXX properties. Then the only example found for the toolchainFile property, totally omits to fill the C/CXX properties. This strongly suggests you either fill in the C/CXX properties, or you fill in the toolchainFIle property. No need for both.
  4. Additionally, vscode-cmake-tools seems to use the compile_commands.json file to grab lots of information for the CPP backend (command line defines etc…). It could find the compilers used in each “command” entry’s first token.

So to me, the fact we need to fill in the C/CXX properties in a CMakeKit defeats the whole purpose to fill all the required information in a toolchain file to support a different target system:

  • If this is not considered a bug/vscode-cmake-tools shortcoming, then the documentation could be at least rephrased to make clearer that if one wants perfect CPP backend configuration by the extension, the C/CXX must be filled in even if the toolchainFile property is already used and the file defines those two.
  • If current behavior is considered a shortcoming of the current vscode-cmake-tools implementation, then C/CXX could be deduced differently. From the compile_commands.json file then provided to the CPP backend the same way command line defines are found. Or by asking nicely cmake to output the C/CXX vars itself and fill automatically those when needed in the CMakeKit. This would avoid users setting up the properties themselves and potentially create configuration mistakes (what happens if the toolchainFile and C/CXX properties don’t agree on which compiler is “used”, the CPP backend will still be mis-configured).

whats is your opinion ?

@edgomez, compileCommands is not even used when configuration provider is CMake Tools. I was surprised that adding it fixed IntelliSense for you and then I noticed that there is a typo in the configuration provider id. It’s “ms-vscode.cmake-tools”. Let us know how things work after you correct that.