find_program and find_library results are only normalise the second time around
On master
as of now, there is an issue with find_program
and find_library
. Basically the first time they run (when there's no value in the cache) it saves the result in the cache but does NOT normalise the path. The second time you configure, it will load the path from the cache and then it DOES normalise it. This result is in a different value (e.g. if the first path was //path/to/foo
the second time round it will be /path/to/foo
).
This causes very tricky to figure out issues! For example if you use that program in an add_custom_command()
then if you configure, make
, configure, then the second configure will delete the OUTPUT
!
This took me a WHOLE DAY to figure out because the it was only triggered in CI due to the $PATH
there containing //
. I ended up reading the CMake source code.
Anyway I think the issue is in this code (and similarly for find_path
and find_library
:
bool cmFindProgramCommand::InitialPass(std::vector<std::string> const& argsIn)
{
this->CMakePathName = "PROGRAM";
// call cmFindBase::ParseArguments
if (!this->ParseArguments(argsIn)) {
return false;
}
this->DebugMode = this->ComputeIfDebugModeWanted(this->VariableName);
if (this->AlreadyDefined) {
this->NormalizeFindResult();
return true;
}
std::string const result = this->FindProgram();
this->StoreFindResult(result);
return true;
}
As you can see this->NormalizeFindResult()
is only called if the value is already defined. I guess the fix should be something like this:
if (!this->AlreadyDefined) {
std::string const result = this->FindProgram();
this->StoreFindResult(result);
}
this->NormalizeFindResult();
return true;
}
But I have not tested it.
More details in this Stackoverflow answer.