Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmakelang/command_tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -533,7 +533,7 @@ class TestInstall(TestBase):
"""
Test various examples of the install command
"""
kExpectNumSidecarTests = 3
kExpectNumSidecarTests = 9


class TestSetTargetProperties(TestBase):
Expand Down
43 changes: 43 additions & 0 deletions cmakelang/command_tests/install_tests.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -92,3 +92,46 @@ install(
TARGETS target #
CONFIGURATIONS Debug
RUNTIME DESTINATION Debug/bin)

# test: install_file_set
install(TARGETS mylib FILE_SET myheaders DESTINATION include/mylib)

# test: install_file_set_with_component
install(
TARGETS mylib
FILE_SET HEADERS
DESTINATION include
COMPONENT Development
FILE_SET mymodules
DESTINATION lib/cmake
COMPONENT Development)

# test: install_runtime_dependency_set
install(
RUNTIME_DEPENDENCY_SET mydeps
LIBRARY DESTINATION lib COMPONENT runtime
RUNTIME DESTINATION bin COMPONENT runtime
PRE_EXCLUDE_REGEXES "api-ms-" "ext-ms-"
POST_EXCLUDE_REGEXES ".*system32/.*\\.dll"
DIRECTORIES ${CMAKE_INSTALL_PREFIX}/bin)

# test: install_targets_with_runtime_dependency_set
install(
TARGETS myapp
RUNTIME_DEPENDENCY_SET mydeps
RUNTIME DESTINATION bin COMPONENT runtime)

# test: install_targets_with_runtime_dependencies
install(
TARGETS myapp
RUNTIME_DEPENDENCIES
PRE_EXCLUDE_REGEXES "api-ms-" "ext-ms-"
POST_EXCLUDE_REGEXES ".*system32/.*\\.dll"
DIRECTORIES ${CMAKE_INSTALL_PREFIX}/bin
RUNTIME DESTINATION bin)

# test: install_cxx_modules_bmi
install(
TARGETS mymodule
FILE_SET CXX_MODULES DESTINATION lib/cxx/miu
CXX_MODULES_BMI DESTINATION lib/cxx/bmi COMPONENT Development)
27 changes: 27 additions & 0 deletions cmakelang/command_tests/misc_tests.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -898,3 +898,30 @@ use_tabchars = True
if(TRUE)
message("Hello world")
endif()

# test: target_sources_file_set
target_sources(
mylib
PUBLIC
FILE_SET HEADERS
BASE_DIRS include
FILES include/mylib.h include/mylib_config.h)

# test: target_sources_file_set_with_type
target_sources(
mylib
PUBLIC
FILE_SET mymodules
TYPE CXX_MODULES
BASE_DIRS src
FILES src/mymodule.cppm)

# test: target_sources_mixed
target_sources(
mylib
PRIVATE src/impl.cpp
PUBLIC
FILE_SET HEADERS
BASE_DIRS include
FILES include/mylib.h
INTERFACE some_interface.h)
2 changes: 1 addition & 1 deletion cmakelang/command_tests/misc_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class TestMiscFormatting(TestBase):
"""
Ensure that various inputs format the way we want them to
"""
kExpectNumSidecarTests = 86
kExpectNumSidecarTests = 89

def test_config_hashruler_minlength(self):

Expand Down
26 changes: 26 additions & 0 deletions cmakelang/parse/additional_nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,32 @@ def parse(cls, ctx, tokens, breakstack):
)


class FileSetNode(StandardArgTree):
"""File sets are children of a `FILE_SET` keyword argument and are used
in target_sources and install commands (CMake 3.23+)."""

@classmethod
def parse(cls, ctx, tokens, breakstack):
"""
::

FILE_SET <set> [TYPE <type>] [BASE_DIRS <dirs>...] [FILES <files>...]

:see: https://cmake.org/cmake/help/latest/command/target_sources.html
"""
return super(FileSetNode, cls).parse(
ctx, tokens,
npargs=1, # The set name
kwargs={
"TYPE": PositionalParser(1),
"BASE_DIRS": PositionalParser('+'),
"FILES": PositionalParser('+'),
},
flags=[],
breakstack=breakstack
)


class FlagGroupNode(PositionalGroupNode):
"""A positinal group where each argument is a flag."""

Expand Down
120 changes: 112 additions & 8 deletions cmakelang/parse/funs/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from cmakelang.parse.simple_nodes import CommentNode
from cmakelang.parse.argument_nodes import (
KeywordGroupNode, PositionalGroupNode, PositionalParser, StandardArgTree)
from cmakelang.parse.additional_nodes import PatternNode
from cmakelang.parse.additional_nodes import FileSetNode, PatternNode
from cmakelang.parse.util import (
WHITESPACE_TOKENS,
get_first_semantic_token,
Expand Down Expand Up @@ -40,13 +40,40 @@ def parse_install_targets_sub(ctx, tokens, breakstack):
breakstack=breakstack)


