[CMake] Temporarily redefining CMake functions

Yves Frederix yves.frederix+cmake at gmail.com
Sat Oct 10 11:24:42 EDT 2015


Hi all,

I have a use case in which I would like to temporarily overwrite
standard CMake functions (e.g., add_library). After searching the
mailing list, I found that when a function is redefined, the original
function is still available but with an underscore prefix, e.g.,

function(add_library)
  message("custom add_library")
  _add_library(${ARGN})
endfunction()

The problem with this solution is that this in fact redefines
add_library permanently. My hope was that if I introduced some
additional scope, I would get the desired result:

function(testfun)
  function(add_library)
    message("custom add_library")
    _add_library(${ARGN})
  endfunction()
  add_library(test SHARED IMPORTED)
endfunction()

testfun()
add_library(test2 SHARED IMPORTED)

As it turns out, this is not the case, and the second call to
add_library actually still calls my custom version, which is
unexpected and of course not what I want.

Under the assumption that only for the standard CMake functions the
underscore version would be created (I haven't found any official
documentation on this behavior), I then tried the following:

function(add_library)
    message("custom add_library")
    _add_library(${ARGN})
endfunction()

add_library(test SHARED IMPORTED)

function(add_library)
    _add_library(${ARGN})
endfunction()

add_library(test2 SHARED IMPORTED)

This actually creates an infinite recursion loop and CMake crashes
with a segmentation fault. This means that the assumption was wrong,
and apparently all existing functions, upon redefinition, are renamed
to an underscore version (hence the infinite recursion).

Using this information, I was able to create the desired behavior in
the following way:

# Ensure that _add_library points to the original version
function(add_library)
endfunction()

# Ensure that __add_library points to the original version
function(_add_library)
endfunction(_add_library)

# Define the custom version
function(add_library)
  message("custom add_library")
  __add_library(${ARGN})
endfunction()

add_library(test SHARED IMPORTED)

# Restore the original implementation
function(add_library)
  __add_library(${ARGN})
endfunction()

add_library(test2 SHARED IMPORTED)


This works, but looks a bit hackish, so I was wondering if there is
maybe a better, more elegant way to achieve the desired behavior?

Regards,
Yves


More information about the CMake mailing list