The result of check_c_source_compiles and similar commands
(check_c_source_runs, check_cxx_source_compiles, etc.) is cached by the
variable name passed in. This caching makes those commands and ones that
depend on them easy to misuse.

For example,

set(potential_flags -Wall -badflag)

foreach(flag ${potential_flags})
    check_cxx_compiler_flag(${flag} has_flag)
    if(has_flag)
        set(flags "${flags} ${flag}")
    endif(has_flag)
endforeach(flag)

Since the variable name "has_flag" is used on every loop iteration, the
result of check_cxx_compiler_flag is the same on every iteration (because
it uses check_cxx_source_compiles internally, which caches by variable
name). Supposing -Wall is a valid flag, flags will be "-Wall -badflag",
even if -badflag isn't valid.

The obvious workaround is to use different variable names for each check.
For example:

set(potential_flags -Wall -badflag)
set(flag_test_counter 0)

foreach(flag ${potential_flags})
    math(EXPR flag_test_counter "${flag_test_counter} + 1")
    set(flag_test "flag_test_${flag_test_counter}")
    check_cxx_compiler_flag(${flag} ${flag_test})
    if(${flag_test})
        set(flags "${flags} ${flag}")
    endif(${flag_test})
endforeach(flag)

But there is still a problem with this. If I run this once, flags will be
"-Wall". If I change potential_flags to "-Wall -Werror" (supposing -Werror
is valid) and run it again, flags will still be "-Wall" because of the
caching. The test on -Werror will use the results for the test on -badflag.

This problem can just as easily occur in simpler situations.

check_cxx_compiler_flag(-Wall has_flag)

if(has_flag)
    message("yep")
endif(has_flag)

If I run this once, change -Wall to -badflag, and run it again, I'll still
enter the if block.

The obvious workaround is to delete the build files after changing
potential_flags.

However, all of this seems pretty error prone. I'm new to CMake, so I may
be missing something obvious. Is there an obvious non-error-prone solution
to this? In future versions, can these commands take arguments that say not
to use the cached result (or something along those lines)? At the very
least, the documentation for the commands and those that depend on them
could mention these pitfalls.
-- 

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: 
http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more 
information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at 
http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake

Reply via email to