forked from ElementsProject/elements
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge #19558: build: split pthread flags out of ldflags and dont use …
…when building libconsensus fc9278d build: AX_PTHREAD serial 27 (fanquake) 15c27c4 build: split PTHREAD_* flags out of AM_LDFLAGS (fanquake) 68e3e22 scripted-diff: add FUZZ_SUITE_LDFLAGS_COMMON (fanquake) afecde8 build: add PTHREAD_LIBS to LDFLAGS configure output (fanquake) Pull request description: TLDR: Split pthread flags out of ldflags, and stop using them when building libconsensus. Building libconsensus on Linux using Clang currently warns. i.e: ```bash ./autogen.sh ./configure --disable-tests --disable-bench --with-utils=no --with-daemon=no --with-gui=no --disable-wallet --with-libs=yes CC=clang CXX=clang++ make V=1 -j6 ... -Wl,-z -Wl,relro -Wl,-z -Wl,now -pthread -Wl,-soname -Wl,libbitcoinconsensus.so.0 -o .libs/libbitcoinconsensus.so.0.0.0 clang: warning: argument unused during compilation: '-pthread' [-Wunused-command-line-argument] clang: warning: argument unused during compilation: '-pthread' [-Wunused-command-line-argument] ``` Besides wanting to quiet the warnings, after digging into this it seemed we could clean up how we are passing around the pthread flags. I also learnt a bit more about how libtools builds shared libraries, and that passing `-pthread` on the link line wouldn't be enough to link against pthreads anyways, due to libtools usage of -nostdlib (see [related discussion where we build DLLs](https://github.com/bitcoin/bitcoin/blob/476436b2dec254bb988f8c7a6cbec1d7bb7cecfd/configure.ac#L603)). This can be demonstrated with a patch to libconsensus: ```patch diff --git a/src/script/bitcoinconsensus.cpp b/src/script/bitcoinconsensus.cpp index 15e204062..10bf3582f 100644 --- a/src/script/bitcoinconsensus.cpp +++ b/src/script/bitcoinconsensus.cpp @@ -10,6 +10,8 @@ #include <script/interpreter.h> #include <version.h> +#include <pthread.h> + namespace { /** A class that deserializes a single CTransaction one time. */ @@ -127,3 +129,10 @@ unsigned int bitcoinconsensus_version() // Just use the API version for now return BITCOINCONSENSUS_API_VER; } + +void *func_pthread(void *x) { return x; } + +void f() { + pthread_t t; + pthread_create(&t,0,func_pthread,0); +} ``` After building, you'll find you have a `libbitcoinconsensus.so` using pthread symbols, but which isn't linked against libpthread: ```bash ldd -r src/.libs/libbitcoinconsensus.so linux-vdso.so.1 (0x00007ffe49378000) libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f553cee7000) libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f553cda2000) libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f553cd88000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f553cbc5000) /lib64/ld-linux-x86-64.so.2 (0x00007f553d15d000) undefined symbol: pthread_create (src/.libs/libbitcoinconsensus.so) ``` This libtool behaviour has been known about for some time, i.e this [thread from 2005](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25460), describes the same issue. The suggestion from libtool maintainers at the time is to add `-lpthread` to LDFLAGS. Also worth noting is that some of the users in those threads were also using the `AX_PTHREADS` macro, same as us, to determine how to compile with/link against pthreads. This macro has [recently been updated](https://git.savannah.gnu.org/gitweb/?p=autoconf-archive.git;a=commitdiff;h=2fb904589643eb6ca6122f834891b58d1d51b347), with reference to this issue. You can compare the output from the version we currently use, to the new version: ```bash # our ax_pthread macro: PTHREAD_CFLAGS = -pthread PTHREAD_LIBS = PTHREAD_CC = gcc / clang # the new ax_pthread macro PTHREAD_CFLAGS = -pthread PTHREAD_LIBS = -lpthread PTHREAD_CC = gcc / clang ``` Note that as part of this PR I've also added `PTHREAD_LIBS` to the split out flags. Although we weren't using it anywhere previously (and wouldn't have seemed to matter for the most part, given it was likely empty for most builders), the macro assumes it's use. i.e: > NOTE: You are assumed to not only compile your program with these flags, > but also to link with them as well. For example, you might link with > $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS ACKs for top commit: laanwj: Code review ACK fc9278d hebasto: re-ACK fc9278d, only rebased and renamed s/`AM_PTHREAD_FLAGS`/`PTHREAD_FLAGS`/ since my [previous](bitcoin/bitcoin#19558 (review)) review.. kallewoof: ACK fc9278d Tree-SHA512: 7c0a5b0f0de4f54b1d7dce0e69020b341c37a383bb7c715867cc96c648774a557b1ddb42eb1b676f7bb2b822b69795bec14dc6272362d80662a21f10cb80331c
- Loading branch information
Showing
7 changed files
with
288 additions
and
263 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
# =========================================================================== | ||
# http://www.gnu.org/software/autoconf-archive/ax_pthread.html | ||
# https://www.gnu.org/software/autoconf-archive/ax_pthread.html | ||
# =========================================================================== | ||
# | ||
# SYNOPSIS | ||
|
@@ -55,6 +55,7 @@ | |
# | ||
# Copyright (c) 2008 Steven G. Johnson <[email protected]> | ||
# Copyright (c) 2011 Daniel Richard G. <[email protected]> | ||
# Copyright (c) 2019 Marc Stevens <[email protected]> | ||
# | ||
# This program is free software: you can redistribute it and/or modify it | ||
# under the terms of the GNU General Public License as published by the | ||
|
@@ -67,7 +68,7 @@ | |
# Public License for more details. | ||
# | ||
# You should have received a copy of the GNU General Public License along | ||
# with this program. If not, see <http://www.gnu.org/licenses/>. | ||
# with this program. If not, see <https://www.gnu.org/licenses/>. | ||
# | ||
# As a special exception, the respective Autoconf Macro's copyright owner | ||
# gives unlimited permission to copy, distribute and modify the configure | ||
|
@@ -82,7 +83,7 @@ | |
# modified version of the Autoconf Macro, you may extend this special | ||
# exception to the GPL to apply to your modified version as well. | ||
|
||
#serial 23 | ||
#serial 27 | ||
|
||
AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD]) | ||
AC_DEFUN([AX_PTHREAD], [ | ||
|
@@ -123,10 +124,12 @@ fi | |
# (e.g. DEC) have both -lpthread and -lpthreads, where one of the | ||
# libraries is broken (non-POSIX). | ||
# Create a list of thread flags to try. Items starting with a "-" are | ||
# C compiler flags, and other items are library names, except for "none" | ||
# which indicates that we try without any flags at all, and "pthread-config" | ||
# which is a program returning the flags for the Pth emulation library. | ||
# Create a list of thread flags to try. Items with a "," contain both | ||
# C compiler flags (before ",") and linker flags (after ","). Other items | ||
# starting with a "-" are C compiler flags, and remaining items are | ||
# library names, except for "none" which indicates that we try without | ||
# any flags at all, and "pthread-config" which is a program returning | ||
# the flags for the Pth emulation library. | ||
ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" | ||
|
@@ -194,14 +197,47 @@ case $host_os in | |
# that too in a future libc.) So we'll check first for the | ||
# standard Solaris way of linking pthreads (-mt -lpthread). | ||
ax_pthread_flags="-mt,pthread pthread $ax_pthread_flags" | ||
ax_pthread_flags="-mt,-lpthread pthread $ax_pthread_flags" | ||
;; | ||
esac | ||
# Are we compiling with Clang? | ||
AC_CACHE_CHECK([whether $CC is Clang], | ||
[ax_cv_PTHREAD_CLANG], | ||
[ax_cv_PTHREAD_CLANG=no | ||
# Note that Autoconf sets GCC=yes for Clang as well as GCC | ||
if test "x$GCC" = "xyes"; then | ||
AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG], | ||
[/* Note: Clang 2.7 lacks __clang_[a-z]+__ */ | ||
# if defined(__clang__) && defined(__llvm__) | ||
AX_PTHREAD_CC_IS_CLANG | ||
# endif | ||
], | ||
[ax_cv_PTHREAD_CLANG=yes]) | ||
fi | ||
]) | ||
ax_pthread_clang="$ax_cv_PTHREAD_CLANG" | ||
# GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC) | ||
# Note that for GCC and Clang -pthread generally implies -lpthread, | ||
# except when -nostdlib is passed. | ||
# This is problematic using libtool to build C++ shared libraries with pthread: | ||
# [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25460 | ||
# [2] https://bugzilla.redhat.com/show_bug.cgi?id=661333 | ||
# [3] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=468555 | ||
# To solve this, first try -pthread together with -lpthread for GCC | ||
AS_IF([test "x$GCC" = "xyes"], | ||
[ax_pthread_flags="-pthread -pthreads $ax_pthread_flags"]) | ||
[ax_pthread_flags="-pthread,-lpthread -pthread -pthreads $ax_pthread_flags"]) | ||
# Clang takes -pthread (never supported any other flag), but we'll try with -lpthread first | ||
AS_IF([test "x$ax_pthread_clang" = "xyes"], | ||
[ax_pthread_flags="-pthread,-lpthread -pthread"]) | ||
# The presence of a feature test macro requesting re-entrant function | ||
# definitions is, on some systems, a strong hint that pthreads support is | ||
|
@@ -224,25 +260,86 @@ AS_IF([test "x$ax_pthread_check_macro" = "x--"], | |
[ax_pthread_check_cond=0], | ||
[ax_pthread_check_cond="!defined($ax_pthread_check_macro)"]) | ||
# Are we compiling with Clang? | ||
AC_CACHE_CHECK([whether $CC is Clang], | ||
[ax_cv_PTHREAD_CLANG], | ||
[ax_cv_PTHREAD_CLANG=no | ||
# Note that Autoconf sets GCC=yes for Clang as well as GCC | ||
if test "x$GCC" = "xyes"; then | ||
AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG], | ||
[/* Note: Clang 2.7 lacks __clang_[a-z]+__ */ | ||
# if defined(__clang__) && defined(__llvm__) | ||
AX_PTHREAD_CC_IS_CLANG | ||
# endif | ||
], | ||
[ax_cv_PTHREAD_CLANG=yes]) | ||
fi | ||
]) | ||
ax_pthread_clang="$ax_cv_PTHREAD_CLANG" | ||
if test "x$ax_pthread_ok" = "xno"; then | ||
for ax_pthread_try_flag in $ax_pthread_flags; do | ||
case $ax_pthread_try_flag in | ||
none) | ||
AC_MSG_CHECKING([whether pthreads work without any flags]) | ||
;; | ||
*,*) | ||
PTHREAD_CFLAGS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\1/"` | ||
PTHREAD_LIBS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\2/"` | ||
AC_MSG_CHECKING([whether pthreads work with "$PTHREAD_CFLAGS" and "$PTHREAD_LIBS"]) | ||
;; | ||
-*) | ||
AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag]) | ||
PTHREAD_CFLAGS="$ax_pthread_try_flag" | ||
;; | ||
pthread-config) | ||
AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no]) | ||
AS_IF([test "x$ax_pthread_config" = "xno"], [continue]) | ||
PTHREAD_CFLAGS="`pthread-config --cflags`" | ||
PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" | ||
;; | ||
*) | ||
AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag]) | ||
PTHREAD_LIBS="-l$ax_pthread_try_flag" | ||
;; | ||
esac | ||
ax_pthread_save_CFLAGS="$CFLAGS" | ||
ax_pthread_save_LIBS="$LIBS" | ||
CFLAGS="$CFLAGS $PTHREAD_CFLAGS" | ||
LIBS="$PTHREAD_LIBS $LIBS" | ||
# Check for various functions. We must include pthread.h, | ||
# since some functions may be macros. (On the Sequent, we | ||
# need a special flag -Kthread to make this header compile.) | ||
# We check for pthread_join because it is in -lpthread on IRIX | ||
# while pthread_create is in libc. We check for pthread_attr_init | ||
# due to DEC craziness with -lpthreads. We check for | ||
# pthread_cleanup_push because it is one of the few pthread | ||
# functions on Solaris that doesn't have a non-functional libc stub. | ||
# We try pthread_create on general principles. | ||
AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h> | ||
# if $ax_pthread_check_cond | ||
# error "$ax_pthread_check_macro must be defined" | ||
# endif | ||
static void *some_global = NULL; | ||
static void routine(void *a) | ||
{ | ||
/* To avoid any unused-parameter or | ||
unused-but-set-parameter warning. */ | ||
some_global = a; | ||
} | ||
static void *start_routine(void *a) { return a; }], | ||
[pthread_t th; pthread_attr_t attr; | ||
pthread_create(&th, 0, start_routine, 0); | ||
pthread_join(th, 0); | ||
pthread_attr_init(&attr); | ||
pthread_cleanup_push(routine, 0); | ||
pthread_cleanup_pop(0) /* ; */])], | ||
[ax_pthread_ok=yes], | ||
[]) | ||
CFLAGS="$ax_pthread_save_CFLAGS" | ||
LIBS="$ax_pthread_save_LIBS" | ||
AC_MSG_RESULT([$ax_pthread_ok]) | ||
AS_IF([test "x$ax_pthread_ok" = "xyes"], [break]) | ||
PTHREAD_LIBS="" | ||
PTHREAD_CFLAGS="" | ||
done | ||
fi | ||
ax_pthread_clang_warning=no | ||
# Clang needs special handling, because older versions handle the -pthread | ||
# option in a rather... idiosyncratic way | ||
|
@@ -261,11 +358,6 @@ if test "x$ax_pthread_clang" = "xyes"; then | |
# -pthread does define _REENTRANT, and while the Darwin headers | ||
# ignore this macro, third-party headers might not.) | ||
PTHREAD_CFLAGS="-pthread" | ||
PTHREAD_LIBS= | ||
ax_pthread_ok=yes | ||
# However, older versions of Clang make a point of warning the user | ||
# that, in an invocation where only linking and no compilation is | ||
# taking place, the -pthread option has no effect ("argument unused | ||
|
@@ -320,78 +412,7 @@ if test "x$ax_pthread_clang" = "xyes"; then | |
fi # $ax_pthread_clang = yes | ||
if test "x$ax_pthread_ok" = "xno"; then | ||
for ax_pthread_try_flag in $ax_pthread_flags; do | ||
case $ax_pthread_try_flag in | ||
none) | ||
AC_MSG_CHECKING([whether pthreads work without any flags]) | ||
;; | ||
-mt,pthread) | ||
AC_MSG_CHECKING([whether pthreads work with -mt -lpthread]) | ||
PTHREAD_CFLAGS="-mt" | ||
PTHREAD_LIBS="-lpthread" | ||
;; | ||
-*) | ||
AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag]) | ||
PTHREAD_CFLAGS="$ax_pthread_try_flag" | ||
;; | ||
pthread-config) | ||
AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no]) | ||
AS_IF([test "x$ax_pthread_config" = "xno"], [continue]) | ||
PTHREAD_CFLAGS="`pthread-config --cflags`" | ||
PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" | ||
;; | ||
*) | ||
AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag]) | ||
PTHREAD_LIBS="-l$ax_pthread_try_flag" | ||
;; | ||
esac | ||
ax_pthread_save_CFLAGS="$CFLAGS" | ||
ax_pthread_save_LIBS="$LIBS" | ||
CFLAGS="$CFLAGS $PTHREAD_CFLAGS" | ||
LIBS="$PTHREAD_LIBS $LIBS" | ||
# Check for various functions. We must include pthread.h, | ||
# since some functions may be macros. (On the Sequent, we | ||
# need a special flag -Kthread to make this header compile.) | ||
# We check for pthread_join because it is in -lpthread on IRIX | ||
# while pthread_create is in libc. We check for pthread_attr_init | ||
# due to DEC craziness with -lpthreads. We check for | ||
# pthread_cleanup_push because it is one of the few pthread | ||
# functions on Solaris that doesn't have a non-functional libc stub. | ||
# We try pthread_create on general principles. | ||
AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h> | ||
# if $ax_pthread_check_cond | ||
# error "$ax_pthread_check_macro must be defined" | ||
# endif | ||
static void routine(void *a) { a = 0; } | ||
static void *start_routine(void *a) { return a; }], | ||
[pthread_t th; pthread_attr_t attr; | ||
pthread_create(&th, 0, start_routine, 0); | ||
pthread_join(th, 0); | ||
pthread_attr_init(&attr); | ||
pthread_cleanup_push(routine, 0); | ||
pthread_cleanup_pop(0) /* ; */])], | ||
[ax_pthread_ok=yes], | ||
[]) | ||
CFLAGS="$ax_pthread_save_CFLAGS" | ||
LIBS="$ax_pthread_save_LIBS" | ||
AC_MSG_RESULT([$ax_pthread_ok]) | ||
AS_IF([test "x$ax_pthread_ok" = "xyes"], [break]) | ||
PTHREAD_LIBS="" | ||
PTHREAD_CFLAGS="" | ||
done | ||
fi | ||
# Various other checks: | ||
if test "x$ax_pthread_ok" = "xyes"; then | ||
|
@@ -438,7 +459,8 @@ if test "x$ax_pthread_ok" = "xyes"; then | |
AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT], | ||
[ax_cv_PTHREAD_PRIO_INHERIT], | ||
[AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <pthread.h>]], | ||
[[int i = PTHREAD_PRIO_INHERIT;]])], | ||
[[int i = PTHREAD_PRIO_INHERIT; | ||
return i;]])], | ||
[ax_cv_PTHREAD_PRIO_INHERIT=yes], | ||
[ax_cv_PTHREAD_PRIO_INHERIT=no]) | ||
]) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.