Project root folder CMakeLists file being ignored when trying to build Windows desktop app

Hi there,

I have interesting dilemma. I’m following this book: “Modern Cmake for C++” authored by Rafal Swidzinski - and in the chapter where they’re discussing the proper partitioning and organisation of a project the author states the following:

“In this structure, the CMakeList.txt file should exist in the following directories: the top-level project directory, src, doc, extern and test.”

They then proceed to state the following:

“The main listfile shouldn’t declare any build steps on its own, but instead, it should use the add_subdirectory() command to execute all of the listfiles in the nested directories”

This is on page 95 of the book. So from what I gather this means that in my project root folder I’ll have a CMakeLists file that starts the process and causes all sub folders to be searched for further CMakeLists files and processes them. That suggests to me however that the root folder CMakeLists file won’t actually be declaring any targets of its own. In the example provided by the author that’s exactly what happens. I’ve made a slightly cut down version of it for simplicity.

Here’s an outline of the project structure:

The top level CMakeLists file just has the following code in it:

cmake_minimum_required(VERSION 3.20.0)
project(Structure CXX)
add_subdirectory(src)

And as expected the lowest one in the src folder just adds an executable and builds the target “main”:

add_executable(main main.cpp)

All the main.cpp file does is include iostream and output a standard line of text:

#include <iostream>

int main()
{
  std::cout << "A structured project" << std::endl;

  return 0;
}

When compiling this using CMake in Visual Studio it works. However when I try to take the exact same project structure and run a simple Windows desktop app this project structure no longer works. When using CMake in Visual Studio it seems it completely ignores the CMakeLists file in the root folder. Here’s the CMakeListis file in the src folder I use when trying to use this project structure for a simple desktop app:

## If following lines are not commented out, and another CMakeLists.txt file is not present
## in the project root folder, this works.
#cmake_minimum_required(VERSION 3.20.0)
#project(About_Box CXX)

add_executable(About WIN32
	       About_Box.cpp
	       About_Box.h	       
	       framework.h
	       Resource.h
		   targetver.h
		   About_Box.rc)

Just builds the standard basic desktop app Visual Studio creates. All the files you see in the above code are located right in the src folder. The CMakeLists file in the root folder is exactly the same as the one posted earlier.

When attempting to configure this CMake complains that there is no line present declaring a project, and states it will now “pretend” there is one there. Clearly it has totally ignored the CMakeLists file in the root folder, but this only happens for desktop apps it seems.

So I don’t know what to do. I’d very much like to use the project structure stated by the book’s author, but it seems I’m doing something wrong when trying to apply it to building desktops apps.

I’d appreciate any help, thanks :slightly_smiling_face:

If you are using the built-in CMake support in Visual Studio, you need to do “Open Folder” on the root folder of your project, not the src folder.

Personally, I find this experience inferior to generating project files and opening the generated project. If you want to do that, then:

mkdir build
cd build
cmake ../root

…asssuming your project root folder is called “root”. I don’t like having the build directory inside the source directory, so I always locate it as a peer to my source directory. I don’t remember where VS decides to put the build directory when you use the built-in CMake support, probably somewhere inside your top-level source directory.

1 Like

I see nothing wrong with declaring targets in the root CMakeLists.txt, I often do it exactly this way. At the same time, there isn’t(?) anything wrong with declaring targets in the nested CMakeLists.txt either, that should work equally fine. So I’d say it is up to you, how you want to organize your project.

As for your build problem with Visual Studio, it seems to me that in your second example you opened the nested CMakeLists.txt instead of the root one, and that is what Visual Studio was trying to use to configure. And in the first example you openned the root one, so it worked fine.

If you’d like us to try to reproduce your problem, you can upload your second example project somewhere.

You could also try explicitly configuring it from command line, almost like Richard said in his post:

$ cd /path/to/your/project
$ mkdir build
$ cd build
# depends which version of Visual Studio you have
$ cmake -G "Visual Studio 17 2022" ..
$ cmake --build . --config Release

or, if you have Ninja:

$ cmake -G Ninja -DCMAKE_BUILD_TYPE=Release ..
$ cmake --build .
1 Like

Thanks muchly for the replies, I wasn’t expecting that much help and so fast as well! I tried exactly what you both kindly suggested and it did indeed work. It works from within Visual Studio when opening the root folder. I’m sure I tried that before but it all got very confusing so I must’ve missed that one.

I also did your command line suggestions and they worked too, which is excellent. If this issue gives me any more trouble I will post back again, but for now it seems to be resolved.

Thanks very much :slightly_smiling_face: