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

[curses] New meta port #22093

Closed
wants to merge 5 commits into from
Closed

[curses] New meta port #22093

wants to merge 5 commits into from

Conversation

dg0yt
Copy link
Contributor

@dg0yt dg0yt commented Dec 19, 2021

@dg0yt
Copy link
Contributor Author

dg0yt commented Dec 19, 2021

NB: Windows static triplets available for CI test after merging #22092.

@LilyWangLL LilyWangLL added the category:new-port The issue is requesting a new library to be added; consider making a PR! label Dec 20, 2021
@LilyWangLL LilyWangLL added the info:reviewed Pull Request changes follow basic guidelines label Dec 20, 2021
@cenit
Copy link
Contributor

cenit commented Dec 20, 2021

what about making ports depending on pdcurses/ncurses depending on this one, instead?

@@ -0,0 +1,20 @@
if(NOT DEFINED CURSES_NEED_NCURSES)
Copy link
Member

Choose a reason for hiding this comment

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

I think we should generate this file with the selection here rather than trying to derive it; I'm concerned that this form makes it path dependent since the supports for this port and the dependencies don't match exactly. Does that seem reasonable?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Generating from portfile is a reasonable request. However this introduces redundancy in implementing the platform condition. This is one reason why I didn't start with that complexity.

(The only way to carry variable dependency information to the portfile is through features. The ideal solution would be attaching platform expressions to members of the default-features array...)

Copy link
Member

Choose a reason for hiding this comment

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

It is unfortunate that it introduces redundancy; however, I'm worried about a case like:

  • A depends on curses

  • B depends on curses

  • The end user wants a program that links with A and B

  • vcpkg install pdcurses

  • vcpkg install A (which installs curses as a dependency, A was built with pdcurses)

  • vcpkg install ncurses

  • vcpkg install B (whoops, now B was built with ncurses because that's what this wrapper prefers)

  • End user program is doomed because the different curses provide different features and/or expect to track information about the console in different globals, etc.

If there is some reason that pdcurses and ncurses can never be installed at the same time, and thus this kind of phantom switch triggered by vcpkg install ncurses can't happen, then we can avoid that.

Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
if(NOT DEFINED CURSES_NEED_NCURSES)
if("@CURSES_BACKEND@" STREQUAL "ncurses")
...
elseif("@CURSES_BACKEND@" STREQUAL "pdcurses")
...
else()
message(FATAL_ERROR "Unknown backend: '@CURSES_BACKEND@'")
endif()

@BillyONeal BillyONeal added requires:author-response and removed info:reviewed Pull Request changes follow basic guidelines labels Dec 20, 2021
@BillyONeal
Copy link
Member

Thanks for fixing this!

@dg0yt
Copy link
Contributor Author

dg0yt commented Dec 20, 2021

what about making ports depending on pdcurses/ncurses depending on this one, instead?

This is left as a separate exercise. Since depending ports can't rely on a simple find_package(Curses) right now, this needs more work.

@dg0yt
Copy link
Contributor Author

dg0yt commented Dec 20, 2021

For the record:

ncurses documentation proposes #include <ncurses.h>. But IIUC the current interaction of CMake and port ncurses requires #include <ncurses/ncurses.h>, and also #include <ncurses/curses.h>.

This port changes that behaviour if CURSES_NEED_NCURSES is not set, by making the ncurses directory part of the include search path.

@BillyONeal
Copy link
Member

what about making ports depending on pdcurses/ncurses depending on this one, instead?

This is left as a separate exercise. Since depending ports can't rely on a simple find_package(Curses) right now, this needs more work.

Fair enough. :) What do you think about the phantom dependency switch concern I discussed in the review comment earlier?

@dg0yt
Copy link
Contributor Author

dg0yt commented Dec 31, 2021

What do you think about the phantom dependency switch concern I discussed in the review comment earlier?

The phantom dependency switching is a general problem, isn't it? It is also what happens with unguarded discovery like

find_package(Pkg)
if(Pkg_FOUND)
    enable_feature(...)

Normally, we need to turn this unguarded discovery into explicit control. With the curses wrapper, I see two layers of this problem: It must do nothing if there is no explicit dependency on curses, and otherwise it must select the implementation which matches curses' dependencies.

The only way I see to handle this situation here is using vcpkg-port-config.cmake: If and only if a port directly depends on port curses, the wrapper may make a choice representing the explicit dependendencies. curses is probably used only for tools, but if it is used for a lib, the choice must also be forwarded to downstream users... perhaps feasible with cmake targets, but starting to leave the trivial sector.
vcpkg-port-config.cmake also doesn't work with user projects. No problem if there is only a single implementation installed. But with alternatives, we need user input (a variable) or we must fail.

@BillyONeal
Copy link
Member

The phantom dependency switching is a general problem, isn't it?

It's a more general problem if things end up getting selected from the system but not generally if someone stays within the catalog right now.

The only way I see to handle this situation here is using vcpkg-port-config.cmake: If and only if a port directly depends on port curses, the wrapper may make a choice representing the explicit dependendencies.

