undefined reference to `clock_gettime'

Bug #1853168 reported by Dirk Zimoch on 2019-11-19
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
EPICS Base
Undecided
Unassigned

Bug Description

I'm getting this linker error when building Base 3.15.6 with mingw:

/usr/bin/x86_64-w64-mingw32-g++ -o Com.dll -shared -Wl,--out-implib,libCom.dll.a -L/home/travis/.cache/base-R3.15.6/lib/windows-x64-mingw -m64 -static-libgcc -static-libstdc++ asLib.obj asTrapWrite.obj bucketLib.obj postfix.obj calcPerform.obj cvtFast.obj resourceLib.obj epicsOnce.obj epicsSingletonMutex.obj dbmf.obj ellLib.obj ellSort.obj envSubr.obj envData.obj errlog.obj errSymLib.obj errSymTbl.obj fdmgr.obj fdManager.obj freeListLib.obj gpHashLib.obj iocsh.obj registry.obj libComRegister.obj iocLog.obj logClient.obj macCore.obj macEnv.obj macUtil.obj alarmString.obj aToIPAddr.obj adjustment.obj cantProceed.obj epicsConvert.obj epicsExit.obj epicsStdlib.obj epicsString.obj truncateFile.obj ipAddrToAsciiAsynchronous.obj epicsUnitTest.obj epicsThread.obj epicsMutex.obj epicsEvent.obj epicsTime.obj epicsMessageQueue.obj epicsMath.obj epicsAtomicOSD.obj epicsGeneralTime.obj osiClockTime.obj osdSock.obj osdSockAddrReuse.obj osiSock.obj systemCallIntMech.obj epicsSocketConvertErrnoToString.obj osdAssert.obj osdFindSymbol.obj osdInterrupt.obj osdPoolStatus.obj osdSignal.obj osdEnv.obj epicsReadline.obj epicsTempFile.obj epicsStdio.obj osdStdio.obj osdThread.obj osdThreadExtra.obj osdThreadHooks.obj osdMutex.obj osdSpin.obj osdEvent.obj osdTime.obj osdProcess.obj osdNetIntf.obj osdMessageQueue.obj devLibVME.obj devLibVMEOSD.obj epicsStackTrace.obj osdBackTrace.obj osdFindAddr.obj poolJob.obj threadPool.obj epicsRingPointer.obj epicsRingBytes.obj taskwd.obj epicsTimer.obj timer.obj timerQueue.obj timerQueueActive.obj timerQueueActiveMgr.obj timerQueuePassive.obj yajl.obj yajl_alloc.obj yajl_buf.obj yajl_encode.obj yajl_gen.obj yajl_lex.obj yajl_parser.obj epicsGetopt.obj setThreadName.obj forceBadAllocException.obj Com.coff -lws2_32 -ladvapi32 -luser32 -lws2_32

osiClockTime.obj:osiClockTime.c:(.text+0xb4): undefined reference to `clock_gettime'

