我有一个CMake-include文件,它覆盖了内置的add_executable
函数,我想找出一种透明的方法,这样,如果另一个文件包括这个文件,但也覆盖了add_executable
,它的行为就像它们与真正的add_executable
交互一样。这里有一个最小的CMakeLists.txt演示了这个问题。
cmake_minimum_required(VERSION 3.18)
project(interposition LANGUAGES C)
function(add_executable)
message(STATUS "Inside of ${CMAKE_CURRENT_FUNCTION}")
_add_executable(${ARGV})
endfunction()
function(add_executable)
message(STATUS "Inside of the second copy of ${CMAKE_CURRENT_FUNCTION}")
_add_executable(${ARGV})
endfunction()
add_executable(main main.c)
这样写的想法是,每个_add_executable
符号都将引用add_executable
的先前定义。事实上,这会导致它进入一个无限循环,在这个循环中,函数的第一个版本调用自己:
-- Inside of the second copy of add_executable
-- Inside of add_executable
-- Inside of add_executable
-- Inside of add_executable
...
如果我将第一个函数更改为调用__add_executable()
(带有两个下划线(,它会显示:
-- Inside of the second copy of add_executable
-- Inside of add_executable
CMake Error at CMakeLists.txt:6 (__add_executable):
Unknown CMake command "__add_executable".
Call Stack (most recent call first):
CMakeLists.txt:11 (_add_executable)
CMakeLists.txt:14 (add_executable)
如果我将第一个函数重命名为_add_executable()
,并同时调用两个下划线的版本,那么它甚至不会被调用:
-- Inside of the second copy of add_executable
-- Configuring done
这是我最期待的一个可能工作(将_add_executable()
更改为cmake_language(CALL ...)
cmake_minimum_required(VERSION 3.18)
project(interposition LANGUAGES C)
function(add_executable)
message(STATUS "Inside of ${CMAKE_CURRENT_FUNCTION}")
cmake_language(CALL _${CMAKE_CURRENT_FUNCTION} ${ARGV})
endfunction()
function(add_executable)
message(STATUS "Inside of the second copy of ${CMAKE_CURRENT_FUNCTION}")
cmake_language(CALL _${CMAKE_CURRENT_FUNCTION} ${ARGV})
endfunction()
add_executable(main main.c)
事实上,这进入了与原始示例相同的无限循环。
我最接近的方法是用一个下划线将前缀重命名为第二个函数,并调用其中的双下划线版本,但这意味着这些函数以错误的顺序相互调用,并抛出了透明工作的想法。
有没有办法让
- 函数的第二个副本调用第一个副本AND
- 第二个副本不需要知道第一个副本的存在吗
感谢Tsyvarev为我指明了正确的方向。他的链接让我看到了这个帖子,解释说该功能不受支持,而且从未打算存在,还有Craig Scott的这篇文章,它证实了多个重写将使真正的函数无法访问。
这是一个非常不令人满意的答案,但知道这是CMake开发人员的官方立场是很有帮助的。