Skip to content

Precompiled Headers

Mael Rouxel-Labbé edited this page Mar 28, 2024 · 1 revision

Introduction

Precompiled Headers (PCH) are headers that has been compiled in a form that is faster to use for the compiler. They are under the form of a file that has the extension .pch, or .gch, and are a mean to accelerate compilation of a program that use large headers several times.

Usage

In cmake, since version 3.16, precompiled headers are created using the function target_precompile_headers(). It should be used for a single target, that uses many sources that will share several header files. Those header files are given as a list of paths to the function. Note that targets that depend on the one given to target_precompile_headers will not beneficit the PCH.

It is also possible, under certain circumstances, to use precompiled headers declared for other targets. To do so, the same function is used, but is given the option REUSE_FROM and another target, which is already using PCH, that will be shared with target.
Note that this requires both targets to share the same set of compiler options, compiler flags and compiler definitions, which is undoubtedly a heavy restriction.
Moreover, in usage with Qt moc system, a bug prevents the rcc, uic and moc commands to be ran on sources of a target that uses PCH the first time cmake is called. It means cmake must be called twice for it to work, but fortunately this bug has been fixed in version 3.18.
For more information, please visit the documentation of cmake regarding this function: https://cmake.org/cmake/help/v3.16/command/target_precompile_headers.html

Examples

Following examples come from the Polyhedron Demo.

Classic usage

We give a list of headers to precompile for use with the existing target demo_framework.

target_precompile_headers(demo_framework PRIVATE
  <QApplication>
  <QMainWindow>
  <QAction>
  <QMessageBox>
  <QObject>
  <QMenu>
  <QString>
  <vector>
  )

Usage of REUSE_FROM

We create a dummy library called PCA_headers based on a dummy cpp source file, containing a single comment to avoid a warning. This source file allows cmake to detect the language used (c++). Then, we declare the list of headers that we want to recompile, and we add the same compiler flags that our plugins use to make the pch compatible. Finally, we specify for each concerned plugin that they must reuse an existing PCH :

add_library(PMP_headers_eigen_las pmp_headers.cpp)
target_precompile_headers(PMP_headers_eigen_las PUBLIC
  [["Scene.h"]]
  [["Scene_surface_mesh_item.h"]]
  [["Scene_points_with_normal_item.h"]]
  [["Messages_interface.h"]]
  [["Scene_polylines_item.h"]]
  [["config.h"]]
  [["Scene_polyhedron_selection_item.h"]]
  <QApplication>
  <CGAL/Three/Three.h>
  <QMainWindow>
  <QAction>
  <CGAL/Three/Polyhedron_demo_plugin_interface.h>
  <QMessageBox>
  <CGAL/Three/Polyhedron_demo_plugin_helper.h>
  <QInputDialog>
  <QObject>
  <CGAL/Three/Viewer_interface.h>
  <fstream>
  <QElapsedTimer>
  <CGAL/Three/Triangle_container.h>
  <QtPlugin>
  <CGAL/Three/Edge_container.h>
  <QtCore/qglobal.h>
  <CGAL/Timer.h>
  <vector>
  <Kernel_type.h>
  <QMenu>
  <algorithm>
  <QString>
  )

  if(TARGET CGAL::TBB_support)
    target_link_libraries(PMP_headers_eigen_las PUBLIC CGAL::TBB_support)
  endif()
  if(TARGET CGAL::Eigen_support)
    target_link_libraries(PMP_headers_eigen_las PUBLIC CGAL::Eigen_support)
  endif()

  if (TARGET CGAL::LASLIB_support)
    target_link_libraries(PMP_headers_eigen_las PUBLIC CGAL::LASLIB_support)
    if (MSVC)
      target_compile_definitions( PMP_headers_eigen_las PUBLIC "-D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS")
    endif()
  endif()

foreach(tgt
  orient_soup_plugin
  point_inside_polyhedron_plugin
  selection_plugin
  surface_intersection_plugin
  )
    target_precompile_headers(${tgt} REUSE_FROM PMP_headers_eigen_las)
  endforeach()
Clone this wiki locally