osiClockTime.obj:osiClockTime.c:(.text+0x33b): undefined reference to `clock_gettime'

collect2: error: ld returned 1 exit status

Dirk Zimoch (dirk.zimoch) wrote :

R3.14.12.8 as well

Hmm, the linker is right - clock_gettime certainly is a POSIX thing. The preprocessor should actually skip most of the code in osiClockTime.c on non-POSIX systems (see https://github.com/epics-base/epics-base/blob/R3.15.6/src/libCom/osi/osiClockTime.c#L43-L47). Could you please double check that CLOCK_REALTIME is really undefined?

P.S.: We are cross-compiling 3.15.6 using MinGW when we build our Debian packages. No problems on Debian 9 (GCC 6.3) and Debian 10 (GCC 8.3).

mdavidsaver (mdavidsaver) wrote :

I have a vague memory of seeing this before, though I can't remember when. It had to do with the mingw "pthread" library http://www.mingw.org/wiki/pthreads_library . Some of the associated headers include posix prototypes, which aren't usable since we don't link against it.

Andrew Johnson (anj) wrote :

Weird, maybe MinGW changed? I have the same linker command-line as you and no errors. What versions are you using? Can you post your output, this is what I get on RHEL-7.7:

tux% x86_64-w64-mingw32-g++ --version
x86_64-w64-mingw32-g++ (GCC) 4.9.3 20150626 (Fedora MinGW 4.9.3-1.el7)

mdavidsaver (mdavidsaver) wrote :

I think the clock_gettime() and CLOCK_REALTIME definitions are pulled in through
the following condition in time.h.

> /* POSIX 2008 says clock_gettime and timespec are defined in time.h header,
> but other systems - like Linux, Solaris, etc - tend to declare such
> recent extensions only if the following guards are met. */
> #if !defined(IN_WINPTHREAD) && \
> ((!defined(_STRICT_STDC) && !defined(__XOPEN_OR_POSIX)) || \
> (_POSIX_C_SOURCE > 2) || defined(__EXTENSIONS__))
> #include <pthread_time.h>
> #endif

https://github.com/mirror/mingw-w64/blob/3ac71ed3105c2989ba378e2e88d9405f65797178/mingw-w64-headers/crt/time.h#L302-L309

Dirk Zimoch (dirk.zimoch) wrote :

Andrew, I cannot type anything on that system. It happens on Travis with Ralphs .ci scripts. I have no idea which mingw version it used or how to debug anything on Travis. I only see the output of the build.

I think clock_gettime() needs -lrt. At least on Linux. I don't know if mingw is more Linux like or more Windows like here.

Dirk Zimoch (dirk.zimoch) wrote :

Working 7.0.3 linker call: https://travis-ci.org/dirk-zimoch/StreamDevice/jobs/614452686#L1259
Failing 3.15.6 linker call: https://travis-ci.org/dirk-zimoch/StreamDevice/jobs/614452682#L1273
Failing 3.14.12.8 linker call: https://travis-ci.org/dirk-zimoch/StreamDevice/jobs/614452674#L861

Differences I see:
7.0.3 does not have epicsOnce.obj but has initHooks.obj and osdMonotonic.obj. All options are the same.

mdavidsaver (mdavidsaver) wrote :

Hi Dirk, If you compare with the main Base CI build configurations

https://travis-ci.org/epics-base/epics-base/branches

You'll see that only the 7.0 branch has mingw DLL builds (STATIC=NO).

Dirk Zimoch (dirk.zimoch) wrote :

Does that mean that mingw DLL builds are unsupported for older EPICS version?

mdavidsaver (mdavidsaver) wrote :

I guess "unsupported" in the sense of "never worked", and no effort being made to change this situation.

The specific clock_gettime() issue you report was probably fixed with 78b6312f493bbe02a37cc6f5fdcff38683d51236 (on 3.16 and 7.0), though I don't believe this was the only change needed.

Andrew Johnson (anj) wrote :

I fixed the ability to do MinGW DLL builds back in 2016 (6623cb01125a61ea) before the 3.14.12.6 and 3.15.5 releases, although apparently some older versions of minGW won't necessarily work. Prior to those releases our MinGW builds were configured with SHARED_LIBRARIES=NO and STATIC_BUILD=YES but that commit removed those and since they we have been doing DLL builds by default, unless you explicitly change the settings in the CONFIG_SITE.linux-x86.win32-x86-mingw and/or CONFIG_SITE.linux-x86.windows-x64-mingw files (the linux-x86_64 files inherit from those).

My version of osiClockTime.obj is not importing clock_gettime for a 7.0 build:

tux% x86_64-w64-mingw32-nm osiClockTime.obj | grep clock_gettime
tux%

However the 3.15 build does:
tux% x86_64-w64-mingw32-nm osiClockTime.obj | grep clock_gettime
                 U clock_gettime

This matches Michael's note about the 78b6312f493bbe02a37cc6f5fdcff38683d51236 commit (which evidently should have been made on an earlier branch). However my 3.15 builds here still work fine, so one of my MinGW libraries must be providing that symbol. It isn't in any of the libraries that are being linked into libCom though: -static-libgcc -static-libstdc++ -lws2_32 -ladvapi32 -luser32

However it is present in these libraries, neither of which my builds explicitly link to:

libpthread.a
00000000000000a0 T clock_gettime
libpthread.dll.a
0000000000000000 T clock_gettime
0000000000000000 I __imp_clock_gettime
libwinpthread.a
00000000000000a0 T clock_gettime
libwinpthread.dll.a
0000000000000000 T clock_gettime
0000000000000000 I __imp_clock_gettime

Can we explain what's happening there?

One solution might be to back-port the 78b6312f493bbe02a37cc6f5fdcff38683d51236 commit to 3.15, but that won't fix builds against older tagged releases. It would seem better to try and fix this in the ci-scripts module if that's possible.

Ralph Lange (ralph-lange) wrote :

I don't like the idea of fixing something for a CI build that doesn't work in a local build.

Adding a patch file to the download page for an old release and applying that patch in the CI build for that release would be a compromise.

Andrew Johnson (anj) wrote :

@ralph Isn't the issue that it works in my (our?) local builds, but that Dirk's CI builds are failing (See his comment #6 above)?

Ralph Lange (ralph-lange) wrote :

I don't have a local build.
The Travis build fails, and Michael says it probably never worked.

I assumed with "fix this in the ci-scripts module" you meant applying a patch to the Base sources.

Dirk Zimoch (dirk.zimoch) wrote :

If it never worked, we can call dynamic linking with mingw in R3.* "unsupported" and close this bug report with "Won't Fix". I will then simply take those builds out of my Travis config.

Andrew Johnson (anj) wrote :

In #13 above I said that MinGW dynamic builds have worked fine for me locally since the 3.14.12.6 and 3.15.5 releases. The Travis-CI builds of Base have also been compiling successfully with WINE=32 TEST=NO STATIC=NO since April 2017. Note that these are configured for dist:trusty.

Dirk's failure is happening while .ci/travis/prepare.sh is building Base as a pre-requisite of his StreamDevice job, for dist:xenial. I just tried building the 3.15 branch of epics-base with dist:xenial and it failed exactly the same way:
    https://travis-ci.org/anjohnson/epics-base/jobs/615249472#L834
Thus this cross-build failure seems to have started with the Xenial distro on Travis. The newer Bionic distro also fails with the same error.

A work-around would thus be to use trusty for building against the older Base branches. We also need to back-port the 78b6312f493bbe02a37cc6f5fdcff38683d51236 commit to the 3.15 branch.

Andrew Johnson (anj) wrote :

PS: I'm not sure if Travis can build a job with multiple dist: settings. I naively tried

dist:
  - trusty
  - xenial

and the job registered and went yellow on my dashboard, but it wouldn't start.

I can confirm that the build fails with "undefined reference to `clock_gettime'" if I'm building with

SHARED_LIBRARIES=YES
STATIC_BUILD=NO

on Ubuntu 19.10 (MinGW 9.2). It builds fine with

SHARED_LIBRARIES=NO
STATIC_BUILD=YES

Ralph Lange (ralph-lange) wrote :

Using trusty for DLL builds is fine as a workaround for the ci-scripts module as it shields the naïve user from dealing with the issue while it is being worked on.

Works. See https://travis-ci.org/ralphlange/ci-scripts/builds/615591319

To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers