[CMake] infinite loop when using function overriding

David Cole david.cole at kitware.com
Wed Mar 9 11:40:49 EST 2011


This is a question for folks at Stack Overflow. Literally. :-)

I'm assuming you mean "_add_library(${name} ${ARGN})"?

The "override and call original with a leading _" is probably not well
documented anywhere. While it's useful on occasion, we do not recommend
using it if there's an alternate technique that you can use.

When you override a function, there is only one "_" original function
reference saved in CMake's data structures. So... if you do it more than
once, the _ version now refers to one of the ones you've defined rather than
the real "orginal" one. It's more like the last one.

So then suddenly, you've turned one of your functions into a recursive one
that calls itself over and over again... hence the crash. Nice bit of
unintended stack overflow.

Moral: if you're going to do this, do it globally at the top level
CMakeLists.txt file and do not allow subdirectories to have their own
overrides. At this point, enforcing this is up to your project. It should
probably be made more robust in CMake itself, but until then, caveat emptor.


HTH,
David


p.s. -- the following CMakeLists file demonstrates the problem using
add_executable -- when you run cmake on this, when it gets to the
"add_executable(exe2" call, it gets into the first override of
add_executable, which ends up calling itself over and over again via the
re-defined _add_executable that it's trying to use.....

cmake_minimum_required(VERSION 2.8.4)
project(test_function_overrides)

file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/test.cxx.in"
"int main(int argc, const char* argv[])
{
  return 0;
}
")

set(src "${CMAKE_CURRENT_BINARY_DIR}/test.cxx")

configure_file(
  "${CMAKE_CURRENT_BINARY_DIR}/test.cxx.in"
  "${src}"
  )

add_executable(exe0 ${src})

function(add_executable name)
  message(STATUS "enter add_executable override1: name='${name}'")
  _add_executable(${name} ${ARGN})
  message(STATUS " exit add_executable override1")
endfunction()

add_executable(exe1 ${src})

function(add_executable name)
  message(STATUS "enter add_executable override2: name='${name}'")
  _add_executable(${name} ${ARGN})
  message(STATUS " exit add_executable override2")
endfunction()

add_executable(exe2 ${src})




On Wed, Mar 9, 2011 at 9:45 AM, Johan Björk <phb at spotify.com> wrote:

> Hi everyone,
>
> I just ran into an infinite loop in CMake. The cause is that I used
> function overrides in two locations in my CMake tree.
> Is the _function_name() syntax documented somewhere? What is the
> expected behavior?
>
>
> My structure is as follows:
> proj1
>  - CMakeLists.txt
>  - common_core
> proj2
>  - CMakeLists.txt
>  - common_core
>
> in proj1 CMakeLists.txt I override a function using
> function(add_library name)
> _add_library_name(...)
> ...
> endfunction()
> include(common_core/common.cmake)
>
> In common.cmake, I also override the function in the same way
> function(add_library name)
> _add_library_name(...)
> ...
> endfunction()
>
> This causes an infinite loop in latest master.
>
> Thanks
> /Johan
>
>
> _______________________________________________
> Powered by www.kitware.com
>
> Visit other Kitware open-source projects at
> http://www.kitware.com/opensource/opensource.html
>
> Please keep messages on-topic and check the CMake FAQ at:
> http://www.cmake.org/Wiki/CMake_FAQ
>
> Follow this link to subscribe/unsubscribe:
> http://www.cmake.org/mailman/listinfo/cmake
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.cmake.org/pipermail/cmake/attachments/20110309/988c182d/attachment.htm>


More information about the CMake mailing list