Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Account for INTERFACE libraries when getting target include directories #121

Merged
merged 3 commits into from
Jan 12, 2019

Conversation

jacobperron
Copy link
Contributor

Fixes #120

CMake does not allow getting the INCLUDE_DIRECTORIES property from
INTERFACE libraries.
Instead, first check if the property exists, if it does not then try to
get the INTERFACE_INCLUDE_DIRECTORIES property.

Note, if INTERFACE_INCLUDE_DIRECTORIES is not defined an empty list is
returned, but we cannot assume the target is not an interface.
This is why the implementation is conditional on INCLUDE_DIRECTORIES
instead.

@jacobperron jacobperron added the in progress Actively being worked on (Kanban column) label Jan 11, 2019
@jacobperron
Copy link
Contributor Author

jacobperron commented Jan 11, 2019

CI (linter tests only):

  • Linux Build Status
  • Linux-aarch64 Build Status
  • macOS Build Status
  • Windows Build Status

edit: re-trigger with typo fix

@jacobperron jacobperron added in review Waiting for review (Kanban column) and removed in progress Actively being worked on (Kanban column) labels Jan 11, 2019
@jacobperron
Copy link
Contributor Author

FYI @Karsten1987

string(REGEX MATCH "^${CMAKE_SOURCE_DIR}.*" _is_match ${_include_dir})
if(_is_match)
# Check if include directory is a subdirectory of the source directory
string(REGEX MATCH "^${CMAKE_SOURCE_DIR}.*" _is_subdirectory ${_include_dir})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This regex will also match sibling directories of e.g packages which start with the same name as this directory. So the regex should have a trailing shash before the wildcard.

Also this might need to consider platform specific path separators.

Same below.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to be a way to do it 0472892
Open to suggestions.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are the returned include dirs always native paths?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My impression was that CMake prefers paths to be stored with forward slashes internally and then converts them on platforms that need it but I can't find the relevant documentation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirmed on a Windows machine that include dirs are cmake paths. I’ll remove the native path command.

@nuclearsandwich
Copy link
Contributor

@jacobperron when you run the next CI round for this can you include rosbag2? I think you'll need to instruct colcon to skip packages that require the ros1 bridge.

@jacobperron
Copy link
Contributor Author

jacobperron commented Jan 11, 2019

when you run the next CI round for this can you include rosbag2? I think you'll need to instruct colcon to skip packages that require the ros1 bridge.

Done:

  • Linux Build Status
  • Windows Build Status

edit: Just building up to rosbag2_test_common

@jacobperron
Copy link
Contributor Author

Regular CI (linter tests only):

  • Linux Build Status
  • Linux-aarch64 Build Status
  • macOS Build Status
  • Windows Build Status

# Check if include directory is a subdirectory of the source directory
string(REGEX MATCH "^${CMAKE_SOURCE_DIR}/.*" _is_subdirectory ${_include_dir})
# Check if include directory is part of a generator expression (e.g. $<BUILD_INTERFACE:...>)
string(REGEX MATCH "^\\$<.*:${CMAKE_SOURCE_DIR}/.*>$" _is_genexp_subdirectory "${_include_dir}")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The CMAKE_SOURCE_DIR might contain characters which have special meaning in a regex. Unfortunately afaik there is no function in CMake to escape a string for that use case (see https://gitlab.kitware.com/cmake/cmake/issues/18409).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the real world impact of this issue is narrowly scoped enough that the TODO in 600fa4c covers it.

A robust string library could probably get around the need for regexp here. Comparing the initia substring of the include directory to the CMAKE_SOURCE_DIR might be sufficient in the usual case but I don't have any idea yet what to do about the Generator Expressions.

CMake does not allow getting the INCLUDE_DIRECTORIES property from
INTERFACE libraries.
Instead, first check if the property exists, if it does not then try to
get the INTERFACE_INCLUDE_DIRECTORIES property.

Note, if INTERFACE_INCLUDE_DIRECTORIES is not defined an empty list is
returned, but we cannot assume the target is not an interface.
This is why the implementation is conditional on INCLUDE_DIRECTORIES
instead.

Signed-off-by: Jacob Perron <jacob@openrobotics.org>
@jacobperron
Copy link
Contributor Author

Looks like a regression, the errors have returned for cppcheck v1.86...

@jacobperron
Copy link
Contributor Author

For some reason ${_include_dirs_defined} is always 0 (false), even though if the property is requested it works as expected:

get_property(_include_dirs_defined
TARGET ${_target}
PROPERTY INCLUDE_DIRECTORIES
DEFINED
)

@jacobperron
Copy link
Contributor Author

Through some experimentation, looks like we can use the TYPE property to check if a target is an INTERFACE_LIBRARY. Update to condition incoming...

…roperty to use

Signed-off-by: Jacob Perron <jacob@openrobotics.org>
@jacobperron
Copy link
Contributor Author

Windows (cppcheck v1.86) Build Status

@jacobperron
Copy link
Contributor Author

Test rosbag2_test_common:

  • Linux: Build Status
  • Windows: Build Status

PROPERTY INCLUDE_DIRECTORIES
)
# Include directories property is different for INTERFACE libraries
get_target_property(_target_type ${_target} TYPE)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉 Glad you found a way to do this.

Copy link
Contributor

@nuclearsandwich nuclearsandwich left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 with passing CI for both default and the rosbag2_test_common package.

@jacobperron
Copy link
Contributor Author

For good measure:

  • Linux Build Status
  • Linux-aarch64 Build Status
  • macOS Build Status
  • Windows Build Status

Signed-off-by: Jacob Perron <jacob@openrobotics.org>
@jacobperron
Copy link
Contributor Author

Windows: Build Status

@jacobperron jacobperron merged commit aa51cab into master Jan 12, 2019
@jacobperron jacobperron deleted the fix_120 branch January 12, 2019 06:40
@jacobperron jacobperron removed the in review Waiting for review (Kanban column) label Jan 12, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants