[cmake-developers] bizarre g_f_c(REALPATH) bug; works backwards(?!)

Brad King brad.king at kitware.com
Thu Mar 14 14:13:37 EDT 2013


On 03/13/2013 08:51 PM, Matthew Woehlke wrote:
> I've discovered an odd an seemingly incorrect behavior of 
> get_filename_component(REALPATH)... apparently there are some conditions 
> when it can take a canonical path and turn it *back into a symlink*.
> 
> To reproduce:
> 
> $ ls -l
> lrwxrwxrwx. 1 matthew matthew   10 Mar 13 20:17 build -> real-build
> drwxrwxr-x. 3 matthew matthew 4096 Mar 13 20:32 real-build
> drwxrwxr-x. 2 matthew matthew 4096 Mar 13 20:30 real-src
> lrwxrwxrwx. 1 matthew matthew    8 Mar 13 20:17 src -> real-src
> 
> $ cat src/CMakeLists.txt
> cmake_minimum_required(VERSION 2.8.10)
> project(Foo)
> get_filename_component(rbd "${CMAKE_BINARY_DIR}" REALPATH)

Reproduced after 's/rbd/r_b_d/'.  This path exists so
r_b_d ends up with the symlinks expanded.

> get_filename_component(rp "${r_b_d}/foo.h" REALPATH)

The implementation is here:

 http://cmake.org/gitweb?p=cmake.git;a=blob;f=Source/cmGetFilenameComponentCommand.cxx;hb=v2.8.10.2#l93

The REALPATH mode works by first doing CollapseFullPath
to make sure it is a full path and then posix realpath().

CollapseFullPath  knows how to translate realpaths back into
symlinked names.  See its use of CheckTranslationPath:

 http://cmake.org/gitweb?p=cmake.git;a=blob;f=Source/kwsys/SystemTools.cxx;hb=v2.8.10.2#l3130

The call to realpath() should expand the symlinks again
but it fails with ENOENT for missing files so CMake uses
the original path.

Summary: REALPATH works only for existing paths.

-Brad



More information about the cmake-developers mailing list