def parse_install_file_set_sub(ctx, tokens, breakstack):
"""
Parse the inner kwargs of an ``install(TARGETS ... FILE_SET)`` command.
FILE_SET requires a set name followed by optional destination kwargs.
:see: https://cmake.org/cmake/help/latest/command/install.html#targets
"""
return StandardArgTree.parse(
ctx, tokens,
npargs=1, # The file set name
kwargs={
"DESTINATION": PositionalParser(1),
"PERMISSIONS": PositionalParser('+'),
"CONFIGURATIONS": PositionalParser('+'),
"COMPONENT": PositionalParser(1),
"NAMELINK_COMPONENT": PositionalParser(1),
},
flags=[
"OPTIONAL",
"EXCLUDE_FROM_ALL",
"NAMELINK_ONLY",
"NAMELINK_SKIP"
],
breakstack=breakstack)


def parse_install_targets(ctx, tokens, breakstack):
"""
::

install(TARGETS targets... [EXPORT <export-name>]
[RUNTIME_DEPENDENCIES <arg>...|RUNTIME_DEPENDENCY_SET <set-name>]
[[ARCHIVE|LIBRARY|RUNTIME|OBJECTS|FRAMEWORK|BUNDLE|
PRIVATE_HEADER|PUBLIC_HEADER|RESOURCE]
PRIVATE_HEADER|PUBLIC_HEADER|RESOURCE|
FILE_SET <set>|CXX_MODULES_BMI]
[DESTINATION <dir>]
[PERMISSIONS permissions...]
[CONFIGURATIONS [Debug|Release|...]]
Expand All @@ -58,11 +85,13 @@ def parse_install_targets(ctx, tokens, breakstack):
[INCLUDES DESTINATION [<dir> ...]]
)

:see: https://cmake.org/cmake/help/v3.14/command/install.html#targets
:see: https://cmake.org/cmake/help/latest/command/install.html#targets
"""
kwargs = {
"TARGETS": PositionalParser('+'),
"EXPORT": PositionalParser(1),
"RUNTIME_DEPENDENCY_SET": PositionalParser(1),
"RUNTIME_DEPENDENCIES": parse_install_runtime_dependencies_sub,
"INCLUDES": PositionalParser('+', flags=["DESTINATION"]),
# Common kwargs
"DESTINATION": PositionalParser(1),
Expand All @@ -79,7 +108,8 @@ def parse_install_targets(ctx, tokens, breakstack):
)
designated_kwargs = (
"ARCHIVE", "LIBRARY", "RUNTIME", "OBJECTS", "FRAMEWORK",
"BUNDLE", "PRIVATE_HEADER", "PUBLIC_HEADER", "RESOURCE"
"BUNDLE", "PRIVATE_HEADER", "PUBLIC_HEADER", "RESOURCE",
"FILE_SET", "CXX_MODULES_BMI"
)

# NOTE(josh): from here on, code is essentially StandardArgTree.parse(),
Expand Down Expand Up @@ -138,8 +168,13 @@ def parse_install_targets(ctx, tokens, breakstack):
# just make sure we check flags first.
word = get_normalized_kwarg(tokens[0])
if word in designated_kwargs:
subtree = KeywordGroupNode.parse(
ctx, tokens, word, parse_install_targets, subtree_breakstack)
# FILE_SET requires a set name argument, so use a different subparser
if word == "FILE_SET":
subtree = KeywordGroupNode.parse(
ctx, tokens, word, parse_install_file_set_sub, subtree_breakstack)
else:
subtree = KeywordGroupNode.parse(
ctx, tokens, word, parse_install_targets_sub, subtree_breakstack)
elif word in kwargs:
subtree = KeywordGroupNode.parse(
ctx, tokens, word, kwargs[word], kwarg_breakstack)
Expand Down Expand Up @@ -280,6 +315,73 @@ def parse_install_export(ctx, tokens, breakstack):
breakstack=breakstack)


