-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
21 changed files
with
322 additions
and
79 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,7 +5,7 @@ | |
!include/ | ||
!py/ | ||
!test/ | ||
!tool/ | ||
!cmake/ | ||
!.clang-format | ||
!.clang-tidy | ||
!.gitignore | ||
|
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
include(NormalizePath) | ||
|
||
# `properties_genexpr(<OUTPUT> <TARGET> <PROPERTIES...>)` | ||
# | ||
# Build a generator expression that expresses `(<property name from PROPERTIES> | ||
# <corresponding property value of TARGET>)...` and store it in `OUTPUT` | ||
function(properties_genex OUTPUT TARGET) | ||
foreach(PROP IN LISTS ARGN) | ||
list(APPEND RETVAL ${PROP} $<TARGET_PROPERTY:${TARGET},${PROP}>) | ||
endforeach() | ||
|
||
set(${OUTPUT} | ||
${RETVAL} | ||
PARENT_SCOPE) | ||
endfunction() | ||
|
||
# `is_source_of_target_genex(<OUTPUT> <TARGET> <FILE>)` | ||
# | ||
# Build a generator expression that checks whether `FILE` is a source of | ||
# `TARGET` and store it in `OUTPUT` | ||
function(is_source_of_target_genex OUTPUT TARGET FILE) | ||
normalize_path(FILE) | ||
|
||
set(SOURCES_GENEX $<TARGET_PROPERTY:${TARGET},SOURCES>) | ||
set(SOURCE_DIR_GENEX $<TARGET_PROPERTY:${TARGET},SOURCE_DIR>) | ||
set(ABSOLUTE_SOURCES_GENEX | ||
$<PATH:ABSOLUTE_PATH,NORMALIZE,${SOURCES_GENEX},${SOURCE_DIR_GENEX}>) | ||
set(FIND_FILE_IN_SOURCES_GENEX $<LIST:FIND,${ABSOLUTE_SOURCES_GENEX},${FILE}>) | ||
|
||
set(${OUTPUT} | ||
"$<NOT:$<EQUAL:${FIND_FILE_IN_SOURCES_GENEX},-1>>" | ||
PARENT_SCOPE) | ||
endfunction() |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
include(NormalizePath) | ||
include(Genex) | ||
include(ScriptAsCommand) | ||
include(Paths) | ||
|
||
set(LINTING_PROPERTIES | ||
INCLUDE_DIRECTORIES | ||
INTERFACE_INCLUDE_DIRECTORIES | ||
COMPILE_DEFINITIONS | ||
INTERFACE_COMPILE_DEFINITIONS | ||
COMPILE_FEATURES | ||
INTERFACE_COMPILE_FEATURES | ||
COMPILE_OPTIONS | ||
INTERFACE_COMPILE_OPTIONS) | ||
|
||
define_property( | ||
TARGET | ||
PROPERTY LINT_COMPLETION_MARKERS | ||
BRIEF_DOCS "List of files which indicates linting operation completion" | ||
FULL_DOCS "A target created by `add_lint_target()` will depend on these \ | ||
files. See `add_lint_target()` and `target_lintables()` respective \ | ||
documentations to learn how this property is populated.") | ||
|
||
define_property( | ||
TARGET | ||
PROPERTY LINTER_COMMAND | ||
BRIEF_DOCS "Command to invoke when linting" | ||
FULL_DOCS | ||
"The command is run when a target created by `add_lint_target()` is built.") | ||
|
||
# `add_lint_target(<NAME> <LINTABLE_TARGET> <COMMAND...>)` | ||
# | ||
# Create the target `NAME` that lints the executable or library | ||
# `LINTABLE_TARGET` with `COMMAND...` | ||
# | ||
# When `NAME` is built, `COMMAND...` is invoked on each source file of | ||
# `LINTABLE_TARGET` that currently appears in its `SOURCES` property (sources | ||
# added after will NOT be linted if not added with `target_lintables()`). | ||
# `COMMAND...` is stored in the `LINTER_COMMAND` property of `NAME`. | ||
# | ||
# Linting-related properties of `LINTABLE_TARGET` are transfered to `NAME` | ||
# (those are listed in `LINTING_PROPERTIES`). | ||
# | ||
# See `target_lintable()` for more information. | ||
function(add_lint_target NAME LINTABLE_TARGET) | ||
add_custom_target(${NAME} | ||
DEPENDS $<TARGET_PROPERTY:${NAME},LINT_COMPLETION_MARKERS>) | ||
|
||
set_property(TARGET ${NAME} PROPERTY LINTER_COMMAND ${ARGN}) | ||
foreach(PROP IN LISTS LINTING_PROPERTIES) | ||
set_property(TARGET ${NAME} | ||
PROPERTY ${PROP} $<TARGET_PROPERTY:${LINTABLE_TARGET},${PROP}>) | ||
endforeach() | ||
|
||
get_property( | ||
TARGET_SOURCES | ||
TARGET ${LINTABLE_TARGET} | ||
PROPERTY SOURCES) | ||
target_lintables(${NAME} ${TARGET_SOURCES}) | ||
endfunction() | ||
|
||
# `target_lintables(<TARGET> <SOURCE_FILES...>)` | ||
# | ||
# Add source files to lint to a target `TARGET` created with `add_lint_target()` | ||
# | ||
# The explicit command is `<TARGET LINTABLE_COMMAND value> <source file> | ||
# (<linting-related property name> <TARGET linting-related property value>)...`. | ||
function(target_lintables TARGET) | ||
foreach(LINTABLE IN LISTS ARGN) | ||
normalize_path(LINTABLE) | ||
properties_genex(LINTING_PROPERTIES_GENEX ${TARGET} ${LINTING_PROPERTIES}) | ||
is_source_of_target_genex(IS_LINTABLE_SOURCE_GENEX ${TARGET} ${LINTABLE}) | ||
script_as_command(TOUCH_COMMAND ${TOUCH_SCRIPT}) | ||
|
||
cmake_path(RELATIVE_PATH LINTABLE BASE_DIRECTORY ${PROJECT_SOURCE_DIR} | ||
OUTPUT_VARIABLE LINTABLE_RELATIVE_PATH) | ||
cmake_path(ABSOLUTE_PATH LINTABLE_RELATIVE_PATH BASE_DIRECTORY | ||
${PROJECT_BINARY_DIR} OUTPUT_VARIABLE COMPLETION_MARKER) | ||
cmake_path(APPEND_STRING COMPLETION_MARKER .${TARGET}) | ||
|
||
add_custom_command( | ||
OUTPUT ${COMPLETION_MARKER} | ||
COMMAND | ||
$<TARGET_PROPERTY:${TARGET},LINTER_COMMAND> ${LINTABLE} | ||
${LINTING_PROPERTIES_GENEX} $<${IS_LINTABLE_SOURCE_GENEX}:IS_SOURCE> | ||
COMMAND ${TOUCH_COMMAND} ${COMPLETION_MARKER} | ||
IMPLICIT_DEPENDS CXX ${LINTABLE} | ||
COMMENT "${TARGET} -- ${LINTABLE_RELATIVE_PATH}" | ||
VERBATIM COMMAND_EXPAND_LISTS) | ||
|
||
set_property( | ||
TARGET ${TARGET} | ||
APPEND | ||
PROPERTY LINT_COMPLETION_MARKERS ${COMPLETION_MARKER}) | ||
endforeach() | ||
endfunction() |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# `normalize_path(<PATH_VAR>)` | ||
# | ||
# Normalize `PATH_VAR` so that it is expressed as an absolute CMake-style path | ||
# | ||
# If `PATH_VAR` is relative, it is considered relative to the current source | ||
# directory. | ||
function(normalize_path PATH_VAR) | ||
set(RETVAL ${${PATH_VAR}}) | ||
cmake_path(SET RETVAL NORMALIZE ${RETVAL}) | ||
cmake_path(IS_RELATIVE RETVAL IS_INPUT_RELATIVE) | ||
|
||
if(IS_INPUT_RELATIVE) | ||
cmake_path(ABSOLUTE_PATH RETVAL) | ||
endif() | ||
|
||
set(${PATH_VAR} | ||
${RETVAL} | ||
PARENT_SCOPE) | ||
endfunction() |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
include(RequireDefined) | ||
|
||
# `parse_cli_function(POSITIONALS <POSITIONAL_ARGUMENT_NAMES...> KEYWORDS | ||
# <KEYWORD_ARGUMENT_NAMES...> OPTIONS <OPTIONAL_ARGUMENT_NAMES...>)` | ||
# | ||
# Parse the arguments passed from command line and set variables whose names | ||
# belong to `POSITIONAL_ARGUMENT_NAMES`, `KEYWORD_ARGUMENT_NAMES` and | ||
# `OPTIONAL_ARGUMENT_NAMES` | ||
# | ||
# The commandline invokation must comply with the following format: `<cmake | ||
# command> <cmake command flags> -P <invoked script> -- <positional arguments> | ||
# (<keyword from KEYWORD_ARGUMENT_NAMES> <value>)... <option from | ||
# OPTIONAL_ARGUMENT_NAMES>...`. Positional arguments are mandatory, keyword and | ||
# optional arguments are not. | ||
function(parse_cli_arguments) | ||
foreach(I RANGE ${CMAKE_ARGC}) | ||
list(APPEND CLI_ARGV ${CMAKE_ARGV${I}}) | ||
endforeach() | ||
|
||
cmake_parse_arguments(PARSE_ARGV 0 "PARSED" "" "" | ||
"POSITIONALS;KEYWORDS;OPTIONS") | ||
cmake_parse_arguments("ARGV" "${PARSED_OPTIONS}" "" "--;${PARSED_KEYWORDS}" | ||
${CLI_ARGV}) | ||
|
||
set(POSITIONALS ${ARGV_--}) | ||
foreach(KEYWORD VALUE IN ZIP_LISTS PARSED_POSITIONALS POSITIONALS) | ||
require_defined_with_message(KEYWORD "Too many positional arguments") | ||
require_defined_with_message( | ||
VALUE "`${KEYWORD}` positional argument must be provided") | ||
set(${KEYWORD} | ||
${VALUE} | ||
PARENT_SCOPE) | ||
endforeach() | ||
|
||
foreach(KEYWORD IN LISTS PARSED_KEYWORDS) | ||
set(${KEYWORD} | ||
${ARGV_${KEYWORD}} | ||
PARENT_SCOPE) | ||
endforeach() | ||
|
||
foreach(OPTION IN LISTS PARSED_OPTIONS) | ||
set(${OPTION} | ||
${ARGV_${OPTION}} | ||
PARENT_SCOPE) | ||
endforeach() | ||
endfunction() |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
cmake_path(APPEND MODULE_PATH ${PROJECT_SOURCE_DIR} cmake module) | ||
|
||
cmake_path(APPEND IWYU_LINTER_SCRIPT ${PROJECT_SOURCE_DIR} cmake script | ||
run-include-what-you-use.cmake) | ||
cmake_path(APPEND TOUCH_SCRIPT ${PROJECT_SOURCE_DIR} cmake script touch.cmake) |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# `require_defined(<VARIABLE>)` | ||
# | ||
# Assert that `VARIABLE` is defined | ||
macro(require_defined VARIABLE) | ||
if(NOT DEFINED ${VARIABLE}) | ||
message(FATAL_ERROR "`${VARIABLE}` should have been defined") | ||
endif() | ||
endmacro() | ||
|
||
# `require_defined_with_message(<VARIABLE> <MESSAGE>)` | ||
# | ||
# Assert that `VARIABLE` is defined and show `MESSAGE` if not | ||
macro(require_defined_with_message VARIABLE MESSAGE) | ||
if(NOT DEFINED ${VARIABLE}) | ||
message(FATAL_ERROR "${MESSAGE}") | ||
endif() | ||
endmacro() |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
include(Paths) | ||
|
||
# `script_as_command(<OUTPUT> <SCRIPT>)` | ||
# | ||
# Take a CMake script, build the corresponding command to invoke it and store it | ||
# in `OUTPUT` | ||
function(script_as_command OUTPUT SCRIPT) | ||
set(${OUTPUT} | ||
${CMAKE_COMMAND} -DCMAKE_MODULE_PATH=${MODULE_PATH} -P ${SCRIPT} -- | ||
PARENT_SCOPE) | ||
endfunction() |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
include(Paths) | ||
include(Linting) | ||
|
||
# `add_iwyu_target(<NAME> <LINTABLE_TARGET>)` | ||
# | ||
# Create the lint target `NAME` that lints `LINTABLE_TARGET` with Include What | ||
# You Use | ||
function(add_iwyu_target NAME LINTABLE_TARGET) | ||
script_as_command(IWYU_LINTER_COMMAND ${IWYU_LINTER_SCRIPT}) | ||
add_lint_target(${NAME} ${LINTABLE_TARGET} ${IWYU_LINTER_COMMAND}) | ||
endfunction() |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
cmake_minimum_required(VERSION 3.5) | ||
|
||
include(ParseCliArguments) | ||
|
||
parse_cli_arguments( | ||
POSITIONALS | ||
SOURCE_FILE | ||
KEYWORDS | ||
INCLUDE_DIRECTORIES | ||
INTERFACE_INCLUDE_DIRECTORIES | ||
COMPILE_DEFINITIONS | ||
INTERFACE_COMPILE_DEFINITIONS | ||
COMPILE_FEATURES | ||
INTERFACE_COMPILE_FEATURES | ||
COMPILE_OPTIONS | ||
INTERFACE_COMPILE_OPTIONS | ||
OPTIONS | ||
IS_SOURCE) | ||
|
||
find_program(IWYU_COMMAND include-what-you-use | ||
DOC "Check inclusion in C and C++ programs" REQUIRED) | ||
|
||
if(NOT IS_SOURCE) | ||
set(INCLUDE_DIRECTORIES ${INTERFACE_INCLUDE_DIRECTORIES}) | ||
set(COMPILE_DEFINITIONS ${INTERFACE_COMPILE_DEFINITIONS}) | ||
set(COMPILE_FEATURES ${INTERFACE_COMPILE_FEATURES}) | ||
set(COMPILE_OPTIONS ${INTERFACE_COMPILE_OPTIONS}) | ||
endif() | ||
|
||
cmake_path(CONVERT "${SOURCE_FILE}" TO_NATIVE_PATH_LIST SOURCE_FILE) | ||
cmake_path(CONVERT "${INCLUDE_DIRECTORIES}" TO_NATIVE_PATH_LIST | ||
INCLUDE_DIRECTORIES) | ||
|
||
set(ISYSTEM_FLAGS ${INCLUDE_DIRECTORIES}) | ||
list(TRANSFORM ISYSTEM_FLAGS PREPEND "-isystem ") | ||
|
||
set(DEFINITION_FLAGS ${COMPILE_DEFINITIONS}) | ||
list(TRANSFORM DEFINITION_FLAGS PREPEND "-D ") | ||
|
||
set(COMPILER_OPTION_FLAGS ${COMPILE_OPTIONS}) | ||
|
||
if(cxx_std_17 IN_LIST COMPILE_FEATURES) | ||
list(APPEND COMPILE_OPTION_FLAGS -std=c++17) | ||
endif() | ||
|
||
execute_process( | ||
COMMAND ${IWYU_COMMAND} ${SOURCE_FILE} ${ISYSTEM_FLAGS} ${DEFINITION_FLAGS} | ||
${COMPILE_OPTION_FLAGS} -Xiwyu --error=1 -Xiwyu --no_fwd_decls | ||
RESULT_VARIABLE COMMAND_RESULT | ||
OUTPUT_VARIABLE COMMAND_OUTPUT | ||
ERROR_VARIABLE COMMAND_OUTPUT) | ||
|
||
if(NOT COMMAND_RESULT EQUAL 0) | ||
message(${COMMAND_OUTPUT}) | ||
message( | ||
FATAL_ERROR | ||
"Include What You Use failed on ${SOURCE_FILE} with error code ${COMMAND_RESULT}" | ||
) | ||
endif() |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
cmake_minimum_required(VERSION 3.5) | ||
|
||
include(ParseCliArguments) | ||
|
||
parse_cli_arguments(POSITIONALS FILE) | ||
|
||
cmake_path(REMOVE_FILENAME FILE OUTPUT_VARIABLE DIR) | ||
cmake_path(NATIVE_PATH FILE FILE) | ||
cmake_path(NATIVE_PATH DIR DIR) | ||
|
||
file(MAKE_DIRECTORY ${DIR}) | ||
file(TOUCH ${FILE}) |
This file contains 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
This file contains 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
This file contains 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
This file contains 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
Oops, something went wrong.