find_program always searches current directory
CMake version: 3.11.1
Platform: GNU/Linux (Arch Linux)
When disabling all CMake search paths in find_program
, the current directory is still searched before any directory in the PATH
environment variable.
Furthermore, a readable but not executable file in the current directory is found in preference to an executable program of the same name found in a PATH
directory.
Consider the following set example, with a foo
in the current directory and in a bin
subdirectory:
% ls -og
total 12
drwxrwx--- 2 4096 May 29 23:01 bin
-rwxrwx--- 1 34 May 29 23:01 foo
-rw-rw---- 1 270 May 29 22:51 runfoo.cmake
% ls -og bin
total 4
-rwxrwx--- 1 28 May 29 23:01 foo
% cat foo
#!/bin/sh
echo foo: wrong; exit 1
% cat bin/foo
#!/bin/sh
echo foo: correct
The runfoo.cmake
script uses find_program
to search for and then execute the program given in the variable foo
:
% cat runfoo.cmake
message(STATUS foo: ${foo})
find_program(foo_path NAMES ${foo} NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH)
message(STATUS path: ${foo_path})
if(foo_path)
execute_process(COMMAND ${foo_path} RESULT_VARIABLE out)
message(STATUS result: ${out})
endif()
The expected behaviour when running this script with a PATH
that includes the bin
subdirectory, but not the current directory, is to indeed find and run bin/foo
, not ./foo
:
% pwd
/tmp/example
% PATH=./bin:/usr/bin cmake -Dfoo=foo -P runfoo.cmake
-- foo:foo
-- path:/tmp/example/foo
foo: wrong
-- result:1
If we make ./foo
not executable, it is still found by find_program
:
% chmod -x foo
% PATH=./bin:/usr/bin cmake -Dfoo=foo -P runfoo.cmake
-- foo:foo
-- path:/tmp/example/foo
-- result:Permission denied
Only if foo
is renamed, is the correct program found:
% mv foo foo_
% PATH=./bin:/usr/bin cmake -Dfoo=foo -P runfoo.cmake
-- foo:foo
-- path:/tmp/example/bin/foo
foo: correct
-- result:0
The current directory is searched even if find_program
is used with NO_DEFAULT_PATH
.
The expected behaviour is:
- The current directory is searched only if
.
is present in one of the relevant path variables. - A non-executable file is not regarded as a candidate for
find_program
.
Essentially, if find_program
is just using the system environment path, then it should be consistent with the system behaviour of that path variable.