Created
January 24, 2023 01:44
-
-
Save kfsone/cc31d7e2b20d7aec2e004e7c97f8296b to your computer and use it in GitHub Desktop.
Add PCH helper
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
include_guard (GLOBAL) | |
# ----------------------------------------------------------------------------- | |
# ADD_PRECOMPILED_HEADERS tells CMake to try and use the given header files as | |
# a list of pre-compiled headers for a given target (where supported), with | |
# language awareness. Default language is C++. | |
# | |
# It fully qualifies each of the headers with the BASE_DIR and it translates | |
# them into a list of generator expressions for the source language. | |
# | |
# Header files that end with "_inl.h" (inline implementations) will be ignored. | |
# | |
# include (AddPrecompiledHeaders.cmake) | |
# ADD_PRECOMPILED_HEADERS ( | |
# TARGET <name of existing target> | |
# [LANGUAGE [CXX [ | C | OBJC | OBJCXX]]] | |
# [BASE_DIR] # Default path for the listed headers, | |
# # assumes CMAKE_CURRENT_LIST_DIR if not specified | |
# HEADERS | |
# <list of filenames or paths) | |
# ) | |
# | |
# Example: | |
# | |
# cmake_minimum_required (VERSION 3.16) | |
# project (MyProj LANGUAGES C CXX OBJC) | |
# add_library ( | |
# MyLib | |
# mylib.cpp | |
# mylib.h | |
# common.cpp | |
# common.h | |
# private.cpp | |
# private.h | |
# ) | |
# include (AddPrecompiledHeaders.cmake) | |
# ADD_PRECOMPILED_HEADERS (TARGET MyLib HEADERS mylib.h common.h private.h) | |
# | |
# add_executable ( | |
# MyExe | |
# main.cpp | |
# common.h | |
# ) | |
# ADD_PRECOMPILED_HEADERS (TARGET MyExe HEADERS common.h) | |
# target_link_libraries ( | |
# MyExe | |
# PUBLIC MyLib | |
# ) | |
function (ADD_PRECOMPILED_HEADERS) | |
cmake_parse_arguments ( | |
"tgt" # Prefix | |
"" # Options | |
"TARGET;LANGUAGE;BASE_DIR" # One-valued keywords | |
"HEADERS" # Multi-valued keywords | |
${ARGN} # Arguments | |
) | |
# The list of languages we accept | |
set (languages C CXX OBJC OBJCXX) | |
# Argument validation | |
if (tgt_UNPARSED_ARGUMENTS) | |
message (SEND_ERROR "${tgt_TARGET}: Invalid arguments to ADD_PRECOMPILED_HEADERS: ${tgt_UNPARSED_ARGUMENTS}") | |
endif () | |
if (NOT tgt_HEADERS) | |
message (DEBUG "${tgt_TARGET}: HEADERS empty, not adding pch.") | |
endif () | |
if (NOT tgt_LANGUAGE) | |
set (tgt_LANGUAGE "CXX") | |
endif () | |
if (NOT tgt_LANGUAGE IN_LIST languages) | |
message (SEND_ERROR "${tgt_TARGET}: Unrecognized language: ${tgt_LANGUAGE}") | |
endif () | |
if (NOT tgt_BASE_DIR) | |
set (tgt_BASE_DIR "${CMAKE_CURRENT_LIST_DIR}") | |
endif () | |
if (NOT IS_DIRECTORY "${tgt_BASE_DIR}") | |
message (SEND_ERROR "${tgt_TARGET}: Invalid 'BASE_DIR': ${tgt_BASE_DIR}") | |
endif () | |
# Translate the local-relative list of header filenames into a list of fully | |
# qualified list of paths in ${headers}, as required by target_precompiled_headers. | |
set (headers "") | |
foreach (filename ${tgt_HEADERS}) | |
# Exclude inline implementation headers. | |
if (NOT filename MATCHES ".*_inl.h") | |
get_filename_component (header ${filename} ABSOLUTE BASE_DIR ${tgt_BASE_DIR}) | |
if (NOT EXISTS ${header}) | |
message (SEND_ERROR "${tgt_TARGET}: ${filename} does not exist.") | |
endif () | |
list (APPEND headers ${header}) | |
endif () | |
endforeach () | |
# Did we find anything meaningful? | |
if (headers) | |
message (VERBOSE "${tgt_TARGET}: Adding C++ precompiled headers: ${tgt_HEADERS}") | |
target_precompile_headers (${tgt_TARGET} PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${headers}>) | |
endif () | |
endfunction () |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment