# cmake project() requirement

**URL:** https://discourse.cmake.org/t/cmake-project-requirement/4663
**Category:** Usage
**Created:** [December 14, 2021, 5:54pm UTC](https://discourse.cmake.org/t/cmake-project-requirement/4663 "2021-12-14T17:54:22Z")
**Posts on this page:** 9
**Page:** 1

<div class="post-metadata">

### Author: ![fry](https://discourse.cmake.org/user_avatar/discourse.cmake.org/fry/32/613_2.png) [@fry](https://discourse.cmake.org/u/fry)
#### Post date: [December 14, 2021, 5:54pm UTC](https://discourse.cmake.org/t/cmake-project-requirement/4663/1 "2021-12-14T17:54:23Z")

</div>

I created a framework to build audio plugins and in order for the build to work there are some variables that needs to be defined BEFORE calling `project()`. So right now, the users of my framework must write something like this:

```cmake
include("cmake/re-cmake.cmake")

# RE_CMAKE_ROOT_DIR is defined when including cmake/re-cmake.cmake
include("${RE_CMAKE_ROOT_DIR}/cmake/RECMakeOptions.cmake")

project(Test LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)

include("${RE_CMAKE_ROOT_DIR}/sdk.cmake")

```

Although you could argue it is not a lot of code to write, I wanted to create a macro like this (so that I can also expand in the future…)

```cmake
macro(re_cmake_project NAME)
  include("${RE_CMAKE_ROOT_DIR}/cmake/RECMakeOptions.cmake")  
  project(${NAME} LANGUAGES CXX)
  set(CMAKE_CXX_STANDARD 17)
  include("${RE_CMAKE_ROOT_DIR}/sdk.cmake")
endmacro()

```

So that the user would only have to do this:

```cmake
include("cmake/re-cmake.cmake")
re_cmake_project(Test)

```

But when you do this, cmake complains (it is a warning) that there is no “project” defined

```auto
CMake Warning (dev) in CMakeLists.txt:
  No project() command is present. The top-level CMakeLists.txt file must
  contain a literal, direct call to the project() command. Add a line of
  code such as

    project(ProjectName)

  near the top of the file, but after cmake_minimum_required().

  CMake is pretending there is a "project(Project)" command on the first
  line.
This warning is for project developers. Use -Wno-dev to suppress it.

```

I understand that you can use `-Wno-dev` to suppress it, but I cannot ask all my users to do that. Nor is it easy to do in CLion for example, without having to go and tweak the way the command line is invoked which again, I don’t want to ask all my users to do…

I was hoping that using a macro (since macros are essentially like defines in C) would help but it does not.

Is there a way to turn off this warning message directly in my `cmake/re-cmake.cmake` included file because this kind of project is defined differently?

---

<div class="post-metadata">

### Author: ![hex](https://discourse.cmake.org/user_avatar/discourse.cmake.org/hex/32/363_2.png) [@hex](https://discourse.cmake.org/u/hex)
#### Post date: [December 14, 2021, 6:33pm UTC](https://discourse.cmake.org/t/cmake-project-requirement/4663/2 "2021-12-14T18:33:16Z")

</div>

no, calling `project` in a macro is not allowed.

---

<div class="post-metadata">

### Author: ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)
#### Post date: [December 14, 2021, 7:13pm UTC](https://discourse.cmake.org/t/cmake-project-requirement/4663/3 "2021-12-14T19:13:00Z")

</div>

Well, it’s _allowed_, but is not sufficient for this.

> [@fry](#):
>
> I was hoping that using a macro (since macros are essentially like defines in C) would help but it does not.

They’re not textual replacement. They have some similar behaviors, but thinking of them as `#define` is not a good mental model for them.

---

<div class="post-metadata">

### Author: ![robert.maynard](https://discourse.cmake.org/user_avatar/discourse.cmake.org/robert.maynard/32/4_2.png) [@robert.maynard](https://discourse.cmake.org/u/robert.maynard)
#### Post date: [December 14, 2021, 10:13pm UTC](https://discourse.cmake.org/t/cmake-project-requirement/4663/4 "2021-12-14T22:13:13Z")

</div>

> [@ben.boeckel](#):
>
> Well, it’s _allowed_, but is not sufficient for this.

It is ambiguous if it is allowed for the root project() call.

From [https://cmake.org/cmake/help/latest/command/project.html#usage](https://cmake.org/cmake/help/latest/command/project.html#usage)

```auto
The top-level CMakeLists.txt file for a project must contain a literal, direct call to the project() command

```

The question would be does a macro meet these requirements. Or would a macro loaded via `include` violate this rule.

---

<div class="post-metadata">

### Author: ![hex](https://discourse.cmake.org/user_avatar/discourse.cmake.org/hex/32/363_2.png) [@hex](https://discourse.cmake.org/u/hex)
#### Post date: [December 15, 2021, 12:16am UTC](https://discourse.cmake.org/t/cmake-project-requirement/4663/5 "2021-12-15T00:16:09Z")

</div>

this was a response to my comment. I wrote that calling `project` in a macro is not allowed, which is false.

the top-level CMakeLists.txt for CMake in project mode must follow this requirement as described in the error message (which is what i meant). A call via macro, function, include or subdirectory doesn’t violate this rule but it doesn’t meet the requirement either.

independently of the requirement, `project()` can additionally be called multiple times in the same scope or anywhere else like other functions, except it cannot be before the first `cmake_minimum_required`. Also, it does set various checks and enables languages so it must be used with caution.

---

<div class="post-metadata">

### Author: ![fry](https://discourse.cmake.org/user_avatar/discourse.cmake.org/fry/32/613_2.png) [@fry](https://discourse.cmake.org/u/fry)
#### Post date: [December 15, 2021, 2:28pm UTC](https://discourse.cmake.org/t/cmake-project-requirement/4663/6 "2021-12-15T14:28:45Z")

</div>

I guess I am still unclear. Clearly it works since I am getting a warning but then it doesn’t prevent the rest of the CMake file to be executed and completes successfully. But the warning states ‘_CMake is pretending there is a “project(Project)” command on the first line_’, so does it mean that the `include` that happens before the `project()` call inside the macro is executed AFTER the “pretend” project that CMake mentions in the warning? The reason is that some variables must be set before calling `project()` for the right toolchain to be set up…

At the end of the day, I strongly believe that what I am doing is not using CMake for what it has not been designed to be used for. It is a very valid use case. I just want to shield my users to have to copy some boiler plate codes over and over in all projects.

---

<div class="post-metadata">

### Author: ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)
#### Post date: [December 15, 2021, 2:34pm UTC](https://discourse.cmake.org/t/cmake-project-requirement/4663/7 "2021-12-15T14:34:31Z")

</div>

> [@fry](#):
>
> But the warning states ‘_CMake is pretending there is a “project(Project)” command on the first line_’, so does it mean that the `include` that happens before the `project()` call inside the macro is executed AFTER the “pretend” project that CMake mentions in the warning?

Yes. CMake first parses the entire file, sees no _literal, direct_ call to `project`, issues the warning, adds a synthesized `project()` call on the first virtual line of the file contents, _then_ executes it. So yes, it happens before your macro does the include.

> [@fry](#):
>
> It is a very valid use case. I just want to shield my users to have to copy some boiler plate codes over and over in all projects.

This piece of boilerplate will just have to be dealt with manually. I don’t know the _reason_ for this synthesized `project()` behavior, but it’s probably to handle some backwards compat behavior. Alas, it cannot be managed by policies because it happens before the contents are executed to be able to manage policies.

---

<div class="post-metadata">

### Author: ![fry](https://discourse.cmake.org/user_avatar/discourse.cmake.org/fry/32/613_2.png) [@fry](https://discourse.cmake.org/u/fry)
#### Post date: [December 15, 2021, 3:05pm UTC](https://discourse.cmake.org/t/cmake-project-requirement/4663/8 "2021-12-15T15:05:03Z")

</div>

> [@ben.boeckel](#):
>
> Yes. CMake first parses the entire file, sees no _literal, direct_ call to `project`, issues the warning, adds a synthesized `project()` call on the first virtual line of the file contents, _then_ executes it. So yes, it happens before your macro does the include.

Ok. So when I say it worked, it really didn’t, because I call `set(CMAKE_OSX_ARCHITECTURES "x86_64" CACHE STRING "")` which, according to the documentation ‘_should be set prior to the first `project()`_’ and the synthesized `project()` then happens before…

That is a real bummer ☹

---

<div class="post-metadata">

### Author: ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)
#### Post date: [December 15, 2021, 3:07pm UTC](https://discourse.cmake.org/t/cmake-project-requirement/4663/9 "2021-12-15T15:07:52Z")

</div>

Yes, that probably appears to work because the variable setting is visible, but the compiler detection almost certainly didn’t use it.
