vscode-cmake-tools
vscode-cmake-tools copied to clipboard
CMake default invocation command arguments differs (ctrl+s on CMakeLists.txt vs. Build)
Brief Issue Summary
-B/build folder taking into account for configuration, but not for build
When pressing ctrl+s on a CMakeLists.txt file opened, vscode-cmake-tools extension may runs the following command :
[proc] Executing command: /usr/bin/cmake --no-warn-unused-cli -DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_C_COMPILER:FILEPATH=/usr/bin/clang -DCMAKE_CXX_COMPILER:FILEPATH=/usr/bin/clang++ -S/mnt/path_to_my_project -B/mnt/c/path_to_my_project/build -G "Unix Makefiles"
So projects ${CMAKE_CURRENT_SOURCE_DIR} and ${CMAKE_CURRENT_BINARY_DIR} differs, which is totally OK.
However, when I press the "Build" button on the bottom side of vscode, then I get :
[proc] Executing command: /usr/bin/cmake --build /mnt/c/path_to_my_project/build --config Debug --target all -j 14 --
And now projects ${CMAKE_CURRENT_SOURCE_DIR} and ${CMAKE_CURRENT_BINARY_DIR} are the same.
This generates files in the sources, suchs as :
- CMakeFiles/
- cmake_install.cmake
- CTestTestfile.cmake
- Makefile
- _deps/
which are most likely duplicates of what already exist in my top-level cmake project's /build
Also, invoking the command CMake: Clean does not clean those cmake-generated files.
CMake Tools Diagnostics
No response
Debug Log
No response
Additional Information
- The build task is the default one, and most likely everything (fresh vscode & extensions installation)
- running on WSL Ubuntu-22.04 LTS
- the projects sources are on Windows 10 (/mnt/c/path_to_project)
- using vscode version 1.68.0
Top-level project's CMakeLists.txt :
cmake_minimum_required(VERSION 3.8 FATAL_ERROR)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_EXPORT_COMPILE_COMMANDS OFF)
# --- Top-project
## Project name = folder
get_filename_component(this_dir_name ${CMAKE_CURRENT_LIST_DIR} NAME)
## cleanup project name
string(REPLACE " " "-" ProjectId ${this_dir_name})
string(REPLACE "/" "_" ProjectId ${ProjectId})
project(${ProjectId})
message(STATUS "[${CMAKE_PROJECT_NAME}] loading content ...")
# --- tests
include(CTest)
enable_testing()
# Loading subdirectories/subprojects
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/subprojects/)
# dependency graph
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/RunGraphviz.cmake)
For the project's FS structure, subprojects is a hierarchy where folders without source code contains the following CMakeLists.txt
# (1) dept-agnostic subdirectory includer
# Loading subdirectories
include(${CMAKE_SOURCE_DIR}/cmake/add_all_subdirectories.cmake)
add_all_subdirectories()
which invokes
# add_all_subdirectories.cmake
# Add all subdirectories in a way that create a hierarchy,
# using INTEFACE library as virtual namespace
function(target_name_from_path output path_value)
# Project name = folder
file(RELATIVE_PATH this_dir_name "${PROJECT_SOURCE_DIR}" "${path_value}")
# cleanup project name
string(REPLACE " " "-" output_alias_value ${this_dir_name})
string(REPLACE "/" "__" output_value ${output_alias_value})
string(REPLACE "/" "::" output_alias_value ${output_alias_value})
# "return" value to parent scope
set(${output} ${output_value} PARENT_SCOPE)
set(${output}_alias ${output_alias_value} PARENT_SCOPE)
endfunction()
function(add_all_subdirectories) # optional : path
if (NOT DEFINED ARGV0)
set(path_to_subdirs ${CMAKE_CURRENT_SOURCE_DIR})
else()
set(path_to_subdirs ${ARGV0})
endif()
target_name_from_path(target_name "${path_to_subdirs}")
message(STATUS "[${PROJECT_NAME}] loading bundle (${target_name_alias}) ...")
add_library(${target_name} OBJECT ${PROJECT_SOURCE_DIR}/cmake/empty) # tricks to create a "group"
if (NOT "${target_name_alias}" STREQUAL "${target_name}")
add_library(${target_name_alias} ALIAS ${target_name})
endif()
file(GLOB subprojects_list LIST_DIRECTORIES true ${path_to_subdirs}/*)
foreach(dir ${subprojects_list})
if (IS_DIRECTORY ${dir} AND EXISTS ${dir}/CMakeLists.txt)
add_subdirectory(${dir})
# top-down hierarchy (for organization/structure purpose)
target_name_from_path(child_target_name "${dir}")
add_dependencies(${target_name} ${child_target_name})
endif()
endforeach()
endfunction()
and directories containing source-code contains the following CMakeLists.txt :
# (2) project and depth agnostic subproject
cmake_minimum_required(VERSION 3.8 FATAL_ERROR)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
include(${CMAKE_SOURCE_DIR}/cmake/add_all_subdirectories.cmake)
target_name_from_path(target_name "${CMAKE_CURRENT_SOURCE_DIR}")
file(RELATIVE_PATH this_dir_name "${PROJECT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}")
message(STATUS "[${CMAKE_PROJECT_NAME}] loading project [${target_name_alias}] ...")
project(${target_name})
add_executable(${PROJECT_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/source.cpp)
add_executable(${target_name_alias} ALIAS ${target_name})
target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_20)
add_test(
NAME test_${PROJECT_NAME}
COMMAND ${PROJECT_NAME}
)
So if in one of (2) CMakeLists.txt file, I add :
message(STATUS ">>>> ${CMAKE_CURRENT_SOURCE_DIR}")
message(STATUS ">>>> ${CMAKE_CURRENT_BINARY_DIR}")
It results the following output :
on ctrl+s (with the pop-up Configuring project: Configuring Project appearing on the bottom-right of the screen)
[cmake] -- >>>> /mnt/c/path_to_project/path_to_subproject/subproject_name
[cmake] -- >>>> /mnt/c/path_to_project/build/path_to_subproject/subproject_name
but when clicking the "build" button
[cmake] -- >>>> /mnt/c/path_to_project/path_to_subproject/subproject_name
[cmake] -- >>>> /mnt/c/path_to_project/path_to_subproject/subproject_name
Are you saying that running a build is reconfiguring CMake? I wouldn't expect the message command to evaluate during a cmake --build command.
If you run those same two cmake commands that you shared in your terminal outside of VS Code (the one for the ctl+s behavior, and the one for clicking the build button), do you get the same result?
Looks like it is reconfiguring indeed : the message is
If I run both command in a terminal, the behavior is the same as if I'd invoke them respectively using ctrl+s shortcut and ⚙Build button.
Which are :
/usr/bin/cmake --no-warn-unused-cli -DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_C_COMPILER:FILEPATH=/usr/bin/clang -DCMAKE_CXX_COMPILER:FILEPATH=/usr/bin/clang++ -S/mnt/c/.../Projects/project_name -B/mnt/c/.../Projects/project_name/build -G "Unix Makefiles"
/usr/bin/cmake --build /mnt/c/.../Projects/project_name/build --config Debug --target all -j 14 --
If I run both command in a terminal, the behavior is the same as if I'd invoke them respectively using
ctrl+sshortcut and⚙Buildbutton.
Just to confirm, when you run the commands in the terminal, does it still generate the build files in the wrong place? I ask because if you can reproduce the problem in the terminal (without our extension), then I don't think there's anything we can do to fix it. A bug would need to be opened against CMake to ask Kitware to fix it.
Yes indeed, as mentioned https://github.com/microsoft/vscode-cmake-tools/issues/2590#issuecomment-1153600142. I'll open an issue on Kitware side then, thanks for your time.
This was determined to be an upstream issue. Closing.