microsoft / vscode-cmake-tools

CMake integration in Visual Studio Code
https://marketplace.visualstudio.com/items?itemName=vector-of-bool.cmake-tools
MIT License
1.44k stars 433 forks source link

Unexpected files being loaded as variants file #2903

Open BobSmun opened 1 year ago

BobSmun commented 1 year ago

Brief Issue Summary

Given the repo organization for a project I'm working on, the .vscode directory is created as a symbolic link to elsewhere in the workspace

This seems to confuse the search for the variants file, as it ends up trying (and failing) to parse CMakeLists.txt and other files at workspace root

CMake Tools Diagnostics

No response

Debug Log

No response

Additional Information

No response

bobbrow commented 1 year ago

Can you share more information about the folder layout and the symlinks so that we can try to reproduce this? The more detail you provide, the more likely it is that we can reproduce and debug this. Thanks!

BenjaminBeichler commented 1 year ago

I have a similar, maybe related problem:

I have a library, which is used as submodule in a different project, which is not using CMake, therefore I want to create a pkg-config file, with the current built (but not installed) library.

Since I'm using a mixture of multi-config generators and single-config generators, I came up with the following code:

# create pkg-config file for easy inclusion into waf
get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
configure_file(wrapper.pc.in "${CMAKE_CURRENT_BINARY_DIR}/wrapper.pc_conf")
if (is_multi_config)
     file(GENERATE OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/wrapper-$<CONFIG>.pc"
                    INPUT "${CMAKE_CURRENT_BINARY_DIR}/wrapper.pc_conf")
     #set pkgconfig file without Config to Debug for backward compability and convenience 
     file(CREATE_LINK "${CMAKE_CURRENT_SOURCE_DIR}/wrapper-Debug.pc" "${CMAKE_CURRENT_SOURCE_DIR}/wrapper.pc"  SYMBOLIC)
else()
     #$<CONFIG> is not properly defined in single-config generators, therefore create only one.
     file(GENERATE OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/wrapper.pc"
                    INPUT "${CMAKE_CURRENT_BINARY_DIR}/wrapper.pc_conf")
endif()

The wrapper pkg-config template wrapper.pc.in looks like this:

Name: wrapper
Description: Wrapper
URL: abc
Version: 1.0
Requires: ext-lib1.0
Cflags: -I"@CMAKE_CURRENT_SOURCE_DIR@/wrapper" -I"@CMAKE_CURRENT_SOURCE_DIR@/inc" -I"@CMAKE_CURRENT_SOURCE_DIR@/example2/"
Libs: -L"$<TARGET_FILE_DIR:wrapper-lib>" -lwrapper-lib -L"$<TARGET_FILE_DIR:constants-lib>" -lconstants -Wl,-rpath,$<TARGET_FILE_DIR:wrapper-lib>

And in Vscode I got the following error

[variant] Invalid variants specified:
[variant]  >> /Name: should be object
[variant]  >> /Description: should be object
[variant]  >> /URL: should be object
[variant]  >> /Version: should be object
[variant]  >> /Requires: should be object
[variant]  >> /Cflags: should be object
[variant]  >> /Libs: should be object
[variant] Loaded default variants

So somehow the cmake-tools are parsing the wrong file. I also tried to create an empty cmake-variants.yaml in the root folder, but that did not work. I currently cannot share the real project, but maybe you can create a bug reproducer, with this.

BenjaminBeichler commented 1 year ago

From a quick view on the code, I guess this code here is the problem

https://github.com/microsoft/vscode-cmake-tools/blob/896f499b99a85e60b36bd8b8bf5a5e779af14236/src/variant.ts#L214-L216

or respectively in the function

https://github.com/microsoft/vscode-cmake-tools/blob/896f499b99a85e60b36bd8b8bf5a5e779af14236/src/variant.ts#L232-L250

If any new file is generated, the function util.chokidarOnAnyChange triggers a call to _reloadVariantsFile with the new file name, but the file name is not checked against the candidates. Or maybe I'm getting it wrong πŸ˜„

BenjaminBeichler commented 1 year ago

I have fixed my problem by moving my created pkg-config files into a different subfolder. This supports my hypothesis, that the util.chokidarOnAnyChange is triggered by my generated file.

