[CMake] Behaviour of CACHE PATH variables

Roger Leigh rleigh at codelibre.net
Wed Mar 25 10:15:30 EDT 2015


Hi folks,

I've come across some odd behaviour when setting CACHE variables of
type PATH, which I didn't spot in the documentation.


With the following minimal testcase:

-----------------------------------------------------------
cmake_minimum_required(VERSION 2.8.12)
cmake_policy(VERSION 2.8.12)

include(GNUInstallDirs)

if (NOT DEFINED TESTDIR1)
  set(TESTDIR1 "test1"
      CACHE PATH "Test path 1")
endif()
  set(TESTDIR2 "test2"
      CACHE PATH "Test path 2")


message(STATUS "sbindir: ${CMAKE_INSTALL_SBINDIR}")
message(STATUS "testdir1: ${TESTDIR1}")
message(STATUS "testdir2: ${TESTDIR2}")
-----------------------------------------------------------

% cmake ..
-- sbindir: sbin
-- testdir1: test1
-- testdir2: test2

% cmake -DTESTDIR1=t1 -DTESTDIR2=t2 -DCMAKE_INSTALL_SBINDIR=priv ..
-- sbindir: priv
-- testdir1: t1
-- testdir2: /home/rleigh/pathtest/test/t2

% cmake -DTESTDIR1:PATH=t1 -DTESTDIR2:PATH=t2 -DCMAKE_INSTALL_SBINDIR=priv ..
-- sbindir: priv
-- testdir1: t1
-- testdir2: t2

This is with cmake 2.8.12.2 (Linux); same behaviour with 3.1.3 (FreeBSD).


Question: Why is TESTDIR2 transformed from "t2" to
"/home/rleigh/pathtest/test/t2" (which is
"$PROJECT_BINARY_DIR/$TESTDIR2)?

This behaviour seems quite undesirable and also inconsistent:

- It's originally set using a relative path with "set(foo CACHE PATH)", and is not
  canonicalised to an absolute path
- If I set it with :PATH using a relative path, it's also not canonicalised to
  an absolute path
- BUT, if I use "set(foo CACHE PATH)" AND I previously set the path *without* a
  :type specifier (i.e. UNINITIALIZED) then this unwanted conversion takes place.
  Since the cache variable was already set, I would have expected this to be a
  no-op.  Given the behaviour in the above two points, I can't see why this is
  happening.

Copying the GNUInstallDirs behaviour of wrapping in an "if (NOT DEFINED foo)" test
mitigates the problem.

For my usage, I'm defining project-specific install dirs derived from the
toplevel GNUInstallDirs dirs.  I'd quite like to be able to specify a relative
(or absolute) path, and then later prepend the install prefix / appropriate
GNUInstallDirs toplevel variable.  Having the current working directory added
by default screws this up quite badly!


Regards,
Roger

-- 
  .''`.  Roger Leigh
 : :' :  Debian GNU/Linux    http://people.debian.org/~rleigh/
 `. `'   schroot and sbuild  http://alioth.debian.org/projects/buildd-tools
   `-    GPG Public Key      F33D 281D 470A B443 6756 147C 07B3 C8BC 4083 E800


More information about the CMake mailing list