Quantcast

check_c_source_compiles caching pitfalls

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

check_c_source_compiles caching pitfalls

Tyson Nottingham
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 | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: check_c_source_compiles caching pitfalls

Alan W. Irwin
On 2017-04-22 18:16-0700 Tyson Nottingham wrote:

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

To deal with cached variables that you want to reuse this way try the
unset command <https://cmake.org/cmake/help/latest/command/unset.html>
within the loop.

Alan
__________________________
Alan W. Irwin

Astronomical research affiliation with Department of Physics and Astronomy,
University of Victoria (astrowww.phys.uvic.ca).

Programming affiliations with the FreeEOS equation-of-state
implementation for stellar interiors (freeeos.sf.net); the Time
Ephemerides project (timeephem.sf.net); PLplot scientific plotting
software package (plplot.sf.net); the libLASi project
(unifont.org/lasi); the Loads of Linux Links project (loll.sf.net);
and the Linux Brochure Project (lbproject.sf.net).
__________________________

Linux-powered Science
__________________________
--

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 | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: check_c_source_compiles caching pitfalls

Hendrik Sattler
In reply to this post by Tyson Nottingham


Am 23. April 2017 03:16:41 MESZ schrieb Tyson Nottingham <[hidden email]>:

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

Try to use variables with a better naming.  This will also solve your problem:
has_flag_${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.

Ask yourself WHY this is done! Rerunning cmake in a build tree should not repeat all those expensive tests.

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

--
Diese Nachricht wurde von meinem Android-Mobiltelefon mit K-9 Mail gesendet.
--

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