def parse_install_runtime_dependencies_sub(ctx, tokens, breakstack):
"""
Parse the inner kwargs of ``RUNTIME_DEPENDENCIES`` within install(TARGETS).
These are the filtering options for runtime dependency resolution.

:see: https://cmake.org/cmake/help/latest/command/install.html#targets
"""
return StandardArgTree.parse(
ctx, tokens,
npargs='*',
kwargs={
"PRE_INCLUDE_REGEXES": PositionalParser('+'),
"PRE_EXCLUDE_REGEXES": PositionalParser('+'),
"POST_INCLUDE_REGEXES": PositionalParser('+'),
"POST_EXCLUDE_REGEXES": PositionalParser('+'),
"POST_INCLUDE_FILES": PositionalParser('+'),
"POST_EXCLUDE_FILES": PositionalParser('+'),
"DIRECTORIES": PositionalParser('+'),
},
flags=[],
breakstack=breakstack)


def parse_install_runtime_dependency_set(ctx, tokens, breakstack):
"""
::

install(RUNTIME_DEPENDENCY_SET <set-name>
[[LIBRARY|RUNTIME|FRAMEWORK]
[DESTINATION <dir>]
[PERMISSIONS permissions...]
[CONFIGURATIONS [Debug|Release|...]]
[COMPONENT <component>]
[NAMELINK_COMPONENT <component>]
[OPTIONAL] [EXCLUDE_FROM_ALL]
] [...]
[PRE_INCLUDE_REGEXES regex...]
[PRE_EXCLUDE_REGEXES regex...]
[POST_INCLUDE_REGEXES regex...]
[POST_EXCLUDE_REGEXES regex...]
[POST_INCLUDE_FILES file...]
[POST_EXCLUDE_FILES file...]
[DIRECTORIES dir...]
)

:see: https://cmake.org/cmake/help/latest/command/install.html#runtime-dependency-set
"""
return StandardArgTree.parse(
ctx, tokens,
npargs='*',
kwargs={
"RUNTIME_DEPENDENCY_SET": PositionalParser(1),
"LIBRARY": parse_install_targets_sub,
"RUNTIME": parse_install_targets_sub,
"FRAMEWORK": parse_install_targets_sub,
"PRE_INCLUDE_REGEXES": PositionalParser('+'),
"PRE_EXCLUDE_REGEXES": PositionalParser('+'),
"POST_INCLUDE_REGEXES": PositionalParser('+'),
"POST_EXCLUDE_REGEXES": PositionalParser('+'),
"POST_INCLUDE_FILES": PositionalParser('+'),
"POST_EXCLUDE_FILES": PositionalParser('+'),
"DIRECTORIES": PositionalParser('+'),
},
flags=[],
breakstack=breakstack)


def parse_install(ctx, tokens, breakstack):
"""
The ``install()`` command has multiple different forms, implemented
Expand All @@ -292,8 +394,9 @@ def parse_install(ctx, tokens, breakstack):
* SCRIPT
* CODE
* EXPORT
* RUNTIME_DEPENDENCY_SET

:see: https://cmake.org/cmake/help/v3.0/command/install.html
:see: https://cmake.org/cmake/help/latest/command/install.html
"""

descriminator_token = get_first_semantic_token(tokens)
Expand All @@ -310,7 +413,8 @@ def parse_install(ctx, tokens, breakstack):
"DIRECTORY": parse_install_directory,
"SCRIPT": parse_install_script,
"CODE": parse_install_script,
"EXPORT": parse_install_export
"EXPORT": parse_install_export,
"RUNTIME_DEPENDENCY_SET": parse_install_runtime_dependency_set,
}
if descriminator not in parsemap:
logger.warning("Invalid install form \"%s\" at %s", descriminator,
Expand Down
7 changes: 6 additions & 1 deletion cmakelang/parse/funs/random.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
PositionalParser,
StandardArgTree,
)
from cmakelang.parse.additional_nodes import FileSetNode
from cmakelang.parse.util import (
iter_semantic_tokens,
)
Expand Down Expand Up @@ -357,14 +358,18 @@ def parse_target_sources(ctx, tokens, breakstack):

target_sources(<target>
<INTERFACE|PUBLIC|PRIVATE> [items1...]
[<INTERFACE|PUBLIC|PRIVATE> [items2...] ...])
[<INTERFACE|PUBLIC|PRIVATE> [items2...] ...]
[<INTERFACE|PUBLIC|PRIVATE>
[FILE_SET <set> [TYPE <type>] [BASE_DIRS <dirs>...] [FILES <files>...]]
...])

:see: https://cmake.org/cmake/help/latest/command/target_sources.html
"""
kwargs = {
"INTERFACE": PositionalParser("+"),
"PUBLIC": PositionalParser("+"),
"PRIVATE": PositionalParser("+"),
"FILE_SET": FileSetNode.parse,
}
return StandardArgTree.parse(ctx, tokens, 1, kwargs, [], breakstack)

Expand Down