sdbbs
sdbbs

Reputation: 5478

Conditionally include a source file with CMake?

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?

Upvotes: 1

Views: 1772

Answers (2)

c4pQ
c4pQ

Reputation: 968

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.

Upvotes: 3

sdbbs
sdbbs

Reputation: 5478

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 ...

Upvotes: 0

Related Questions