41

I'm trying to reuse the CMakeLists.txt of a third-party project whose source I don't want to change (expat, to be exact). I've added the project as a subproject of the top level using add_subdirectory.

This works but now I would like to set the value of some of the subproject's options in the top level CMakeLists.txt. How do I do this?

thehouse
  • 7,957
  • 7
  • 33
  • 32
  • 1
    Possible duplicate of [Overriding a default option(...) value in CMake from a parent CMakeLists.txt](http://stackoverflow.com/questions/3766740/overriding-a-default-option-value-in-cmake-from-a-parent-cmakelists-txt) – Claudiu Dec 15 '15 at 17:24

4 Answers4

52

If the sub-project uses option (not set) for its configuration settings, then you can specify values using option before adding the subdirectory:

option(LIB_OPTION1 "" OFF)
option(LIB_OPTION2 "" ON)
add_subdirectory(${CMAKE_SOURCE_DIRECTORY}/lib)
Abai
  • 760
  • 1
  • 8
  • 16
Drew Noakes
  • 300,895
  • 165
  • 679
  • 742
  • What if the sub project doesn't use `option`, but uses `set`, is there a way to override existing uses of `set` without using cache? – CMCDragonkai Sep 04 '17 at 06:59
47

See the similar question with a good answer.

Answer in short:

SET(SOME_EXPAT_OPTION OFF CACHE BOOL "Use some expat option")
Community
  • 1
  • 1
ronkot
  • 5,915
  • 4
  • 27
  • 41
  • 11
    For some reason this does not work for Visual Studio generators in my case (CMake 3.4.0), but works fine for Makefiles generators. Other answers suggest to use *option* that works fine for both Visual Studio and Makefiles generators. – Pidhorskyi Nov 10 '15 at 07:20
  • How can we do it from the command line? I have one set of options that I invoke `cmake` with for LLVM, but one subproject seems to need an extra option. – jww Nov 18 '18 at 01:12
  • 1
    @ronkot Like in your linked answer, I would add, that sometimes it is necessary to add `FORCE` as additional parameter after the description string. – stackprotector Jul 06 '20 at 16:09
7

You can define the options with the desired settings (ON or OFF) before calling ADD_SUBDIRECTORY. This will then take precedence over the OPTION commands in expat's CMakeLists.txt since the last parameter to OPTION is only a default value (which is neglected if that settings already exists).

Johannes S.
  • 4,566
  • 26
  • 41
  • 1
    I tried that but it had no effect. I think the trick is to use `CACHE` as in @kullero's answer – thehouse Dec 28 '12 at 15:04
  • @thehouse I was pretty sure that the `OPTION` command caches its effect and I just tried and it works. Of course, the value may not be in cache already, but that is true for the `SET` command as well unless you use `FORCE`. I have to admit that the `SET` way is more generic since `OPTION` only allows boolean values, but in the end that was what you asked for. – Johannes S. Dec 28 '12 at 16:11
  • Sorry, I misinterpreted your original answer. I thought you meant define the option using `SET`. I see what you mean now so upvoted. – thehouse Dec 28 '12 at 17:08
-2

The SET-command has the 'PARENT_SCOPE' option:

If PARENT_SCOPE is present, the variable will be set in the scope above the current
scope. Each new directory or function creates a new scope. This command will set the 
value of a variable into the parent directory or calling function (whichever is 
applicable to the case at hand). PARENT_SCOPE cannot be combined with CACHE.

(see: http://www.cmake.org/cmake/help/v2.8.10/cmake.html#command:set )

guini
  • 752
  • 1
  • 7
  • 18
  • 1
    Does this not do the opposite of what I'm after? I'm trying to get a variable in the parent scope to affect a subscope. – thehouse Dec 28 '12 at 13:58