2

I do not really know cmake, but I am trying to setup some sort of an option in CMake - a single line that can be commented or uncommented - and depending on its existence, an additional file should be included in the set of source files.

So, based on:

... I came up with following example CMakeFiles.txt:

project(MyApp) option(ADD_EXTRA_FILE TRUE) set(MyApp_sources main.c file1.c file2.c ) if(NOT ADD_EXTRA_FILE) set(MyApp_sources ${MyApp_sources} "extra_file.c") endif(NOT ADD_EXTRA_FILE) message(STATUS "ADD_EXTRA_FILE: ${ADD_EXTRA_FILE}") message(STATUS "MyApp_sources: ${MyApp_sources}") 

When I run this, I would expect ADD_EXTRA_FILE to be TRUE, and therefore if(NOT ADD_EXTRA_FILE) should evaluate to FALSE, and therefore the extra file should not be added; however:

$ cmake . -- ADD_EXTRA_FILE: OFF -- MyApp_sources: main.c;file1.c;file2.c;extra_file.c -- Configuring done -- Generating done -- Build files have been written to: /tmp 

... it turns out, ADD_EXTRA_FILE is OFF (?), and apparently if(NOT ADD_EXTRA_FILE) evaluates to TRUE, and the extra file is added anyways.

Is it possible to achieve what I want in Cmake - and if so, how?

1
  • 1
    Consider using target_sources for adding sources to a given target. I'd prefer list(APPEND MyApp_sources extra_file.c) to add a new element to the source list btw, should you decide to keep using it. Commented Jun 29, 2022 at 16:39

2 Answers 2

4

I'd personally won't recommend usage of plain set for option. @sdbbs did everything right except cleaning cache. If one doesn't provide option manually it's set once and value won't change after just running cmake to reconfigure project.

So the following work as expected:

project(MyApp) option(ADD_EXTRA_FILE "include extra file" ON) set(MyApp_sources main.c file1.c file2.c ) if(NOT ADD_EXTRA_FILE) set(MyApp_sources ${MyApp_sources} "extra_file.c") endif(NOT ADD_EXTRA_FILE) message(STATUS "ADD_EXTRA_FILE: ${ADD_EXTRA_FILE}") message(STATUS "MyApp_sources: ${MyApp_sources}") 

with the following output:

> cmake .. -- The C compiler identification is GNU 9.4.0 -- The CXX compiler identification is GNU 9.4.0 -- Check for working C compiler: /usr/bin/cc -- Check for working C compiler: /usr/bin/cc -- works -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Detecting C compile features -- Detecting C compile features - done -- Check for working CXX compiler: /usr/bin/c++ -- Check for working CXX compiler: /usr/bin/c++ -- works -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Detecting CXX compile features -- Detecting CXX compile features - done -- ADD_EXTRA_FILE: ON -- MyApp_sources: main.c;file1.c;file2.c -- Configuring done -- Generating done 

PS

Of course, from the sanity point ADD_EXTRA_FILE should be OFF by default and if(ADD_EXTRA_FILE) adds the file.

Sign up to request clarification or add additional context in comments.

4 Comments

Indeed, that was it - I did not clear the cache; in my case, I was testing with CMakeFiles.txt in /tmp and with cmake .; so to clean the cache, I had to do rm -rf CMakeCache.txt CMakeFiles cmake_install.cmake - and after that, the option works as noted here. However, with option I have to remember to clear cache, and with set I do not, which is why I like set better ...
1) why do you create a list of source files ? 2) why you simply didn't use target_sources(MyApp PRIVATE extra_file.c) in a if() statement or even better, use a generator expression ! ref: cmake.org/cmake/help/latest/command/target_sources.html
Can you please explain what is changed, compared to the question? It's hard to tell, looks the same. Did you only change TRUE to ON?
@Osman-pasha, yep. But it doesn't matter. My answer refers to the solution by sddbs himself with set() call. The answer is to clean the cache to get the expected result.
0

Well, I saw documentation for https://cmake.org/cmake/help/latest/command/option.html , and it turns out it accepts values ON or OFF; and the right syntax should be:

 option(ADD_EXTRA_FILE "help text" ON) 

... but even with this setup, I still get printout OFF (?).

So, it turns out, instead of option() I should just use set() for a plain boolean variable - and then it works as expected. Also, my variable naming logic above is incorrect, so correcting for all that, I get CMakeLists.txt which is:

project(MyApp) # set(DONOT_ADD_EXTRA_FILE TRUE) set(MyApp_sources main.c file1.c file2.c ) if(NOT DONOT_ADD_EXTRA_FILE) set(MyApp_sources ${MyApp_sources} "extra_file.c") endif(NOT DONOT_ADD_EXTRA_FILE) message(STATUS "DONOT_ADD_EXTRA_FILE: ${DONOT_ADD_EXTRA_FILE}") message(STATUS "MyApp_sources: ${MyApp_sources}") 

... and since set(DONOT_ADD_EXTRA_FILE TRUE) above is commented, if(NOT DONOT_ADD_EXTRA_FILE) also evaluates to TRUE, and the file is added:

$ cmake . -- DONOT_ADD_EXTRA_FILE: OFF -- MyApp_sources: main.c;file1.c;file2.c;extra_file.c -- Configuring done -- Generating done -- Build files have been written to: /tmp 

(seemingly, when not otherwise set, DONOT_ADD_EXTRA_FILE is seen as an option?)

But if I uncomment that line, DONOT_ADD_EXTRA_FILE becomes TRUE, the condition if(NOT DONOT_ADD_EXTRA_FILE) evaluates to FALSE, and the file is not added, as expected:

$ cmake . -- DONOT_ADD_EXTRA_FILE: TRUE -- MyApp_sources: main.c;file1.c;file2.c -- Configuring done -- Generating done -- Build files have been written to: /tmp 

Well, hopefully someone can provide a proper answer - for now, I guess I'll go along with this ...

1 Comment

regarding you getting ... but even with this setup, I still get printout OFF (?). you just have to clean cache and run configure from scratch and you see what you expect

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.