Проверка включения заголовка - CMake

Я хочу получить поведение в CMake похожее на функцию в Bazel cc_library. Вот описание.

У меня есть директория, в которой лежат несколько файлов.

explorer/a.h
explorer/b.h

Я хочу создать библиотеки

  • a_lib состоит из a.h
  • b_lib состоит из b.h и a_lib

Для этого я написал функцию function(mi_cc_library).

explorer/a.h

struct a {
  int _a;
};

explorer/b.h

#include "explorer/a.h"

struct b {
  a   _a;
  int _b;
};

В CMake просто создаю две библиотеки.


Ситуация 1.

# explorer/CMakeLists.txt

mi_cc_library(
  NAME a_iib
  SRCS a.h
)

mi_cc_library(
  NAME b_iib
  SRCS b.h
  DEPS a_lib
)

Должна быть ошибка, файл a.h приватный в a_lib (потому что в SRCS) и не подключен к b_lib.


Ситуация 2.

# explorer/CMakeLists.txt

mi_cc_library(
  NAME a_lib
  HDRS a.h
)

mi_cc_library(
  NAME b_lib
  SRCS b.h
  DEPS a_lib
)

В a_lib файл a.h открытый (потому что в HDRS), ошибок нет.


Ситуация 3.

# explorer/CMakeLists.txt

mi_cc_library(
  NAME a_lib
  SRCS a.h
)

mi_cc_library(
  NAME b_lib
  SRCS a.h b.h
  DEPS a_lib
)

В a_lib файл a.h приватный (потому что в SRCS), но он подключен напрямую к b_lib, ошибок нет.


Проблема в том, что если я реализую mi_cc_library примерно так, то к библиотеке добавляется полностью вся папка с исходниками, тогда все *.h файлы ей доступны вне зависимости от того, подключал ли я их в HDRS или SRCS.

function(mi_cc_library)
  cmake_parse_arguments(
    _RULE
    "PUBLIC;TESTONLY;SHARED"
    "NAME;WINDOWS_DEF_FILE"
    "HDRS;TEXTUAL_HDRS;SRCS;COPTS;DEFINES;LINKOPTS;DATA;DEPS;INCLUDES"
    ${ARGN}
  )

  if(NOT _RULE_IS_INTERFACE)
  ...
  else()
    # Generating header-only library.
    add_library(${_NAME} INTERFACE)
    target_include_directories(${_NAME} SYSTEM
      INTERFACE
        "$<BUILD_INTERFACE:${MI_SOURCE_DIR}>"
        "$<BUILD_INTERFACE:${MI_BINARY_DIR}>"
    )
    target_link_libraries(${_NAME}
      INTERFACE
        ${_RULE_DEPS}
    )
    _mi_cc_library_add_object_deps(${_NAME} ${_RULE_DEPS})
    mi_add_data_dependencies(NAME ${_NAME} DATA ${_RULE_DATA})
    target_compile_definitions(${_NAME}
      INTERFACE
        ${_RULE_DEFINES}
    )
  endif()
endfunction()

Ответы (0 шт):