如何让CMake检查我的标题是否自给自足?

Tem*_*Rex 5 c++ cmake header-files buildconfiguration build-dependencies

建立

我有一个使用CMake构建并运行良好的项目.我的项目设置如下:

??? CMakeLists.txt
|
??? include/
?   ??? standalone/
?       ??? x.hpp
|
??? src/
    ??? standalone/
        ??? main.cpp
Run Code Online (Sandbox Code Playgroud)

我的标题的内容是这样的:

// ------x.hpp--------
#pragma once
#include <iostream>

class X
{
public:
  void hello()
  {
    std::cout << "Hello World!\n"; // needs <iostream>
  }
};

// -------main.cpp-------
#include <standalone/x.hpp>

int main()
{
  X x;
  x.hello();
}
Run Code Online (Sandbox Code Playgroud)

我使用以下内容 CMakeLists.txt

cmake_minimum_required(VERSION 2.8)
project(standalone)

###############################################################
# Compiler settings
###############################################################

# use C++11 features
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")

# set warning level
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -pedantic -pedantic-errors -Wall -Wextra")

###############################################################
# header dependencies
###############################################################

# compile against project headers
include_directories(${PROJECT_SOURCE_DIR}/include)

# the header files
file(GLOB_RECURSE header_files FOLLOW_SYMLINKS "include/*.hpp")

# the source files
file(GLOB_RECURSE source_files FOLLOW_SYMLINKS "src/*.cpp")

###############################################################
# build target
###############################################################

# the program depends on the header files and the source files
add_executable(main ${header_files} ${source_files})
Run Code Online (Sandbox Code Playgroud)

命令序列mkdir build,cd build, cmake ..,make,和./main正确地输出"Hello World!" 没有警告.

问题

以上设置是正确的.但是假设<iostream>不包括在内,x.hpp而是包含在内main.cpp.然后程序仍然可以正确构建,但x.hpp不会是一个独立的头.所以我想测试我的标题的自给自足,即对于每个标题我想编译一个小的测试程序

#include "some_header.hpp"
int main() {}
Run Code Online (Sandbox Code Playgroud)

但是,如果我将以下部分添加到 CMakeList.txt

###############################################################
# header self-sufficiency
###############################################################

set(CMAKE_REQUIRED_FLAGS ${CMAKE_CXX_FLAGS})
message("REQUIRED_FLAGS=${CMAKE_REQUIRED_FLAGS}")
set(CMAKE_REQUIRED_INCLUDES ${CMAKE_SOURCE_DIR}/include)
message("REQUIRED_INCLUDES=${CMAKE_REQUIRED_INCLUDES}")
include(CheckIncludeFiles)
check_include_files("${header_files}" IS_STANDALONE)
Run Code Online (Sandbox Code Playgroud)

${header_files}正确扩展到标头x.hpp,但check_include_files()命令无法正确编译它

REQUIRED_FLAGS= -std=c++11 -Werror -pedantic -pedantic-errors -Wall -Wextra
REQUIRED_INCLUDES=/home/rein/projects/standalone/include
-- Looking for include file /home/rein/projects/standalone/include/standalone/x.hpp
-- Looking for include file /home/rein/projects/standalone/include/standalone/x.hpp - not found.
Run Code Online (Sandbox Code Playgroud)

显然我错过了一些配置变量,让CMake在正确的位置搜索.即使是正确的标题,check_include_files()也行不通.我需要做些什么来完成这项工作?只有当正确的标题被认为是正确的时候,我才能继续测试不正确的标题.

注意除非绝对必要,否则我对shell脚本或者直接调用CMake for循环TRY_COMPILE或类似的东西不感兴趣.AFAICS,这就是CheckIncludeFiles模块的用途,我想知道如何正确配置它,如果可能的话.

Fra*_*ser 5

对于C++标头而不是C标头,您需要使用CheckIncludeFileCXX.此模块的不同之处CheckIncludeFiles在于,您一次只能将一个文件传递给此宏.

也可能是您需要设置CMAKE_REQUIRED_INCLUDES或文档中列出的其他变量之一.

例如,如果您的某些标题引用彼此(如#include "h1.hpp"),那么您将需要:

set(CMAKE_REQUIRED_FLAGS ${CMAKE_CXX_FLAGS})
set(CMAKE_REQUIRED_INCLUDES ${CMAKE_SOURCE_DIR}/include)
include(CheckIncludeFileCXX)
foreach(project_header ${project_headers})
  get_filename_component(header_name ${project_header} NAME_WE)
  check_include_file_cxx("${project_header}" ${header_name}_IS_STANDALONE)
endforeach()
Run Code Online (Sandbox Code Playgroud)

在CMake wiki文章如何编写平台检查中有更多信息.