1

I want to create a project with CMake in windows with Visual Studio (the particular version I'm using is 2022), I've never used CMake in windows before so I'm just following what visual studio says to me.

I want to have a project structure where I have an App directory that generates an executable, an Engine folder that generates a dll shared lib.

I want to run them separately, so when I'm done with Engine and press run, I just want the project to generate the dll files and do nothing with the App directory.

Then, when I run App, I want it to generate an exe that depends on the dlls created by the Engine, and not re-generate the Engine directory.

I want these to be on the same solution like this:

Project/
├─ libs/
├─ README.md
├─ Solutionfile_or_smthng.vprojx
├─ App/
│  ├─ include/
│  ├─ src/
│  ├─ CMakeLists.txt
│  ├─ main.cpp
├─ Engine/
│  ├─ src/
│  ├─ include/
│  ├─ Engine.hpp
│  ├─ CMakeLists.txt
├─ .gitignore

Normally when create a visual studio project it creates a solution and I can just right click on the solution to say add project and configure accordingly. But when I create a cmake project it just gives me a folder and there is no add project when I right click on it.

enter image description here

It doesn't necessarily have to be a solution, as long as I achieve 2 separate builds in the same view I'm fine. Actually I prefer not having a solution.

The problem right now is, as far as I understand visual studio puts a CMakeLists.txt file in the root of the project which it runs when I press build. Right now when I add the folders manually my project structure looks like this:

MyProject/
├─ libs/
├─ App/
│  ├─ src/
│  ├─ include/
│  ├─ main.cpp
│  ├─ CMakeLists.txt
├─ Engine/
│  ├─ include/
│  ├─ src/
│  ├─ CMakeLists.txt
│  ├─ Engine.hpp
├─ .gitignore
├─ CMakeLists.txt

I don't want to have a single CMakeLists.txt file that runs once. If I have to do two separate projects, how can I view them on the same window and how can I make App see generated dll's from Engine?

starball
  • 20,030
  • 7
  • 43
  • 238
Turgut
  • 711
  • 3
  • 25
  • I edited your title. What Visual Studio calls "projects", are basically what CMake calls "targets", and what Visual Studio calls "solutions", as analogous to what CMake calls "projects". As far as I can see, you do not have or want multiple CMake projects. You just have multiple CMake targets (multiple Visual Studio projects under one single Visual Studio solution (one single CMake project)). – starball Mar 25 '23 at 18:16
  • have you used CMake at all before? If you haven't, I was misled by your second sentence to think that you had. Maybe you should change it if so. – starball Mar 25 '23 at 19:57

1 Answers1

2

The CMakeLists.txt does not "run when you press build". It's a configuration file. It's used to configure CMake ("teach" CMake how) to generate a particular type of buildsystem (which here is a Visual Studio solution). Configuration of a buildsystem is separate from invoking the buildsystem to perform builds. Just write a CMakeLists.txt file for the project like you would for any platform (your first few sentences seem to imply you've used it on other platforms). There are special things you can do for windows, but I don't see a particular need for those here. You have two CMake targets, which turn into two VS projects. Once you've generated the VS buildsystem (solution files), build each project like you would in the VS GUI normally.

Right now, given your file layout, you probably want something along the lines of the following:

MyProject/CMakeLists.txt:

cmake_minimum_required(VERSION 3.25) # or whatever is suitable/available for you
project(MyProject CXX)

link_directories(libs)
add_subdirectory(Engine)
add_subdirectory(App)

MyProject/Engine/CMakeLists.txt:

add_library(Engine SHARED src/foo.cpp src/bar.cpp src/baz.cpp)
target_include_directories(Engine PUBLIC include .) # . is for your Engine.hpp, which I find weird that it's not in your include/ folder.

MyProject/App/CMakeLists.txt:

add_executable(App main.cpp src/foo.cpp src/bar.cpp src/baz.cpp)
target_include_directories(App PRIVATE include)
target_link_libraries(App PRIVATE Engine)

This is just to get you started. If you want to do installations, then you'd have to look at install(), and I'd suggest the Mastering CMake chapter on installing things. You might also want to take a look at target_compile_features(), GenerateExportHeader.cmake, an the SOVERSION and VERSION target properties.

You generate the buildsystem as you'd do on any other platform: cmake -S <path to source dir> -B <path to build dir> -G <name of visual studio generator you want (Ex. Visual Studio 17 2022)> <other args you want>. See the list of Visual Studio generators, and the docs on running CMake to generate a project buildsystem. The generated buildsystem will have a Visual Studio Solution file that you can open up in Visual Studio. You will need to regenerate the buildsystem if the CMake configuration changes. CMake is pretty good at detecting that and doing that automatically though when you run the build.

To build a CMake target (Visual Studio project), you can use the Visual Studio GUI (look for actions for building projects there. you'll probably see on in context menus when right-clicking on projects in the solution explorer, and in the top menu, and one for building the currently selected project in the top bar). Outside of Visual Studio, you can use cmake --build <path to build dir> --target <name of target(s)> (see docs for more info). When you do target_link_libraries, CMake registers a target dependency, so the generated buildsystem will know to rebuild dependencies of a target that you want to build if needed.

See also my answer to "Most simple but complete CMake example" which goes into a bit more length explaining the basics near the middle section.

starball
  • 20,030
  • 7
  • 43
  • 238
  • So the `CmakeLists` in root dir acts like a solution? One question tho, where does the .dll files appear? – Turgut Mar 25 '23 at 19:36
  • As for your first comment, The CMakeLists.txt file _configures CMake_ (tells CMake about the structure of a buildsystem to generate). You run CMake to generate a buildsystem based on that CMake configuration. – starball Mar 25 '23 at 19:56
  • conversation continuing in chat: https://chat.stackoverflow.com/rooms/252910/room-for-user-and-rickytad – starball Apr 01 '23 at 01:54