MantisBT - CMake
View Issue Details
0010718CMakeCMakepublic2010-05-15 13:342016-06-10 14:31
irwin 
Kitware Robot 
normalminoralways
closedmoved 
CMake-2-8 
 
0010718: FIND_XXX command results should be determined by whichever alternative name is highest on the SUPER_PATH
To define an important term used in this bug report, SUPER_PATH is made up of all the components of the alternative paths used in find_xxx commands. For example, for FIND_PROGRAM, the SUPER_PATH consists (from the documentation) of (1) the components of <prefix>/[s]bin for each <prefix> in CMAKE_PREFIX_PATH, CMAKE_PROGRAM_PATH, and CMAKE_APPBUNDLE_PATH where each of these choices are specified as cmake options; (2) the components of the same three choices specified as environment variables; (3) the paths specified by the HINTS option of FIND_PROGRAM; (4) the components of the system environment variable PATH; (5) the components of CMAKE_SYSTEM_PREFIX_PATH, CMAKE_SYSTEM_PROGRAM_PATH, and CMAKE_SYSTEM_APPBUNDLE_PATH appearing in Platform files; and (6) the paths specified by the PATHS option for FIND_PROGRAM. Similar but not identical choices make up the SUPER_PATH for the FIND_FILE, FIND_LIBRARY, and FIND_PATH commands.

The fundamental issue for all FIND_XXX commands is that the vector of names in NAMES is iterated over in an outer loop while an inner loop checks all components of the SUPER_PATH for the presence of one of the names. This means the order of names in NAMES decides FIND_XXX outcomes rather than whichever of the alternative names appears highest in the SUPER_PATH.

Here is a simple CMakeLists.txt file that demonstrates the issue for FIND_PROGRAM.

####
cmake_minimum_required(VERSION 2.8.1)
project(test NONE)
option(ALIAS_FIRST "Put alias first on NAMES LIST" ON)

if(ALIAS_FIRST)
  FIND_PROGRAM(LS_EXECUTABLE
    NAMES
    ls_alias1
    ls
    )
else(ALIAS_FIRST)
  FIND_PROGRAM(LS_EXECUTABLE
    NAMES
    ls
    ls_alias1
    )
endif(ALIAS_FIRST)

message(STATUS "LS_EXECUTABLE = ${LS_EXECUTABLE}")
####

If you place that file in /tmp then you can demonstrate the issue as follows:
software@raven> touch /tmp/ls_alias1
software@raven> cd /tmp; mkdir test_cmake; cd test_cmake
software@raven> rm -rf *
cmake -DALIAS_FIRST=ON -DCMAKE_PROGRAM_PATH:PATH=/tmp /tmp
software@raven> cmake -DALIAS_FIRST=ON -DCMAKE_PROGRAM_PATH:PATH=/tmp /tmp
-- LS_EXECUTABLE = /tmp/ls_alias1
-- Configuring done
-- Generating done
-- Build files have been written to: /tmp/test_cmake
software@raven> rm -rf *
software@raven> cmake -DALIAS_FIRST=OFF -DCMAKE_PROGRAM_PATH:PATH=/tmp /tmp
-- LS_EXECUTABLE = /bin/ls
-- Configuring done
-- Generating done
-- Build files have been written to: /tmp/test_cmake

Note, that the result depends on the order of names in NAMES rather than on the highest one of the NAMES in the SUPER_PATH.

Bill Hoffman has confirmed this issue in the method

kwsys_stl::string SystemTools::FindProgram(
  const kwsys_stl::vector<kwsys_stl::string>& names,
  const kwsys_stl::vector<kwsys_stl::string>& path,
  bool noSystemPath)

in kwsys/SystemTools.cxx. That method iterates over the names and for each one of those calls another variant of FindProgram

kwsys_stl::string SystemTools::FindProgram(
  const char* nameIn,
  const kwsys_stl::vector<kwsys_stl::string>& userPaths,
  bool no_system_path)

