web-dev-qa-db-ja.com

CMakeでプリコンパイル済みヘッダーを使用する

CMakeのプリコンパイル済みヘッダーのサポートをまとめてハッキングすることについて、 'ネット上でいくつかの(古い)投稿を見てきました。それらはすべて、その場所全体で少し見えますし、誰もがそれを行う独自の方法を持っています。現在、それを行う最善の方法は何ですか?

96
Glutinous

「Cotire」という名前のサードパーティCMakeモジュール があり、CMakeベースのビルドシステムのプリコンパイル済みヘッダーの使用を自動化し、ユニティビルドもサポートします。

73
sakra

次のマクロを使用してプリコンパイル済みヘッダーを生成および使用しています。

MACRO(ADD_MSVC_PRECOMPILED_HEADER PrecompiledHeader PrecompiledSource SourcesVar)
  IF(MSVC)
    GET_FILENAME_COMPONENT(PrecompiledBasename ${PrecompiledHeader} NAME_WE)
    SET(PrecompiledBinary "${CMAKE_CURRENT_BINARY_DIR}/${PrecompiledBasename}.pch")
    SET(Sources ${${SourcesVar}})

    SET_SOURCE_FILES_PROPERTIES(${PrecompiledSource}
                                PROPERTIES COMPILE_FLAGS "/Yc\"${PrecompiledHeader}\" /Fp\"${PrecompiledBinary}\""
                                           OBJECT_OUTPUTS "${PrecompiledBinary}")
    SET_SOURCE_FILES_PROPERTIES(${Sources}
                                PROPERTIES COMPILE_FLAGS "/Yu\"${PrecompiledHeader}\" /FI\"${PrecompiledHeader}\" /Fp\"${PrecompiledBinary}\""
                                           OBJECT_DEPENDS "${PrecompiledBinary}")  
    # Add precompiled header to SourcesVar
    LIST(APPEND ${SourcesVar} ${PrecompiledSource})
  ENDIF(MSVC)
ENDMACRO(ADD_MSVC_PRECOMPILED_HEADER)

すべてのソースファイルに変数$ {MySources}があるとします。使用するコードは次のようになります。

ADD_MSVC_PRECOMPILED_HEADER("precompiled.h" "precompiled.cpp" MySources)
ADD_LIBRARY(MyLibrary ${MySources})

コードは、非MSVCプラットフォームでも正常に機能します。きれいです:)

34
larsmoa

以下は、プロジェクトにプリコンパイル済みヘッダーを使用できるようにするためのコードスニペットです。必要に応じてmyprecompiledheadersmyproject_SOURCE_FILESを置き換えて、CMakeLists.txtに次を追加します。

if (MSVC)

    set_source_files_properties(myprecompiledheaders.cpp
        PROPERTIES
        COMPILE_FLAGS "/Ycmyprecompiledheaders.h"
        )
    foreach( src_file ${myproject_SOURCE_FILES} )
        set_source_files_properties(
            ${src_file}
            PROPERTIES
            COMPILE_FLAGS "/Yumyprecompiledheaders.h"
            )
    endforeach( src_file ${myproject_SOURCE_FILES} )
    list(APPEND myproject_SOURCE_FILES myprecompiledheaders.cpp)
endif (MSVC)
20
Dave Hillier

最終的に、larsmマクロの適応バージョンを使用しました。 pchパスに$(IntDir)を使用すると、デバッグ用とビルド用のプリコンパイル済みヘッダーが別々に保持されます。

MACRO(ADD_MSVC_PRECOMPILED_HEADER PrecompiledHeader PrecompiledSource SourcesVar)
  IF(MSVC)
    GET_FILENAME_COMPONENT(PrecompiledBasename ${PrecompiledHeader} NAME_WE)
    SET(PrecompiledBinary "$(IntDir)/${PrecompiledBasename}.pch")
    SET(Sources ${${SourcesVar}})

    SET_SOURCE_FILES_PROPERTIES(${PrecompiledSource}
                                PROPERTIES COMPILE_FLAGS "/Yc\"${PrecompiledHeader}\" /Fp\"${PrecompiledBinary}\""
                                           OBJECT_OUTPUTS "${PrecompiledBinary}")
    SET_SOURCE_FILES_PROPERTIES(${Sources}
                                PROPERTIES COMPILE_FLAGS "/Yu\"${PrecompiledHeader}\" /FI\"${PrecompiledHeader}\" /Fp\"${PrecompiledBinary}\""
                                           OBJECT_DEPENDS "${PrecompiledBinary}")  
    # Add precompiled header to SourcesVar
    LIST(APPEND ${SourcesVar} ${PrecompiledSource})
  ENDIF(MSVC)
