
- #Cmake function code#
- #Cmake function professional#
Any attempt to call find_package() will result in infinite recursion if _find_package() is called by the new implementation. The original find_package() command becomes permanently inaccessible. Execution never reaches the first implementation.įor the find_package() example mentioned earlier, the implications of find_package() being redefined more than once are catastrophic. This enters the second implementation which also calls _printme(), but _printme() points back at the second implementation again and infinite recursion results. When printme() is called, execution enters the third implementation, which calls _printme(). Again, CMake finds an existing command by that name, so it redefines the name _printme to point to the old command (which is the second implementation) and sets printme to point to the new definition. The third implementation of printme() is encountered. CMake finds an existing command by that name, so it defines the name _printme to point to the old command and sets printme to point to the new definition. The second implementation of printme() is encountered. No command by that name previously existed, so no further action is required. The first implementation of printme() is created and made available as a command of that name. When CMake processes the above, here is what occurs: One may naively expect the output to be as follows: Hello from thirdīut instead, the first implementation is never called because the second one ends up calling itself in an infinite loop. This has the potential to lead to infinite recursion, as the following contrived example demonstrates: function(printme) The prepending of one underscore to “save” the previous command only applies to the current name, it is not applied recursively to all previous overrides. If a command is only ever overridden once, techniques like in the example above appear to work, but if the command is overridden again, then the original command is no longer accessible. This applies whether the old name is for a built-in command, a custom function or a macro. When function() or macro() is called to define a new command, if a command already exists with that name, the undocumented CMake behavior is to make the old command available using the same name except with an underscore prepended. #Cmake function professional#
(The following explanation is largely extracted from the Functions And Macros chapter of the book Professional CMake: A Practical Guide) It relies on undocumented behavior to call through to the original implementation using _find_package(). Otherwise, the call should be forwarded to the original built-in find_package() command. If it is in that list, then it should be assumed that the package will be added to the project directly via add_subdirectory() and the find_package() call should do nothing.
#Cmake function code#
The intent behind the above block of CMake code is to redefine the built-in find_package() command such that it checks if the package to be found is one of those named in the as_subproject list variable. In the section of the talk where package management is discussed, the following example code is presented (around 52m38s): set(CMAKE_PREFIX_PATH "/prefix") The example in question relies on undocumented behavior, the dangers of which may not be immediately obvious and can lead to infinite recursion.
Message("# After change the value of arg.In this article, we take a closer look at a particular example from the popular Effective CMake talk by Dan Pfeifer.
Message("# After change the value of arg.") I wrote a sample code below: set(var "ABC")