9

I work on a number of code projects, some open source and some not. Many of these projects are intended to be cross-platform, most often running on either Linux (my natural habitat) or Windows and generally relying on CMake to build. Recently, I noticed that a Windows developer on one of the projects checked in .sln files and .vcxproj and .vcxproj.filters files strewn about in nearly every directory.

Some of these files appear to contain things like paths that seem likely to be unique to that particular person's particular computer, which prompted the question about whether these should be added to the projects .gitignore file or more generally excluded from version control.

My criteria

The criteria I typically use for deciding whether things belong in version control:

  1. It is required to build one or more artifacts (including docs, source code, graphics)
  2. It is required to be there for other reasons (e.g. README and LICENSE files)
  3. If it's a built artifact, it should NOT go into version control

What I've looked at

There is this question which asks about which Visual C++ file types should be checked in for a Visual C++ project. (My emphasis.) This isn't really that; the intent is actually to use CMake to create the build system, one of which could be Visual Studio. That question and most of the answers seem to assume that everyone will be using VS, which is not the case here.

I've also consulted Microsoft's docs on using CMake in Visual Studio, which seems to indicate that for a CMake project, the .sln files, and others will either not be needed or will be regenerated if they are. For that reason, they seem to fail under criteron 1 above. On the other hand, it's common for autotools-based projects to include things in their repositories that autotools creates so that those who rebuild from source don't need autotools.

Finally, of course, I actually spoke to the other developer who, like me, could see arguments either way. Since both of us are apparently too annoyingly collaborative to make the definitive decision in this case, I thought I'd inquire here.

My questions

  1. Should .sln and .vcxproj and .vcxproj.filters files be checked in to version control for multi-platform projects?
  2. If so, is there a way that non-VS developers can easily omit those files to reduce clutter and distraction?
  3. If not, should VS developers be given any particular guidance on how to use CMake?

To be clear, I'm looking primarily for a logical rationale that we might be able to apply as policy for future projects and NOT unsupported opinion.

Edward
  • 204
  • 1
  • 9
  • 1
    I haven't worked with VS since university, but iirc with some care it's files can be made to use relative paths. – jaskij Jan 19 '21 at 09:17
  • @JanDorniak: the question is if CMake can be made to generate vcxproj files for Visual Studio with relative paths – Doc Brown Jan 19 '21 at 17:31
  • @DocBrown that is a good question. I doubt it, since AFAIK CMake uses absolute paths in the generated build files as a matter of principle, to avoid having any issues later on – jaskij Jan 19 '21 at 17:35
  • 3
    Ok, in case that's true, that would be a really strong argument against checking in the VS project files. Everyone who maintains this project actively, keeping it cross-platform, should be enouraged to use CMake, and I think it is a good idea to provide some guidance for folks who are not used to that build system... – Doc Brown Jan 19 '21 at 18:00
  • I'll investigate the absolute paths issue. Thanks for the comments! – Edward Jan 19 '21 at 18:02
  • ... however, that does not mean one could not provide a generated version of the project files additionally for those who just want to build a local fork for their own environment, and may only provide some PRs in the form of applying some changes to existing files. But that makes IMHO only sense if those project files can be created with relative paths exclusively. – Doc Brown Jan 19 '21 at 18:04

2 Answers2

5

According to this Stackoverflow answer from 2017 and this question from the CMake FAQ, CMake uses always absolute paths in the generated build files "by design" (credits to @Jan Dorniak's comment).

So to answer to your questions #1 & #2: including build files created by CMake into version control - regardless if they are Visual Studio project files or standard Unix makefiles - is not a good idea, they will never fit to everyones local checkout paths, hence they must be regenerated either.

The answer to your question #3 is definitely "yes": for most projects it is a good idea to document the minimal prerequisites for the development environment. CMake can be installed as an optional component for Visual Studio, but AFAIK it is not standard in the "Visual Studio Workload for C++ development". It is definitely helpful if you leave some hints for contributors or the next dev who comes after you what tools are required, how to install them, how they should be used and where to find further information. Getting all participants to run CMake before opening their Visual Solution, or before running make shouldn't require a huge manual, a short "Readme" file should probably be sufficient. There you could also leave the advice not to change any compiler options directly in the .vcxproj through the VS GUI, but only in the CMakeLists file.

If you want to allow others to rebuild the code without CMake, you need some VS project files with relative paths and no other specifics about the local dev environment. Given your build requirements are "simple enough", and you don't require "out-of-source builds" or other stuff which is incompatible with relative paths, I can imagine that it will be possible to create a small program or Powershell script which converts the absolute paths to relative ones. The script has to read the project files generated by CMake (which are human readable XML files) and replace all absolute paths and other environmental stuff by relative paths and less localized configurations.

The output of that script can then either be included in version control, or provided in other form for external contributors. The documentation, however, should make clear these project files should not be maintained manually, but regenerated whenever the CMake scripts are changed.

Doc Brown
  • 199,015
  • 33
  • 367
  • 565
  • We have decided to banish VS-specific files from the repository. – Edward Jan 28 '21 at 15:10
  • Edward, a simplistic rule like that will cause you trouble. – gnasher729 Jan 29 '21 at 06:45
  • @Edward Somebody in the future is going to hate you. It might even be you. If somebody ever wants something new added to the project, the next developer will find that they have to manually re-import all the code back into Visual Studio, and then spend hours setting up all the compilation options just right, in order to get it to build again. – Simon B Jan 29 '21 at 11:12
  • The [most popular](https://github.com/trending/c++?since=monthly) C++ project on github for the month of January 2021 is ethminer. That project has made the same choice, suggesting it's not as onerous as you imagine. See their [.gitignore](https://github.com/ethereum-mining/ethminer/blob/master/.gitignore) file. – Edward Jan 29 '21 at 11:31
  • 1
    @SimonB: not sure if we have the same understanding of the OPs case, but if the VS project files are generated by CMake, compilation options must stay untouched in the VS GUI. Adding files or components to the project, or changing compilation options must be done by changing the `CMakeLists` file. – Doc Brown Jan 29 '21 at 11:36
1

If my colleague and I need identical files, and me changing the file means it must be changed for my colleague, then it must be checked in. If the files cannot be the same for me and my colleague then they must not be checked in. Any files that will be generated automatically if they are missing should not be checked in.

Vs specific or not doesn’t make the slightest difference. I use Xcode, I have a project file, a few configuration files, a bridging header and a pre-compiled header file, all Xcode specific but need to be identical for everyone. Therefore they are checked in.

gnasher729
  • 42,090
  • 4
  • 59
  • 119
  • 1
    If you would generate your XCode files by CMake, you would probably not check them in into source control. That is the situation described by the OP. – Doc Brown Jan 29 '21 at 11:00