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

Generate and install a cmake configuration file, which can be #447

Conversation

mmassing
Copy link
Contributor

automatically picked up by downstream cmake projects.

Downstream projects can link to Clipper2 or Clipper2Z by adding 'Clipper2::Clipper2' or 'Clipper2::Clipper2Z' as target dependency, and don't need to implement a FindPackage module.

@AngusJohnson
Copy link
Owner

AngusJohnson commented Mar 17, 2023

Hi again Manuel.
Thank you for your PR. Since I'm completely unable to critique your changes (since my knowledge of CMake is negligible), I'm hoping one or two semi-regular Clipper2 contributors who are knowledgeable in CMake might comment before I merge.

@sethhillbrand
Copy link
Contributor

@mmassing I think that you might need to include some documentation about how you propose that this be used. Are you suggesting that a downstream package pull Clipper2 as a git submodule and include the CmakeList that way or are you suggesting (as it seems to be) that the downstream project install Clipper2 locally and then include the generated CmakeList file instead of the base one here?

@mmassing
Copy link
Contributor Author

mmassing commented Mar 28, 2023

Hi @sethhillbrand, this change will instruct CMake to export and install a cmake config-file. This is a concept similar to pkgconfig, where cmake provides information about exported targets, libraries, and include directories for Clipper2 by writing them to a config file. The patch exports the targets Clipper2::Clipper2 and Clipper2::Clipper2Z (apparently Clipper2Z is now optional, so I will need to adapt the patch for that).

Install step: E.g., under bash, build clipper2 locally, and perform a "system"-wide install:

mkdir -p build-clipper2; cd build-clipper2
cmake ${CLIPPER2_SOURCE} -DCMAKE_BUILD_TYPE=Debug
make -j && sudo make install

Downstream project usage is straightforward (cmake should pick the config file up automatically):

find_package(Clipper2 REQUIRED)

# Create executable which links against clipper2
# Note that include paths / compile flags / transitive dependencies are 
# automatically imported from the target
add_executable(test-clipper2 main.cpp)
target_link_libraries(test-clipper2 PRIVATE Clipper2::Clipper2)

add_executable(test-clipper2z main-with-z.cpp)
target_link_libraries(test-clipper2z PRIVATE Clipper2::Clipper2Z)

@sethhillbrand
Copy link
Contributor

I'll be honest here that I can't imagine ever wanting to use Clipper2 in this fashion. That said, maybe someone does?

However, the install appears to pick out a GNU-centric destination that probably will have limited applicability. What is the expected behavior when using this proposed method on Mac or MSVC? Should this be gated?

@mmassing
Copy link
Contributor Author

Hi Seth,

thanks for your feedback. Incorporating a cmake config file follows modern CMake practice and helps to streamline dependency management and integration with other projects. It is more flexible and portable than relying on library-specific cmake-modules (the "old-fashioned" way). You may of course still choose to not use cmake for your downstream projects, or integrate Clipper2 as a subproject.
Although my example used bash command-line syntax, cmake config files are not GNU-centric. The config files work across different OS and architectures, as described in the CMake documentation: https://cmake.org/cmake/help/latest/command/find_package.html#config-mode-search-procedure
CMake config files are particularly useful for building platforms in cross-compilation scenarios, non-system wide installation prefixes, and containerized environments such as Docker (to provide a "builder" platform image).
I hope this provides a clearer understanding of the benefits of the proposed cmake config file patch for Clipper2.

cheers, Manuel

Copy link
Contributor

@sethhillbrand sethhillbrand left a comment

Choose a reason for hiding this comment

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

Well, as I mentioned, others may find this useful and it doesn't appear to impact normal usage. I've left a couple of comments that you might look over.

include(CMakePackageConfigHelpers)
include(GNUInstallDirs)

write_basic_package_version_file("${PROJECT_BINARY_DIR}/Clipper2ConfigVersion.cmake" COMPATIBILITY AnyNewerVersion)
Copy link
Contributor

Choose a reason for hiding this comment

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

Because the API changes between even minor versions of Clipper2, this should be "ExactVersion"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You're correct in principle, but the prevailing practice is to be lenient for the configuration script, since the downstream is free to add additional constraints - e.g. request a specific version using
find_package(Clipper2 1.2.3 EXACT REQUIRED), or restricting to e.g. a specific minor version: find_package(Clipper2 1.2 REQUIRED). SameMajorVersion might be sensible, though.

