7

設定

CMake で正常にビルドおよび実行されるプロジェクトがあります。私のプロジェクト設定は次のようなものです:

├── CMakeLists.txt
|
├── include/
│   └── standalone/
│       └── x.hpp
|
├── src/
    └── standalone/
        └── main.cpp

私のヘッダーの内容は次のようなものです:

// ------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();
}

私は以下を使用します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})

mkdir buildコマンド、cd buildcmake ..make、およびのシーケンスは、 ./main「Hello World!」を正しく出力します。警告なし。

問題

上記の設定は正しいです。しかし、含まれていたので<iostream>はなく、含まれてx.hppいたとしmain.cppます。その後、プログラムは正しくビルドされx.hppますが、スタンドアロン ヘッダーにはなりません。したがって、ヘッダーの自給自足をテストしたいと思います。つまり、ヘッダーごとに小さなテストプログラムをコンパイルしたいと思います

#include "some_header.hpp"
int main() {}

ただし、次のセクションを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)

マクロ${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.

質問

どうやら、CMake が適切な場所で検索できるようにする構成変数がいくつかありません。正しいヘッダーであってもcheck_include_files()機能しません。これを機能させるにはどうすればよいですか? 正しいヘッダーが正しいと見なされた場合にのみ、正しくないヘッダーをテストできます。

絶対に必要な場合を除き、シェル スクリプトや、直接呼び出しを行う複雑な CMake for ループなどには興味がありませんTRY_COMPILE。AFAICS、それがCheckIncludeFilesモジュールの目的です。可能であれば、それを正しく構成する方法を知りたいです。

4

2 に答える 2

6

C ヘッダーではなく C++ ヘッダーの場合は、CheckIncludeFileCXX. CheckIncludeFilesこのモジュールは、一度に 1 つのファイルしかこのマクロに渡せないという点でも異なります。

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()

CMake wiki 記事How To Write Platform Checksにもう少し情報があります。

于 2013-05-07T22:31:52.037 に答える
1

出力を閲覧した後、許可された構成オプションでは克服できないCMakeFiles/CMakeError.log2つの基本的な制限があるようです(これらの点の確認があるようです):check_include_files()

  1. C++ コンパイラではなく、常に C コンパイラが呼び出されますこれは、-std=C++11渡す有効なコマンド ライン オプションではないことを意味します。
  2. で手動で追加しても、標準のシステム インクルード パス (/usr/includeなど)は無視されset(CMAKE_REQUIRED_INCLUDES ${CMAKE_SOURCE_DIR}/include "/usr/include")ます。したがって、#include <iostream>内部x.hppは正しく検出されません。

エラー ログには次のフラグメントがあります。

/usr/bin/gcc   -I/home/rein/projects/standalone/include    -o CMakeFiles/cmTryCompileExec4052324189.dir/CheckIncludeFiles.c.o   -c /home/rein/projects/standalone/build/CMakeFiles/CMakeTmp/CheckIncludeFiles.c
In file included from /home/rein/projects/standalone/build/CMakeFiles/CMakeTmp/CheckIncludeFiles.c:2:0:
/home/rein/projects/standalone/include/standalone/x.hpp:2:20: fatal error: iostream: No such file or directory
compilation terminated.

これは本質的に、自己充足性をチェックするという考えをシステム C ヘッダーに制限します。このSO の質問など、シェル スクリプトの代替手段を探す必要があるようです。

更新: @Fraser の更新された回答のおかげで、私の質問はcheck_include_file_cxx、コンパイラ フラグとインクルード パスを事前に設定することで解決されるようになりました。

于 2013-05-08T18:15:12.997 に答える