3

I use cmake and Visual Studio and have the following directory structure:

workspace
    CMakeLists.txt
    project1
        src
    project2
        src
    build

The idea behind this is an out-of-source build, so that the generated build files by cmake do not spoil my src folders. This is also described here as top answer: Looking for a 'cmake clean' command to clear up cmake output

However, if I generate the visual studio project being in the build directory using the CMakeLists.txt in the workspace directory like so:

cmake ..

, then everything will be created fine but when I open my visual studio solution and add a file to any of the projects, it will be added into the build folder of the corresponding project...

Of course, this is incorrect. It should put the file in the corresponding directory of the src path. Also, it should show the directory structure. So, if I have:

workspace
    project1
        src
            package1
                module1.cpp
                module2.cpp
            package2
                module3.cpp
                module4.cpp

, then naturally my visual studio project should show both the package folders. I realize that visual studio's filters do not offer this functionality. But when I hit "Show all files", it usually switches to a view where I can see usual file system directories, which is exactly what I want - only that it should have its root in the corresponding src folder and not in the build path.

Can I arrange this somehow?

Community
  • 1
  • 1
IceFire
  • 4,016
  • 2
  • 31
  • 51

1 Answers1

3

Your quandry is that you want to generate a build-file set, with CMake, that is displaced from the source tree and then in the generated build-file set run an IDE project that is not displaced from the source tree. You can't have it both ways.

The CMake build directory, whether in-source or out-of-source, is the directory in which CMake will generate build files for your project, for some target build system. These artifacts are of service to the end-user who wants to build your project from packaged source. You need to distinguish the target build system from your development environment. Your development environment is a personal productivity choice that has no essential link with the target build system.

It is just co-incidence that your target build system is Visual Studio and so is your development environment. Imagine instead that your development environment is, say, Code::Blocks, and your target build system is GNU Make, with CMake employed to generate the GNU Make build files.

In that case you have a Code::Blocks .cbp project file that defines your development project, and a CMakeLists.txt file that defines a distributable GNU Make build.

The CMake project and the Code::Blocks project have no connection with each other except the connections you choose to make in terms of common tools, files and targets. You might have more files and/or targets in your development project than you ever choose to reflect in the CMakeLists.txt. The target toolchain could be different from the development toolchain. As far as the CMake project is concerned it doesn't matter at all where the Code::Blocks .cbp file resides or if such a thing exists, although you will want the .cbp file as well as the CMakeLists.txt to be under source control in your development branch.

When you run CMake and create build files, you come under no compulsion to stop using your CodeBlocks project, in situ, as your development environment and somehow migrate the development environment into the build-files folder. Even if you instructed CMake to generate a Code::Blocks .cbp file in the build-files, so that end-users of the package can build it with Code::Blocks, you wouldn't then be tempted to start using that project file as for your development environment: it's a throw-away artifact of running CMake.

If you want to develop the project with Visual Studio then make a VS project for your development purposes in a normal relationship to the source tree. Make a CMake project for distribution of the project on your target build system. Forget the incidental fact that the target build-system is also Visual Studio. Keep the files and targets of your CMake project aligned with those of your development project to the extent that the CMake project is up to date whenever you build it. And ensure, of course, that the gating tests you run, for commit, release or whatever, are all run on the CMake build.

If you are not interested in distributing your project and are using CMake merely for the purpose of generating a Visual Studio project in which to develop it - well that would be a gratuitously laborious alternative to just developing it in Visual Studio - but if it's what you want to do you will have to be clear that CMake and Visual Studio cannot both control the composition of the project. CMake controls it and the VS project is just a CMake artifact. If you want to add files to the project or change it in any other way then you must do it CMakeLists.txt, then rerun CMake and accept the VS project that drops out - even if you don't quite like the look of it.

Mike Kinghan
  • 55,740
  • 12
  • 153
  • 182
  • Great post, thanks!! I would actually like to let cmake control my project. Why? Because I also use QT and cmake does a great job mocing und uicing files, where VS fails. Also, is cmake really no basis for creating a development solution? I could version-control CMakeLists.txt and my src/include files and another developer could checkout, cmake it and use the upcoming project for his IDE to develop within the project. Just seeing the cmake output as a build and not as a development basis would not allow this. In fact, I think this is a perfectly fine use case, don't you think? – IceFire Jul 10 '16 at 20:41
  • `"well that would be a gratuitously laborious alternative to just developing it in Visual Studio"`. That's when you have one developer. And when you have multiple and some prefer to work in Visual Studio, but other in CLion, CMake is a solution: everyone can work in their IDE of choice and it's all synced. And it's not overly laborious. Makes sense to do it this way in this case IMO. And then it makes sense to have settings in VS to set "new file default directory" that's separate from .vcxproj file. And also to set start directory for "Show all files". – KulaGGin Feb 19 '23 at 14:56