[GHC] #13935: AC_CHECK_FUNC yields incorrect result for pthread functions on NixOS causing build to fail

GHC ghc-devs at haskell.org
Fri Jul 7 21:02:43 UTC 2017


#13935: AC_CHECK_FUNC yields incorrect result for pthread functions on NixOS
causing build to fail
-------------------------------------+-------------------------------------
           Reporter:  mjvoge02       |             Owner:  (none)
               Type:  bug            |            Status:  new
           Priority:  normal         |         Milestone:
          Component:  Build System   |           Version:
           Keywords:  autoconf,      |  Operating System:  Linux
  AC_CHECK_FUNC, configure, nixos    |
       Architecture:  x86_64         |   Type of failure:  None/Unknown
  (amd64)                            |
          Test Case:                 |        Blocked By:
           Blocking:                 |   Related Tickets:
Differential Rev(s):                 |         Wiki Page:
-------------------------------------+-------------------------------------
 Code in [[GhcFile(configure.ac)]] incorrectly assesses that pthread
 functions will be available without explicitly providing `-lpthread` to
 gcc. This causes the build to fail.

 Forcing `need_lpthread=1` in [[GhcFile(configure.ac)]] causes the build to
 succeed and produce a perfectly functional GHC.

 From conversation on #GHC:

 "It looks like the combination of the following two commits has caused the
 breakage: e94bfb677298de3c4b4e0d1223fbc589849b79be,
 c0872bf99ff891e440f118bf9eea20b980c2cfca.[[br]]
 The first makes the configure script check if the `-lpthread` argument is
 required when building GHC, and the second uses that knowledge at runtime
 to decide whether to pass `-lpthread` when linking programs. [[br]]
 Stage 0 builds stage 1 just fine, since it doesn't have these commits and
 decides whether to pass `-lpthread` based purely on the platform. But the
 code from the first commit is yielding a false result (I don't know why),
 so stage 1 fails to build stage 2, since the second commit makes it use
 the false result to choose not to pass `-lpthread`."

 Also, doesn't determining the need for `-lpthread` like this have
 problematic implications for cross compilation? Whether `-lpthread` is
 required could be different between linking GHC and GHC doing linking
 (e.g. a cross compiler built on a system that does need the flag targeting
 a system that doesn't.)

 Ignoring that, using AX_PTHREAD or ACX_PTHREAD could potentially help
 resolve the issue.

 Relevant code from [[GhcFile(configure.ac)]]:
 {{{#!bash
 dnl Some platforms (e.g. Android's Bionic) have pthreads support available
 dnl without linking against libpthread. Check whether -lpthread is
 necessary
 dnl to use pthreads.
 dnl
 dnl Note that it is important that this happens before we
 AC_CHECK_LIB(thread)
 AC_MSG_CHECKING(whether -lpthread is needed for pthreads)
 AC_CHECK_FUNC(pthread_create,
     [
         AC_MSG_RESULT(no)
         need_lpthread=0
     ],
     [
         AC_CHECK_LIB(pthread, pthread_create,
             [
                 AC_MSG_RESULT(yes)
                 need_lpthread=1
             ],
             [
                 AC_MSG_RESULT([no pthreads support found.])
                 need_lpthread=0
             ])
     ])
 AC_DEFINE_UNQUOTED([NEED_PTHREAD_LIB], [$need_lpthread],
     [Define 1 if we need to link code using pthreads with -lpthread])

 }}}

 System information:
 Linux nixos 4.9.30 x86_64 GNU/Linux

 gcc 5.4.0

 ghc 7.10.3

 Attempting to build GHC HEAD fails with
 {{{#!bash
 ...
 "inplace/bin/ghc-stage1" -hisuf hi -osuf  o -hcsuf hc -static  -O0 -H64m
 -Wall    -Iincludes -Iincludes/dist -Iincludes/dist-
 derivedconstants/header -Iincludes/dist-ghcconstants/header   -this-unit-
 id ghc-8.3 -hide-all-packages -i -icompiler/backpack -icompiler/basicTypes
 -icompiler/cmm -icompiler/codeGen -icompiler/coreSyn -icompiler/deSugar
 -icompiler/ghci -icompiler/hsSyn -icompiler/iface -icompiler/llvmGen
 -icompiler/main -icompiler/nativeGen -icompiler/parser -icompiler/prelude
 -icompiler/profiling -icompiler/rename -icompiler/simplCore
 -icompiler/simplStg -icompiler/specialise -icompiler/stgSyn
 -icompiler/stranal -icompiler/typecheck -icompiler/types -icompiler/utils
 -icompiler/vectorise -icompiler/stage2/build -Icompiler/stage2/build
 -icompiler/stage2/build/./autogen -Icompiler/stage2/build/./autogen
 -Icompiler/. -Icompiler/parser -Icompiler/utils
 -Icompiler/../rts/dist/build -Icompiler/stage2   -optP-DGHCI -optP-include
 -optPcompiler/stage2/build/./autogen/cabal_macros.h -package-id
 base-4.10.0.0 -package-id deepseq-1.4.3.0 -package-id directory-1.3.0.2
 -package-id process-1.6.0.0 -package-id bytestring-0.10.8.2 -package-id
 binary-0.8.4.1 -package-id time-1.8.0.1 -package-id containers-0.5.10.2
 -package-id array-0.5.1.2 -package-id filepath-1.4.1.2 -package-id
 template-haskell-2.12.0.0 -package-id hpc-0.6.0.3 -package-id
 transformers-0.5.2.0 -package-id ghc-boot-8.3 -package-id ghc-boot-th-8.3
 -package-id ghci-8.3 -package-id unix-2.7.2.2 -package-id terminfo-0.4.1.0
 -Wall -fno-warn-name-shadowing -this-unit-id ghc -XHaskell2010 -optc-
 DTHREADED_RTS -DGHCI_TABLES_NEXT_TO_CODE -DSTAGE=2 -Rghc-timing -O0  -no-
 user-package-db -rtsopts       -Wnoncanonical-monad-instances  -odir
 compiler/stage2/build -hidir compiler/stage2/build -stubdir
 compiler/stage2/build   -dynamic-too -c compiler/hsSyn/HsTypes.hs -o
 compiler/stage2/build/HsTypes.o -dyno compiler/stage2/build/HsTypes.dyn_o

 includes/rts/OSThreads.h:58:0: error:
      error: undefined reference to 'pthread_mutex_trylock'
    |
 58 |     return pthread_mutex_trylock(mutex);
    | ^

 includes/rts/OSThreads.h:58:0: error:
      error: undefined reference to 'pthread_mutex_trylock'
    |
 58 |     return pthread_mutex_trylock(mutex);
    | ^

 rts/posix/OSThreads.c:137:0: error:
      error: undefined reference to 'pthread_create'
     |
 137 |   int result = pthread_create(pId, NULL, (void *(*)(void
 *))startProc, param);
     | ^

 rts/posix/OSThreads.c:139:0: error:
      error: undefined reference to 'pthread_detach'
     |
 139 |     pthread_detach(*pId);
     | ^

 rts/posix/OSThreads.c:141:0: error:
      error: undefined reference to 'pthread_setname_np'
     |
 141 |     pthread_setname_np(*pId, name);
     | ^

 rts/posix/OSThreads.c:184:0: error:
      error: undefined reference to 'pthread_key_create'
     |
 184 |     if ((r = pthread_key_create(key, NULL)) != 0) {
     | ^

 rts/posix/OSThreads.c:203:0: error:
      error: undefined reference to 'pthread_setspecific'
     |
 203 |     if ((r = pthread_setspecific(*key,value)) != 0) {
     | ^

 rts/posix/OSThreads.c:212:0: error:
      error: undefined reference to 'pthread_key_delete'
     |
 212 |     if ((r = pthread_key_delete(*key)) != 0) {
     | ^

 rts/posix/OSThreads.c:233:0: error:
      error: undefined reference to 'pthread_create'
     |
 233 |     int result = pthread_create(&tid, NULL,
     | ^

 rts/posix/OSThreads.c:236:0: error:
      error: undefined reference to 'pthread_detach'
     |
 236 |         pthread_detach(tid);
     | ^

 rts/posix/OSThreads.c:192:0: error:
      error: undefined reference to 'pthread_getspecific'
     |
 192 |     return pthread_getspecific(*key);
     | ^

 rts/posix/OSThreads.c:371:0: error:
      error: undefined reference to 'pthread_kill'
     |
 371 |     pthread_kill(id, SIGPIPE);
     | ^

 rts/posix/itimer/Pthread.c:171:0: error:
      error: undefined reference to 'pthread_create'
     |
 171 |     if (! pthread_create(&thread, NULL, itimer_thread_func,
 (void*)handle_tick)) {
     | ^

 rts/posix/itimer/Pthread.c:210:0: error:
      error: undefined reference to 'pthread_join'
     |
 210 |         if (pthread_join(thread, NULL)) {
     | ^

 rts/posix/itimer/Pthread.c:173:0: error:
      error: undefined reference to 'pthread_setname_np'
     |
 173 |         pthread_setname_np(thread, "ghc_ticker");
     | ^

 rts/posix/itimer/Pthread.c:214:0: error:
      error: undefined reference to 'pthread_detach'
     |
 214 |         pthread_detach(thread);
     | ^

 includes/rts/OSThreads.h:58:0: error:
      error: undefined reference to 'pthread_mutex_trylock'
    |
 58 |     return pthread_mutex_trylock(mutex);
    | ^
 collect2: error: ld returned 1 exit status
 `gcc' failed in phase `Linker'. (Exit code: 1)
 make[1]: *** [iserv/ghc.mk:72: iserv/stage2/build/tmp/ghc-iserv] Error 1
 make[1]: *** Waiting for unfinished jobs....
 <<ghc: 755844888 bytes, 149 GCs, 9956929/25185088 avg/max bytes residency
 (7 samples), 61M in use, 0.000 INIT (0.000 elapsed), 0.853 MUT (1.097
 elapsed), 0.495 GC (0.509 elapsed) :ghc>>
 <<ghc: 2330135232 bytes, 288 GCs, 19895226/58582272 avg/max bytes
 residency (9 samples), 155M in use, 0.000 INIT (0.000 elapsed), 2.533 MUT
 (2.833 elapsed), 1.352 GC (1.362 elapsed) :ghc>>
 <<ghc: 8736365112 bytes, 461 GCs, 112580024/575893400 avg/max bytes
 residency (11 samples), 1191M in use, 0.000 INIT (0.000 elapsed), 4.416
 MUT (4.569 elapsed), 7.235 GC (7.250 elapsed) :ghc>>
 <<ghc: 15569982136 bytes, 4099 GCs, 61572431/188646672 avg/max bytes
 residency (20 samples), 454M in use, 0.000 INIT (0.000 elapsed), 9.533 MUT
 (10.274 elapsed), 6.490 GC (6.536 elapsed) :ghc>>
 make: *** [Makefile:127: all] Error 2
 }}}

--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13935>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list