pcb2gcode / pcb2gcode

Command-line tool for isolation, routing and drilling of PCBs
GNU General Public License v3.0
399 stars 98 forks source link

Which libgeos version? #681

Open typerat opened 10 months ago

typerat commented 10 months ago

Description of bug:

I'm trying to build pcb2gcode into a Docker image, as I've had trouble in the past with dependencies on different machines. Here's my Dockerfile(remove .txt extension). It needs tidying, but illustrates the issue I face right now. Comment out the respective lines, then build it with docker build -t pcb2gcode . and run docker run --rm pcb2gcode to reproduce the issue. Any help appreciated :pray:

What did you try (include command-line arguments):

  1. Just including pcb2gcode in the image (L31) This fails for obvious reasons, it requires some dependencies (gerbv initially).

  2. Installing gerbv in the image (L29) Now tells me another dependency it's missing:

    /usr/bin/pcb2gcode: error while loading shared libraries: libgeos.so.3.12.0: cannot open shared object file: No such file or directory

    Looks like it wants v3.12.0 of that library.

  3. Installing libgeos v3.12.0 (L32) Seems like it isn't compatible with that version?

    /usr/bin/pcb2gcode: Symbol `_ZTVN4geos4geom18GeometryCollectionE' has different size in shared object, consider re-linking
    /usr/bin/pcb2gcode: Symbol `_ZTVN4geos4geom5PointE' has different size in shared object, consider re-linking
    /usr/bin/pcb2gcode: Symbol `_ZTVN4geos4geom10LinearRingE' has different size in shared object, consider re-linking
    /usr/bin/pcb2gcode: Symbol `_ZTVN4geos4geom7PolygonE' has different size in shared object, consider re-linking

    Actually putting data into pcb2gcode causes a segfault.

What happened:

pcb2gcode is unclear about which version of libgeos it needs. It seems to say it wants v3.12.0, but fails to run with that version.

What did you expect to happen:

