#1068708 Building with EPICS fails because the compiler cannot find `compilerSpecific.h`.

Package:
epics-dev
Source:
epics-dev
Description:
EPICS header files
Submitter:
Florian Forster
Date:
2024-04-10 14:03:03 UTC
Severity:
normal
#1068708#5
Date:
2024-04-09 13:38:56 UTC
From:
To:
Building with EPICS fails because the compiler cannot find `
compilerSpecific.h`:

```
In file included from /usr/include/epics/epicsThread.h:62,
                 from /usr/include/epics/cadef.h:35,
                 from src/epics.c:26:
/usr/include/epics/compilerDependencies.h:21:10: fatal error:
compilerSpecific.h: No such file or directory
  21 | #include "compilerSpecific.h"
     | ^~~~~~~~~~~~~~~~~~~~
compilation terminated.
make[1]: *** [Makefile:8195: src/epics_la-epics.lo] Error 1
```

The file exists at `/usr/include/epics/compiler/gcc/compilerSpecific.h`,
which is not a directory searched by the compiler.

`"compilerSpecific.h"` is included unconditionally, and fails when not
compiled with GCC. My recommendation is to guard the inclusion of the file
with an appropriate check, for example:

```
// /usr/include/epics/compilerDependencies.h, line 21
#if __GNUC__
# include "compiler/gcc/compilerSpecific.h"
#endif
```

Best regards
—octo

#1068708#10
Date:
2024-04-10 10:43:23 UTC
From:
To:
Hi Florian,

According to /usr/share/pkgconfig/epics-base.pc,
/usr/include/compiler/gcc should be added to include path when compiling.

What compiler do you use? Does this patch work for you? If so, it is
probably worth upstreaming it. Can you as well try to add
/usr/include/compiler/gcc to your compiler's include path?

Best wishes,
Andrius

#1068708#15
Date:
2024-04-10 13:40:11 UTC
From:
To:
Hi Andrius,

pkg-config references paths (/build/reproducible-path/…) that likely exist
on the build system, but are not provided by the package:

```
# pkg-config epics-base --cflags | sed -e 's/  */\n/g'
-I/build/reproducible-path/epics-base-7.0.8+dfsg1/include
-I/build/reproducible-path/epics-base-7.0.8+dfsg1/include/os/Linux
-I/build/reproducible-path/epics-base-7.0.8+dfsg1/include/compiler/gcc
-D_GNU_SOURCE
-D_DEFAULT_SOURCE
-D_X86_64_
-DUNIX
-Dlinux
-ffile-prefix-map=/build/reproducible-path/epics-base-7.0.8+dfsg1=.
-D_FORTIFY_SOURCE=2
-ffile-prefix-map=/build/reproducible-path/epics-base-7.0.8+dfsg1=.
-fstack-protector-strong
-fstack-clash-protection
-fcf-protection
-D_FORTIFY_SOURCE=2
-mtune=generic
-m64
# dpkg -L epics-dev | grep /build; echo $?
1
```

Unrelated to this bug: my recommendation would be to keep the CPP flags
(`-I`, `-D`) and remove the C flags (`-f`, `-m`).

We test our project with GCC and clang.

Kind of. It fixes the compiler specific include described in the initial
report, but fails to find an OS specific include:

```
In file included from /usr/include/epics/cadef.h:35,
                 from src/epics.c:26:
/usr/include/epics/epicsThread.h:468:10: fatal error: osdThread.h: No such
file or directory
  468 | #include "osdThread.h"
      |          ^~~~~~~~~~~~~
```
include path?

That path alone is not enough, but this works:

```
make CPPFLAGS="-I/usr/include/epics -I/usr/include/epics/compiler/gcc
-I/usr/include/epics/os/Linux"
```

Thanks for your time and effort maintaining this package, I appreciate it!
—octo

#1068708#20
Date:
2024-04-10 13:59:26 UTC
From:
To:
Hi Florian,

You are right - this has been reported as bug #1059706 and marked as
fixed since, although incorrect paths apparently were left in
epics-base.pc. I have reopened #1059706 to deal with that.

It seems that EPICS straightforwardly puts its build flags to
epics-base.pc. Many of these flags are specific to EPICS build and
should not be used for reverse-dependencies.

OK, thanks.

I guess that both /usr/include/epics/os/Linux/ and
/usr/include/epics/compiler/gcc/ should be in the include path. Thus the
following should work on GCC without patching EPICS code:

make CPPFLAGS="-I/usr/include/epics -I/usr/include/epics/compiler/gcc
-I/usr/include/epics/os/Linux"

I wonder why clang cannot work with compilerSpecific.h. Most likely it
contains GCC-specific instructions.

I think a viable solution for clang would be to create an empty file in
/usr/include/epics/compiler/clang/compilerSpecific.h (no compiler
specific settings for clang) and use include paths to indicate the used
compiler, for clang:

make CPPFLAGS="-I/usr/include/epics -I/usr/include/epics/compiler/clang
-I/usr/include/epics/os/Linux"

However, this should better be discussed with the upstream. They may
want to automatically identify the compiler using __GNUC__ and similar
checks.

Thank you for the report!

Best wishes,
Andrius