# \`FetchContent\` and \`\<PROJECT-NAME\>\_VERSION\`

**URL:** https://discourse.cmake.org/t/fetchcontent-and-project-name-version/7762
**Category:** Development
**Created:** [March 24, 2023, 9:42am UTC](https://discourse.cmake.org/t/fetchcontent-and-project-name-version/7762 "2023-03-24T09:42:34Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![Lecris](https://discourse.cmake.org/user_avatar/discourse.cmake.org/lecris/32/3193_2.png) [@Lecris](https://discourse.cmake.org/u/Lecris)
#### Post date: [March 24, 2023, 9:42am UTC](https://discourse.cmake.org/t/fetchcontent-and-project-name-version/7762/1 "2023-03-24T09:42:34Z")

</div>

Let’s assume that the a project uses:

```cmake
FetchContent_Declare(SomeProject
		GIT_REPOSITORY https://github.com/Someone/SomeProject
		GIT_TAG main)
FetchContent_MakeAvailable(SomeProject)

```

Then the user does not have access to `SomeProject_VERSION` because that value is not propagated. Should `<PROJECT-NAME>_VERSION` type of variables be converted to cache values when `project()` is called?

One possible clash I see is if someone implements something like:

```auto
FetchContent_Declare(SomeProject
		GIT_REPOSITORY https://github.com/Someone/SomeProject
		GIT_TAG v${SomeProject_VERSION})
FetchContent_MakeAvailable(SomeProject)

```

For example `-DSomeProject_VERSION=v1.0.1-rc2` but after `project()` it is converted to `SomeProject_VERSION=1.0.1`. I think that that should be an intended behaviour, as long as it is possible to override the cli/cached passed argument with the cached version from `project()`

---

<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: [March 24, 2023, 9:54am UTC](https://discourse.cmake.org/t/fetchcontent-and-project-name-version/7762/2 "2023-03-24T09:54:41Z")

</div>

Do not try to set project versions as cache arguments on the command line. They should be set by the project, and the project should be able to assume nothing will interfere with those variables.

~~I believe the various `<projectName>_VERSION*` variables are stored in the cache, so after `FetchContent_MakeAvailable()` returns, those cache variables should be readable from any variable scope.~~

Sorry, that bit about the cache was wrong. Only `CMAKE_PROJECT_VERSION*` variables are stored in the cache, and those are for the top level project.

---

<div class="post-metadata">

### Author: ![Lecris](https://discourse.cmake.org/user_avatar/discourse.cmake.org/lecris/32/3193_2.png) [@Lecris](https://discourse.cmake.org/u/Lecris)
#### Post date: [March 24, 2023, 10:07am UTC](https://discourse.cmake.org/t/fetchcontent-and-project-name-version/7762/3 "2023-03-24T10:07:43Z")

</div>

But still we have an inconsistency between `find_package` and `FetchContent` because you can retrieve `<PackageName>_VERSION` in one, but not the other.

Currently the workaround that I’ve found is to wrap it around an if at the end:

```cmake

if (CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
	# Commands for find_package()
	write_basic_package_version_file(...)
else ()
	# Propagate variables for FetchContent
	return(PROPAGATE
			MyProj_VERSION
			MyProj_VERSION_MAJOR
			MyProj_VERSION_MINOR
			MyProj_VERSION_PATCH
			MyProj_VERSION_TWEAK
			)
endif ()

```

---

<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: [March 24, 2023, 11:43pm UTC](https://discourse.cmake.org/t/fetchcontent-and-project-name-version/7762/4 "2023-03-24T23:43:43Z")

</div>

_EDIT: updated from the original suggestion after giving this more thought_

If a project calls `FetchContent_Declare(SomeProject ...)` without the `FIND_PACKAGE_ARGS` keyword, then it should not expect `SomeProject_VERSION` variables to be populated. If the `SomeProject` dependency wants to support being used with `FIND_PACKAGE_ARGS` and to provide version variables, it can do so by writing its own `${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}/someproject-config-version.cmake` file which sets that version. For example, it can put code like the following somewhere after the `project()` call in its top level `CMakeLists.txt` file:

```cmake
file(WRITE ${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}/someproject-config-version.cmake
    "set(PACKAGE_VERSION ${PROJECT_VERSION})\n" # Addresses the need of this discussion
    "set(PACKAGE_VERSION_COMPATIBLE TRUE)\n" # Required for find_package() redirection to work
    "set(PACKAGE_VERSION_EXACT TRUE)\n" # Might be able to do better than this
)
endif()

```

I can even see how this could be generalised to automatically be applied to every project or a specific selection of projects by making use of `CMAKE_PROJECT_INCLUDE`, but you’d be making some assumptions about the name given to `project()` commands and how that maps to package names (or you’d have to implement such a mapping in the file you include using `CMAKE_PROJECT_INCLUDE`).

---

<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: [March 25, 2023, 12:31am UTC](https://discourse.cmake.org/t/fetchcontent-and-project-name-version/7762/5 "2023-03-25T00:31:49Z")

</div>

After giving this more thought, I’ve updated the previous comment with a more appropriate way of providing version details. It also may be possible to implement that approach in FetchContent to make it easier for projects to opt-in to that. I created [issue 24636](https://gitlab.kitware.com/cmake/cmake/-/issues/24636) to track that proposal.

Thanks for prompting this discussion, I didn’t see that solution when I originally implemented the `find_package()` integration back in CMake 3.24, but it looks viable to me now.