pcb2gcode running as intended (or telling me the next missing dependency.

pcb2gcode version (run pcb2gcode --version to see this):

v2.5.0 binary downloaded from GitHub release.

eyal0 commented 10 months ago

In your docker file, it seems that you copied the pcb2gcode binary into the second container but you did not copy the libgeos shared object. You need to copy both, right?

eyal0 commented 10 months ago

How about this Dockerfile:

FROM ubuntu:latest as builder

RUN apt-get update
RUN apt-get install -y curl jq bzip2 cmake g++

WORKDIR /tmp

# get latest pcb2gcode release
RUN export URL="$(curl -s https://api.github.com/repos/pcb2gcode/pcb2gcode/releases/latest | jq -r .assets[0].browser_download_url)" && \
    curl -s -L -o /tmp/pcb2gcode.tar.gz $URL
RUN tar -xvf /tmp/pcb2gcode.tar.gz && rm pcb2gcode.tar.gz && mv pcb2gcode* pcb2gcode

# get latest geos release
RUN export URL="$(curl -s https://api.github.com/repos/libgeos/geos/releases/latest | jq -r .assets[0].browser_download_url)" && \
    curl -s -L -o /tmp/geos.tar.bz2 $URL
RUN tar -xvf /tmp/geos.tar.bz2 && rm geos.tar.bz2 && mv geos* geos

# build geos
RUN mkdir /tmp/geos/build
WORKDIR /tmp/geos/build
RUN cmake -DCMAKE_BUILD_TYPE=Release ..
RUN make -j 20
RUN make install

RUN apt-get install -y gerbv

ENTRYPOINT [ "/tmp/pcb2gcode/pcb2gcode" ]

This works for me:

docker build -t pcb2gcode
docker run --rm pcb2gcode --version
└──> docker run --rm pcb2gcode --version
/tmp/pcb2gcode/pcb2gcode: Symbol `_ZTVN4geos4geom18GeometryCollectionE' has different size in shared object, consider re-linking
/tmp/pcb2gcode/pcb2gcode: Symbol `_ZTVN4geos4geom5PointE' has different size in shared object, consider re-linking
/tmp/pcb2gcode/pcb2gcode: Symbol `_ZTVN4geos4geom10LinearRingE' has different size in shared object, consider re-linking
/tmp/pcb2gcode/pcb2gcode: Symbol `_ZTVN4geos4geom7PolygonE' has different size in shared object, consider re-linking
2.5.0
Git commit: v2.5.0
Boost: 106600
Gerbv: 2.7A~714932
Geos: 3.12.0dev
mateusznowakdev commented 10 months ago

Hi,

is libgeos really necessary? I've had some dependency problems as well, and it seems like pcb2gcode works fine without geos, following the instructions in README:

FROM debian:11

RUN apt-get update \
    && apt-get install build-essential automake autoconf autoconf-archive libtool libboost-program-options-dev libgtkmm-2.4-dev gerbv git librsvg2-dev -y

RUN git clone https://github.com/pcb2gcode/pcb2gcode.git \
    && cd pcb2gcode \
    && git checkout v2.5.0 \
    && autoreconf -fvi \
    && ./configure \
    && make \
    && make install

(I can't make it to run with stable Debian, because gerbv is not detected even if it's installed... but it works fine with oldstable.)

Output:

2.5.0
Git commit: v2.5.0
Boost: 107400
Gerbv: 2.7.0
Geos: Not installed
typerat commented 10 months ago

Thanks for taking a look at this! @eyal0 copying geos to the final image is step 3 of the things I tried (Line 32, only commented out in the Dockerfile I uploaded to show the first error). When it's present, I get the same result as you, with the linker warnings about different size. If you try to run pcb2gcode from your image with actual input data, it should fail as well. The version command likely doesn't call any of the geometry functions, so it won't segfault.

eyal0 commented 10 months ago

The geos in the release doesn't match the geos that you're installing.

If you're going to the trouble of compiling geos, how about you just compile pcb2gcode, too?

typerat commented 10 months ago

The geos in the release doesn't match the geos that you're installing.

Where is that version specified? I assumed the error message /usr/bin/pcb2gcode: error while loading shared libraries: libgeos.so.3.12.0: cannot open shared object file: No such file or directory was referring to the expected version.

If you're going to the trouble of compiling geos, how about you just compile pcb2gcode, too?

I thought I could take a shortcut by using the pre-compiled version, as building pcb2gcode apparently isn't as easy as geos. I'll look into that next. I'd still have to specify the required geos version somewhere, right? In case it isn't obvious, I have close to no experience in compiling C++ projects.

eyal0 commented 10 months ago

You built geos in one container and then you copied pcb2gcode into another container but you copied it without the geos library! You would need to copy both.

typerat commented 10 months ago

Sorry for the confusion. The Dockerfile I uploaded represents the state at step 2 of my initial comment. If you uncomment L32 in that Dockerfile (COPY --from=builder /tmp/geos/build/lib/libgeos.so.3.12.0 /usr/lib), then it copies both pcb2gcode and geos (corresponding to step 3 of my initial comment). If you try to run that, you get the same result as with the Dockerfile from your comment.

eyal0 commented 10 months ago

I see. Hmm. Maybe the one that I build from in the CI is not the same as the one that you built from?

eyal0 commented 10 months ago

Yeah, I'm not using a fixed version of geos:

https://github.com/pcb2gcode/pcb2gcode/blob/master/.github/workflows/ci.yml#L174

So it makes sense that we'd get those warnings and errors. I guess don't use the release? I was never very good at that release stuff anyway.

pisemsky commented 2 weeks ago

On GNU Guix the current release of pcb2gcode v2.5.0 does not build with the current geos version 3.12.1 throwing the following error:

geos_helpers.cpp:7:10: fatal error: geos/geom/CoordinateSequenceFactory.h: No such file or directory
    7 | #include <geos/geom/CoordinateSequenceFactory.h>
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.

But with geos downgraded to version 3.11.4 it builds successfully.

Maybe this information answers the question from the issue title.