I don't understand why there would need to be a vcpkg-port-config.cmake; all the port has to do is have a separate vcpkg-cmake-wrapper.cmake for pdcurses and ncurses, and install the matching one.

@BillyONeal
Copy link
Member

what about making ports depending on pdcurses/ncurses depending on this one, instead?

This is left as a separate exercise. Since depending ports can't rely on a simple find_package(Curses) right now, this needs more work.

Wait, now I'm confused. Is the entire purpose of this port not to make that work?

@dg0yt
Copy link
Contributor Author

dg0yt commented Jan 7, 2022

It's a more general problem if things end up getting selected from the system but not generally if someone stays within the catalog right now.

It is a problem within the catalog: if a port build randomly picks a dependency already installed at build time, but doesn't make it part of its ABI hash and doesn't forward the usage requirements. In the best case, it explodes right at consuming the port in a build. In the worst case, it explodes randomly at run-time.

All the port has to do is have a separate vcpkg-cmake-wrapper.cmake for pdcurses and ncurses, and install the matching one.

For now this should work.

@@ -0,0 +1,20 @@
if(NOT DEFINED CURSES_NEED_NCURSES)
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
if(NOT DEFINED CURSES_NEED_NCURSES)
if("@CURSES_BACKEND@" STREQUAL "ncurses")
...
elseif("@CURSES_BACKEND@" STREQUAL "pdcurses")
...
else()
message(FATAL_ERROR "Unknown backend: '@CURSES_BACKEND@'")
endif()

@@ -0,0 +1,3 @@
set(VCPKG_POLICY_EMPTY_PACKAGE enabled)
file(INSTALL "${CMAKE_CURRENT_LIST_DIR}/vcpkg-cmake-wrapper.cmake" DESTINATION "${CURRENT_PACKAGES_DIR}/share/${PORT}")
Copy link
Contributor

@strega-nil-ms strega-nil-ms Jan 7, 2022

Choose a reason for hiding this comment

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

Suggested change
file(INSTALL "${CMAKE_CURRENT_LIST_DIR}/vcpkg-cmake-wrapper.cmake" DESTINATION "${CURRENT_PACKAGES_DIR}/share/${PORT}")
if(VCPKG_TARGET_IS_WINDOWS AND NOT VCPKG_TARGET_IS_MINGW)
set(CURSES_BACKEND "pdcurses")
else()
set(CURSES_BACKEND "ncurses")
endif()
configure_file(
"${CMAKE_CURRENT_LIST_DIR}/vcpkg-cmake-wrapper.cmake"
"${CURRENT_PACKAGES_DIR}/share/${PORT}/vcpkg-cmake-wrapper.cmake"
@ONLY
)

I understand you don't want to re-write the logic, but I think that doing this in the build is necessary.

@dg0yt
Copy link
Contributor Author

dg0yt commented Jan 9, 2022

Updated.

I tried to find some test ports, but as expected, vcpkg's focus on libs doesn't help.
libmysql needs (n)curses on Linux but tells the user to install it from the system package manager.
behaviortree-cpp would use ncurses (not curses) but this is disabled in vcpkg.

@BillyONeal
Copy link
Member

If someone can't be expected to just say they need curses and be able to not care then I'm not sure what this change is doing?

@mathisloge mathisloge mentioned this pull request Jan 31, 2022
1 task
Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

You have modified or added at least one vcpkg.json where a "license" field is missing.

If you feel able to do so, please consider adding a "license" field to the following files:

  • ports/curses/vcpkg.json
  • scripts/test_ports/cmake-user/vcpkg.json

Valid values for the license field can be found in the documentation

@LilyWangLL LilyWangLL added the info:reviewed Pull Request changes follow basic guidelines label Feb 22, 2022
@BillyONeal
Copy link
Member

BillyONeal commented Mar 17, 2022

The reason I'm still in 'waiting' state here is that as far as I understand it there's still no practical use of this metaport, because every consumer described still needs to have the check for which particular curses that they got. Put another way, what would a consumer of this metaport look like?

Note that the "customer" doesn't need to be a port :)

@BillyONeal BillyONeal added requires:author-response and removed info:reviewed Pull Request changes follow basic guidelines labels Mar 17, 2022
@BillyONeal BillyONeal dismissed their stale review March 17, 2022 18:24

The requested configuration bit I asked for is fixed so I'm dropping 'request changes' status but I want the consumer question answered first.

@LilyWangLL
Copy link
Contributor

LilyWangLL commented Apr 12, 2022

The reason I'm still in 'waiting' state here is that as far as I understand it there's still no practical use of this metaport, because every consumer described still needs to have the check for which particular curses that they got. Put another way, what would a consumer of this metaport look like?

Note that the "customer" doesn't need to be a port :)

Ping @dg0yt for response. And could you please resolve the conflicts?

@LilyWangLL
Copy link
Contributor

Closing this PR since it seems that no progress is being made. Please reopen if work is still being done.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
category:new-port The issue is requesting a new library to be added; consider making a PR!
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants