There may indeed be a bug (at least in the documentation).<br><br>In CMake 'if' statements are a little different than you might think. From the documentation of 'if' (cmake --help-command if):<br><br> if(variable STREQUAL string)<br>
if(string STREQUAL string)<br><br>Now with your code you had:<br><br><span style="font-family: courier new,monospace;">foreach(opt ${options})</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> message(STATUS "opt = ${opt}")</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> if(${opt} STREQUAL fine)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> ...</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">endforeach()</span><br style="font-family: courier new,monospace;"><br>Now what the expression states is 'if (${opt} STREQUAL fine)' or if (fine STRQUAL fine). ${opt} gets replaced by its value and you compare 'fine' with 'fine'. It might have appeared to work had you used opt instead of ${opt}, but you wouldn't have been able to turn the option(fine) on and off. The if statement would have always been false.<br>
<br>Things get tricky when the right side of the STREQUAL is a string that matches the name of a variable:<br><br><span style="font-family: courier new,monospace;">set(var "stuff")</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">set(stuff ON)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">if(var STREQUAL "stuff")</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> message("var STREQUAL stuff")</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">else()</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> message("NOT var STREQUAL stuff")</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">endif()</span><br style="font-family: courier new,monospace;">
<br>According to the docs, I would expect this to return "var STREQUAL ON", but it instead returns "NOT var STREQUAL ON", meaning that it dereferenced the value of stuff in the if statement rather than treating it as a string literal. This is inconsistent with the documentation that indicates that right side operator is a string and not a variable.<br>
<br>To get what you want in your code, you need the following:<br><br><span style="font-family: courier new,monospace;">option(fine_on "Fine" OFF)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">option(good_on "Good" ON)</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">option(bad_on "Bad" OFF) # This isn't actually used</span> <br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">foreach(opt ${options})</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> message(STATUS "opt = ${opt}")\</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> # Only accept opt == fine when fine_on is true</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> if(fine_on AND opt STREQUAL "fine")</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> message(STATUS "This is fine")</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> # Only accept opt == good when good_on is true</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> elseif(good_on AND opt STREQUAL "good")</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> message(STATUS "This is good")</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> # Everything else is bad</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> else()</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> message(ERROR " This is bad!")</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> endif()</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">endforeach(opt ${options})</span><br><br>James<br style="font-family: courier new,monospace;">
<br>On Mon, Mar 30, 2009 at 4:28 AM, Marcel Loose <<a href="mailto:loose@astron.nl">loose@astron.nl</a>> wrote:<br>> Hi all,<br>><br>> I am running cmake version 2.6-patch 2.<br>> I stumbled over the following, and I think it is a bug.<br>
><br>> If I run cmake on this CMakeLists.txt:<br>><br>> cmake_minimum_required(VERSION 2.6)<br>> set(options<br>> fine<br>> good<br>> bad)<br>> #option(fine "Fine" OFF)<br>> #option(good "Good" OFF)<br>
> option(bad "Bad" OFF)<br>> foreach(opt ${options})<br>> message(STATUS "opt = ${opt}")<br>> if(${opt} STREQUAL fine)<br>> message(STATUS "This is fine")<br>> elseif(${opt} STREQUAL good)<br>
> message(STATUS "This is good")<br>> else(${opt} STREQUAL fine)<br>> message(FATAL_ERROR "This is bad!")<br>> endif(${opt} STREQUAL fine)<br>> endforeach(opt ${options})<br>><br>
> I get the following output:<br>> ...<br>> -- val = fine<br>> -- fine<br>> -- val = good<br>> -- good<br>> -- val = bad<br>> CMake Error at CMakeLists.txt:14 (message):<br>> bad<br>> ...<br>
><br>> which is to be expected.<br>><br>> However, when I uncomment the line option(fine...), I get the following<br>> output:<br>> ...<br>> -- opt = fine<br>> -- This is fine<br>> -- opt = good<br>
> -- This is good<br>> -- opt = bad<br>> -- This is fine<br>> -- Configuring done<br>> ...<br>><br>> which is clearly wrong! Uncommenting the line option(good...) yields<br>> almost the same output, but now the elseif branch is followed.<br>
><br>> Is this a bug, or am I overlooking something?<br>><br>> Best regards,<br>> Marcel Loose.<br>><br>><br>><br>> _______________________________________________<br>> Powered by <a href="http://www.kitware.com">www.kitware.com</a><br>
><br>> Visit other Kitware open-source projects at <a href="http://www.kitware.com/opensource/opensource.html">http://www.kitware.com/opensource/opensource.html</a><br>><br>> Please keep messages on-topic and check the CMake FAQ at: <a href="http://www.cmake.org/Wiki/CMake_FAQ">http://www.cmake.org/Wiki/CMake_FAQ</a><br>
><br>> Follow this link to subscribe/unsubscribe:<br>> <a href="http://www.cmake.org/mailman/listinfo/cmake">http://www.cmake.org/mailman/listinfo/cmake</a><br>><br><br>