John
John

Reputation: 3484

Why the `unset` does not work as expected?

Here is the shell script which invokes the cmake

rm -rf build && mkdir build && cd build && cmake .. -DPULISH_VERSION=ON 

Here is the CMakeLists.txt:

cmake_minimum_required(VERSION 3.13)

option(WITH_FOO "whether FOO is enabled or not" on)
option(PULISH_VERSION "whether is the pulished verion or not" on)

if(PULISH_VERSION)
    if(WITH_FOO)
        message("FOO should not be enabled for the published version.")
        unset(WITH_FOO) # It seems `WITH_FOO` does not work, what a surprise!
    endif()
endif()

if(WITH_FOO)
    message("Attention! FOO is enabled!")
    add_compile_definitions(WITH_FOO_ENABLED)
endif()

add_executable(demo main.c)

Here is the content of the main.c:

int main(){return 0;}

Here is the output when the aforementioned shell script is called:

cmake .. -DPULISH_VERSION=ON                               
-- The C compiler identification is GNU 4.9.4
-- The CXX compiler identification is GNU 4.9.4
-- 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
FOO should not be enabled for the published version.
Attention! FOO is enabled!
-- Configuring done
-- Generating done
-- Build files have been written to: /home/John/demo/build

As per the output above, it seems the unset does not work as expected. What a surprise!

Upvotes: 0

Views: 324

Answers (2)

3CxEZiVlQ
3CxEZiVlQ

Reputation: 38499

WITH_FOO is the option, a cache variable, not a scope (local) variable. unset(WITH_FOO) tries to unset the scope variable WITH_FOO, that does not exits. The scope variable does not exist and if(WITH_FOO) fallbacks to the value of the option WITH_FOO. You might want to set the variable set(WITH_FOO OFF) that will hide the option value.

There is a better choice - cmake dependent option:

cmake_dependent_option(WITH_FOO "whether FOO is enabled or not" ON "NOT PULISH_VERSION" OFF)

Makes WITH_FOO option ON if PULISH_VERSION is OFF. Otherwise, a local variable named WITH_FOO is set to OFF.

Upvotes: 2

John
John

Reputation: 3484

Thanks to @273k

cmake_minimum_required(VERSION 3.13)

include(CMakeDependentOption)

option(PULISH_VERSION "whether is the pulished verion or not" on)

cmake_dependent_option(WITH_FOO "whether FOO is enabled or not" ON "NOT PULISH_VERSION" OFF)

if(WITH_FOO)
    message("Attention! FOO is enabled!")
    add_compile_definitions(WITH_FOO_ENABLED)
endif()

add_executable(demo main.c)

Upvotes: 0

Related Questions