How to create a development environment for build123d

Hello,

I am very new to Nix and NixOS since my first install 2024-03-15 19:52. I am learning how to create a development environment for build123d, a Python based CAD API. A few days have passed and the struggle continues . . . I almost have it (I think).

If you can, please review what I have done, help me get it working, and give me some suggestions. Also, I don’t know Haskell, JSON, or Nix . . . so if you can clue me into what some of the common and best practices are. Thanks for sharing your time.

Here is my work:

  • The intended goal is to create a python development shell for the CAD application build123d.

  • System Information:

$ nixos-version  
24.05pre608655.ff0dbd94265a (Uakari)

$ inxi -z
CPU: 8-Core AMD Ryzen 7 7730U with Radeon Graphics (-MT MCP-) speed/min/max: 2061/400/4546 MHz Kernel: 6.6.25 x86_64 
Up: 13h 20m Mem: 22698.6/63719.8 MiB (35.6%) Storage: 1.82 TiB (83.1% used) Procs: 466 Shell: Bash inxi: 3.3.04 
# Recommended
>>> pip install build123d

or

# Development
>>> python3 -m pip install --upgrade pip
>>> git clone https://github.com/gumyr/build123d.git
>>> cd build123d
>>> python3 -m pip install -e .
>>> python
>>> from build123d import *
>>> print(Solid.make_box(1,2,3).show_topology(limit_class="Face"))
  • The test should yield the results similar to:
Solid        at 0x165e75379f0, Center(0.5, 1.0, 1.5)
└── Shell    at 0x165eab056f0, Center(0.5, 1.0, 1.5)
        ├── Face at 0x165b35a3570, Center(0.0, 1.0, 1.5)
        ├── Face at 0x165e77957f0, Center(1.0, 1.0, 1.5)
        ├── Face at 0x165b3e730f0, Center(0.5, 0.0, 1.5)
        ├── Face at 0x165e8821570, Center(0.5, 2.0, 1.5)
        ├── Face at 0x165e88218f0, Center(0.5, 1.0, 0.0)
        └── Face at 0x165eb21ee70, Center(0.5, 1.0, 3.0)
  • The output from the configured shell does not match the expected result, it is instead:
$ python

Python 3.11.8 (main, Feb  6 2024, 21:21:21) [GCC 13.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.

>>> from build123d import *

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/technicus/Projects/CAD/build123d/build123d_03/build123d/lib/python3.11/site-packages/build123d/__init__.py", line 3, in <module>
    from build123d.build_common import *
  File "/home/technicus/Projects/CAD/build123d/build123d_03/build123d/lib/python3.11/site-packages/build123d/build_common.py", line 57, in <module>
    from build123d.geometry import Axis, Location, Plane, Vector, VectorLike
  File "/home/technicus/Projects/CAD/build123d/build123d_03/build123d/lib/python3.11/site-packages/build123d/geometry.py", line 54, in <module>
    from OCP.Bnd import Bnd_Box, Bnd_OBB
ImportError: libstdc++.so.6: cannot open shared object file: No such file or directory
  • It is evidently having a problem linking libstdc++.so.6 libraries.

  • I have tried to follow What package provides libstdc++.so.6? and others like it, but have had no success, considering that I am having a little trouble following how to implement any of the solutions.

Thanks for reviewing my post.

2 Likes

Yeah, you did get pretty close. :o)

The most immediate problem is in the shellHook of the shell-python.nix.

    # Augment the dynamic linker path
    export "LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${lib-path}"

    # fixes libstdc++ issues and libgl.so issues
    LD_LIBRARY_PATH = lib.makeLibraryPath [ pkgs.stdenv.cc.cc ];

In bash, A = abc and A=abc don’t mean the same thing. (And so this trips up when bash runs the shellHook).

The shellHook is a string that gets run by bash. – However, the ${...} values within the string get interpolated before being passed to bash. So, any “nix code” (like the lib.makeLibraryPath application) should be in a ${...}.

– I see these shells include e.g. lolcat and cowsay. That’s good troubleshooting instinct. The smaller problem to focus on could’ve been “why isn’t lolcat showing up?”. Perhaps adding a few echos into the shellHook (at the start, in the middle) would’ve helped you.

The next steps involve figuring out where to pass those native dependencies that Python wants. – Reading through the code, LD_LIBRARY_PATH uses lib-path, which is defined in terms of buildInputs, which also looks at the extraBuildInputs attribute that the shell-build123d.nix calls shell-python.nix with.

Should be:

  extraBuildInputs = with pkgs; [
    # this list contains packages that you want to be available at runtime and might not be able to be installed properly via pip
    stdenv.cc.cc.lib
  ];

I’d suggest putting those example Python commands in a script like demo.py

from build123d import *
print(Solid.make_box(1,2,3).show_topology(limit_class="Face"))

That way, you can see if this runs by running the command:

nix-shell shell-build123d.nix --command "python demo.py"

There are a few more shared libs you need, so extraBuildInputs needs a few more things. This’d best be left as an exercise, but you’re impatient:

  extraBuildInputs = with pkgs; [
    # this list contains packages that you want to be available at runtime and might not be able to be installed properly via pip
    stdenv.cc.cc.lib
    expat
    libGL
    xorg.libX11
    zlib
  ];
2 Likes

:sparkles: WOW! THANKS!!! :sparkles:

I knew it had to be something small.
I was also expecting more libraries to be needed.

This is awesome!

My first Nix shell . . . I have been struggling a few days.
A few people were insisting that I give up and leave Nix behind.

Or . . . try different approaches, like SergeK’s response in Why is it so hard to use a Python package?.

Now, I almost understand most of what this shell is doing.
Your explanation is great, I am going to be rereading it many times!
That test suggestion is awesome too!

Thanks so much!!!

1 Like

An addition aspect has come to attention involving utility of tools for build123d. Specifically CQ-Editor, which is not in the Nix packages. There is a release which I can download, but due to how Nix manages packages, the binary can not be started.

So I need to learn how to (Run non Nix executables)[Frequently Asked Questions — nix.dev documentation]. There are multiple methods, I will start with trying to add a library path that only applies to CQ-Editor by using nix-ld. Source code is available, so I will also try compiling it.

This is so exciting!

There is also now cq-flake for the editor, although I can’t speak to how well it works