Hi, attached is a short CMakeLists.txt which shows a strange behaviour of mark_as_advanced(), find_program() and the cache.
What it does is the following: it sets a variable FOO to "foo", then marks it as advanced (although it is not in the cache), then does a find_program() on the variable, and after that find_program() FOO is suddenly empty. I.e. the output is: ... -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- FOO = "foo" -- FOO = "foo" -- FOO = "foo" -- FOO = "" -- Configuring done I tested this with current HEAD (or master) and CMake 2.6.2. Both give the same result. FOO is then also in the cache with value "". What happens is this: first set() sets the value, but not in the cache. Then there comes the mark_as_advanced(), which creates a cache entry, but with empty value: bool cmMarkAsAdvancedCommand ::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &) { ... for(; i < args.size(); ++i) { std::string variable = args[i]; cmCacheManager* manager = this->Makefile->GetCacheManager(); cmCacheManager::CacheIterator it = manager->GetCacheIterator(variable.c_str()); if ( it.IsAtEnd() ) { this->Makefile->GetCacheManager() ->AddCacheEntry(variable.c_str(), 0, 0, cmCacheManager::UNINITIALIZED); overwrite = true; } Now this variable is kind-of in the cache. Then comes find_program(): bool cmFindProgramCommand ::InitialPass(std::vector<std::string> const& argsIn, cmExecutionStatus &) { this->VariableDocumentation = "Path to a program."; this->CMakePathName = "PROGRAM"; // call cmFindBase::ParseArguments if(!this->ParseArguments(argsIn)) { return false; } if(this->AlreadyInCache) { // If the user specifies the entry on the command line without a // type we should add the type and docstring but keep the original // value. if(this->AlreadyInCacheWithoutMetaInfo) { this->Makefile->GetDefinition(this->VariableName.c_str())); this->Makefile->AddCacheDefinition(this->VariableName.c_str(), "", this->VariableDocumentation.c_str(), cmCacheManager::FILEPATH); } return true; } This sees the variable is already in the cache, but without meta info and adds it using AddCacheDefinition(). After this call, makefile->GetDefinition("FOO") returns an empty string, before this call it still returns "foo". I didn't figure out the correct way how to improve this. Making mark_as_advanced() put it in the cache with the current value has the effect that find_program() also hits the same branch, but after the AddCacheDefinition() FOO has the value of "/home/alex/src/CMake/tests/find-cache-var-test/bH/foo", which is due to the type FILEPATH, which, when set, causes AddCacheDefinition to expand the value to a full path. If it is set simply as "STRING" in the cache, it stays "FOO". I think it should end up in the cache as "foo" with the type "FILEPATH", but I didn't figure out how to achieve this. Alex
cmake_minimum_required(VERSION 2.6) macro(print var) message(STATUS "${var} = \"${${var}}\"") endmacro(print) set(FOO foo) print(FOO) # gives "foo" find_program(FOO ls) # this line doesn't affect the result at all print(FOO) mark_as_advanced(FOO) # without this line FOO is still "foo" after the next find_program() # with this line it is empty print(FOO) # gives "foo" find_program(FOO ls) # does nothing, since FOO is already valid print(FOO) # gives ""
_______________________________________________ Powered by www.kitware.com Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Follow this link to subscribe/unsubscribe: http://www.cmake.org/mailman/listinfo/cmake