Hoping to make a aarch64-darwin flake for Cadquery / OCP -- libclang.dylib woes

Hi all,

My work so far: GitHub - n8henrie/nix-cadquery: nix-cadquery (currently not even close)

I’ve been spinning my wheels for a couple weeks trying to make my first “real” flake / package (something that actually requires build steps and is somewhat complex) – my goal is to use nix to get cadquery working in a jupyterlab environment: GitHub - CadQuery/cadquery: A python parametric CAD scripting framework based on OCCT

I’ve never used cadquery, so this as much a “nix learning adventure” as anything. I’m pretty familiar with python but relatively new to nix and totally new to cmake, c++, and clang, so I have my work cut out for me. Thankfully there are a few things going for me: a couple existing projects for Linux I can use for ideas, some sketched out instructions for building with conda / docker, and I have no immediate need for cadquery (and could always just use conda like their team recommends) to there is no deadline to meet.

I’m hoping to document my path in this post, and also get some pointers along the way. In particular, I’m struggling right off the bat to sort out what combination of llvmPackages_??.libclang.{lib,dev,cc} - ?-unwrapped ?apple_sdk or stdenv I’m supposed to be using (and how I can guess better going foward).

It looks like several of the dependencies like VTK and opencascade are already packaged so I can hopefully use them when I get a little farther.

Overall, my understanding is that I need to:

  1. build pywrap
  2. use pywrap to create the bindings to OCCT, specifically using the -l flag to specify a path to libclang.dylib and one or more -i for includes.
  3. use those to build OCP
  4. I think the final step will be tying things together in a python environment with cadquery and jupyterlab, which imports the arm64 OCP from step 3.

Right now, my flake seems able to build the python-clang dependency and pywrap package.

I was able to find a very helpful thread of someone working through M1 compilation that includes an example pywrap script that worked. I can use my nix-built pywrap with this script and it seems to successfully run the pywrap step. However, this script is impure and specifically references e.g. -l /Library/Developer/CommandLineTools/usr/lib/libclang.dylib.

This is the first part I need help with. I copied the script linked in that post, and locally cloned the OCP repo (and submodules), and I’m trying to replace the impure dependencies with nix versions (to make sure I can manually build, before I try to turn the whole thing into a derivation). However, taking libclang.dylib from nixpkgs is giving me a lot of errors that I’m not seeing when using the dependencies from MacOS.

My version that seems to build manually: https://github.com/n8henrie/nix-cadquery/blob/3adc4c1590b46a00b57d8826548184c7789199c8/pywrap-manual.sh

If I, for example, use nix-locate libclang.dylib to find a likely candidate and

diff --git a/pywrap-manual.sh b/pywrap-manual.sh
index 05e2616..df38ce3 100755
--- a/pywrap-manual.sh
+++ b/pywrap-manual.sh
@@ -17,7 +17,7 @@ main() {
     -i /Library/Developer/CommandLineTools/SDKs/MacOSX12.sdk/usr/include/c++/v1 \
     -i /Library/Developer/CommandLineTools/SDKs/MacOSX12.sdk/usr/include \
     -i /opt/homebrew/Caskroom/miniconda/base/envs/cadquery/include/vtk-9.2 \
-    -l /Library/Developer/CommandLineTools/usr/lib/libclang.dylib \
+    -l "$(nix build --print-out-paths --no-link github:nixos/nixpkgs#libclang.lib)/lib/libclang.dylib" \
     all ocp.toml
 }
 main "$@"

However, this then gives me a bunch of complaints about fatal error: 'stdarg.h' file not found

So then I nix-locate this file, then add:

-i "$(nix build --print-out-paths --no-link github:nixos/nixpkgs#libclang.lib)/lib/clang/11.1.0/include" \

That works, but then once I try to remove /Library/Developer/CommandLineTools/SDKs/MacOSX12.sdk/usr/include/c++/v1, I now get a bunch of

./opencascade/Standard_Std.hxx:20:10: fatal error: 'type_traits' file not found

Via nix-locate, it looks like libcxx.dev might be a good source for this:

-i "$(nix build --print-out-paths --no-link github:nixos/nixpkgs#libcxx.dev)/include/c++/v1" \

Now I am getting fatal error: 'stddef.h' file not found:

[W 230517 07:42:28 translation_unit:48] /nix/store/insw8afz8y04rzv323dra01rl5ppqr38-libcxx-11.1.0-dev/include/c++/v1/cstddef:44:15: fatal error: 'stddef.h' file not found

Repeat the process, it looks like stddef.h is already in a path included above:

$ file "$(nix build --print-out-paths --no-link github:nixos/nixpkgs#libclang.lib)/lib/clang/11.1.0/include/stddef.h"
/nix/store/mr9nvdpa2avn4w65aazv988chypyhxfl-clang-11.1.0-lib/lib/clang/11.1.0/include/stddef.h: C++ source, ASCII text

So what gives, why is this not found?

Because the working impure script is using paths from /Library/Developer/CommandLineTools/SDKs/MacOSX12.sdk I was thinking that perhaps I need to include some paths from darwin.apple_sdk.MacOSX-SDK, but I don’t see libclang.dylib anywhere there (though I’m not convinced that nix-locate is searching those paths):

$ nix-locate clang | awk '$1 ~ /darwin/'
$ 

Thanks in advance for thoughts on how I can move forward, and as always suggestions to improve my process going forward. As I mentioned, this is my first time trying to package some thing moderately complex, so I welcome feedback!

Prior work

Other helpful links

1 Like