# Project variants?

**URL:** https://discourse.cmake.org/t/project-variants/205
**Category:** Code
**Created:** [November 14, 2019, 1:38pm UTC](https://discourse.cmake.org/t/project-variants/205 "2019-11-14T13:38:25Z")
**Posts on this page:** 11
**Page:** 1

<div class="post-metadata">

### Author: ![DavidA](https://discourse.cmake.org/user_avatar/discourse.cmake.org/davida/32/128_2.png) [@DavidA](https://discourse.cmake.org/u/DavidA)
#### Post date: [November 14, 2019, 1:38pm UTC](https://discourse.cmake.org/t/project-variants/205/1 "2019-11-14T13:38:25Z")

</div>

Hi, I’ve just created my first full-scale CMake project, but I have a lot to learn. My project builds an executable and a set of shared libraries. The build of each shared library is enabled by a CMake option. I’m now considering how to present these options to fellow developers who aren’t familiar with CMake.

The developer will want to build a subset of libraries that depends on the project he/she is working on. How would I implement ‘super-options’ that would switch a set of options ON?

i.e. Proj1 requires -D Option1=ON Option3=ON

I guess I could do this with a shell script.

Or I could do it in CMakeLists.txt:

```
option(Proj1 "Build libraries for Proj1" OFF)
if(Proj1)
    set(Option1 "ON")
    set(Option3 "ON")
endif()

```

or is there a better way?

I noticed that VS Code extension ‘CMake-Tools’ has a concept of ‘CMake Variants’. Does CMake have anything similar?

Any recommendations appreciated.

BR  
David

---

<div class="post-metadata">

### Author: ![McMartin](https://discourse.cmake.org/user_avatar/discourse.cmake.org/mcmartin/32/150_2.png) [@McMartin](https://discourse.cmake.org/u/McMartin)
#### Post date: [November 14, 2019, 4:23pm UTC](https://discourse.cmake.org/t/project-variants/205/2 "2019-11-14T16:23:09Z")

</div>

The documentation of the [`option` command](https://cmake.org/cmake/help/latest/command/option.html) mentions the [`CMakeDependentOption` module](https://cmake.org/cmake/help/latest/module/CMakeDependentOption.html#module:CMakeDependentOption) for this use case.

---

<div class="post-metadata">

### Author: ![DavidA](https://discourse.cmake.org/user_avatar/discourse.cmake.org/davida/32/128_2.png) [@DavidA](https://discourse.cmake.org/u/DavidA)
#### Post date: [November 14, 2019, 4:42pm UTC](https://discourse.cmake.org/t/project-variants/205/3 "2019-11-14T16:42:08Z")

</div>

I don’t think that meets my usecase. I want to implement a ‘preset’ where a ‘super option’ turns on a subset of options. This isn’t a dependency.

---

<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: [November 14, 2019, 6:45pm UTC](https://discourse.cmake.org/t/project-variants/205/4 "2019-11-14T18:45:54Z")

</div>

@ben.boeckel This sounds exactly like what VTK does with groups. Did you have any tips?

---

<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: [November 14, 2019, 9:23pm UTC](https://discourse.cmake.org/t/project-variants/205/5 "2019-11-14T21:23:45Z")

</div>

Not with groups exactly. I’d structure the code this way:

```cmake
set(PROJECT_VARIANT "<DEFAULT>"
  CACHE STRING "Project variant")
set_property(CACHE PROJECT_VARIANT
  PROPERTY STRINGS "<DEFAULT>;VARIANT1;VARIANT2;NONE")

# Defaults for each option.
set(option1_default ON)
set(option2_default OFF)

# Select a default variant. Do this in case the default changes
# in the future, old build trees automatically get it too.
if (PROJECT_VARIANT STREQUAL "<DEFAULT>")
  set(PROJECT_VARIANT "VARIANT1")
endif ()

if (PROJECT_VARIANT STREQUAL "VARIANT1")
  set(option1_default OFF) # VARIANT1 doesn't want this option
endif ()

option(OPTION1 "docstring" "${option1_default}")

```

---

<div class="post-metadata">

### Author: ![DavidA](https://discourse.cmake.org/user_avatar/discourse.cmake.org/davida/32/128_2.png) [@DavidA](https://discourse.cmake.org/u/DavidA)
#### Post date: [November 15, 2019, 1:07pm UTC](https://discourse.cmake.org/t/project-variants/205/6 "2019-11-15T13:07:11Z")

</div>

@ben.boeckel Thanks, your suggestion is really helpful. I will try that out.

Just as a sanity check on my understanding: Am I correct in thinking that if several variants are to be built, they should be built in separate build directories - not in the same one? (Where a build directory is from where I call cmake).

---

<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: [November 15, 2019, 1:20pm UTC](https://discourse.cmake.org/t/project-variants/205/7 "2019-11-15T13:20:19Z")

</div>

> [@DavidA](#):
>
> Am I correct in thinking that if several variants are to be built, they should be built in separate build directories - not in the same one?

This depends on whether they should conflict or not. Instead of a single string, you can use a set of booleans for whether that variant should be supported. Basically, if variants are mutually exclusive, use the above code structure. If they’re additive, use options.

---

<div class="post-metadata">

### Author: ![DavidA](https://discourse.cmake.org/user_avatar/discourse.cmake.org/davida/32/128_2.png) [@DavidA](https://discourse.cmake.org/u/DavidA)
#### Post date: [November 15, 2019, 1:22pm UTC](https://discourse.cmake.org/t/project-variants/205/8 "2019-11-15T13:22:52Z")

</div>

@ben.boeckel Thanks again.

---

<div class="post-metadata">

### Author: ![DavidA](https://discourse.cmake.org/user_avatar/discourse.cmake.org/davida/32/128_2.png) [@DavidA](https://discourse.cmake.org/u/DavidA)
#### Post date: [November 18, 2019, 9:52am UTC](https://discourse.cmake.org/t/project-variants/205/9 "2019-11-18T09:52:20Z")

</div>

@ben.boeckel I have a few questions about your suggested solution:

Please will you explain the line:

```
set_property(CACHE PROJECT_VARIANT PROPERTY STRINGS "<DEFAULT>;VARIANT1;VARIANT2;NONE")

```

I understand that a target can have a property value but what does a property mean for the CACHE?

Why do we need that line in addition to:

```
set(PROJECT_VARIANT "<DEFAULT>" CACHE STRING "Project variant")

```

Is this:

```
"<DEFAULT>;VARIANT1;VARIANT2;NONE"

```

an enumeration of possible values?

Thanks in advance,  
David

---

<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: [November 18, 2019, 9:08pm UTC](https://discourse.cmake.org/t/project-variants/205/10 "2019-11-18T21:08:41Z")

</div>

> [@DavidA](#):
>
> an enumeration of possible values?

That’s exactly what it is. [https://cmake.org/cmake/help/latest/prop\_cache/STRINGS.html](https://cmake.org/cmake/help/latest/prop_cache/STRINGS.html)

---

<div class="post-metadata">

### Author: ![DavidA](https://discourse.cmake.org/user_avatar/discourse.cmake.org/davida/32/128_2.png) [@DavidA](https://discourse.cmake.org/u/DavidA)
#### Post date: [November 19, 2019, 10:26am UTC](https://discourse.cmake.org/t/project-variants/205/11 "2019-11-19T10:26:46Z")

</div>

@ben.boeckel Thanks again.
