如何在cmake中定义宏内的函数

ale*_*des 3 cmake

我一直在一个使用 cmake 的软件项目中工作,其中文件结构如下所示:

  • cmake
  • 测试
  • 建造
  • 源代码
    • 模块1
    • 模块2
    • 模块3
      • 子模块1
      • 子模块2
        • 暗示
          • 后端1
          • 后端2

每个文件夹都包含一个 CMakeLists.txt,这基本上会将更多文件添加到 src 文件夹中 CMakeLists.txt 中定义的源代码文件列表中。问题是,使用 PARENT_SCOPE 将所有这些变量沿着作用域堆栈传递是不切实际的,因此我们使用属性来实现这一点。

它运行良好,直到我们决定为了简化测试,将每个子模块构建在静态库上会很有用。所以我一直在使用一个如下所示的宏:

macro(define_build_unit unit_name unit_root)
  function(${unit_name}_add_sources)
    message(STATUS ${ARGN})
    file(RELATIVE_PATH _relPath ${unit_root} "${CMAKE_CURRENT_SOURCE_DIR}")
    foreach(_src ${ARGN})
      if(_relPath)
        list(APPEND ${unit_name}_SRCS "${_relPath}/${_src}")
      else()
        list(APPEND ${unit_name}_SRCS "${_src}")
      endif()
    endforeach()
    if(_relPath)
      set_property(GLOBAL APPEND PROPERTY ${unit_name}_SRCS ${${unit_name}_SRCS})
    endif()
  endfunction()

  function(${unit_name}_add_link_deps)
    foreach(_dep ${ARGN})
      list(APPEND ${unit_name}_DEPS "${_dep}")
    endforeach()
    set_property(GLOBAL APPEND PROPERTY ${unit_name}_DEPS ${${unit_name}_DEPS})
  endfunction()

  function(${unit_name}_add_include_dirs)
    foreach(_inc ${ARGN})
      list(APPEND ${unit_name}_INC_DIRS "${_inc}")
    endforeach()
    set_property(GLOBAL APPEND PROPERTY ${unit_name}_INC_DIRS ${${unit_name}_INC_DIRS})
  endfunction()
endmacro()
Run Code Online (Sandbox Code Playgroud)

问题是 ARGN 是从 Define_build_unit 宏中替换的,而不是从相应的函数中替换的。我已经尝试了宏/函数的所有组合,但似乎没有任何效果。

所以,问题是:cmake 中的变量参数是否有比 ARGN 全局变量更好的方法?像宏(my_macro args ...)之类的东西?如果没有,有人知道完成相同任务的等效方法吗?

小智 6

这个问题已经被接受,但是,就我而言,我确实需要在宏内部包含函数定义。原因?我想根据宏参数以编程方式生成专用函数。这意味着利用宏的文本替换功能,同时生成动态创建的函数,然后可以在构建的其余部分中使用该函数。

macro(build_my_func func_name)
    message(${ARGV})
    function(my_${func_name})
        set(func_ARGV ARGV)
        message(${${func_ARGV}})
    endfunction()
endmacro()
Run Code Online (Sandbox Code Playgroud)

“技巧”是在函数内设置一个变量,其中包含要访问的变量的名称,在本例中为ARGV。然后,它可以作为变量-变量来访问,即:${${func_ARGV}}。在本例中,内部变量${func_ARGV}被替换为 ARGV,最终解析为${ARGV}

这是一种解决方法,但可以是访问外部宏可能消除的任何变量的有用方法。它还可用于将宏参数缓存为要在函数中使用的值,以自定义其行为。