ENDMACRO(ADD_MSVC_PRECOMPILED_HEADER)

ADD_MSVC_PRECOMPILED_HEADER("stdafx.h" "stdafx.cpp" MY_SRCS)
ADD_EXECUTABLE(MyApp ${MY_SRCS})
13
jari

Daveから適応しましたが、より効率的です(各ファイルではなく、ターゲットプロパティを設定します)。

if (MSVC)
   set_target_properties(abc PROPERTIES COMPILE_FLAGS "/Yustd.h")
   set_source_files_properties(std.cpp PROPERTIES COMPILE_FLAGS "/Ycstd.h")
endif(MSVC)
12
martjno

車輪を再発明したくない場合は、上の回答が示すようにCotireを使用するか、より単純なものを使用してください-cmake-precompiled-headerここ 。それを使用するには、モジュールをインクルードして呼び出します:

include( cmake-precompiled-header/PrecompiledHeader.cmake )
add_precompiled_header( targetName StdAfx.h FORCEINCLUDE SOURCE_CXX StdAfx.cpp )
7
Roman Kruglov

私見の最良の方法は、martjnoが示唆したように、プロジェクト全体にPCHを設定することであり、必要に応じていくつかのソース(生成されたソースなど)のPCHを無視する機能と組み合わせます:

# set PCH for VS project
function(SET_TARGET_PRECOMPILED_HEADER Target PrecompiledHeader PrecompiledSource)
  if(MSVC)
     SET_TARGET_PROPERTIES(${Target} PROPERTIES COMPILE_FLAGS "/Yu${PrecompiledHeader}")
     set_source_files_properties(${PrecompiledSource} PROPERTIES COMPILE_FLAGS "/Yc${PrecompiledHeader}")
  endif(MSVC)
endfunction(SET_TARGET_PRECOMPILED_HEADER)

# ignore PCH for a specified list of files
function(IGNORE_PRECOMPILED_HEADER SourcesVar)
  if(MSVC)  
    set_source_files_properties(${${SourcesVar}} PROPERTIES COMPILE_FLAGS "/Y-")
  endif(MSVC)
endfunction(IGNORE_PRECOMPILED_HEADER)

したがって、ターゲットMY_TARGETがあり、生成されたソースのリストIGNORE_PCH_SRC_LISTがある場合は、次のようにします。

SET_TARGET_PRECOMPILED_HEADER(MY_TARGET stdafx.h stdafx.cpp)
IGNORE_PRECOMPILED_HEADER(IGNORE_PCH_SRC_LIST)

このアプローチはテストされ、完全に機能します。

4
Vram Vardanian

CmakeとVisual Studio 2015を使用したプリコンパイル済みヘッダーの使用例

「stdafx.h」、「stdafx.cpp」-プリコンパイル済みヘッダー名。

以下をルートcmakeファイルに追加します。

if (MSVC)
    # For precompiled header.
    # Set 
    # "Precompiled Header" to "Use (/Yu)"
    # "Precompiled Header File" to "stdafx.h"
    set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Yustdafx.h /FIstdafx.h")
endif()

プロジェクトのcmakeファイルに以下を追加します。

「src」-ソースファイルのあるフォルダー。

set_source_files_properties(src/stdafx.cpp
    PROPERTIES
    COMPILE_FLAGS "/Ycstdafx.h"
)
4
Maks

さて、プロジェクトファイルの1行を変更するたびにクアッドコアマシンでビルドに10分以上かかると、Windows用のプリコンパイル済みヘッダーを追加する時間がわかります。 * nuxでは、ccacheを使用するだけで、心配する必要はありません。

私はメインアプリケーションとそれが使用するいくつかのライブラリに実装しました。ここまではうまくいきます。また、必要なことの1つは、pchソースとヘッダーファイルを作成し、ソースファイルにプリコンパイルするすべてのヘッダーを含める必要があることです。私はMFCで12年間これをしましたが、それを思い出すのに数分かかりました。

