-
Notifications
You must be signed in to change notification settings - Fork 448
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
[cmake] Add alias target expat::expat
#903
Conversation
As the find module and the config create the expat::expat alias for expat, the build-process should do this also to make it easier to include this in a chainbuild
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Vollstrecker I'm not sure I understand the issue. Could you elaborate what problem this is solving? At the risk of missing something obvious: Is anything keeping a projecting including Expat on CMake level keeping from adding a line like that themselves and how would it help them? Thanks in advance!
The examples show how to search in config mode and then using target_link_libraries(...expat::expat) as this target is created by the config. If there no local installation is found I could use fetchcontent (git submodule or a copy of the code would also work) and just let expat be built and installed in one run of cmake instead of first config/build/install expat and then again config/build/install my project. If done that way, I would have to use target_link_libraries(... expat), as only that target is created atm. |
@Vollstrecker I've been experimenting with FetchContent a bit myself again now and found this… cmake_minimum_required(VERSION 3.11)
include(FetchContent)
project(hello VERSION 1.0.0)
FetchContent_Declare(
expat
GIT_REPOSITORY https://github.com/libexpat/libexpat/
GIT_TAG 88b3ed553d8ad335559254863a33360d55b9f1d6 # i.e. R_2_6_3
)
FetchContent_MakeAvailable(expat)
add_subdirectory("${expat_SOURCE_DIR}/expat")
add_executable(hello
hello.c
)
target_link_libraries(hello PUBLIC expat) …to work as expected and… target_link_libraries(hello PUBLIC expat::expat) …to only work after something like… if (NOT TARGET expat::expat)
add_library(expat::expat ALIAS expat)
endif() …before that, on top. My personal conclusion from that is that:
I think I'm still missing part of the picture of your use case? I'm happy to learn what this picture of mine is missing. Thank you! |
I'm just on the run now, so I will come to back this next wed.
Ecactly, but the config is not executed if it wasn't installed (or if someone just executes fetchcontent/git submodule/whatever) to test against head or just use a newer version. In this case the source itself is included and the alias is never created, that's why it needs to be created here. Having the Config and the CMakeLists.txt executed in one run would be a bad mistake by a user.
I didn't read the doc yet, but noone should pull in a lib two different ways in one run. With the new function in fetchcontent it's possible to let the system know about the repo, so find_package will either find it with the config or download it via fetchcontent. It's always a one or the other situation and then one line here is much better than 3 lines in every program that wants to use to lib.
You just think about what happens if users use your stuff the wrong way. In regards of the code itself (memleaks etc.) it's the best approach you can do. In this case you would support users that will have other problems with their approach, but otoh. any dev that uses it right need to do extra steps to get a consistent usage of the lib. No dev should need to care about where the lib comes from. |
@Vollstrecker understood, I figured after my previous reply that those two
So we're only talking about
…then for For unpatched Git cmake_minimum_required(VERSION 3.24)
include(FetchContent)
project(hello VERSION 1.0.0)
FetchContent_Declare(
expat
GIT_REPOSITORY https://github.com/libexpat/libexpat/
GIT_TAG 88b3ed553d8ad335559254863a33360d55b9f1d6 # i.e. R_2_6_3
FIND_PACKAGE_ARGS
)
FetchContent_MakeAvailable(expat)
if(NOT expat_FOUND) # with regard to find_package
add_subdirectory("${expat_SOURCE_DIR}/expat")
add_library(expat::expat ALIAS expat)
endif()
add_executable(hello
hello.c
)
target_link_libraries(hello PUBLIC expat::expat) Given the apparent need for conditional I should note that adding
For option case (b) I only find use in
Thanks for the heads up, see you! |
My Case ist find_package and if(NOT EXPAT_FOUND) fetchcontent, which basically happens internally in all your cases.
As fetchcontent_makeavailable does the add_subdirectory after find_package did the if, the only thing left ist the alias, that's the reason for this change.
Sure, but this means someone ist pulling in head unconditionally and a) hopes for the best which never is a good Idea or b) they want to See If Something Breaks to have time to react before the Release. As you already noticed, importing find_package and pulling in the source are exklusive to each other. With this change they would behave identical. If they have somehow imported an installed Release and master at the Same time, I guess the break because of the alias would be their littlest Problem. This works in cryptopp-cmake, libupnp and even qt, so I can't Imagine people could complain about this. |
@Vollstrecker I cannot confirm that
So the
I'm with you that following
With regard to the target name: yes; the two paths still have plenty of differences which e.g. becomes visible when dumping all variables known to CMake: With
|
Now, I'm at least on a bigger display. First thing:
As you see by yourself, you need the expat-path. fetchcontent does add_subdirectory, but in this case there is no CMakeLists.txt in there. If you add 'SOURCE_SUBDIR expat' to the declare, it works. Second, including your sourcetree doesn't set expat_FOUND as long as you don't do that in your CMakelists.txt, same as with the alias. Third, Findpackage_ARGS is the find-module fetchcontent should try first and if not successfull it downloads the source. For the other way around you want OVERRIDE_FIND_PACKAGE, then you get the source if you use find_package(expat) and nothing is found. Fourth: you found the old cryptopp where everything from 2.very.old should be supported, follow the link in the README.md and you'll find this line. Btw. The line you've found was to work around old cmakes that don't create the alias (like you atm.) for a third party lib (not cryptopp), what is stated at the comment above. But hey, if you want a guarded version, feel free. Maybe with a message stating that if someone sees the message he should open an issue and post a link to his project, and if the usage is correct I owe you a box of german beer of your choice (or of mine if you don't know the good ones). |
@Vollstrecker I confirm that cmake_minimum_required(VERSION 3.24)
include(FetchContent)
project(hello VERSION 1.0.0)
FetchContent_Declare(
expat
GIT_REPOSITORY https://github.com/libexpat/libexpat/
GIT_TAG 88b3ed553d8ad335559254863a33360d55b9f1d6 # i.e. R_2_6_3
SOURCE_SUBDIR expat/
FIND_PACKAGE_ARGS
)
FetchContent_MakeAvailable(expat)
add_executable(hello
hello.c
)
target_link_libraries(hello PUBLIC expat)
I fail to make sense of that statement. Could you rephrase it to help me understand?
Yes.
In my practical test I always got the source with cmake_minimum_required(VERSION 3.24)
include(FetchContent)
project(hello VERSION 1.0.0)
FetchContent_Declare(
expat
GIT_REPOSITORY https://github.com/libexpat/libexpat/
GIT_TAG 88b3ed553d8ad335559254863a33360d55b9f1d6 # i.e. R_2_6_3
SOURCE_SUBDIR expat/
OVERRIDE_FIND_PACKAGE
)
FetchContent_MakeAvailable(expat)
find_package(expat 2.2.8 CONFIG REQUIRED char dtd ns)
add_executable(hello
hello.c
)
target_link_libraries(hello PUBLIC expat) …to see it with your own eyes. Same after dropping any to all of
I confirm that your link adds an alias the same way that you're suggesting here.
The guard would need to be around the second call but ours — the one suggested to introduce here — would be the first, so we cannot do anything about that, correct? |
If found: yes, but your example did add_subdirectory and then if(NOT expat_FOUND) and never called find_package.
From the docs:
Nope: The call would be the second one if the first one is find_package (that succeeds) and then the source is pulled without checking the result. Or if the source is pulled with another name a second time, but that would be plain bullshit. |
@Vollstrecker I think we're both referring to my example from #903 (comment) here, correct? FetchContent_Declare(
expat
GIT_REPOSITORY https://github.com/libexpat/libexpat/
GIT_TAG 88b3ed553d8ad335559254863a33360d55b9f1d6 # i.e. R_2_6_3
FIND_PACKAGE_ARGS
)
FetchContent_MakeAvailable(expat)
if(NOT expat_FOUND) # with regard to find_package
add_subdirectory("${expat_SOURCE_DIR}/expat")
add_library(expat::expat ALIAS expat)
endif() Here
There is nothing in there claiming that FetchContent_Declare(
expat
GIT_REPOSITORY https://github.com/libexpat/libexpat/
GIT_TAG 88b3ed553d8ad335559254863a33360d55b9f1d6 # i.e. R_2_6_3
SOURCE_SUBDIR expat/
OVERRIDE_FIND_PACKAGE
)
FetchContent_MakeAvailable(expat)
find_package(expat)
I see. Having thought about this pull request more I come to this conclusion:
|
Actions(deps): Bump actions/upload-artifact from 4.3.6 to 4.4.0 Merge pull request libexpat#898 from libexpat/gitignore-sync `.gitignore`: Add missing example `element_declarations` Merge pull request libexpat#902 from libexpat/tests-reduce-use-of-global-parser Tests: Reduce use of global parser Merge pull request libexpat#904 from libexpat/tests-resolve-duplicate-handler tests: Resolve duplicate handler `accumulate_char_data` Merge pull request libexpat#906 from libexpat/dependabot/github_actions/actions/checkout-4.2.0 Actions(deps): Bump actions/checkout from 4.1.7 to 4.2.0 Merge pull request libexpat#905 from libexpat/readme-document-use-via-cmake-fetchcontent `README.md`: Document use of Expat via CMake >=3.18 with `FetchContent` and `SOURCE_SUBDIR` Merge pull request libexpat#903 from Vollstrecker/patch-1 Add alias expat::expat Merge pull request libexpat#907 from libexpat/ci-clang-19 CI: Upgrade to Clang 19 Merge pull request libexpat#910 from libexpat/fix-ci Fix CI / `linux.yml`: Fix mishandling of package `debsuryorg-archive-keyring` Merge pull request libexpat#912 from libexpat/dependabot/github_actions/actions/upload-artifact-4.4.3 Actions(deps): Bump actions/upload-artifact from 4.4.0 to 4.4.3 Merge pull request libexpat#911 from libexpat/dependabot/github_actions/actions/checkout-4.2.1 Actions(deps): Bump actions/checkout from 4.2.0 to 4.2.1 Merge pull request libexpat#913 from libexpat/migrate-off-of-soon-gone-macos-12 `macos.yml`: Drop `macos-12` and add `macos-15` Merge pull request libexpat#914 from hannob/fixformatsign Fix signedness of format strings Merge pull request libexpat#917 from libexpat/dependabot/github_actions/actions/checkout-4.2.2 Actions(deps): Bump actions/checkout from 4.2.1 to 4.2.2 Merge pull request libexpat#915 from libexpat/stop-resumeparser-from-crashing [CVE-2024-50602] Stop `XML_ResumeParser` from crashing Merge pull request libexpat#918 from libexpat/issue-317-improve-tests Improve tests for libexpat#317 (follow-up to libexpat#318) Merge pull request libexpat#920 from libexpat/issue-919-prepare-release Prepare release 2.6.4 (part of libexpat#919, ETA 2024-11-xx)
As the find module and the config create the expat::expat alias for expat, the build-process should do this also to make it easier to include this in a chainbuild