# First CMakeLists.txt feedback please

**URL:** <https://discourse.cmake.org/t/first-cmakelists-txt-feedback-please/11606>\
**Category:** Code\
**Created:** [September 7, 2024, 2:26pm UTC](https://discourse.cmake.org/t/first-cmakelists-txt-feedback-please/11606 "2024-09-07T14:26:01Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![RWobben](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/r/e9a140/32.png) [@RWobben](https://discourse.cmake.org/u/RWobben)\
**Post date:** [September 7, 2024, 2:26pm UTC](https://discourse.cmake.org/t/first-cmakelists-txt-feedback-please/11606/1 "2024-09-07T14:26:01Z")

</div>

Hello,

I try to learn c++ by doing this course : [https://www.learncpp.com/](https://www.learncpp.com/)

Now I like to use CMake instead of doing all by myself.

So I have a directory that contains :

main.cpp  
io.cpp  
io.h

Is this a good CMakeLists to get things compiling

```auto
project (CHALLENGE3)
cmake_minimum_required(VERSION 3.0)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)

add_executable(Challenge3 main.cpp io.cpp)

```

or should I add the header file also ?

---

<div class="post-metadata">

**Author:** ![retif](https://discourse.cmake.org/user_avatar/discourse.cmake.org/retif/32/1776_2.png) [@retif](https://discourse.cmake.org/u/retif)\
**Post date:** [September 7, 2024, 4:25pm UTC](https://discourse.cmake.org/t/first-cmakelists-txt-feedback-please/11606/2 "2024-09-07T16:25:49Z")

</div>

That project already looks quite good. Except for perhaps `cmake_minimum_required()` - that should be the first line in the file. And probably with a newer version of CMake too, I would put `3.22` there (_that’s the one that comes packaged in Ubuntu 22.04_).

> should I add the header file also

Not required, but I see people are doing so, usually to get them to show up in their IDEs. I mostly build stuff from CLI, so I never needed to add headers to target sources.

Also, I would probably recommend you not to add sources right in the `add_executable()`, so instead it would be something like:

```cmake
add_executable(${PROJECT_NAME})
set(sources
    ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/io.cpp
)
target_sources(${PROJECT_NAME} PRIVATE ${sources})

```

In newer versions of CMake there is now also [file sets](https://cmake.org/cmake/help/latest/command/target_sources.html#file-sets), which is likely an even better way to handle target sources, but I haven’t tried those myself yet.

---

<div class="post-metadata">

**Author:** ![RWobben](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/r/e9a140/32.png) [@RWobben](https://discourse.cmake.org/u/RWobben)\
**Post date:** [September 7, 2024, 4:35pm UTC](https://discourse.cmake.org/t/first-cmakelists-txt-feedback-please/11606/3 "2024-09-07T16:35:22Z")

</div>

> [@retif](#):
>
> ```auto
> add_executable(${PROJECT_NAME})
> set(sources
> ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
> ${CMAKE_CURRENT_SOURCE_DIR}/io.cpp
> )
> target_sources(${PROJECT_NAME} PRIVATE ${sources})
> 
> ```

Thanks,

What does the line of `target-sources` exactly do

---

<div class="post-metadata">

**Author:** ![retif](https://discourse.cmake.org/user_avatar/discourse.cmake.org/retif/32/1776_2.png) [@retif](https://discourse.cmake.org/u/retif)\
**Post date:** [September 7, 2024, 4:45pm UTC](https://discourse.cmake.org/t/first-cmakelists-txt-feedback-please/11606/4 "2024-09-07T16:45:55Z")

</div>

It is documented in the article that I linked, but actually, given the context, one could probably say that it’s pretty much self-explanatory 🙂

---

<div class="post-metadata">

**Author:** ![craig.scott](https://discourse.cmake.org/user_avatar/discourse.cmake.org/craig.scott/32/20_2.png) [@craig.scott](https://discourse.cmake.org/u/craig.scott)\
**Post date:** [September 7, 2024, 11:00pm UTC](https://discourse.cmake.org/t/first-cmakelists-txt-feedback-please/11606/5 "2024-09-07T23:00:08Z")

</div>

> [@retif](#):
>
> ```auto
> add_executable(${PROJECT_NAME})
> set(sources
> ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
> ${CMAKE_CURRENT_SOURCE_DIR}/io.cpp
> )
> target_sources(${PROJECT_NAME} PRIVATE ${sources})
> 
> ```

There’s a few things here I wouldn’t do:

- Don’t use `${PROJECT_NAME}` for the target name. They are two distinct concepts, a target doesn’t have to match the project name. Most projects will have more than one target (your project has tests, right? right…? 😉 ).
- Don’t use variables to hold lists of files if you can put that list of files directly in the command instead. The `sources` variable here is unnecessary.
- The poster’s original approach of putting the list of files directly in the `add_executable()` call is fine. If you can do it that way and it doesn’t make the project any more complicated to do so, then that’s what I would do. Simpler is better. The main reasons you’d have a separate `target_sources()` call would be you either need to only add things conditionally (say, platform-specific files) or if you want to add source files progressively from subdirectories.
- There’s no need to prefix the source files with `${CMAKE_CURRENT_SOURCE_DIR}`, as long as you specify 3.13 or later as the version in the `cmake_minimum_required(VERSION X.Y)` call at the start of your `CMakeLists.txt` file. If you list files directly in the call to `add_executable()` instead of `target_sources()`, the CMake version doesn’t matter, you can leave out `${CMAKE_CURRENT_SOURCE_DIR}` because it’s always assumed for relative paths in that case.

Apart from swapping the order of the `cmake_minimum_required()` and `project()` calls at the start of the `CMakeLists.txt` file and specifying a higher minimum CMake version (as @retif already highlighted), I think the poster’s original example is ok. As you get more familiar with CMake, follow @retif’s suggestion to take a look at [file sets](https://cmake.org/cmake/help/latest/command/target_sources.html#file-sets). They are fast becoming a recommended way of listing your headers. This will become more relevant to you as your project gets bigger and you start using subdirectories, linking targets together across directories, and so on.

---

<div class="post-metadata">

**Author:** ![retif](https://discourse.cmake.org/user_avatar/discourse.cmake.org/retif/32/1776_2.png) [@retif](https://discourse.cmake.org/u/retif)\
**Post date:** [September 8, 2024, 8:48am UTC](https://discourse.cmake.org/t/first-cmakelists-txt-feedback-please/11606/6 "2024-09-08T08:48:58Z")

</div>

> Most projects will have more than one target

You are right here, it’s just my own “deformation” - I rarely have more than one target per project (_yeah, no tests 🙂_), and most of my nested targets are their own projects (_as any component can be built “standalone”_).

Good recommendations otherwise, and I probably should re-consider my reluctance towards adding sources right in the `add_executable()`/`add_library()`.
