open62541 / open62541

Open source implementation of OPC UA (OPC Unified Architecture) aka IEC 62541 licensed under Mozilla Public License v2.0
http://open62541.org
Mozilla Public License 2.0
2.59k stars 1.24k forks source link

Build on 1.4 branch requires Linux header files #6360

Open sgoll opened 7 months ago

sgoll commented 7 months ago

Description

The dev version on the 1.4 branch does not compile anymore with musl instead of GNU libc. The 1.3 branch still compiles without error, so this seems like a regression.

/open62541/arch/eventloop_posix_eth.c:18:10: fatal error: linux/if_packet.h: No such file or directory
   18 | #include <linux/if_packet.h>
      |          ^~~~~~~~~~~~~~~~~~~
compilation terminated.
make[2]: *** [CMakeFiles/open62541-plugins.dir/build.make:418: CMakeFiles/open62541-plugins.dir/arch/eventloop_posix_eth.c.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:301: CMakeFiles/open62541-plugins.dir/all] Error 2
make: *** [Makefile:136: all] Error 2

Background Information / Reproduction Steps

Used CMake options: (none)

The issue can be reproduced with the following Dockerfile using the Alpine Linux distribution:[^1]

[^1]: It is sufficient to run the Docker build like so: docker build -t test .

FROM alpine:3.19
RUN apk add --no-cache alpine-sdk cmake python3
WORKDIR /
RUN git clone https://github.com/open62541/open62541.git -b 1.4
WORKDIR /open62541
RUN mkdir build && cd build && cmake ..
WORKDIR /open62541/build
RUN make

If -b 1.4 is replaced with -b 1.3, the build finishes successfully without compilation errors.

Checklist

Please provide the following information:

jpfr commented 7 months ago

linux/if_packet.h is a Linux header. It exists independently of whether you use musl or the GNU glibc. Try if you can install Linux headers additionally.

Otherwise the Ethernet connectivity can be disabled without affecting the TCP/UDP/... We can add a flag to manually disable Ethernet-based communication.

sgoll commented 7 months ago

linux/if_packet.h is a Linux header. It exists independently of whether you use musl or the GNU glibc. Try if you can install Linux headers additionally.

Thank you. You are correct, the build completes successfully on Alpine Linux with the following line in the above Dockerfile (note the addition of package linux-headers):

RUN apk add --no-cache alpine-sdk cmake linux-headers python3

Otherwise the Ethernet connectivity can be disabled without affecting the TCP/UDP/... We can add a flag to manually disable Ethernet-based communication.

I think this additional flag would be very useful. For our Rust bindings, we would like to impose as little external dependencies on the consumer crates as possible.

sgoll commented 7 months ago

By the way, here is a better reproduction for the issue, targeting musl libc from Ubuntu instead of Alpine (where musl libc is the default in the latter, we are cross-compiling in a way with Ubuntu).

The following Dockerfile works on the 1.3 branch but not on the 1.4 branch:

FROM ubuntu:22.04
RUN apt update && apt install -y build-essential cmake git musl-tools python3
WORKDIR /
RUN git clone https://github.com/open62541/open62541.git -b 1.4
WORKDIR /open62541
RUN mkdir build && cd build && CC="musl-gcc" cmake -DCMAKE_C_FLAGS="-static" ..
WORKDIR /open62541/build
RUN make

Instead, the cmake line must be adjusted like this, manually including the system-wide headers for Linux but also including GNU headers as well for the asm/ directory used by the Linux headers:

RUN mkdir build && cd build && CC="musl-gcc" cmake -DCMAKE_C_FLAGS="-static -idirafter/usr/include/ -idirafter/usr/include/$(uname -m)-linux-gnu/" ..

So even in this case it would be useful to disable the optional use of Ethernet connectivity and only use regular, non-Linux header files by default.