I know, my approach of generating files into the source tree is also not best practice, but anyway, the current behavior of the cmake-tools is not ideal.

BobSmun commented 1 year ago

Can you share more information about the folder layout and the symlinks so that we can try to reproduce this? The more detail you provide, the more likely it is that we can reproduce and debug this. Thanks!

Folder structure looks a little like the following:

Workspace root
β”œβ”€β”€ .vscode -> symbolic link to devenv/.vscode
β”œβ”€β”€ src
β”‚   β”œβ”€β”€ artifact1
β”‚   β”‚   └── .svn
β”‚   └── artifact2
β”‚       └── .svn
β”œβ”€β”€ devenv
β”‚   β”œβ”€β”€ .svn
β”‚   β”œβ”€β”€ .vscode
β”‚   β”‚   β”œβ”€β”€ settings.json
β”‚   β”‚   └── CMakeKits.json
β”‚   β”œβ”€β”€ _init.sh
β”‚   └── CMakeLists.txt
└── CMakeLists.txt -> symbolic link to devenv/CMakeLists.txt

Initial setup would be to checkout devenv and then run the _init.sh script, which would set up the rest of the checkout - including using ln -sf ... to set up the symbolic links. Although this is for linux, I strongly suspect the windows equivalent would have the same issue

I have a similar, maybe related problem:

Albeit slightly different way to reproduce, the end result appears the similar enough to what I'm seeing - that unrelated files at root are being parsed

Having a quick look at the code, I also see

https://github.com/microsoft/vscode-cmake-tools/blob/896f499b99a85e60b36bd8b8bf5a5e779af14236/src/variant.ts#L187-L190

Changing followSymlinks to true appears to address my particular instance, but I suspect that is too narrow to my case. It seems that the filewatcher is getting a little confused and ends up adding the workspace root (and thus any files that end up there). My guess is that, as a result, _reloadVariantsFile is getting an unexpected non-null filepath, which is then used blindly

I.e. it seems there are 2 related issues:

github-actions[bot] commented 9 months ago

This issue is now marked as 'stale' due to there being no activity on it for the past 30 days and being labelled 'more info needed'. Unless the 'stale' label is removed or the issue is commented on, this will be closed in 7 days. If you would like to make this issue exempt from getting stale, please remove the 'more info needed' and 'stale' labels or add the 'stale-exempt' label

NeroBurner commented 1 month ago

This happens to me on a symlinked build_nero.sh file (symlinked as it is in a different git-repo for versioning)

I get the following error when ms-code.cmake-tools wrongly tries to parse the *.sh file as a variant:

[variant] Error parsing /home/nero/repos/external/myproject/build_nero.sh: 
    YAMLException: end of the stream or a document separator is expected (5:1)

 2 | set -ex
 3 | 
 4 | # install build dependencies ...
 5 | if [ "$1" = "--install-debs" ]; then
