vscode-cmake-tools icon indicating copy to clipboard operation
vscode-cmake-tools copied to clipboard

Support Multiple CMakeLists.txt without Requiring a Multi-Root Workspace

Open MBetters opened this issue 4 years ago • 20 comments

Brief Issue Summary

I maintain a repo in which there are multiple target architectures. For the most part, the executables being built for the different architectures have separate code, build dirs, and CMakeLists.txt files, because the processes running on the different archs do completely separate things (think a multi-component system made up of RTOS devices, beefier "cortex" boards, etc). There are some libs and include dirs shared commonly between these exec dirs, but not many. The ideal solution would be for CMake Tools to build these separate architectures independently. I tried a multi-root workspace + symlinks for the common code, but ran into issues with that (see https://github.com/microsoft/vscode-cmake-tools/issues/1371). Since symlinks are clunky and not great for developers who don't want to use Unix, ideally there'd be a way to just give CMake Tools a list of CMakeLists.txt files for it to build- something like cmake.cmakelist_files. Maybe such a setting could default to [] so that CMake Tools would carry on using ${cmake.sourceDirectory}/CMakeLists.txt like it normally does, but if cmake.cmakelist_files is set to multiple CMakeLists.txt files, it would build them all separately with different build-* dirs. Obviously it'd also be ideal that intellisense is supported from using the compile_commands.json from all the resulting build-* dirs, and auto-switches context depending on what file you're looking at.

A few potential ways to do this:

  • Run multiple CMake Tools processes? Can VSCode even do that?
  • Run CMake Configuration on all the CMakeLists.txt files listed in cmake.cmakelist_files (thus producing multiple build-* dirs), then merge all the compile_commands.json files into a single such file?

This request might sound a little far fetched, but I could see it being quite valuable and crucial to this extension's long-term success. Having to run CMake multiple times is quite common, not just for repos with multiple components. For example, building third-party libs that don't support add_subdirectory(path/to/some-third-party-lib). It'd be AMAZING to have full intellisense support on such third-party libs.

Thanks for the awesome extension!

Expected:

N/A

Apparent Behavior:

N/A

CMake Tools Log

N/A

Developer Tools Log

N/A

Platform and Versions

  • Operating System: Win10 Remote-SSH'd into Ubuntu 20.04
  • CMake Version: 3.16.3
  • VSCode Version: 1.47.1
  • CMake Tools Extension Version: 1.4.1
  • Compiler/Toolchain: Multiple (hence the issue as described lol)

Other Notes/Information

N/A

MBetters avatar Jul 17 '20 18:07 MBetters

I was surprised to learn this feature didnt exist today ;(

ryanwinter avatar Aug 23 '20 22:08 ryanwinter

I'd like to pile up on this request.

It should be possible to open a single folder with multiple sub-folders holding CMake projects, without requiring a VSCode workspace listing each folder separately.

If there's a root CMakeLists.txt, then that's fine. Otherwise, a quick scan (perhaps configurably depth-limited) looking for root CMakeLists.txt would be much appreciated.

TheJCAB avatar Nov 23 '20 19:11 TheJCAB

Same here. Got different CMakeLists.txt files for different platforms.

ragnarruutel avatar Dec 28 '20 12:12 ragnarruutel

Count me in as well! Would love to see this feature.

ladislas avatar Jan 04 '21 15:01 ladislas

Bump

Maxzor avatar Dec 21 '21 11:12 Maxzor

The way to bump the priority of this is to click the 👍 on the first comment.

bobbrow avatar Dec 27 '21 16:12 bobbrow

I upvote too. Additionally I would like to add that multi-architecture projects are not the only use case, monorepos are also impacted. This extension is basically unusable with monorepos.

Frankly the whole extension could just work by scanning all CMakeLists.txt in all subfolders and just consider each of them as a separate project. That means completely removing all logic that depend upon root folders, which maybe should never have been there in the first place. That would completely do the job and I don't see why it would cause any kind of problem. (I may be wrong on this, maybe some dependency managers tend to checkout a lot of CMakeLists.txt. But that could also be fixed by ignoring ignored folders in .gitignore, like some other extensions do.)

nicolas-van avatar Apr 16 '22 09:04 nicolas-van

Looking forward to this feature

hongshui3000 avatar Jun 08 '22 02:06 hongshui3000

What is the minimum number of thumb ups required to catch the attention of vscode and cmake developers?

jx2014 avatar Jun 26 '22 22:06 jx2014

+1

hongshui3000 avatar Jul 01 '22 06:07 hongshui3000

2 years later...

hongshui3000 avatar Jul 01 '22 06:07 hongshui3000

Well, since it is free, we just have to be patient.

jx2014 avatar Jul 03 '22 22:07 jx2014

This is my most wanted feature and would be really excited if it gets noticed and implemented

hongshui3000 avatar Jul 10 '22 05:07 hongshui3000

This isn't one of my use-cases, but I'm just curious to know if anyone has investigated workarounds for this. For example, assuming you have a monorepo with multiple cmake projects each in their own subdirectory, how viable would it be to create a cmake project at the root of the repo that does add_subdirectory for each of the sub-projects? Would it address this problem? What other implications would there be, and what are the pros and cons?

I'm also curious if there are other IDEs which implement this functionality. I've only ever used VS Code, but does Visual Studio have such functionality? Assuming it can only have one cmake-generated visual studio project open at a time, it would also not have the feature that is being requested here, right? Does anyone here know?

david-fong avatar Aug 08 '22 21:08 david-fong

Visual Studio supports this. You go to Project -> CMake Workspace Settings and add "sourceDirectory": [ "dir1", "dir2", ...] to the json file.

bobbrow avatar Aug 08 '22 23:08 bobbrow

In the following, there is a proposal on how to change the design to support this feature.

elahehrashedi avatar Aug 18 '22 19:08 elahehrashedi

To solve my particular use case in lieu of this feature being added, what I did as a temporary workaround is use CMakePresets.json (which CMake Tools supports) that lists different presets, one for each top-level folder in my mono-repo. I have the presets using different toolchainFile settings where the toolchain files set global CMake vars, then I have a top-level CMakeLists.txt that checks which var is set and calls the appropriate add_subdirectory(...) commands. This is a clunky workaround, and a better way would definitely still be to support multiple top-level CMakeLists.txt as I requested in my issue.

MBetters avatar Aug 18 '22 19:08 MBetters

This is a proposal on how to change the design of the extension to accept multiple CMake projects in the same workspace folder. Currently, we are supporting the multi-root case, in which there is only one Cmake project in every root.

1. The case where there is only one project per workspacefolder (the current design):

In this scenario the sourceDirectory and buildDirectory are defined as below:

"cmake.sourceDirectory": "${workspaceFolder}",
"cmake.buildDirectory": "${workspaceFolder}/build",

The buildDirectory, if not defined, will default to "${workspaceFolder}/build".

2. The case where there are multiple project folders in the same workpaceFolder (options for the future design):

In this scenario, the sourceDirectory will be defined as below:

    "cmake.sourceDirectory" : [
        "D:/tests/multiroot/root1",
        "D:/tests/multiroot/root1/subroot1",
        "D:/tests/multiroot/root1/subroot2"
    ],

Based on this, there are few approaches to define the buildDirectory:

2.1. defining an array of buildDirectory, …

	"cmake.buildDirectory" : [
	    "D:/tests/multiroot/root1/build",
	    "D:/tests/multiroot/root1/subroot1/build",
	    "D:/tests/multiroot/root1/subroot2/build"
	]

Cons: • In this approach, we will need to define install directory, and etc. as an array too. • User would have to match the paths across arrays, which is error-prone

2.2. Keeping the default as below, but change the way we resolve ${workspaceFolder}:

"cmake.buildDirectory": "${workspaceFolder}/build"

In this approach, we resolve the workspaceFolder using the source directory path. Cons: • This will break the current users that their source directory was not the same as their workspace folder, e.g. the CMakeLists.txt is not located in the root of their workspace folder, or is even located outside of the workspace folder.

2.3. Creating a new variable ${sourceDirectory} and encouraging the user to use this as their buildDirectory:

"cmake.buildDirectory": "${sourceDirectory}/build"
  • In this approach, when the user is adding the "cmake.buildDirectory" for the first time in their settings.json, we will default to "${sourceDirectory}/build". This will work in both situations where the user is defining a single or multiple source directories.
  • If the user hasn't defined the buildDirectory and has defined only one source directory, we will default to "${workspaceFolder}/build" as before. This behavior is currently in place and we don't want to change it.
  • If the user has defined multiple source directories, and has not defined a buildDirectory, we will default to "${sourceDirectory}/build".
  • If the user has defined multiple source directories, and has defined the buildDirectory as "${workspaceFolder}/build" we will show a warning explaining that this will create an issue for them, as there are multiple projects in the same workspaceFolder, and as a result, all will try to write the build files in the same folder.

We are planning to implement design # 2.3.

elahehrashedi avatar Aug 18 '22 20:08 elahehrashedi

It is best to support ignoring cmake projects under a certain folder, so as to avoid too many projects being included in a single workspace and it(build) is difficult to choose

hongshui3000 avatar Aug 19 '22 10:08 hongshui3000

It is best to support ignoring cmake projects under a certain folder, so as to avoid too many projects being included in a single workspace and it(build) is difficult to choose

What do you mean? It's up to you to tell us which projects you care about by setting the cmake.sourceDirectory setting. If you don't want to include a project, you wouldn't put it in the setting.

bobbrow avatar Aug 19 '22 20:08 bobbrow

This is available starting in 1.13.33. We are fixing a regression it introduced with PR #2926 and will release 1.13.35 with the fix.

bobbrow avatar Jan 09 '23 17:01 bobbrow

In a ROS2 project, using the sourceDirectory variable doesn't work well.

YXL76 avatar Jan 10 '23 06:01 YXL76

@YXL76 can you please open an issue and describe the problem for us?

bobbrow avatar Jan 19 '23 16:01 bobbrow

@YXL76 set buildDirectory to "${sourceDirectory}/build" and delete all existing build leftover and run command "reset cmake tools" might help.

tothedistance avatar Feb 16 '23 12:02 tothedistance