with a single name and the path (SUPER_PATH) vector through which it searches for the name. The fairly trivial fix is to swap these two methods around so the outer iteration is over the various components of the SUPER_PATH and the inner iteration is over the names so that whichever of the alternative names is highest in the SUPER_PATH is the one that is chosen.

My knowledge of the cmake source code and C++ skills are limited so I have been unable to identify the equivalent code that does name and SUPER_PATH iterations for FIND_FILE, FIND_LIBRARY, and FIND_PATH. However, I have constructed test CMakeLists.txt files very similar to the above which shows this fundamental issue also occurs for FIND_FILE, FIND_LIBRARY, and FIND_PATH and should be fixed in those cases as well.

I have classified this bug as minor because the fix should not be disruptive.
The reason is the NAMES order is ordinarily fixed via Find modules that users tend not to modify. Instead, they attempt to modify what cmake finds by manipulating the SUPER_PATH (e.g., by supplying CMAKE_PROGRAM_PATH, CMAKE_INCLUDE_PATH or CMAKE_LIBRARY_PATH). With the current code that manipulation sometimes fails to get the desired result. The proposed fix would fix that issue and would not be disruptive since few if any users would go out of their way to manipulate the SUPER_PATH in expectation that that manipulation would fail.
No tags attached.
has duplicate 0012442closed David Cole find_library iterates through paths before names 
Issue History
2010-05-15 13:34irwinNew Issue
2010-06-28 22:36Clinton StimpsonRelationship addedparent of 0010823
2010-06-29 00:14Clinton StimpsonRelationship deletedparent of 0010823
2010-06-29 00:14Clinton StimpsonRelationship addedchild of 0010823
2010-07-02 17:49Clinton StimpsonRelationship deletedchild of 0010823
2010-07-22 07:21David ColeNote Added: 0021458
2011-01-17 16:46David ColeAssigned To => Bill Hoffman
2011-01-17 16:46David ColeStatusnew => assigned
2011-09-02 17:05David ColeRelationship addedhas duplicate 0012442
2012-10-31 16:33Brad KingNote Added: 0031364
2012-10-31 16:33Brad KingAssigned ToBill Hoffman =>
2012-10-31 16:33Brad KingStatusassigned => backlog
2016-06-10 14:28Kitware RobotNote Added: 0041699
2016-06-10 14:28Kitware RobotStatusbacklog => resolved
2016-06-10 14:28Kitware RobotResolutionopen => moved
2016-06-10 14:28Kitware RobotAssigned To => Kitware Robot
2016-06-10 14:31Kitware RobotStatusresolved => closed

Notes
(0021458)
David Cole   
2010-07-22 07:21   
With respect to fixing 10718, *if* we fix it (and that's a big *if* because it's a sweeping change in behavior with largely unpredictable real world consequences), I suggest that we:
- have both loops in CMake,
- and that the default behavior remains the same as it is now,
- and that we activate the new behavior by adding new keyword arguments: perhaps NAMES_FIRST and PATHS_FIRST

That way, stuff stays the same as it is now unless a "finder" activates it explicitly in *new* CMake code.

I'm going to add this as a note to 10718, and a pointer to this whole thread if there's not already one there.

(very long) mailing list thread:http://www.cmake.org/pipermail/cmake/2010-July/thread.html#38284 [^]
(0031364)
Brad King   
2012-10-31 16:33   
The thread mentioned in 0010718:0021458 is also archived on gmane here:

 http://thread.gmane.org/gmane.comp.programming.tools.cmake.user/30192/focus=30311 [^]

I've taught find_library a "NAMES_PER_DIR" option to enable this behavior optionally:

 http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=66759eea [^]

Additional work will be needed to port this to the other find_* commands. Moving to backlog awaiting a volunteer.
(0041699)
Kitware Robot   
2016-06-10 14:28   
Resolving issue as `moved`.

This issue tracker is no longer used. Further discussion of this issue may take place in the current CMake Issues page linked in the banner at the top of this page.