Repository navigation
Conversation
On MSVC, OCCT's Standard_Handle.hxx defines `Handle_X` as a non-template subclass of `opencascade::handle<X>` (for C++/CLI export), whereas on other compilers it is a plain typedef. The C++ bridge assumed the typedef everywhere, so opencascade-sys fails to compile with MSVC (error C2440 / C2665) and, once that is fixed, fails to link. Changes: - Construct `Handle_X` directly instead of `opencascade::handle<X>` when wrapping in `std::unique_ptr<Handle_X>` (b_rep, gc, geom, geom2d, geom_api, top_tools). Identical on typedef compilers. In GCE2d_MakeSegment_point_point, go through a local `opencascade::handle<...>` first, since Handle_X's own constructors reject the MakeSegment implicit conversion. - cxx binds a function/member pointer directly to some OCCT methods that take `Handle(X)`. A pointer needs an exact type match, so the `Handle_X` parameter no longer matches on MSVC. Route these through small inline wrappers instead: BRepLib_ToolTriangulatedShape::ComputeNormals, BRepOffsetAPI_MakePipeShell::SetLaw, ShapeAnalysis_FreeBounds::ConnectEdgesToWires, and the generic `handle_try_deref<T>` (bound from poly.rs and top_tools.rs). The high-level crate call sites are updated accordingly. - Link advapi32 on Windows: TKernel's OSD_* uses the Win32 security and registry API, and linking any binary otherwise fails with ~23 unresolved externals (SetFileSecurityW, OpenProcessToken, ...). Tested only on Windows 11, MSVC 14.44 (VS 2022 17.14), OCCT 7.8.1 via occt-sys: `cargo build` and a test that builds a box and cylinder, subtracts/unions them, checks the exact volume, and writes STEP all pass. Not tested on Linux or macOS; the changes are meant to be no-ops there.
|
Thanks for this. camcraft is a CAM app built on You mentioned you couldn't test on macOS or Linux, so I tried this PR's head (00b4505) on macOS with Apple clang and OCCT 7.8.1 via
camcraft is also developed on macOS and has built there with these sources since September. I haven't tried Linux. It would be great to see this merged so camcraft can drop its vendored copy. |
…e-rs#234 No duplicate issue upstream: #234 is open, mergeable and a superset of the vendored patch here (it also wraps the cxx pointer bindings and links advapi32), with one downstream confirmation on Windows and macOS. Recorded in #1, the backlog and edition-publishing.md; the next step is to port it onto third_party/opencascade-sys rather than extend our own 17-line edit.
`third_party/opencascade-sys` is now a verbatim 0.3.0 with bschwind/opencascade-rs#234 applied (head 00b4505), replacing the local fix for the `unique_ptr` sites. The PR is a superset: it also wraps the cxx member/function-pointer bindings (`ComputeNormals`, `SetLaw`, `ConnectEdgesToWires`, `handle_try_deref<T>`), which we had not solved, and adds `advapi32` to the Windows link line — TKernel's `OSD_*` needs the Win32 security/registry API, so the final binary would have hit ~23 unresolved externals after the compile errors were gone. Only the `crates/opencascade-sys/` hunks are taken; the PR's `crates/opencascade/` call-site updates are for a crate this workspace does not use. `PATCHES.md` records the provenance (0.3.0 sha256 + PR head), the three failure classes, why the directory must keep the name `opencascade-sys` (the headers use `#include "opencascade-sys/include/…"`, which does not resolve in the registry's `opencascade-sys-0.3.0` checkout) and the removal condition: drop both the directory and the `[patch.crates-io]` entry once a published release carries the fix. Verified: `cargo check -p ferrocad_occt -p ferrocad_part` (every split bridge is recompiled). The Windows proof is the dispatch-only `.github/workflows/edition-windows.yml`.
|
Facing this issue when attempting to port FreeCAD's Part workbench to rust. Alternatively, upgrading to OCCT 8.0 seems to be a way forward as it dropped legacy MSVC support. Technical info: DetailsIndependent confirmation from a third downstream project [FerroCAD](https://github.com/ferrocad/ferrocad), a FreeCAD-compatible CAD app that links `opencascade-sys` through a vendored copy.The same three failure classes on a different toolchain: VS 18 / MSVC 14.51.36231, OCCT 7.8.1 from conda-forge (not
With this PR applied:
Nothing here looked risky to a consumer: the wrappers are all |
…lds on MSVC `gh workflow run edition-windows.yml` is green end to end on the vendored `opencascade-sys` (0.3.0 + upstream PR #234): kernel build, `xtask bundle --edition parametric --occt --check-init` boots the staged payload with only the bundled `lib/` on the loader path, the portable zip is produced, and `ferrocad.bat --check-init` passes on the unpacked artifact. - `release.yml`'s `edition` matrix regains the `windows-latest` entry, so a tag from here yields four artifacts (two base, two Parametric). Its comment records the OCCT `Handle_T` dependency. - `edition-windows.yml` stays, re-described as the dispatch-only reproduction of that leg rather than a pre-merge gate. - `v0.1.4` stays documented as three artifacts (its Windows leg predated the fix); `releasing.md`, `distribution.md`, `edition-publishing.md` §6, `packaging/*`, the README and the backlog now say the Windows Parametric zip returns with the next tag. The backlog item is closed with the mechanism and the links (#1, bschwind/opencascade-rs#234).
Fix Windows/MSVC build (
Handle_Xis a distinct class under MSVC)opencascade-sysdoes not build with MSVC today. I hit this while using the crate on Windows 11 with VS 2022 Build Tools (MSVC 14.44), OCCT 7.8.1 viaocct-sys(builtinfeature), at32758df.Root cause
OCCT's
Standard_Handle.hxxdefinesHandle_Xdifferently per compiler:Under MSVC
Handle_Xis a subclass ofopencascade::handle<X>, not an alias. The bridge assumes the alias in a few places, which shows up in three ways.What this PR changes
std::unique_ptr<Handle_X>(new opencascade::handle<X>(...))fails with C2440 (base-to-derived pointer). Nownew Handle_X(...), which is identical whereHandle_Xis a typedef (b_rep,gc,geom,geom2d,geom_api,top_tools). InGCE2d_MakeSegment_point_pointthe direct construction fromGCE2d_MakeSegmentis rejected byHandle_X's own constructors, so it goes through a localopencascade::handle<...>first.Handle(X). A pointer needs an exact type, so theHandle_Xparameter no longer matches (C2440 "overloaded-function"). These go through small inline wrappers instead:BRepLib_ToolTriangulatedShape::ComputeNormals,BRepOffsetAPI_MakePipeShell::SetLaw,ShapeAnalysis_FreeBounds::ConnectEdgesToWires, andhandle_try_deref<T>(bound frompoly.rsandtop_tools.rs). The call sites inopencascadeare updated.OSD_*uses the Win32 security/registry API, so any final binary fails with ~23 unresolved externals (SetFileSecurityW,OpenProcessToken,RegOpenKeyExW, ...). Addsadvapi32next to the existinguser32.19 files, +96/-31. No behaviour change intended on GCC/Clang.
Testing
Windows 11, MSVC 14.44, OCCT 7.8.1:
cargo buildsucceeds, and a downstream test that builds a box and a cylinder, does a union and a subtraction, checks the exact volume viaBRepGProp::VolumeProperties(1e-6), and writes STEP, passes.Not tested on Linux or macOS; I have no access to them. Reviewers there please check that nothing regresses. I also have not run the repo's own examples or
cargo testfor the whole workspace on Windows.Related note (not changed here)
The
#include "opencascade-sys/include/..."paths only resolve when the crate directory is literally namedopencascade-sys. Cargo's registry checkout isopencascade-sys-0.3.0, so the crates.io release does not build on Windows for that reason alone (the git dependency does). I worked around it by vendoring and did not touch it here; happy to open a separate issue if useful.🤖 Generated with Claude Code