0
John M Drescher

CMakeはPCHのサポートを獲得しました。2019-10-01に予定されている3.16リリースで利用可能になるはずです。

https://gitlab.kitware.com/cmake/cmake/merge_requests/355

  target_precompile_headers(<target>
    <INTERFACE|PUBLIC|PRIVATE> [header1...]
    [<INTERFACE|PUBLIC|PRIVATE> [header2...] ...])

ターゲット間でのPCHの共有のサポートに関する継続的な議論があります: https://gitlab.kitware.com/cmake/cmake/issues/19659

https://blog.qt.io/blog/2019/08/01/precompiled-headers-and-unity-jumbo-builds-in-upcoming-で利用可能な追加のコンテキスト(動機、数字)がありますcmake /

0
janisozaur

最もクリーンな方法は、プリコンパイル済みオプションをグローバルオプションとして追加することです。 vcxprojファイルでは、これは<PrecompiledHeader>Use</PrecompiledHeader>そして、個々のファイルごとにこれを行うわけではありません。

次に、CreateオプションをStdAfx.cppに追加する必要があります。以下は私がそれを使用する方法です:

MACRO(ADD_MSVC_PRECOMPILED_HEADER SourcesVar)
    SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /YuStdAfx.h")
    set_source_files_properties(StdAfx.cpp
        PROPERTIES
        COMPILE_FLAGS "/YcStdAfx.h"
        )
    list(APPEND ${${SourcesVar}} StdAfx.cpp)
ENDMACRO(ADD_MSVC_PRECOMPILED_HEADER)

file(GLOB_RECURSE MYDLL_SRC
    "*.h"
    "*.cpp"
    "*.rc")

ADD_MSVC_PRECOMPILED_HEADER(MYDLL_SRC)
add_library(MyDll SHARED ${MYDLL_SRC})

これはテストされ、MSVC 2010で機能し、MyDll.pchファイルを作成します。使用するファイル名はわからないので、指定する努力はしませんでした。

0
uncletall

プリコンパイル済みヘッダーオプションはrcファイルでは機能しないため、jariが提供するマクロを調整する必要がありました。

#######################################################################
# Makro for precompiled header
#######################################################################
MACRO(ADD_MSVC_PRECOMPILED_HEADER PrecompiledHeader PrecompiledSource SourcesVar)
  IF(MSVC)
    GET_FILENAME_COMPONENT(PrecompiledBasename ${PrecompiledHeader} NAME_WE)
    SET(PrecompiledBinary "$(IntDir)/${PrecompiledBasename}.pch")
    SET(Sources ${${SourcesVar}})

    # generate the precompiled header
    SET_SOURCE_FILES_PROPERTIES(${PrecompiledSource}
                                PROPERTIES COMPILE_FLAGS "/Zm500 /Yc\"${PrecompiledHeader}\" /Fp\"${PrecompiledBinary}\""
                                            OBJECT_OUTPUTS "${PrecompiledBinary}")

    # set the usage of this header only to the other files than rc
    FOREACH(fname ${Sources})
        IF ( NOT ${fname} MATCHES ".*rc$" )
            SET_SOURCE_FILES_PROPERTIES(${fname}
                                        PROPERTIES COMPILE_FLAGS "/Zm500 /Yu\"${PrecompiledHeader}\" /FI\"${PrecompiledHeader}\" /Fp\"${PrecompiledBinary}\""
                                                    OBJECT_DEPENDS "${PrecompiledBinary}")
        ENDIF( NOT ${fname} MATCHES ".*rc$" )
    ENDFOREACH(fname)

    # Add precompiled header to SourcesVar
    LIST(APPEND ${SourcesVar} ${PrecompiledSource})
  ENDIF(MSVC)
ENDMACRO(ADD_MSVC_PRECOMPILED_HEADER)

編集:このプリコンパイル済みヘッダーを使用すると、メインプロジェクトの全体的なビルド時間が4分30秒から1分40秒に短縮されました。これは私にとって本当に良いことです。プリコンパイルヘッダーには、boost/stl/Windows/mfcなどのヘッダーのみがあります。

0
schorsch_76