vscode-cmake-tools
vscode-cmake-tools copied to clipboard
Feature to auto-add new files directly to CMakeLists.txt
Hi team!
I am looking to write an extension which will allow any added source file to be detected and automatically added to your CMakeLists.txt file in whichever way is prefered (i.e. whether the file get added to a specific variable or straight to e.g. the add_executable command).
This feature is common in many IDEs and, since CMake best practices recommends not to glob files, it makes sense to automatically add these files to the CMakeLists.txt file if the IDE has the ability, so that the user does not have to edit the CMakeLists.txt each time a file is added.
My question is, would this be a feature that could potentially be added to cmake-tools itself? Or should I look at making this its own separate extension?
I'm just not too sure if this falls within the scope of "CMake Tools", although I really think it would be a nice feature to have that many people using this extension would happily enable!
Let me know and I'll work on this as an update to the current extension and create a PR when finished.
Cheers, Gary
@gvcallen, thank you for the feature idea. We think it would fit best in CMake Tools instead of a distinct new extension. It would be great if you have time to prototype this feature. Once in good shape, we can review, test and integrate it.
@andreeis I've started investigation into this feature by checking how it behaviours in other IDEs.
I believe the most non-intrusive way would be to receive an activation event from VS when a new C++ file is created, but I can't seem to find such an activation event in the VS extension docs.
Am I missing something or is this yet to be implemented? Activation Events
@gvcallen, thank you for looking into this. Since we recommend adding this functionality as part of the CMake Tools (as opposed to a distinct new extension), you don't need to use activation events. CMake Tools is already activated when you are working in your project. You can experiment with "vscode.workspace.onDidCreateFiles". You can add this new listener in src/cmake-tools.ts, function _init(), along the similar "vscode.workspace.onDidOpenTextDocument" and "vscode.workspace.onDidSaveTextDocument".
@andreeis thanks for the reply. Not sure why I forgot about the fact that simply having a CMakeLists.txt means the extension is already activated!
This info is a perfect starting point for me. I will send any updates through onto this thread. Appreciate thte help!
I have had a look at how CLion and QtCreator implement this feature and quite frankly was a bit disappointed.
I remember Qt used to implement this, but it in fact does not anymore. I believe they simply used to add new files to a hard-coded variable PROJECT_SOURCES, which I don't think was configurable. This method can of course only go so far.
CLion is a bit more sophisticated. It however does not auto-add the file, but rather asks the user with a nice dialog box where they would like for it to be added. It detects all add_executable and add_library commands, as well as any variables passed in to those commands, and lists them in the dialog as options. The default-selected variable when multiple variables are passed to this command seems to be that which is closest to the command.
CLion however breaks down when target_sources is used, as well as when a custom macro is used. Neither of these are detected and presented as options. Furthermore, it fails to keep my desired formatting when adding the file. I imagine that it will break down for any complicated use cases and therefore is quite restrictive.
I have decided to employ the following scheme. @andreeis you can let me know if you have any objections. It might seem quite complicated but I believe it will be relatively robust and flexibile, as well as expandible if users desire even more flexibility in the future.
CMake tools will detect a list of "prompts" in CMakeLists.txt files, and these prompts will be used as guidance as to where to insert the filename. The prompts will also have a priority order in which they are checked. These are listed below from highest to lowest priority:
"Command prompts":
- target_sources
- add_executable
- add_library
- a user-defined list of "variable names" e.g. "SOURCES", "PROJECTSOURCES" etc.
- a user-defined list of "command names" e.g. "mylib_add_executable". these are treated to have the same formatting as add_executable
"Visibility prompts":
- PRIVATE
- INTERFACE
- PUBLIC
"Source prompts":
- Variables (with the same file extension)
- Variables (any)
- Filename literals
The process will be as follows:
- Receive callback from VSC when a new file is created with language C++
- Disregard file if within a user-defined list of folders to ignore (to cater for large, uniquely designed projects)
- If in "manual" mode, prompt the user for the target the file should be added to. Otherwise if in "smart" mode, the first suitable target is used
- Search for the relevant CMakeLists.txt. First look in the same directory as the source, then check each folder recursively upwards until reaching the workspace directory
- Search for command prompts as each candidate CMakeLists.txt is found. If in "manual" mode, only accept if command contains same name as selected target. If in "smart" mode, choose a command prompt based on priority. If two commands have same priority, the last should be used.
- Choose a visibility prompt (if applicable) and then a source prompt
- Add filename to relevant location, e.g. to set(...) command for variables, or directly into the command if only literals were found. Keep same formatting as user.
A future refined for the "manual" mode would be to allow the user to pick e.g. which variable the file is added to as CLion does, however this would require GUI input which I'm not too comfortable so can maybe be added in the future
Let me know if you disagree with anything, and hopefully I'll be able to start on this within the next week or so!
@gvcallen, this is excellent, thank you for starting to think about this. For (1), let's also consider when a file is deleted, not only when it is created. I understand overall and the logic sounds good. It would be great if you follow up with some examples, code snippets of relevant pieces of CMakeLists.txt, which target is selected and how that impacts "manual mode" (what you describe in (5))... No UI mock windows, not needed, only text examples to make this design more clear. We are excited to see this feature take shape.
@gvcallen Hi Gary,
I wonder what is your status with this feature request and if you are still working on it. Seems to me a great idea but of course requires to be worked out. I don't know if you already checked how VS2019 or 2022 works with CMake projects, anyway it should not be so different from the other IDEs and your draft logic seems fine to me. This really should be implemented into CMake Tools.
hi. I think this is a great idea. I sometimes move source file locations and sometimes rename files. It would be great if cmakelist could be updated automatically.
Hi all, sorry for the inactivity. I haven't forgotten about this. I've got a break now from other work so will see if I can plan a bit more and get into the implementation of things. @rtxa thanks for that link - I think the way its done in VS is catered for in my previous draft but if there's anything you think is missing let me know!
I've seen similar behavior already implemented in a vscode based ROS IDE. When we create new file in src or include directory the ide pop-up ask whether the file must be added to an executable in CMakeLists.txt
would be great to have this for any extension (not just .cpp)
I'm not sure if I missed something, but has this feature been added yet or is it still unreleased? I really like this feature but I can't use it in vscode
No updates yet from the Microsoft side, but we are planning some language service work for CMake scripts in an upcoming release. @gvcallen if you're still interested in adding project editing functionality, please sync up with us so that we can make sure we're not overlapping work.
CLion has this feature. It's very neat and useful. It's not a single time I compiled an app that had files missing and because the functions were not called anywhere else but in those two files the compiler would not warn although the #include
existed.