CadQuery / ocp-build-system

A system to build Python wheel PyPI packages for OCP.
Apache License 2.0
8 stars 11 forks source link

Error Saying We Need to Compile Wheel On Older Toolchain #1

Closed jmwright closed 2 years ago

jmwright commented 2 years ago

@fpq473 and @roipoussiere

I'm trying to update the wheel builds in CI to support OCP 7.6.*, and I'm getting this error. Did either of you experience this when you were originally figuring out this build method?

fpq473 commented 2 years ago

From the 3.9 ubuntu logs:

DEBUG:auditwheel.policy.versioned_symbols:Package requires GLIBCXX_3.4.30, incompatible with policy manylinux_2_31_x86_64 which requires {'GLIBCXX_3.4.16', 'GLIBCXX_3.4.20', 'GLIBCXX_3.4.4', 'GLIBCXX_3.4.15', 'GLIBCXX_3.4.23', 'GLIBCXX_3.4.24', 'GLIBCXX_3.4.27', 'GLIBCXX_3.4.25', 'GLIBCXX_3.4.2', 'GLIBCXX_3.4.6', 'GLIBCXX_3.4.1', 'GLIBCXX_3.4.8', 'GLIBCXX_3.4.21', 'GLIBCXX_3.4.26', 'GLIBCXX_3.4.9', 'GLIBCXX_3.4.10', 'GLIBCXX_3.4.13', 'GLIBCXX_3.4.18', 'GLIBCXX_3.4.17', 'GLIBCXX_3.4.12', 'GLIBCXX_3.4.3', 'GLIBCXX_3.4.22', 'GLIBCXX_3.4.7', 'GLIBCXX_3.4.11', 'GLIBCXX_3.4.5', 'GLIBCXX_3.4.14', 'GLIBCXX_3.4', 'GLIBCXX_3.4.19', 'GLIBCXX_3.4.28'}

This seems consistent with the fact that GLIBCXX_3.4.30 comes with GCC 12.1.0 (according to this) and I see this in the conda env:

The following packages will be downloaded:

    package                    |            build
    ---------------------------|-----------------
    ...
    libstdcxx-ng-12.1.0        |      ha89aaad_16         4.3 MB  conda-forge

I don't know how OCCT and OCP (and possibly other things) were built, but is it possible to build them using an older version of GCC? GCC 10.1.0 uses GLIBCXX_3.4.28 and that is provided as part of the manylinux_2_31 standard. I found a commit which suggests this might be possible.

Put another way, though I'm really out of my depth here, is it possible to build a OCP conda pkg that works with libstdcxx-ng-10.1.0? I tried imposing this condition on conda-install and it refused.

The alternative is to wait for a manylinux_2_35 standard to be established. But this may take time, and I believe this also then restricts the wheel to environments where glibc 2.35 is available (ubuntu 22.04 and later, fedora 36 and later).

mojca commented 2 years ago

Do you happen to know which dependency pulls in gcc (libstdcxx) 12? I have zero experience with conda, but I would suspect that this dependency might be pulled in just because it simply installs the latest available/compatible version of everything?

fpq473 commented 2 years ago

@mojca I'm not too familiar with conda either and wasn't able to figure out the dependencies.

But I was able to create a pseudo-"manylinux_2_35" wheel simply by allowing GLIBCXX_3.4.30. Then I examined the libraries in the wheel, and found:

# objdump -D -C ./cadquery_ocp.libs/* | grep -E '^[.]/|GLIBCXX_3.4.30'

./cadquery_ocp.libs/libvtkCommonCore-9-c55e73f7.1.so.9.1.0:     file format elf64-x86-64
  3551ce:   ff 15 14 e5 41 00       callq  *0x41e514(%rip)        # 7736e8 <std::condition_variable::wait(std::unique_lock<std::mutex>&)@GLIBCXX_3.4.30>

./cadquery_ocp.libs/libvtkIOAsynchronous-9-510bd448.1.so.9.1.0:     file format elf64-x86-64
    5bde:   ff 15 b4 60 00 00       callq  *0x60b4(%rip)        # bc98 <std::condition_variable::wait(std::unique_lock<std::mutex>&)@GLIBCXX_3.4.30>
    75e6:   ff 15 ac 46 00 00       callq  *0x46ac(%rip)        # bc98 <std::condition_variable::wait(std::unique_lock<std::mutex>&)@GLIBCXX_3.4.30>

./cadquery_ocp.libs/libvtkIOFFMPEG-9-be851eba.1.so.9.1.0:     file format elf64-x86-64
    c2ab:   ff 15 5f 79 00 00       callq  *0x795f(%rip)        # 13c10 <std::condition_variable::wait(std::unique_lock<std::mutex>&)@GLIBCXX_3.4.30>
    c8f2:   ff 15 18 73 00 00       callq  *0x7318(%rip)        # 13c10 <std::condition_variable::wait(std::unique_lock<std::mutex>&)@GLIBCXX_3.4.30>
    cffd:   ff 15 0d 6c 00 00       callq  *0x6c0d(%rip)        # 13c10 <std::condition_variable::wait(std::unique_lock<std::mutex>&)@GLIBCXX_3.4.30>
    d13d:   ff 15 cd 6a 00 00       callq  *0x6acd(%rip)        # 13c10 <std::condition_variable::wait(std::unique_lock<std::mutex>&)@GLIBCXX_3.4.30>

So it seems like those three VTK libs (as compiled for conda) need GLIBCXX_3.4.30.

If there's a better way to analyze what dependencies the "manylinux_2_35" wheel has, please let me know and I can run it.

mojca commented 2 years ago

vtk says that it needs gcc >= 4.8 (the code needs at least C++11) and wheels are provided for manylinux2014.

This is how they seem to build the wheels: https://gitlab.kitware.com/vtk/vtk/-/blob/master/.gitlab/os-linux.yml

It makes sense to start investigating what happens if one tries to install just vtk (via either conda or pip). I see no reason why gcc 12 would be pulled in (other than opportunistically taking the latest version). There should be a way to specify the version of gcc explicitly.

jmwright commented 2 years ago

@fpq473 @mojca So can we just not copy the VTK libs before running auditwheel and add the vtk wheel as a dependency in setup.py, or will that cause other problems?

fpq473 commented 2 years ago

@mojca I'm clearly not understanding something (or maybe everything), because I followed your suggestion:

# mamba install python=3.9 vtk=9.1 'libstdcxx-ng<11'

This succeeds, but I still see:

# objdump -CD ./opt/conda/lib/libvtkIOFFMPEG-9.1.so | grep CXX_3.4.30
    c2ab:       ff 15 5f 79 00 00       callq  *0x795f(%rip)        # 13c10 <std::condition_variable::wait(std::unique_lock<std::mutex>&)@GLIBCXX_3.4.30>
    ...

@jmwright I've considered that idea before.

I also just tried the following variant:

  1. Install ocp 7.6 and vtk 9.1 into conda.
  2. Forcibly delete all vtk files.
  3. pip install vtk (manylinux wheel)
  4. For every conda-provided file that points to the conda-provided vtk (now deleted), use patchelf to make it point to the pip-provided vtk.
  5. As is done currently, put vtk and OCP into a wheel and run auditwheel.

This produces a manylinux_2_31 that appears to work with https://github.com/CadQuery/cadquery/pull/1156.

fpq473 commented 2 years ago

Managed to get 7.6.3a0 manylinux_2_31 wheels built here: https://github.com/CadQuery/ocp-build-system/actions/runs/3169218456

@jmwright Is it safe to simply trigger the release workflow?

jmwright commented 2 years ago

@fpq473 Thanks!

I believe that a tag for the release has to be created in this repo before running the release workflow. It also looks like version 7.5.3 is hard coded into the release workflow. I was probably just trying to get everything working and forgot to make it more generic later. https://github.com/CadQuery/ocp-build-system/blob/main/.github/workflows/release.yml

fpq473 commented 2 years ago

The wheels seem to be properly named now, e.g.

Uploaded /home/runner/work/ocp-build-system/ocp-build-system/dist/cadquery_ocp-7.6.3a0-cp310-cp310-manylinux_2_31_x86_64.whl (100.0%) bytes 134217728:140563693

link

So should I create a 7.6.3a0 release using these instructions (which include making the tag)? https://docs.github.com/en/repositories/releasing-projects-on-github/managing-releases-in-a-repository#creating-a-release

And then trigger the release workflow?

jmwright commented 2 years ago

Sure.

a0 (as you have above) is the proper designation rather than alpha0, correct?

fpq473 commented 2 years ago

Yes, a0 is correct per https://peps.python.org/pep-0440/#pre-releases.

I'll give it a shot now.

jmwright commented 2 years ago

I would say this issue has been addressed. Thanks again @fpq473 !