-----^
 6 |     if [ ! -f /etc/apt/sources.l ...
 7 |         sudo apt install cmake ninja-build
    at generateError (/home/nero/.vscode/extensions/ms-vscode.cmake-tools-1.18.41/dist/main.js:27569:10)
    at throwError (/home/nero/.vscode/extensions/ms-vscode.cmake-tools-1.18.41/dist/main.js:27573:9)
    at readDocument (/home/nero/.vscode/extensions/ms-vscode.cmake-tools-1.18.41/dist/main.js:29031:5)
    at loadDocuments (/home/nero/.vscode/extensions/ms-vscode.cmake-tools-1.18.41/dist/main.js:29074:5)
    at Object.load (/home/nero/.vscode/extensions/ms-vscode.cmake-tools-1.18.41/dist/main.js:29100:19)
    at VariantManager._reloadVariantsFile (/home/nero/.vscode/extensions/ms-vscode.cmake-tools-1.18.41/dist/main.js:70901:41)
[variant] Loaded new set of variants
rc-jpbarbosa commented 3 weeks ago

I believe I'm also running into this issue. Generating a symlink to an exported compile_commands.json with cmake results in

[variant] Invalid variants specified:
[variant]  >> : should be object
[variant] Loaded default variants
v-frankwang commented 2 weeks ago

@rc-jpbarbosa I used a simple project to reproduce this issue but it doesn't reproduce, can you provide a simple project that can reproduce this issue so that we can reproduce it and how to go about fixing it subsequently?

rc-jpbarbosa commented 2 weeks ago

@v-frankwang I've stripped it down to a very simple project and I can still reproduce it.

# CMakeLists.txt
cmake_minimum_required(VERSION 3.15 FATAL_ERROR)

project(hello_cmake C CXX)

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

if (CMAKE_EXPORT_COMPILE_COMMANDS)
    execute_process(
        COMMAND ${CMAKE_COMMAND} -E create_symlink
        ${CMAKE_BINARY_DIR}/compile_commands.json
        ${CMAKE_SOURCE_DIR}/compile_commands.json
    )
endif()

add_executable(hello_cmake main.cpp)
# .vscode/cmake-variants.yaml
buildType:
  default: debug
  choices:
    debug:
      short: Debug
      long: Emit debug information for the compilation target.
      buildType: Debug
    release:
      short: Release
      long: Optimize generated code for the compilation target.
      buildType: Release
model:
  default: Foo
  choices:
    Foo:
      short: "Foo"
      long: "Foo"
      settings:
        OPTION_MODEL: "Foo"
    Bar:
      short: "Bar"
      long: "Bar"
      settings:
        OPTION_MODEL: "Bar"
// main.cpp
#include <iostream>
int main(int argc, char *argv[]) {
    std::cout << "Hello, world!\n";
}

Output

[main] Configuring project: hello_cmake
[proc] Executing command: /usr/bin/cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Debug -DOPTION_MODEL:STRING=Bar -DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE -DCMAKE_C_COMPILER:FILEPATH=/usr/bin/clang -DCMAKE_CXX_COMPILER:FILEPATH=/usr/bin/clang++ -S/home/ubuntu/dev/projects/hello_cmake -B/home/ubuntu/dev/projects/hello_cmake/build/debug-Bar -G Ninja
[cmake] Not searching for unused variables given on the command line.
[cmake] -- Configuring done
[cmake] -- Generating done
[cmake] -- Build files have been written to: /home/ubuntu/dev/projects/hello_cmake/build/debug-Bar
[variant] Invalid variants specified:
[variant]  >> : should be object
[variant] Loaded default variants

Environment

*I tried to test in pure Windows as well, outside of WSL + VSCode Server, but I am running into some permissions issue when cmake tries to create the symlink and haven't looked into it further.

Notes

v-frankwang commented 1 week ago

@gcampbell-msft I reproduced the issue using a simple project provided by a user, here are the steps I took to reproduce it:

ENV: vscode version : 1.19.1 Ubuntu : 18.04 CMake Tools extension : v1.18.43 CMake:v3.30.0

Repro steps:

  1. Create a folder named hello_cmake on your linux machine
  2. Open vscode and run the command WSL: connect to WSL in New Windows
  3. Open the folder named hello_cmake.
  4. Create a CMakeLists.txt file and add the following code:
    
    cmake_minimum_required(VERSION 3.15 FATAL_ERROR)

project(hello_cmake C CXX)

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

if (CMAKE_EXPORT_COMPILE_COMMANDS) execute_process( COMMAND ${CMAKE_COMMAND} -E create_symlink ${CMAKE_BINARY_DIR}/compile_commands.json ${CMAKE_SOURCE_DIR}/compile_commands.json ) endif()

add_executable(hello_cmake main.cpp)

5. Create a **main.cpp** file and add the following code:

include

int main(int argc, char *argv[]) { std::cout << "Hello, world!\n"; }

6. Create a **cmake-variants.yaml** file in the .vscode folder and add the following code:

buildType: default: debug choices: debug: short: Debug long: Emit debug information for the compilation target. buildType: Debug release: short: Release long: Optimize generated code for the compilation target. buildType: Release model: default: Foo choices: Foo: short: "Foo" long: "Foo" settings: OPTION_MODEL: "Foo" Bar: short: "Bar" long: "Bar" settings: OPTION_MODEL: "Bar"


8. Run the command:**CMake:Configure**

Actual result:
![image](https://github.com/user-attachments/assets/4e6b1628-dc6a-41c5-9f79-ca242fa8a3c4)