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

Build and run tests for CMake builds #162

Closed
wants to merge 7 commits into from

Conversation

StefanBruens
Copy link
Contributor

[ This MR contains everything from #161, as building is to broken otherwise. MR #161 should be merged first ]

Add the missing definitions for building and running the test when using the CMake build.

In case `PYBIND11_PROTOBUF_ENABLE_PYPROTO_API` is not defined, the
py_proto_api_ member of the GlobalState singleton is never changed from
its default nullptr value.

Any code protected by a `GlobalState::instance()->py_proto_api()` check
can thus also be made dependent on the `PYPROTO_API` define. This allows
to remove the dependency on the proto_api.h header file.

As the call to check_unknown_fields::CheckRecursively is also protected
by the `py_proto_api()` it can be stubbed out.

See pybind#127.
The PYBIND11_PROTOBUF_ENABLE_PYPROTO_API define was never set in
CMake builds, add a corresponding option.

As the check_unknown_fields code is only called dependent on the
define remove it from the build if not used.
As pybind11 does not guarantee stable ABI for its types (e.g.
pybind11::handle), these types have "hidden" visibility at least on
Linux.

This visibility is propagated to any method which has any of the pybind11
types in its parameters, which is the case for many of the public methods
in proto_cast_util.{h,cc}. Trying to link to e.g. a SHARED
pybind11_native_proto_caster library will create linker errors to to
undefined symbols for any non-trivial case.

The other approach would be to move everything which uses a pybind11
type to the headers, and only leave pybind11 agnostic methods in the
shared library. While this is trivially possible for e.g.
PyBytesAsStringView, for the majority of the methods (e.g. anything
depending on the GlobalState object) a significant refactoring would
be required.

See pybind#160.
The current implementation reimplements CMake's native handling of
system packages, i.e. "FIND_PACKAGE_ARGS" in `FetchContent_Declare`.

Add options to force usage of system provided abseil-cpp/protobuf/pybind11,
to avoid having different versions here and in dependent packages.

Use the correct version for protobuf, v23.3 corresponds to 4.23.3.

The output for FetchContent is a little bit less verbose now, but in
case debugging is required it is much more useful to use the
"-DFETCHCONTENT_QUIET=False" option.
@StefanBruens StefanBruens force-pushed the cmake_add_tests branch 2 times, most recently from ad10fd1 to 1a48382 Compare June 15, 2024 01:47
Building and running tests was never implemented for CMake, create
the same test cases as for the Bazel build.

Use the standard "BUILD_TESTING" option (implicitly added by CTest).
@rwgk
Copy link
Contributor

rwgk commented Jun 15, 2024

Add the missing definitions for building and running the test when using the CMake build.

Wow, that's awesome, thanks a lot!

Source-of-truth for pybind11_protobuf is the Google codebase, which uses a completely different source code versioning system. I have some hope that we can get automatic import of PRs working early next week. We'll try that on your PRs.

@StefanBruens
Copy link
Contributor Author

Note, the automatic test run is currently missing in the workflow file, something like the following needs to be added (untested):

      - name: CMake Ctest run
        shell: bash
        run: |
          ctest --output-on-failure --test-dir ./build/

@rwgk
Copy link
Contributor

rwgk commented Jun 15, 2024

Note, the automatic test run is currently missing in the workflow file

Oh, I was wondering, thanks!

Could you add that to this PR? (Did you already and it needs more work?)

@StefanBruens StefanBruens force-pushed the cmake_add_tests branch 2 times, most recently from f744f92 to d64b104 Compare June 15, 2024 15:19
@rwgk
Copy link
Contributor

rwgk commented Jun 15, 2024

Hi @mkruskal-google, is there a chance that you could 1. review the cmake changes here, 2. maybe help troubleshooting the errors in the ubuntu-build / cmake job (in case @StefanBruens hasn't knocked them out already before you get a chance to look)?

@StefanBruens
Copy link
Contributor Author

Due to some very questionable decisions on the protobuf side, is is likely impossible to enable the tests with a protobuf checkout from github:

protocolbuffers/protobuf#15671

The CMake build does not generate the required python protocols, and thus anything from "google.protobuf" is not usable (e.g. desriptor_pb2.py is missing).

The only way I can see to make the tests work is to only use the system provided protobuf (i.e. protobuf and python3-protobuf). Of course this disallows usage of ENABLE_PYPROTO_API, though that is disabled by default anyway.

@StefanBruens
Copy link
Contributor Author

@rwgk My current suggestion would be to add another independent build, i.e. have "ubuntu-build / cmake" and "ubuntu-build / cmake-with-system-deps". The latter would use absl/protobuf/pybind11 from the Ubuntu base system (hopefully, that is recent enough), while the other build would keep using the stuff fetched from Github, but only builds the tests without running them.

- name: CTest Run
shell: bash
run: |
ctest --test-dir ./build --output-on-failure
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you please do something like this here?

echo 'DISABLED ctest --test-dir ./build --output-on-failure'

Just enough that GHA succeed. I think it's best to merge and do follow-on work separately.

(Aiming for merging on Monday.)

@StefanBruens
Copy link
Contributor Author

@rwgk My current suggestion would be to add another independent build, i.e. have "ubuntu-build / cmake" and "ubuntu-build / cmake-with-system-deps". The latter would use absl/protobuf/pybind11 from the Ubuntu base system (hopefully, that is recent enough), while the other build would keep using the stuff fetched from Github, but only builds the tests without running them.

Unfortunately, using system dependencies is not an option on Ubuntu/Debian, as the protobuf-devel package does not ship any CMake files (only fixed in Debian Experimental):

https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1027876

So, on Ubuntu pybind11_protobuf is more or less unusable:

  • You can not build with the system provided protobuf
  • You can not use the system provided python-protobuf, as that has a different version than the fetched protobuf
  • You can not use python-protobuf from the fetched sources, as that is not built

I have tested the CMake build and tests on openSUSE Tumbleweed, using the system packages, and all works fine ...

@rwgk
Copy link
Contributor

rwgk commented Jun 16, 2024

Ugh ... sorry to see you going through such a series of frustrations.

Do you want to remove the cmake-system-dependencies job again? — Then we can merge this PR (on Monday) and take it from there.

@StefanBruens
Copy link
Contributor Author

Ugh ... sorry to see you going through such a series of frustrations.

Do you want to remove the cmake-system-dependencies job again? — Then we can merge this PR (on Monday) and take it from there.

Yeah, thats unfortunately the only working solution at the moment. Even Ubuntu 2024.04 does not have a good protobuf package.

@rwgk
Copy link
Contributor

rwgk commented Jun 21, 2024

@StefanBruens I merged #165 and then updated this PR accordingly (using git merge main, resolving conflicts; I'm intentionally avoiding rebases and force pushes).

Test pass.

Could you please review my commits? I'll import this PR into the internal repo after your review.

@StefanBruens
Copy link
Contributor Author

@StefanBruens I merged #165 and then updated this PR accordingly (using git merge main, resolving conflicts; I'm intentionally avoiding rebases and force pushes).

Rebasing is totally fine when using it for merge requests, these are typically not considered public branches. More or less all projects I am aware of (Linux kernel, KDE, many others) use rebases. On the other hand, doing these reverts creates broken intermediate states, i.e. harming e.g. git bisect.

Could you please review my commits? I'll import this PR into the internal repo after your review.

Look ok so far.

copybara-service bot pushed a commit that referenced this pull request Jun 28, 2024
    Add the missing definitions for building the test when using the CMake build.

Manual import. The Google-internal repo is the source of truth for pybind11_protobuf. Sorry we didn't get to automating imports from GitHub PRs.

PiperOrigin-RevId: 647572543
@rwgk
Copy link
Contributor

rwgk commented Jun 28, 2024

I created the internal change, which is exported to #166.

I'll look for a reviewer internally tomorrow (my timezone).

On the other hand, doing these reverts creates broken intermediate states, i.e. harming e.g. git bisect.

The (my) main reason for avoiding rebases is that all references to commits to that point are invalidated.

In this repo, reverts in a PR don't matter for sure, because we have to go through the internal code base anyway (which exports as one commit).

More typical for github: On pybind11 master we always "Squash and merge". — I.e. with simple merges the developments under a PR are easy to follow (for a reviewer, or backtracking), but master receives only one commit, therefore bisecting later on master will not be affected by whatever happened under the PR.

copybara-service bot pushed a commit that referenced this pull request Jun 28, 2024
* Add the missing definitions for building the tests when using the CMake build.

Actually running the tests is left for another PR (see #162 for difficulties encountered):

* #162 (comment)

Manual import. The Google-internal repo is the source of truth for pybind11_protobuf. Sorry we didn't get to automating imports from GitHub PRs.

PiperOrigin-RevId: 647572543
copybara-service bot pushed a commit that referenced this pull request Jun 28, 2024
* Add the missing definitions for building the tests when using the CMake build.

Actually running the tests is left for another PR (see #162 for difficulties encountered):

* #162 (comment)

Manual import. The Google-internal repo is the source of truth for pybind11_protobuf. Sorry we didn't get to automating imports from GitHub PRs.

PiperOrigin-RevId: 647572543
copybara-service bot pushed a commit that referenced this pull request Jun 28, 2024
* Add the missing definitions for building the tests when using the CMake build.

Actually running the tests is left for another PR (see #162 for difficulties encountered):

* #162 (comment)

Manual import. The Google-internal repo is the source of truth for pybind11_protobuf. Sorry we didn't get to automating imports from GitHub PRs.

PiperOrigin-RevId: 647572543
copybara-service bot pushed a commit that referenced this pull request Jun 28, 2024
* Add the missing definitions for building the tests when using the CMake build.

Actually running the tests is left for another PR (see #162 for difficulties encountered):

* #162 (comment)

Manual import. The Google-internal repo is the source of truth for pybind11_protobuf. Sorry we didn't get to automating imports from GitHub PRs.

PiperOrigin-RevId: 647572543
copybara-service bot pushed a commit that referenced this pull request Jun 28, 2024
* Add the missing definitions for building the tests when using the CMake build.

Actually running the tests is left for another PR (see #162 for difficulties encountered):

* #162 (comment)

Manual import. The Google-internal repo is the source of truth for pybind11_protobuf. Sorry we didn't get to automating imports from GitHub PRs.

PiperOrigin-RevId: 647572543
copybara-service bot pushed a commit that referenced this pull request Jun 28, 2024
* Add the missing definitions for building the tests when using the CMake build.

Actually running the tests is left for another PR (see #162 for difficulties encountered):

* #162 (comment)

Manual import. The Google-internal repo is the source of truth for pybind11_protobuf. Sorry we didn't get to automating imports from GitHub PRs.

PiperOrigin-RevId: 647802705
@rwgk
Copy link
Contributor

rwgk commented Jun 29, 2024

#166 was merged. The only differences compared to this PR are:

# FIXME What is the difference to the "extension_test"?` comment 
# add_py_test(extension_disallow_unknown_fields)

Thanks to @laramiel for catching this!

@rwgk rwgk closed this Jun 29, 2024
@StefanBruens
Copy link
Contributor Author

I created the internal change, which is exported to #166.

I'll look for a reviewer internally tomorrow (my timezone).

On the other hand, doing these reverts creates broken intermediate states, i.e. harming e.g. git bisect.

The (my) main reason for avoiding rebases is that all references to commits to that point are invalidated.

For this, there must be an external reference in the first place. Github at least is fairly capable to keep track of rebases and keep references intact. The most typical references are done later, i.e. in other MRs/commits, but these reference
the commit which had been merged, but then the commit SHA is fixed. And by squashing the commits, all references to them were invalidated anyway.

In this repo, reverts in a PR don't matter for sure, because we have to go through the internal code base anyway (which exports as one commit).

More typical for github: On pybind11 master we always "Squash and merge". — I.e. with simple merges the developments under a PR are easy to follow (for a reviewer, or backtracking), but master receives only one commit, therefore bisecting later on master will not be affected by whatever happened under the PR.

Honestly, the "squash everything" approach is quite bad. By doing so, almost all of the commit messages were lost. Anyone looking for the reasoning of a change (i.e. via git annotate) will have a hard time to figure it out. E.g. there is no longer any mention of the change from SHARED to STATIC libraries, an no mention of the added CMake build options for system dependencies.

The git history should be the source of truth, without any dependencies where the git is hosted and how. Development history should not depend on any "external" sources, like github issues, or something internal to google. If it is not part of the commit message, consider it lost.

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.

2 participants