# zeros in version numbers; cmake\_policy(SET CMP0096 NEW) ?

**URL:** https://discourse.cmake.org/t/zeros-in-version-numbers-cmake-policy-set-cmp0096-new/9296
**Category:** Usage
**Created:** [October 27, 2023, 1:25pm UTC](https://discourse.cmake.org/t/zeros-in-version-numbers-cmake-policy-set-cmp0096-new/9296 "2023-10-27T13:25:47Z")
**Posts on this page:** 12
**Page:** 1

<div class="post-metadata">

### Author: ![LadyGreyTeaService](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/l/f07891/32.png) [@LadyGreyTeaService](https://discourse.cmake.org/u/LadyGreyTeaService)
#### Post date: [October 27, 2023, 1:25pm UTC](https://discourse.cmake.org/t/zeros-in-version-numbers-cmake-policy-set-cmp0096-new/9296/1 "2023-10-27T13:25:48Z")

</div>

I’m trying to have a zero in the minor part of version. Step1/CMakeLists.txt is

```auto
cmake_policy(SET CMP0096 NEW)                                                                         
cmake_minimum_required(VERSION 3.22.1)                                                                
project(Tutorial VERSION 1.0.3.4                                                                      
        DESCRIPTION "This is a tutorial for cmake"                                                    
        HOMEPAGE_URL cmake.org                                                                        
        LANGUAGES CXX)                                                                                
set(CMAKE_CXX_STANDARD 11)                                                                            
set(CMAKE_CXX_STANDARD_REQUIRED True)                                                                 
configure_file(TutorialConfig.h.in TutorialConfig.h)                                                  
add_executable(tutorial tutorial.cxx)                                                                 
target_include_directories(tutorial PRIVATE ${PROJECT_BINARY_DIR})

```

TutorialConfig.h.in is

```auto
// the configured options and settings for Tutorial                                                   
#cmakedefine PROJECT_NAME "@PROJECT_NAME@"                                                            
#cmakedefine PROJECT_VERSION_MAJOR "@PROJECT_VERSION_MAJOR@"                                          
#cmakedefine PROJECT_VERSION_MINOR "@PROJECT_VERSION_MINOR@"                                          
#cmakedefine Tutorial_VERSION_MAJOR "@Tutorial_VERSION_MAJOR@"                                        
#cmakedefine Tutorial_VERSION_MINOR "@Tutorial_VERSION_MINOR@"

```

But this produces undefined minor version numbers in TutorialConfig.h

```auto
// the configured options and settings for Tutorial      
#define PROJECT_NAME "Tutorial"                                                                       
#define PROJECT_VERSION_MAJOR "1"                                                                     
/* #undef PROJECT_VERSION_MINOR */                                                                    
#define Tutorial_VERSION_MAJOR "1"                                                                    
/* #undef Tutorial_VERSION_MINOR */

```

Reading documentation it say old behaviour is to remove lead zeros from version numbers. Does this mean if it is only zero then it removes it entirely? I saw CMP0096 in policy options. Will this fix the problem and if so then how do I use it?

If I set the version to 1.2.3.4 it works and gives me version\_minor variables and #defines correctly.  
Using version 1.0.3.4 causes the problem. adding or removing the

```auto
cmake_policy(SET CMP0096 NEW) 

```

line has no effect.

`cmake --version`  
gives

```auto
cmake version 3.22.1

CMake suite maintained and supported by Kitware (kitware.com/cmake).

```

---

<div class="post-metadata">

### Author: ![jtxa](https://discourse.cmake.org/user_avatar/discourse.cmake.org/jtxa/32/1535_2.png) [@jtxa](https://discourse.cmake.org/u/jtxa)
#### Post date: [October 28, 2023, 11:44pm UTC](https://discourse.cmake.org/t/zeros-in-version-numbers-cmake-policy-set-cmp0096-new/9296/2 "2023-10-28T23:44:09Z")

</div>

This has nothing to do with policy CMP0096.

Please see the documentation of [configure\_file](https://cmake.org/cmake/help/latest/command/configure_file.html):  
`#cmakedefine` … _any value not considered a false constant by the `if()` command_

---

<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: [October 29, 2023, 12:04pm UTC](https://discourse.cmake.org/t/zeros-in-version-numbers-cmake-policy-set-cmp0096-new/9296/3 "2023-10-29T12:04:04Z")

</div>

The tutorial should not use `#cmakedefine` here and instead just `#define`.

Cc: @betsy.mcphail

---

<div class="post-metadata">

### Author: ![LadyGreyTeaService](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/l/f07891/32.png) [@LadyGreyTeaService](https://discourse.cmake.org/u/LadyGreyTeaService)
#### Post date: [October 29, 2023, 12:59pm UTC](https://discourse.cmake.org/t/zeros-in-version-numbers-cmake-policy-set-cmp0096-new/9296/4 "2023-10-29T12:59:40Z")

</div>

Thanks for your help explaining this.  
Wow! That behaviour is unexpectedly crap. What could possibly be the rationale?  
It means that whenever anyone defines a cmake variable that might have the value zero, and they want to use it in c++ code they then have to do something like

```auto
#cmakedefine VAR @VAR@                                          
#ifndef VAR                                                                        
# define VAR 0                                                                    
#endif

```

And a similar kind of thing for all the other constants interpreted to be false (and there are a lot of them).  
Unless there is some more elegant alternative?

It also means the solution to the tutorial Step 1 Exercise 3  
[https://cmake.org/cmake/help/latest/guide/tutorial/A%20Basic%20Starting%20Point.html#id12](https://cmake.org/cmake/help/latest/guide/tutorial/A%20Basic%20Starting%20Point.html#id12)  
IS WRONG:

```auto
// the configured options and settings for Tutorial
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@

```

I got it to work with:

```auto
// the configured options and settings for Tutorial                                                   
#cmakedefine Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@                                          
#ifndef Tutorial_VERSION_MAJOR                                                                        
# define Tutorial_VERSION_MAJOR 0                                                                    
#endif                                                                                                
#cmakedefine Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@                                          
#ifndef Tutorial_VERSION_MINOR                                                                        
# define Tutorial_VERSION_MINOR 0                                                                    
#endif

```

Looking at the code in cmProjectCommand.cxx for parsing the version number: a regular expression and sscanf… Hmmmm… At least it gets the right result before #cmakedefine throws it away.

---

<div class="post-metadata">

### Author: ![LadyGreyTeaService](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/l/f07891/32.png) [@LadyGreyTeaService](https://discourse.cmake.org/u/LadyGreyTeaService)
#### Post date: [October 29, 2023, 1:06pm UTC](https://discourse.cmake.org/t/zeros-in-version-numbers-cmake-policy-set-cmp0096-new/9296/5 "2023-10-29T13:06:21Z")

</div>

Thanks I see it works with

```auto
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@ 

```

The documentation for configure\_file lead me down the wrong path mentioning #cmakedefine but not #define.  
Apologies for my dimness.

---

<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: [October 29, 2023, 1:41pm UTC](https://discourse.cmake.org/t/zeros-in-version-numbers-cmake-policy-set-cmp0096-new/9296/6 "2023-10-29T13:41:00Z")

</div>

> [@LadyGreyTeaService](#):
>
> Wow! That behaviour is unexpectedly crap. What could possibly be the rationale?

It is there to emulate `autoconf`’s behavior when configuring `config.h.in` files.

---

<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: [October 29, 2023, 4:51pm UTC](https://discourse.cmake.org/t/zeros-in-version-numbers-cmake-policy-set-cmp0096-new/9296/7 "2023-10-29T16:51:00Z")

</div>

> [@LadyGreyTeaService](#):
>
> The documentation for configure\_file lead me down the wrong path mentioning #cmakedefine but not #define.

There’s nothing special about `#define`, so there’s nothing really to mention.

---

<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: [October 29, 2023, 9:06pm UTC](https://discourse.cmake.org/t/zeros-in-version-numbers-cmake-policy-set-cmp0096-new/9296/8 "2023-10-29T21:06:35Z")

</div>

Here’s an example taken from my Professional CMake book which may be of interest. It uses `+0` in strategic places to conveniently handle version number components which might not be set. It has no problem with them being set to zero either.

```c++
std::string getFooBarVersion()
{
    return "@FooBar_VERSION@";
}

unsigned getFooBarVersionMajor()
{
    return @FooBar_VERSION_MAJOR@;
}

unsigned getFooBarVersionMinor()
{
    return @FooBar_VERSION_MINOR@ +0;
}

unsigned getFooBarVersionPatch()
{
    return @FooBar_VERSION_PATCH@ +0;
}

unsigned getFooBarVersionTweak()
{
    return @FooBar_VERSION_TWEAK@ +0;
}

```

---

<div class="post-metadata">

### Author: ![LadyGreyTeaService](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/l/f07891/32.png) [@LadyGreyTeaService](https://discourse.cmake.org/u/LadyGreyTeaService)
#### Post date: [October 30, 2023, 7:57am UTC](https://discourse.cmake.org/t/zeros-in-version-numbers-cmake-policy-set-cmp0096-new/9296/9 "2023-10-30T07:57:04Z")

</div>

Yes. It’s now so obvious that #define would work after substitution. God I’ve been so thick.

---

<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: [October 30, 2023, 8:03pm UTC](https://discourse.cmake.org/t/zeros-in-version-numbers-cmake-policy-set-cmp0096-new/9296/10 "2023-10-30T20:03:52Z")

</div>

Something else to consider. If you are using `#define` to provide your version numbers, I’m assuming you’re putting that in header files. This has the drawback that every time you change the version, all files that pull in that header will need to be rebuilt, even if nothing else in the header changes. A more build-friendly way to structure things is to provide the version details through functions like those in the example of my previous comment. In your header file, you just have function prototypes which never change. Only your private .cpp file implementation sees the changing version numbers, so only that .cpp file needs to be recompiled. With this arrangement, everyone who uses your library only needs to recompile the parts of their project which are affected by a change in your API. If your API doesn’t change, just its implementation, all a consuming project has to do is relink.

---

<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: [October 31, 2023, 12:22am UTC](https://discourse.cmake.org/t/zeros-in-version-numbers-cmake-policy-set-cmp0096-new/9296/11 "2023-10-31T00:22:22Z")

</div>

I’ll add that sometimes it is useful to provide compilation and runtime version information. Most users will care about runtime, but sometimes compile-time can matter.

Also, this seems to come from the tutorial, so maybe this can be better presented.

---

<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: [October 31, 2023, 1:03am UTC](https://discourse.cmake.org/t/zeros-in-version-numbers-cmake-policy-set-cmp0096-new/9296/12 "2023-10-31T01:03:30Z")

</div>

A `-config.cmake` file could provide the version details directly (so it can be made available at compile time), since it knows what package version it corresponds to. A Find module can’t do that, so there’s another reason to prefer a `-config.cmake` over a Find module.