Copy link
Contributor

Choose a reason for hiding this comment

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

Fair enough.

@@ -212,15 +216,52 @@ endif()
file(COPY ../Tests/Polygons.txt DESTINATION ${CMAKE_BINARY_DIR} FILE_PERMISSIONS OWNER_READ GROUP_READ WORLD_READ )
endif()

# create package config file
include(CMakePackageConfigHelpers)
include(GNUInstallDirs)
Copy link
Contributor

Choose a reason for hiding this comment

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

This shouldn't be used for MSVC or MacOS builds (not sure if there is an alternative available for them

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I guess you are concererned about GNUInstallDirs? CMake provides it to establish a convention for install directories (${CMAKE_INSTALL_INCLUDEDIR}, etc.), and contrary to what the name suggests it can be used on all platforms (e.g. Microsofts' own vcpkg uses this convention).

@AngusJohnson
Copy link
Owner

AngusJohnson commented Mar 28, 2023

@mmassing in case you're wondering, Seth is very kindly acting as my proxy here (at my request) because of my very limited knowledge of CMake.

@LazyDodo
Copy link

LazyDodo commented Apr 1, 2024

Stumbled upon this shortly before sending an almost identical PR, this PR seemed well on it's way, and i'm a bit confused on the sudden closure, is this worth dusting off? or were there fundamental issues at hand?

Context: i'm the windows platform dev for blender (CMake based, pkg-config doesn't exist in the stock microsoft tooling), and we're looking to take on a new dependency on manifold which is mostly cmake based, except for where they used pkg-config to find Clipper2 since it exports no cmake config, so i'm looking to fix this issue in Clipper2, so I can fix the issue in manifold, so i ..... yeah... fun times... while I can easily fix this locally with some patches, it's nicer not having to maintain patches and lending a hand upstream.

What is the expected behavior when using this proposed method on Mac or MSVC? Should this be gated?

No need to gate it, CMake config files aren't specific to MSVC, It'll will work across all platforms supported by CMake, I see no problem with generating both formats for all platforms (the msys/mingw based toolchains on windows do have pkg-config, so there will be people that'll appreciate support being there), people can pick and use whatever they prefer.

@AngusJohnson
Copy link
Owner

AngusJohnson commented Apr 2, 2024

and i'm a bit confused on the sudden closure, is this worth dusting off? or were there fundamental issues at hand?

I only closed this PR when there seemed little interest in or need for it. (And I have enough problems trying to understand what's happening in CMake without making it more complex. And every time I change something, I potentially break something.) Nevertheless, if enough people will find this helpful and (the changes not too radical), then I'd be happy to accommodate them.

@AngusJohnson AngusJohnson reopened this Apr 2, 2024
Copy link

@LazyDodo LazyDodo left a comment

Choose a reason for hiding this comment

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

minor fixes required to build with CLIPPER2_USINGZ=OFF

CPP/CMakeLists.txt Outdated Show resolved Hide resolved
CPP/CMakeLists.txt Outdated Show resolved Hide resolved
@mmassing
Copy link
Contributor Author

mmassing commented Apr 3, 2024

@LazyDodo thanks for picking this back up again, somehow got lost by the wayside! Are you currently working on this? Otherwise I'm happy to update the PR with Seths suggestions, and handle the USINGZ case.

@mmassing mmassing force-pushed the feature/generate-and-install-cmake-config branch from 4168fb5 to b7f22c6 Compare April 3, 2024 12:43
…ically

picked up by downstream cmake projects.

Downstream projects can link to Clipper2 or Clipper2Z by adding
'Clipper2::Clipper2' or 'Clipper2::Clipper2Z' as target dependency, and
don't need to implement a FindPackage module.
@mmassing mmassing force-pushed the feature/generate-and-install-cmake-config branch from b7f22c6 to a3510c6 Compare April 3, 2024 12:43
@AngusJohnson
Copy link
Owner

If everyone contributing is now happy with the current state of this PR, I'll press the merge button.

@AngusJohnson AngusJohnson merged commit 0135062 into AngusJohnson:main Apr 6, 2024
7 checks passed
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.

4 participants