summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcsilvers <csilvers@6b5cf1ce-ec42-a296-1ba9-69fdba395a50>2007-04-16 20:49:32 +0000
committercsilvers <csilvers@6b5cf1ce-ec42-a296-1ba9-69fdba395a50>2007-04-16 20:49:32 +0000
commit74ad5d57ec08abace386befc6c3c695d85f44d1a (patch)
tree1a5611be12a74fde48de69d13476ab02ca7d20cc
parentddbf2f027fb4ca8781fd50820ceb870570f414bc (diff)
downloadgperftools-74ad5d57ec08abace386befc6c3c695d85f44d1a.tar.gz
Fri Apr 13 14:50:51 2007 Google Inc. <opensource@google.com>
* google-perftools: version 0.90 release * (As the version-number jump hints, this is a major new release: almost every piece of functionality was rewritten. I can't do justice to all the changes, but will concentrate on highlights.) *** USER-VISIBLE CHANGES: * Ability to "release" unused memory added to tcmalloc * Exposed more tweaking knobs via environment variables (see docs) * pprof tries harder to map addresses to functions * tcmalloc_minimal compiles and runs on FreeBSD 6.0 and Solaris 10 *** INTERNAL CHANGES: * Much better 64-bit support * Better multiple-processor support (e.g. multicore contention tweaks) * Support for recent kernel ABI changes (e.g. new arg to mremap) * Addition of spinlocks to tcmalloc to reduce contention cost * Speed up tcmalloc by using __thread on systems that support TLS * Total redesign of heap-checker to improve liveness checking * More portable stack-frame analysis -- no more hard-coded constants! * Disentangled heap-profiler code and heap-checker code * Several new unittests to test, e.g., thread-contention costs * Lots of small (but important!) bug fixes: e.g., fixing GetPC on amd64 *** KNOWN PROBLEMS: * CPU-profiling may crash on x86_64 (64-bit) systems. See the README * Profiling/heap-checking may deadlock on x86_64 systems. See README git-svn-id: http://gperftools.googlecode.com/svn/trunk@28 6b5cf1ce-ec42-a296-1ba9-69fdba395a50
-rw-r--r--ChangeLog26
-rw-r--r--INSTALL95
-rw-r--r--Makefile.am283
-rw-r--r--Makefile.in1260
-rw-r--r--README92
-rw-r--r--TODO14
-rw-r--r--aclocal.m43677
-rwxr-xr-xconfig.guess947
-rwxr-xr-xconfig.sub189
-rwxr-xr-xconfigure8784
-rw-r--r--configure.ac49
-rw-r--r--doc/cpuprofile.html (renamed from doc/cpu_profiler.html)309
-rw-r--r--doc/designstyle.css115
-rw-r--r--doc/heap_checker.html646
-rw-r--r--doc/heap_profiler.html325
-rw-r--r--doc/heapprofile.html355
-rw-r--r--doc/index.html7
-rw-r--r--doc/tcmalloc.html436
-rw-r--r--ltmain.sh1962
-rw-r--r--packages/deb/changelog141
-rw-r--r--packages/deb/docs46
-rw-r--r--packages/rpm/rpm.spec2
-rw-r--r--src/addressmap-inl.h14
-rw-r--r--src/base/atomicops-internals-macosx.h212
-rw-r--r--src/base/atomicops-internals-x86-msvc.h132
-rw-r--r--src/base/atomicops-internals-x86.cc119
-rw-r--r--src/base/atomicops-internals-x86.h253
-rw-r--r--src/base/atomicops.h142
-rw-r--r--src/base/basictypes.h116
-rw-r--r--src/base/commandlineflags.h16
-rw-r--r--src/base/elfcore.h158
-rw-r--r--src/base/googleinit.h10
-rw-r--r--src/base/linux_syscall_support.h1602
-rw-r--r--src/base/linuxthreads.c157
-rw-r--r--src/base/linuxthreads.h6
-rw-r--r--src/base/logging.cc37
-rw-r--r--src/base/logging.h104
-rw-r--r--src/base/low_level_alloc.cc411
-rw-r--r--src/base/low_level_alloc.h90
-rw-r--r--src/base/mutex.cc79
-rw-r--r--src/base/mutex.h131
-rw-r--r--src/base/spinlock.cc120
-rw-r--r--src/base/spinlock.h107
-rw-r--r--src/base/stl_allocator.h90
-rw-r--r--src/base/sysinfo.cc177
-rw-r--r--src/base/sysinfo.h111
-rw-r--r--src/base/thread_lister.c2
-rw-r--r--src/base/thread_lister.h2
-rw-r--r--src/config.h.in27
-rw-r--r--src/google/heap-checker.h400
-rw-r--r--src/google/heap-profiler.h75
-rw-r--r--src/google/malloc_extension.h32
-rw-r--r--src/google/malloc_hook.h62
-rw-r--r--src/google/profiler.h34
-rw-r--r--src/google/stacktrace.h18
-rw-r--r--src/heap-checker-bcad.cc15
-rw-r--r--src/heap-checker.cc2578
-rw-r--r--src/heap-profile-table.cc389
-rw-r--r--src/heap-profile-table.h216
-rw-r--r--src/heap-profiler-inl.h222
-rw-r--r--src/heap-profiler.cc977
-rw-r--r--src/internal_logging.cc2
-rw-r--r--src/internal_logging.h6
-rw-r--r--src/internal_spinlock.h151
-rw-r--r--src/malloc_extension.cc22
-rw-r--r--src/malloc_hook.cc280
-rw-r--r--src/maybe_threads.cc11
-rw-r--r--src/memory_region_map.cc432
-rw-r--r--src/memory_region_map.h199
-rwxr-xr-xsrc/pprof513
-rw-r--r--src/profiler.cc383
-rw-r--r--src/solaris/libstdc++.la51
-rw-r--r--src/stacktrace.cc78
-rw-r--r--src/stacktrace_generic-inl.h4
-rw-r--r--src/stacktrace_libunwind-inl.h37
-rw-r--r--src/stacktrace_x86-inl.h52
-rw-r--r--src/stacktrace_x86_64-inl.h33
-rw-r--r--src/system-alloc.cc76
-rw-r--r--src/system-alloc.h11
-rw-r--r--src/tcmalloc.cc1050
-rw-r--r--src/tests/addressmap_unittest.cc11
-rw-r--r--src/tests/atomicops_unittest.cc111
-rw-r--r--src/tests/frag_unittest.cc101
-rwxr-xr-xsrc/tests/heap-checker-death_unittest.sh145
-rw-r--r--src/tests/heap-checker_unittest.cc586
-rwxr-xr-xsrc/tests/heap-checker_unittest.sh66
-rw-r--r--src/tests/heap-profiler_unittest.cc14
-rwxr-xr-xsrc/tests/heap-profiler_unittest.sh95
-rw-r--r--src/tests/low_level_alloc_unittest.cc191
-rw-r--r--src/tests/markidle_unittest.cc105
-rw-r--r--src/tests/memalign_unittest.cc193
-rwxr-xr-xsrc/tests/profiler_unittest.sh125
-rw-r--r--src/tests/ptmalloc/malloc-machine.h2
-rw-r--r--src/tests/stacktrace_unittest.cc26
-rw-r--r--src/tests/tcmalloc_large_unittest.cc8
-rw-r--r--src/tests/tcmalloc_unittest.cc41
-rw-r--r--src/tests/testutil.cc72
-rw-r--r--src/tests/testutil.h41
-rw-r--r--src/tests/thread_dealloc_unittest.cc78
99 files changed, 22691 insertions, 11914 deletions
diff --git a/ChangeLog b/ChangeLog
index 90bf766..4cd8dc9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -100,3 +100,29 @@ Wed Jun 14 15:11:14 2006 Google Inc. <opensource@google.com>
* Better compiler support for no-THREADS and for old compilers (csilvers)
* Make libunwind the default stack unwinder for x86-64 (aruns)
* Somehow the COPYING file got erased. Regenerate it (csilvers)
+
+Fri Apr 13 14:50:51 2007 Google Inc. <opensource@google.com>
+
+ * google-perftools: version 0.90 release
+ * (As the version-number jump hints, this is a major new release:
+ almost every piece of functionality was rewritten. I can't do
+ justice to all the changes, but will concentrate on highlights.)
+ *** USER-VISIBLE CHANGES:
+ * Ability to "release" unused memory added to tcmalloc
+ * Exposed more tweaking knobs via environment variables (see docs)
+ * pprof tries harder to map addresses to functions
+ * tcmalloc_minimal compiles and runs on FreeBSD 6.0 and Solaris 10
+ *** INTERNAL CHANGES:
+ * Much better 64-bit support
+ * Better multiple-processor support (e.g. multicore contention tweaks)
+ * Support for recent kernel ABI changes (e.g. new arg to mremap)
+ * Addition of spinlocks to tcmalloc to reduce contention cost
+ * Speed up tcmalloc by using __thread on systems that support TLS
+ * Total redesign of heap-checker to improve liveness checking
+ * More portable stack-frame analysis -- no more hard-coded constants!
+ * Disentangled heap-profiler code and heap-checker code
+ * Several new unittests to test, e.g., thread-contention costs
+ * Lots of small (but important!) bug fixes: e.g., fixing GetPC on amd64
+ *** KNOWN PROBLEMS:
+ * CPU-profiling may crash on x86_64 (64-bit) systems. See the README
+ * Profiling/heap-checking may deadlock on x86_64 systems. See README
diff --git a/INSTALL b/INSTALL
index 316e397..ca0c7a2 100644
--- a/INSTALL
+++ b/INSTALL
@@ -5,6 +5,101 @@ Foundation, Inc.
unlimited permission to copy, distribute and modify it.
+Perftools-Specific Install Notes
+================================
+
+Perftools right now has only been tested on linux systems, both 32-bit
+and 64-bit. tcmalloc_minimal, the basic memory-allocation library,
+may also work on *BSD systems. However, the advanced tools, including
+the cpu-profiler, heap-profiler, and heap-checker, have quite a bit of
+linux- and x86-specific code, and are unlikely to work on other
+architectures.
+
+
+*** NOTE FOR 64-BIT LINUX SYSTEMS
+
+ The glibc built-in stack-unwinder on 64-bit systems has some
+problems with the perftools libraries. (In particular, the cpu/heap
+profiler may be in the middle of malloc, holding some malloc related
+locks when they invoke the stack unwinder. The built-in
+stack-unwinder may call malloc recursively, which may require the
+thread to acquire a lock it already holds: deadlock.)
+
+ For that reason, if you use a 64-bit system, we strongly recommend
+you install libunwind before trying to configure or install google
+perftools. libunwind can be found at
+
+ http://download.savannah.nongnu.org/releases/libunwind/libunwind-snap-070410.tar.gz
+
+ Even if you already have libunwind installed, you will probably
+still need to install from the snapshot to get the latest version.
+
+ CAUTION: if you install libunwind from the url above, be aware that
+you may have trouble if you try to statically link your binary with
+pertools: that is, if you link with 'gcc -static -lgcc_eh ...'. This
+is because both libunwind and libgcc implement the same C++ exception
+handling APIs, but they implement them differently on some platforms.
+This is not likely to be a problem on ia64, but may be on x86-64.
+Using -static is rare, though, so unless you know this will affect you
+it probably won't.
+
+ If you cannot or do not wish to install libunwind, you can still
+try to use the built-in stack-unwinder. The built-in stack-unwinder
+requires that your application, the tcmalloc library, and system
+libraries like libc, all be compiled with a frame pointer. This is
+*not* the default for x86-64.
+
+ If you are on x86-64 system, know that you have a set of system
+libraries with frame-pointers enabled, and compile all your
+applications with -fno-omit-frame-pointer, then you can enable the
+built-in perftools stack-unwinder by passing the
+--enable-frame-pointers flag to configure.
+
+ Even with the use of libunwind, there are still known problems
+with stack-unwinding on 64-bit systems, particularly x86-64. See
+the "64-BIT ISSUES" section in README.
+
+
+*** NOTE FOR *BSD SYSTEMS
+
+ This code does not yet run fully on *BSD systems such as FreeBSD,
+but it may not be that far away. We've gotten the basic tcmalloc
+library, tcmalloc_minimal, to compile and run on a FreeBSD 6.0 system.
+To compile only tcmalloc_minimal:
+ % make tcmalloc_minimal_unittest tcmalloc_minimal_large_unittest
+ % ./tcmalloc_minimal_unittest # should say PASS if all goes well!
+ % ./tcmalloc_minimal_large_unittest
+
+ The cpu-profiler, heap-profiler, and heap-checker all depend on
+Linux kernel-specific syscalls, and will be harder to port. However,
+tcmalloc_minimal.so itself is perfectly usable as a malloc/new
+replacement.
+
+
+*** NOTE FOR SOLARIS SYSTEMS
+
+ This code does not yet run fully on Solaris systems such as Solaris
+10, but we've gotten the basic tcmalloc library, tcmalloc_minimal,
+to compile and run on a Solaris 10 6/06 system. Note that this uses
+g++ rather than the Sun C++ compiler; porting to Sun's cc may be a
+significantly more difficult task. To compile only tcmalloc_minimal:
+ % PATH=${PATH}:/usr/sfw/bin/:/usr/ccs/bin ./configure LDFLAGS="-Lsrc/solaris -lrt"
+ % PATH=${PATH}:/usr/sfw/bin/:/usr/ccs/bin make -k tcmalloc_minimal_unittest tcmalloc_minimal_large_unittest
+ % ./tcmalloc_minimal_unittest # should say PASS if all goes well!
+ % ./tcmalloc_minimal_large_unittest
+
+ If you're curious in the details of these commands: the PATH allows
+use of gcc, and the LDFLAGS both works around a Solaris 10 bug (see
+src/solaris/libstdc++.la for more info) and does a cheap hack to
+introduce a needed solaris library. (This *should* be done as inside
+configure.am. Maybe one day.)
+
+ The cpu-profiler, heap-profiler, and heap-checker all depend on
+Linux kernel-specific syscalls, and will be harder to port. However,
+tcmalloc_minimal.so itself is perfectly usable as a malloc/new
+replacement.
+
+
Basic Installation
==================
diff --git a/Makefile.am b/Makefile.am
index 83fa966..ee5fa53 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -9,6 +9,8 @@ ACLOCAL_AMFLAGS = -I `pwd`/../autoconf
# This is so we can #include <google/foo>
AM_CPPFLAGS = -I$(top_srcdir)/src
+# This is initialized in configure.ac (though we might add to it later)
+AM_CXXFLAGS = $(EXTRA_CXXFLAGS)
googleincludedir = $(includedir)/google
# The .h files you want to install (that is, .h files that people
@@ -31,30 +33,86 @@ dist_doc_DATA = AUTHORS COPYING ChangeLog INSTALL NEWS README TODO
# The libraries (.so's) you want to install
# We'll add to this later, on a library-by-library basis
lib_LTLIBRARIES =
+# This is for 'convenience libraries' -- basically just a container for sources
+noinst_LTLIBRARIES =
# unittests you want to run when people type 'make check'.
-# TESTS is for binary unittests, check_SCRIPTS for script-based unittests.
-# TESTS_ENVIRONMENT sets environment variables for when you run unittest,
-# but it only seems to take effect for *binary* unittests (argh!)
-# We'll add to this later, on a library-by-library basis
+# Note: tests cannot take any arguments!
+# In theory, unittests that are scripts should be added to check_SCRIPTS
+# instead. But check_SCRIPTS is definitely a second-class testing mechanims:
+# it don't get TESTS_ENVIRONMENT, and it doesn't get success/failure counting
+# (in fact, a script failure aborts all the rest of the tests, even with -k).
+# So, for scripts, we add the script to tests, and also put in an empty
+# rule so automake doesn't try to build the script as a C binary.
TESTS =
-check_SCRIPTS =
+# TESTS_ENVIRONMENT sets environment variables for when you run unittest.
+# We always get "srcdir" set for free.
+# We'll add to this later, on a library-by-library basis.
TESTS_ENVIRONMENT =
-# Every time you add a unittest to check_SCRIPTS, add it here too
+# All script tests should be added her
noinst_SCRIPTS =
+# If your test calls another program that, like the test itself, shouldn't
+# be installed, add it here. (Stuff in TESTS is automatically added later).
+noinst_PROGRAMS =
## vvvv RULES TO MAKE THE LIBRARIES, BINARIES, AND UNITTESTS
-dist_doc_DATA += doc/index.html
+dist_doc_DATA += doc/index.html doc/designstyle.css
+
+
+### ------- library routines, in src/base
+
+# spinlock is the only code that uses atomicops.
+SPINLOCK_INCLUDES = src/base/spinlock.h \
+ src/base/atomicops.h \
+ src/base/atomicops-internals-macosx.h \
+ src/base/atomicops-internals-x86-msvc.h \
+ src/base/atomicops-internals-x86.h
+
+# This is a 'convenience library' -- it's not actually installed or anything
+noinst_LTLIBRARIES += libspinlock.la
+libspinlock_la_SOURCES = src/base/spinlock.cc \
+ src/base/atomicops-internals-x86.cc \
+ $(SPINLOCK_INCLUDES)
+
+LOGGING_INCLUDES = src/base/logging.h \
+ src/base/commandlineflags.h \
+ src/base/basictypes.h
+noinst_LTLIBRARIES += liblogging.la
+liblogging_la_SOURCES = src/base/logging.cc \
+ $(LOGGING_INCLUDES)
+
+### Unittests
+TESTS += low_level_alloc_unittest
+LOW_LEVEL_ALLOC_UNITTEST_INCLUDES = src/base/low_level_alloc.h \
+ src/base/basictypes.h \
+ src/google/malloc_hook.h \
+ $(SPINLOCK_INCLUDES) \
+ $(LOGGING_INCLUDES)
+low_level_alloc_unittest_SOURCES = src/base/low_level_alloc.cc \
+ src/malloc_hook.cc \
+ src/tests/low_level_alloc_unittest.cc \
+ $(LOW_LEVEL_ALLOC_UNITTEST_INCLUDES)
+low_level_alloc_unittest_LDADD = libspinlock.la liblogging.la libstacktrace.la
+
+TESTS += atomicops_unittest
+ATOMICOPS_UNITTEST_INCLUDES = src/base/atomicops.h \
+ src/base/atomicops-internals-macosx.h \
+ src/base/atomicops-internals-x86-msvc.h \
+ src/base/atomicops-internals-x86.h \
+ $(LOGGING_INCLUDES)
+atomicops_unittest_SOURCES = src/tests/atomicops_unittest.cc \
+ $(ATOMICOPS_UNITTEST_INCLUDES)
+atomicops_unittest_LDADD = libspinlock.la liblogging.la
+
### ------- stack trace
### The header files we use. We divide into categories based on directory
S_STACKTRACE_INCLUDES =
SG_STACKTRACE_INCLUDES = src/google/stacktrace.h
-SGP_STACKTRACE_INCLUDES = src/config.h \
- src/stacktrace_generic-inl.h \
+SGP_STACKTRACE_INCLUDES = src/stacktrace_generic-inl.h \
src/stacktrace_libunwind-inl.h \
src/stacktrace_x86_64-inl.h \
src/stacktrace_x86-inl.h
@@ -66,28 +124,48 @@ perftoolsinclude_HEADERS += $(SGP_STACKTRACE_INCLUDES)
lib_LTLIBRARIES += libstacktrace.la
libstacktrace_la_SOURCES = src/stacktrace.cc \
$(STACKTRACE_INCLUDES)
+# TODO(csilvers): only add these two things when stacktrace.cc would
+# #include "stacktrace_libunwind-inl.h"
+libstacktrace_la_LIBADD = $(UNWIND_LIBS) libspinlock.la
STACKTRACE_SYMBOLS = '(GetStackTrace)'
libstacktrace_la_LDFLAGS = -export-symbols-regex $(STACKTRACE_SYMBOLS)
### Unittests
TESTS += stacktrace_unittest
-STACKTRACE_UNITTEST_INLCUDES = $(STACKTRACE_INCLUDES) \
- src/base/commandlineflags.h \
- src/base/logging.h
+STACKTRACE_UNITTEST_INLCUDES = src/base/commandlineflags.h \
+ $(STACKTRACE_INCLUDES) \
+ $(LOGGING_INCLUDES)
stacktrace_unittest_SOURCES = src/tests/stacktrace_unittest.cc \
$(STACKTRACE_UNITTEST_INLCUDES)
-stacktrace_unittest_LDADD = libstacktrace.la
+stacktrace_unittest_LDADD = libstacktrace.la liblogging.la
### Documentation
dist_doc_DATA +=
+
+### ------- pprof
+
+bin_SCRIPTS = src/pprof
+
+### Unittests
+check_SCRIPTS = pprof_unittest
+pprof_unittest: $(top_srcdir)/src/pprof
+ $< -test
+
+# Let unittests find pprof if they need to run it
+TESTS_ENVIRONMENT += PPROF_PATH=$(top_srcdir)/src/pprof
+
+### Documentation
+dist_man_MANS = doc/pprof.1
+dist_doc_DATA += doc/pprof_remote_servers.html
+
+
### ------- tcmalloc_minimal (thread-caching malloc)
### The header files we use. We divide into categories based on directory
-S_TCMALLOC_MINIMAL_INCLUDES = src/config.h \
- src/internal_logging.h \
+S_TCMALLOC_MINIMAL_INCLUDES = src/internal_logging.h \
src/system-alloc.h \
- src/internal_spinlock.h \
+ $(SPINLOCK_INCLUDES) \
src/base/commandlineflags.h \
src/base/basictypes.h \
src/pagemap.h \
@@ -112,15 +190,15 @@ libtcmalloc_minimal_la_SOURCES = src/internal_logging.cc \
libtcmalloc_minimal_la_CXXFLAGS = $(PTHREAD_CFLAGS) -DNDEBUG
TCMALLOC_MINIMAL_SYMBOLS = '(malloc|free|realloc|calloc|cfree|memalign|valloc|pvalloc|posix_memalign|malloc_stats|MallocExtension|MallocHook)'
libtcmalloc_minimal_la_LDFLAGS = $(PTHREAD_CFLAGS) -export-symbols-regex $(TCMALLOC_MINIMAL_SYMBOLS)
-libtcmalloc_minimal_la_LIBADD = $(PTHREAD_LIBS) libstacktrace.la
+libtcmalloc_minimal_la_LIBADD = $(PTHREAD_LIBS) \
+ libstacktrace.la libspinlock.la liblogging.la
### Unittests
# Commented out for the moment because malloc(very_big_num) is broken in
# standard libc! At least, in some situations, some of the time.
## TESTS += malloc_unittest
-## MALLOC_UNITEST_INCLUDES = src/config.h \
-## src/google/malloc_extension.h \
+## MALLOC_UNITEST_INCLUDES = src/google/malloc_extension.h \
## src/google/malloc_hook.h \
## src/base/basictypes.h \
## src/google/perftools/hash_set.h \
@@ -140,7 +218,15 @@ tcmalloc_unittest_SOURCES = src/tests/tcmalloc_unittest.cc \
$(TCMALLOC_UNITTEST_INCLUDES)
tcmalloc_unittest_CXXFLAGS = $(PTHREAD_CFLAGS)
tcmalloc_unittest_LDFLAGS = $(PTHREAD_CFLAGS)
-tcmalloc_unittest_LDADD = libtcmalloc.la $(PTHREAD_LIBS)
+tcmalloc_unittest_LDADD = libtcmalloc.la liblogging.la $(PTHREAD_LIBS)
+
+TESTS += tcmalloc_minimal_unittest
+tcmalloc_minimal_unittest_SOURCES = src/tests/tcmalloc_unittest.cc \
+ $(TCMALLOC_UNITTEST_INCLUDES)
+tcmalloc_minimal_unittest_CXXFLAGS = $(PTHREAD_CFLAGS)
+tcmalloc_minimal_unittest_LDFLAGS = $(PTHREAD_CFLAGS)
+tcmalloc_minimal_unittest_LDADD = libtcmalloc_minimal.la \
+ liblogging.la $(PTHREAD_LIBS)
TESTS += tcmalloc_large_unittest
tcmalloc_large_unittest_SOURCES = src/tests/tcmalloc_large_unittest.cc
@@ -148,6 +234,12 @@ tcmalloc_large_unittest_CXXFLAGS = $(PTHREAD_CFLAGS)
tcmalloc_large_unittest_LDFLAGS = $(PTHREAD_CFLAGS)
tcmalloc_large_unittest_LDADD = libtcmalloc.la $(PTHREAD_LIBS)
+TESTS += tcmalloc_minimal_large_unittest
+tcmalloc_minimal_large_unittest_SOURCES = src/tests/tcmalloc_large_unittest.cc
+tcmalloc_minimal_large_unittest_CXXFLAGS = $(PTHREAD_CFLAGS)
+tcmalloc_minimal_large_unittest_LDFLAGS = $(PTHREAD_CFLAGS)
+tcmalloc_minimal_large_unittest_LDADD = libtcmalloc_minimal.la $(PTHREAD_LIBS)
+
# performance/unittests originally from ptmalloc2
TESTS += ptmalloc_unittest1 ptmalloc_unittest2
PTMALLOC_UNITTEST_INCLUDES = src/tests/ptmalloc/t-test.h \
@@ -166,6 +258,32 @@ ptmalloc_unittest2_CFLAGS = $(PTHREAD_CFLAGS) -DUSE_PTHREADS
ptmalloc_unittest2_LDFLAGS = $(PTHREAD_CFLAGS)
ptmalloc_unittest2_LDADD = $(PTHREAD_LIBS)
+TESTS += frag_unittest
+frag_unittest_SOURCES = src/tests/frag_unittest.cc
+frag_unittest_CXXFLAGS = $(PTHREAD_CFLAGS)
+frag_unittest_LDFLAGS = $(PTHREAD_CFLAGS)
+frag_unittest_LDADD = libtcmalloc_minimal.la $(PTHREAD_LIBS)
+
+TESTS += markidle_unittest
+markidle_unittest_SOURCES = src/tests/markidle_unittest.cc \
+ src/tests/testutil.h src/tests/testutil.cc
+markidle_unittest_CXXFLAGS = $(PTHREAD_CFLAGS)
+markidle_unittest_LDFLAGS = $(PTHREAD_CFLAGS)
+markidle_unittest_LDADD = libtcmalloc_minimal.la $(PTHREAD_LIBS)
+
+TESTS += memalign_unittest
+memalign_unittest_SOURCES = src/tests/memalign_unittest.cc
+memalign_unittest_CXXFLAGS = $(PTHREAD_CFLAGS)
+memalign_unittest_LDFLAGS = $(PTHREAD_CFLAGS)
+memalign_unittest_LDADD = libtcmalloc_minimal.la $(PTHREAD_LIBS)
+
+TESTS += thread_dealloc_unittest
+thread_dealloc_unittest_SOURCES = src/tests/thread_dealloc_unittest.cc \
+ src/tests/testutil.h src/tests/testutil.cc
+thread_dealloc_unittest_CXXFLAGS = $(PTHREAD_CFLAGS)
+thread_dealloc_unittest_LDFLAGS = $(PTHREAD_CFLAGS)
+thread_dealloc_unittest_LDADD = libtcmalloc_minimal.la $(PTHREAD_LIBS)
+
### Documentation
dist_doc_DATA += doc/tcmalloc.html \
doc/overview.gif \
@@ -207,22 +325,23 @@ dist_doc_DATA += doc/overview.dot \
### ------- tcmalloc (thread-caching malloc + heap profiler + heap checker)
### The header files we use. We divide into categories based on directory
-S_TCMALLOC_INCLUDES = src/config.h \
- src/internal_logging.h \
+S_TCMALLOC_INCLUDES = src/internal_logging.h \
src/system-alloc.h \
- src/internal_spinlock.h \
src/pagemap.h \
- src/heap-profiler-inl.h \
src/addressmap-inl.h \
+ src/heap-profile-table.h \
src/base/basictypes.h \
src/base/commandlineflags.h \
- src/base/logging.h \
src/base/googleinit.h \
src/base/elfcore.h \
src/base/linux_syscall_support.h \
src/base/linuxthreads.h \
src/base/thread_lister.h \
- src/maybe_threads.h
+ src/base/sysinfo.h \
+ src/base/stl_allocator.h \
+ src/maybe_threads.h \
+ $(SPINLOCK_INCLUDES) \
+ $(LOGGING_INCLUDES)
SG_TCMALLOC_INCLUDES = src/google/malloc_hook.h \
src/google/malloc_extension.h \
src/google/heap-profiler.h \
@@ -235,40 +354,51 @@ perftoolsinclude_HEADERS += $(SGP_TCMALLOC_INCLUDES)
### Making the library
lib_LTLIBRARIES += libtcmalloc.la
+# Note: heap-checker-bcad is last, in hopes its global ctor will run first
libtcmalloc_la_SOURCES = src/internal_logging.cc \
src/system-alloc.cc \
src/tcmalloc.cc \
src/malloc_hook.cc \
src/malloc_extension.cc \
src/maybe_threads.cc \
+ src/memory_region_map.cc \
src/heap-profiler.cc \
+ src/heap-profile-table.cc \
src/heap-checker.cc \
- src/heap-checker-bcad.cc \
src/base/linuxthreads.c \
src/base/thread_lister.c \
- $(TCMALLOC_INCLUDES)
+ src/base/sysinfo.cc \
+ src/base/low_level_alloc.cc \
+ $(TCMALLOC_INCLUDES) \
+ src/heap-checker-bcad.cc
libtcmalloc_la_CXXFLAGS = $(PTHREAD_CFLAGS) -DNDEBUG
TCMALLOC_SYMBOLS = '(malloc|free|realloc|calloc|cfree|memalign|valloc|pvalloc|posix_memalign|malloc_stats|MallocExtension|MallocHook|HeapProfilerStart|HeapProfilerStop|HeapProfilerDump|GetHeapProfile|HeapCleaner|HeapLeakChecker)'
libtcmalloc_la_LDFLAGS = $(PTHREAD_CFLAGS) -export-symbols-regex $(TCMALLOC_SYMBOLS)
-libtcmalloc_la_LIBADD = $(PTHREAD_LIBS) libstacktrace.la
+libtcmalloc_la_LIBADD = $(PTHREAD_LIBS) \
+ libstacktrace.la libspinlock.la liblogging.la
### Unittests
+
+# These unittests often need to run binaries. They're in the current dir
+TESTS_ENVIRONMENT += BINDIR=.
+
TESTS += addressmap_unittest
ADDRESSMAP_UNITTEST_INCLUDES = src/addressmap-inl.h \
- src/base/logging.h \
- src/base/commandlineflags.h
+ src/base/commandlineflags.h \
+ $(LOGGING_INCLUDES)
addressmap_unittest_SOURCES = src/tests/addressmap_unittest.cc \
$(ADDRESSMAP_UNITTEST_INCLUDES)
addressmap_unittest_CXXFLAGS = -g
+addressmap_unittest_LDADD = liblogging.la
-check_SCRIPTS += heap-profiler_unittest_sh
-noinst_SCRIPTS += src/tests/heap-profiler_unittest.sh
+TESTS += heap-profiler_unittest.sh
+heap_profiler_unittest_sh_SOURCES = src/tests/heap-profiler_unittest.sh
+noinst_SCRIPTS += $(heap_profiler_unittest_sh_SOURCES)
+heap-profiler_unittest.sh: $(heap_profiler_unittest_sh_SOURCES)
+ cp -a $(heap_profiler_unittest_sh_SOURCES) $@
# These are sub-programs used by heap-profiler_unittest.sh
-HEAP_PROFILER_UNITTESTS = heap-profiler_unittest
-heap-profiler_unittest_sh: $(HEAP_PROFILER_UNITTESTS)
- $(top_srcdir)/src/tests/heap-profiler_unittest.sh . $(top_srcdir)/src
-
+noinst_PROGRAMS += heap-profiler_unittest
HEAP_PROFILER_UNITTEST_INCLUDES = src/google/heap-profiler.h
heap_profiler_unittest_SOURCES = src/tests/heap-profiler_unittest.cc \
$(HEAP_PROFILER_UNITTEST_INCLUDES)
@@ -276,34 +406,34 @@ heap_profiler_unittest_CXXFLAGS = -g
heap_profiler_unittest_LDFLAGS = -g $(PTHREAD_CFLAGS)
heap_profiler_unittest_LDADD = libtcmalloc.la $(PTHREAD_LIBS)
-check_SCRIPTS += heap_checker_unittest_sh
-noinst_SCRIPTS += src/tests/heap-checker_unittest.sh
+TESTS += heap-checker_unittest.sh
+heap_checker_unittest_sh_SOURCES = src/tests/heap-checker_unittest.sh
+noinst_SCRIPTS += $(heap_checker_unittest_sh_SOURCES)
+heap-checker_unittest.sh: $(heap_checker_unittest_sh_SOURCES)
+ cp -a $(heap_checker_unittest_sh_SOURCES) $@
-# These are sub-programs used by heap-checker_unittest.sh
-HEAP_CHECKER_UNITTESTS = heap-checker_unittest
-heap_checker_unittest_sh: $(HEAP_CHECKER_UNITTESTS)
- $(top_srcdir)/src/tests/heap-checker_unittest.sh . $(top_srcdir)/src
+TESTS += heap-checker-death_unittest.sh
+heap_checker_death_unittest_sh_SOURCES = src/tests/heap-checker-death_unittest.sh
+noinst_SCRIPTS += $(heap_checker_death_unittest_sh_SOURCES)
+heap-checker-death_unittest.sh: $(heap_checker_death_unittest_sh_SOURCES)
+ cp -a $(heap_checker_death_unittest_sh_SOURCES) $@
-HEAP_CHECKER_UNITTEST_INCLUDES = src/config.h \
- src/base/logging.h \
+# These are sub-programs used by heap-checker_unittest.sh
+noinst_PROGRAMS += heap-checker_unittest
+HEAP_CHECKER_UNITTEST_INCLUDES = src/memory_region_map.h \
+ src/base/commandlineflags.h \
src/base/googleinit.h \
- src/google/heap-profiler.h \
- src/google/heap-checker.h
+ src/google/heap-checker.h \
+ $(LOGGING_INCLUDES)
heap_checker_unittest_SOURCES = src/tests/heap-checker_unittest.cc \
$(HEAP_CHECKER_UNITTEST_INCLUDES)
heap_checker_unittest_CXXFLAGS = -g $(PTHREAD_CFLAGS)
heap_checker_unittest_LDFLAGS = -g $(PTHREAD_CFLAGS)
# tcmalloc has to be specified last!
-heap_checker_unittest_LDADD = $(PTHREAD_LIBS) -ltcmalloc
-
-check_SCRIPTS += heap-checker-death_unittest
-noinst_SCRIPTS += src/tests/heap-checker-death_unittest.sh
-
-heap-checker-death_unittest:
- PPROF_PATH=$(top_srcdir)/src/pprof sh $(top_srcdir)/src/tests/heap-checker-death_unittest.sh
+heap_checker_unittest_LDADD = $(PTHREAD_LIBS) liblogging.la -ltcmalloc
### Documentation (above and beyond tcmalloc_minimal documentation)
-dist_doc_DATA += doc/heap_profiler.html \
+dist_doc_DATA += doc/heapprofile.html \
doc/heap-example1.png \
doc/heap_checker.html
@@ -311,10 +441,12 @@ dist_doc_DATA += doc/heap_profiler.html \
### ------- CPU profiler
### The header files we use. We divide into categories based on directory
-S_CPU_PROFILER_INCLUDES = src/config.h \
- src/base/commandlineflags.h \
+S_CPU_PROFILER_INCLUDES = src/base/commandlineflags.h \
src/base/googleinit.h \
- src/base/logging.h
+ src/base/logging.h \
+ src/base/mutex.h \
+ $(SPINLOCK_INCLUDES) \
+ $(LOGGING_INCLUDES)
SG_CPU_PROFILER_INCLUDES = src/google/profiler.h \
src/google/stacktrace.h
SGP_CPU_PROFILER_INCLUDES =
@@ -325,25 +457,25 @@ perftoolsinclude_HEADERS += $(SGP_CPU_PROFILER_INCLUDES)
### Making the library
lib_LTLIBRARIES += libprofiler.la
libprofiler_la_SOURCES = src/profiler.cc \
- src/stacktrace.cc \
+ src/base/mutex.cc \
$(CPU_PROFILER_INCLUDES)
+libprofiler_la_LIBADD = libspinlock.la liblogging.la libstacktrace.la
CPU_PROFILER_SYMBOLS = '(ProfilerStart|ProfilerStop|ProfilerEnable|ProfilerDisable|ProfilerFlush|ProfilerRegisterThread|ProfilerThreadState)'
libprofiler_la_LDFLAGS = -export-symbols-regex $(CPU_PROFILER_SYMBOLS)
### Unittests
-check_SCRIPTS += profiler_unittest_sh pprof_unittest
-noinst_SCRIPTS += src/tests/profiler_unittest.sh
+TESTS += profiler_unittest.sh
+profiler_unittest_sh_SOURCES = src/tests/profiler_unittest.sh
+noinst_SCRIPTS += $(profiler_unittest_sh_SOURCES)
+profiler_unittest.sh: $(profiler_unittest_sh_SOURCES)
+ cp -a $(profiler_unittest_sh_SOURCES) $@
# These are sub-programs used by profiler_unittest.sh
-PROFILER_UNITTESTS = profiler1_unittest profiler2_unittest profiler3_unittest \
- profiler4_unittest
-profiler_unittest_sh: $(PROFILER_UNITTESTS)
- $(top_srcdir)/src/tests/profiler_unittest.sh . $(top_srcdir)/src
-
-PROFILER_UNITTEST_INCLUDES = src/config.h \
- src/google/profiler.h
+noinst_PROGRAMS += profiler1_unittest profiler2_unittest profiler3_unittest \
+ profiler4_unittest
+PROFILER_UNITTEST_INCLUDES = src/google/profiler.h
PROFILER_UNITTEST_SRCS = src/tests/profiler_unittest.cc \
- $(PROFILER_UNITTEST_INCLUDES)
+ $(PROFILER_UNITTEST_INCLUDES)
profiler1_unittest_SOURCES = $(PROFILER_UNITTEST_SRCS)
profiler1_unittest_CXXFLAGS = -g
profiler1_unittest_LDADD = libprofiler.la
@@ -359,12 +491,8 @@ profiler4_unittest_CXXFLAGS = -g $(PTHREAD_CFLAGS) -DWITH_THREADS
profiler4_unittest_LDFLAGS = $(PTHREAD_CFLAGS)
profiler4_unittest_LDADD = -lprofiler $(PTHREAD_LIBS)
-pprof_unittest: $(top_srcdir)/src/pprof
- $< -test
-
### Documentation
-dist_man_MANS = doc/pprof.1
-dist_doc_DATA += doc/cpu_profiler.html \
+dist_doc_DATA += doc/cpuprofile.html \
doc/pprof-test-big.gif \
doc/pprof-test.gif \
doc/pprof-vsnprintf-big.gif \
@@ -376,9 +504,7 @@ dist_doc_DATA += doc/cpu_profiler.html \
# This should always include $(TESTS), but may also include other
# binaries that you compile but don't want automatically installed.
# We'll add to this later, on a library-by-library basis
-noinst_PROGRAMS = $(TESTS) $(PROFILER_UNITTESTS) $(HEAP_PROFILER_UNITTESTS) \
- $(HEAP_CHECKER_UNITTESTS)
-bin_SCRIPTS = src/pprof
+noinst_PROGRAMS += $(TESTS)
rpm: dist-gzip packages/rpm.sh packages/rpm/rpm.spec
@cd packages && ./rpm.sh ${PACKAGE} ${VERSION}
@@ -390,6 +516,7 @@ libtool: $(LIBTOOL_DEPS)
$(SHELL) ./config.status --recheck
EXTRA_DIST = packages/rpm.sh packages/rpm/rpm.spec packages/deb.sh packages/deb \
- $(SCRIPTS) libtool
+ $(SCRIPTS) libtool \
+ src/solaris/libstdc++.la
DISTCLEANFILES = src/google/perftools/hash_set.h
diff --git a/Makefile.in b/Makefile.in
index aee8fcf..7678229 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -44,14 +44,17 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-noinst_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2)
+noinst_PROGRAMS = heap-profiler_unittest$(EXEEXT) \
+ heap-checker_unittest$(EXEEXT) profiler1_unittest$(EXEEXT) \
+ profiler2_unittest$(EXEEXT) profiler3_unittest$(EXEEXT) \
+ profiler4_unittest$(EXEEXT) $(am__EXEEXT_1)
DIST_COMMON = README $(am__configure_deps) $(dist_doc_DATA) \
$(dist_man_MANS) $(googleinclude_HEADERS) \
$(perftoolsinclude_HEADERS) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in $(top_srcdir)/configure \
- $(top_srcdir)/src/google/perftools/config.h.in AUTHORS COPYING \
- ChangeLog INSTALL NEWS TODO compile config.guess config.sub \
- depcomp install-sh ltmain.sh missing mkinstalldirs
+ $(top_srcdir)/src/config.h.in AUTHORS COPYING ChangeLog \
+ INSTALL NEWS TODO compile config.guess config.sub depcomp \
+ install-sh ltmain.sh missing mkinstalldirs
subdir = .
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.ac
@@ -60,7 +63,7 @@ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
configure.lineno configure.status.lineno
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
-CONFIG_HEADER = $(top_builddir)/src/google/perftools/config.h
+CONFIG_HEADER = $(top_builddir)/src/config.h
CONFIG_CLEAN_FILES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
@@ -73,75 +76,145 @@ am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \
"$(DESTDIR)$(googleincludedir)" \
"$(DESTDIR)$(perftoolsincludedir)"
libLTLIBRARIES_INSTALL = $(INSTALL)
-LTLIBRARIES = $(lib_LTLIBRARIES)
-am__DEPENDENCIES_1 =
-libheapchecker_la_DEPENDENCIES = libheapprofiler.la \
- $(am__DEPENDENCIES_1)
+LTLIBRARIES = $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES)
+liblogging_la_LIBADD =
am__objects_1 =
-am__objects_2 = $(am__objects_1) $(am__objects_1) $(am__objects_1)
-am_libheapchecker_la_OBJECTS = libheapchecker_la-heap-checker.lo \
- libheapchecker_la-heap-checker-bcad.lo $(am__objects_2)
-libheapchecker_la_OBJECTS = $(am_libheapchecker_la_OBJECTS)
-libheapprofiler_la_DEPENDENCIES = libtcmalloc.la $(am__DEPENDENCIES_1)
-am_libheapprofiler_la_OBJECTS = libheapprofiler_la-heap-profiler.lo \
- libheapprofiler_la-heap-checker-bcad.lo $(am__objects_2)
-libheapprofiler_la_OBJECTS = $(am_libheapprofiler_la_OBJECTS)
-libprofiler_la_LIBADD =
-am_libprofiler_la_OBJECTS = profiler.lo stacktrace.lo $(am__objects_2)
+am_liblogging_la_OBJECTS = logging.lo $(am__objects_1)
+liblogging_la_OBJECTS = $(am_liblogging_la_OBJECTS)
+libprofiler_la_DEPENDENCIES = libspinlock.la liblogging.la \
+ libstacktrace.la
+am__objects_2 = $(am__objects_1) $(am__objects_1)
+am__objects_3 = $(am__objects_2) $(am__objects_1) $(am__objects_1)
+am_libprofiler_la_OBJECTS = profiler.lo mutex.lo $(am__objects_3)
libprofiler_la_OBJECTS = $(am_libprofiler_la_OBJECTS)
-libstacktrace_la_LIBADD =
-am_libstacktrace_la_OBJECTS = stacktrace.lo $(am__objects_2)
+libspinlock_la_LIBADD =
+am_libspinlock_la_OBJECTS = spinlock.lo atomicops-internals-x86.lo \
+ $(am__objects_1)
+libspinlock_la_OBJECTS = $(am_libspinlock_la_OBJECTS)
+am__DEPENDENCIES_1 =
+libstacktrace_la_DEPENDENCIES = $(am__DEPENDENCIES_1) libspinlock.la
+am__objects_4 = $(am__objects_1) $(am__objects_1) $(am__objects_1)
+am_libstacktrace_la_OBJECTS = stacktrace.lo $(am__objects_4)
libstacktrace_la_OBJECTS = $(am_libstacktrace_la_OBJECTS)
-libtcmalloc_la_DEPENDENCIES = $(am__DEPENDENCIES_1) libstacktrace.la
+libtcmalloc_la_DEPENDENCIES = $(am__DEPENDENCIES_1) libstacktrace.la \
+ libspinlock.la liblogging.la
am_libtcmalloc_la_OBJECTS = libtcmalloc_la-internal_logging.lo \
libtcmalloc_la-system-alloc.lo libtcmalloc_la-tcmalloc.lo \
libtcmalloc_la-malloc_hook.lo \
- libtcmalloc_la-malloc_interface.lo $(am__objects_2)
+ libtcmalloc_la-malloc_extension.lo \
+ libtcmalloc_la-maybe_threads.lo \
+ libtcmalloc_la-memory_region_map.lo \
+ libtcmalloc_la-heap-profiler.lo \
+ libtcmalloc_la-heap-profile-table.lo \
+ libtcmalloc_la-heap-checker.lo linuxthreads.lo \
+ thread_lister.lo libtcmalloc_la-sysinfo.lo \
+ libtcmalloc_la-low_level_alloc.lo $(am__objects_3) \
+ libtcmalloc_la-heap-checker-bcad.lo
libtcmalloc_la_OBJECTS = $(am_libtcmalloc_la_OBJECTS)
-am__EXEEXT_1 = stacktrace_unittest$(EXEEXT) malloc_unittest$(EXEEXT) \
- tcmalloc_unittest$(EXEEXT) ptmalloc_unittest1$(EXEEXT) \
- ptmalloc_unittest2$(EXEEXT) addressmap_unittest$(EXEEXT) \
- heap-checker_unittest$(EXEEXT)
-am__EXEEXT_2 = profiler1_unittest$(EXEEXT) profiler2_unittest$(EXEEXT) \
- profiler3_unittest$(EXEEXT) profiler4_unittest$(EXEEXT)
+libtcmalloc_minimal_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+ libstacktrace.la libspinlock.la liblogging.la
+am__objects_5 = $(am__objects_1)
+am__objects_6 = $(am__objects_5) $(am__objects_1) $(am__objects_1)
+am_libtcmalloc_minimal_la_OBJECTS = \
+ libtcmalloc_minimal_la-internal_logging.lo \
+ libtcmalloc_minimal_la-system-alloc.lo \
+ libtcmalloc_minimal_la-tcmalloc.lo \
+ libtcmalloc_minimal_la-malloc_hook.lo \
+ libtcmalloc_minimal_la-malloc_extension.lo \
+ libtcmalloc_minimal_la-maybe_threads.lo $(am__objects_6)
+libtcmalloc_minimal_la_OBJECTS = $(am_libtcmalloc_minimal_la_OBJECTS)
+am__EXEEXT_1 = low_level_alloc_unittest$(EXEEXT) \
+ atomicops_unittest$(EXEEXT) stacktrace_unittest$(EXEEXT) \
+ tcmalloc_unittest$(EXEEXT) tcmalloc_minimal_unittest$(EXEEXT) \
+ tcmalloc_large_unittest$(EXEEXT) \
+ tcmalloc_minimal_large_unittest$(EXEEXT) \
+ ptmalloc_unittest1$(EXEEXT) ptmalloc_unittest2$(EXEEXT) \
+ frag_unittest$(EXEEXT) markidle_unittest$(EXEEXT) \
+ memalign_unittest$(EXEEXT) thread_dealloc_unittest$(EXEEXT) \
+ addressmap_unittest$(EXEEXT) \
+ heap-profiler_unittest.sh$(EXEEXT) \
+ heap-checker_unittest.sh$(EXEEXT) \
+ heap-checker-death_unittest.sh$(EXEEXT) \
+ profiler_unittest.sh$(EXEEXT)
PROGRAMS = $(noinst_PROGRAMS)
am_addressmap_unittest_OBJECTS = \
addressmap_unittest-addressmap_unittest.$(OBJEXT) \
- $(am__objects_1)
+ $(am__objects_5)
addressmap_unittest_OBJECTS = $(am_addressmap_unittest_OBJECTS)
-addressmap_unittest_LDADD = $(LDADD)
+addressmap_unittest_DEPENDENCIES = liblogging.la
+am_atomicops_unittest_OBJECTS = atomicops_unittest.$(OBJEXT) \
+ $(am__objects_5)
+atomicops_unittest_OBJECTS = $(am_atomicops_unittest_OBJECTS)
+atomicops_unittest_DEPENDENCIES = libspinlock.la liblogging.la
+am_frag_unittest_OBJECTS = frag_unittest-frag_unittest.$(OBJEXT)
+frag_unittest_OBJECTS = $(am_frag_unittest_OBJECTS)
+frag_unittest_DEPENDENCIES = libtcmalloc_minimal.la \
+ $(am__DEPENDENCIES_1)
+am_heap_checker_death_unittest_sh_OBJECTS =
+heap_checker_death_unittest_sh_OBJECTS = \
+ $(am_heap_checker_death_unittest_sh_OBJECTS)
+heap_checker_death_unittest_sh_LDADD = $(LDADD)
am_heap_checker_unittest_OBJECTS = \
heap_checker_unittest-heap-checker_unittest.$(OBJEXT) \
- $(am__objects_1)
+ $(am__objects_5)
heap_checker_unittest_OBJECTS = $(am_heap_checker_unittest_OBJECTS)
-heap_checker_unittest_DEPENDENCIES = libheapchecker.la \
+heap_checker_unittest_DEPENDENCIES = $(am__DEPENDENCIES_1) \
+ liblogging.la
+am_heap_checker_unittest_sh_OBJECTS =
+heap_checker_unittest_sh_OBJECTS = \
+ $(am_heap_checker_unittest_sh_OBJECTS)
+heap_checker_unittest_sh_LDADD = $(LDADD)
+am_heap_profiler_unittest_OBJECTS = \
+ heap_profiler_unittest-heap-profiler_unittest.$(OBJEXT) \
+ $(am__objects_1)
+heap_profiler_unittest_OBJECTS = $(am_heap_profiler_unittest_OBJECTS)
+heap_profiler_unittest_DEPENDENCIES = libtcmalloc.la \
+ $(am__DEPENDENCIES_1)
+am_heap_profiler_unittest_sh_OBJECTS =
+heap_profiler_unittest_sh_OBJECTS = \
+ $(am_heap_profiler_unittest_sh_OBJECTS)
+heap_profiler_unittest_sh_LDADD = $(LDADD)
+am_low_level_alloc_unittest_OBJECTS = low_level_alloc.$(OBJEXT) \
+ malloc_hook.$(OBJEXT) low_level_alloc_unittest.$(OBJEXT) \
+ $(am__objects_2)
+low_level_alloc_unittest_OBJECTS = \
+ $(am_low_level_alloc_unittest_OBJECTS)
+low_level_alloc_unittest_DEPENDENCIES = libspinlock.la liblogging.la \
+ libstacktrace.la
+am_markidle_unittest_OBJECTS = \
+ markidle_unittest-markidle_unittest.$(OBJEXT) \
+ markidle_unittest-testutil.$(OBJEXT)
+markidle_unittest_OBJECTS = $(am_markidle_unittest_OBJECTS)
+markidle_unittest_DEPENDENCIES = libtcmalloc_minimal.la \
$(am__DEPENDENCIES_1)
-am_malloc_unittest_OBJECTS = \
- malloc_unittest-tcmalloc_unittest.$(OBJEXT) \
- malloc_unittest-malloc_hook.$(OBJEXT) \
- malloc_unittest-malloc_interface.$(OBJEXT)
-malloc_unittest_OBJECTS = $(am_malloc_unittest_OBJECTS)
-malloc_unittest_DEPENDENCIES = $(am__DEPENDENCIES_1)
-am__objects_3 = profiler1_unittest-profiler_unittest.$(OBJEXT) \
+am_memalign_unittest_OBJECTS = \
+ memalign_unittest-memalign_unittest.$(OBJEXT)
+memalign_unittest_OBJECTS = $(am_memalign_unittest_OBJECTS)
+memalign_unittest_DEPENDENCIES = libtcmalloc_minimal.la \
+ $(am__DEPENDENCIES_1)
+am__objects_7 = profiler1_unittest-profiler_unittest.$(OBJEXT) \
$(am__objects_1)
-am_profiler1_unittest_OBJECTS = $(am__objects_3)
+am_profiler1_unittest_OBJECTS = $(am__objects_7)
profiler1_unittest_OBJECTS = $(am_profiler1_unittest_OBJECTS)
profiler1_unittest_DEPENDENCIES = libprofiler.la
-am__objects_4 = profiler2_unittest-profiler_unittest.$(OBJEXT) \
+am__objects_8 = profiler2_unittest-profiler_unittest.$(OBJEXT) \
$(am__objects_1)
-am_profiler2_unittest_OBJECTS = $(am__objects_4)
+am_profiler2_unittest_OBJECTS = $(am__objects_8)
profiler2_unittest_OBJECTS = $(am_profiler2_unittest_OBJECTS)
profiler2_unittest_DEPENDENCIES =
-am__objects_5 = profiler3_unittest-profiler_unittest.$(OBJEXT) \
+am__objects_9 = profiler3_unittest-profiler_unittest.$(OBJEXT) \
$(am__objects_1)
-am_profiler3_unittest_OBJECTS = $(am__objects_5)
+am_profiler3_unittest_OBJECTS = $(am__objects_9)
profiler3_unittest_OBJECTS = $(am_profiler3_unittest_OBJECTS)
profiler3_unittest_DEPENDENCIES = libprofiler.la $(am__DEPENDENCIES_1)
-am__objects_6 = profiler4_unittest-profiler_unittest.$(OBJEXT) \
+am__objects_10 = profiler4_unittest-profiler_unittest.$(OBJEXT) \
$(am__objects_1)
-am_profiler4_unittest_OBJECTS = $(am__objects_6)
+am_profiler4_unittest_OBJECTS = $(am__objects_10)
profiler4_unittest_OBJECTS = $(am_profiler4_unittest_OBJECTS)
profiler4_unittest_DEPENDENCIES = $(am__DEPENDENCIES_1)
+am_profiler_unittest_sh_OBJECTS =
+profiler_unittest_sh_OBJECTS = $(am_profiler_unittest_sh_OBJECTS)
+profiler_unittest_sh_LDADD = $(LDADD)
am_ptmalloc_unittest1_OBJECTS = ptmalloc_unittest1-t-test1.$(OBJEXT) \
$(am__objects_1)
ptmalloc_unittest1_OBJECTS = $(am_ptmalloc_unittest1_OBJECTS)
@@ -150,18 +223,44 @@ am_ptmalloc_unittest2_OBJECTS = ptmalloc_unittest2-t-test2.$(OBJEXT) \
$(am__objects_1)
ptmalloc_unittest2_OBJECTS = $(am_ptmalloc_unittest2_OBJECTS)
ptmalloc_unittest2_DEPENDENCIES = $(am__DEPENDENCIES_1)
-am__objects_7 = $(am__objects_2)
+am__objects_11 = $(am__objects_4) $(am__objects_1)
am_stacktrace_unittest_OBJECTS = stacktrace_unittest.$(OBJEXT) \
- $(am__objects_7)
+ $(am__objects_11)
stacktrace_unittest_OBJECTS = $(am_stacktrace_unittest_OBJECTS)
-stacktrace_unittest_DEPENDENCIES = libstacktrace.la
+stacktrace_unittest_DEPENDENCIES = libstacktrace.la liblogging.la
+am_tcmalloc_large_unittest_OBJECTS = \
+ tcmalloc_large_unittest-tcmalloc_large_unittest.$(OBJEXT)
+tcmalloc_large_unittest_OBJECTS = \
+ $(am_tcmalloc_large_unittest_OBJECTS)
+tcmalloc_large_unittest_DEPENDENCIES = libtcmalloc.la \
+ $(am__DEPENDENCIES_1)
+am_tcmalloc_minimal_large_unittest_OBJECTS = tcmalloc_minimal_large_unittest-tcmalloc_large_unittest.$(OBJEXT)
+tcmalloc_minimal_large_unittest_OBJECTS = \
+ $(am_tcmalloc_minimal_large_unittest_OBJECTS)
+tcmalloc_minimal_large_unittest_DEPENDENCIES = libtcmalloc_minimal.la \
+ $(am__DEPENDENCIES_1)
+am_tcmalloc_minimal_unittest_OBJECTS = \
+ tcmalloc_minimal_unittest-tcmalloc_unittest.$(OBJEXT) \
+ $(am__objects_1)
+tcmalloc_minimal_unittest_OBJECTS = \
+ $(am_tcmalloc_minimal_unittest_OBJECTS)
+tcmalloc_minimal_unittest_DEPENDENCIES = libtcmalloc_minimal.la \
+ liblogging.la $(am__DEPENDENCIES_1)
am_tcmalloc_unittest_OBJECTS = \
tcmalloc_unittest-tcmalloc_unittest.$(OBJEXT) $(am__objects_1)
tcmalloc_unittest_OBJECTS = $(am_tcmalloc_unittest_OBJECTS)
-tcmalloc_unittest_DEPENDENCIES = libtcmalloc.la $(am__DEPENDENCIES_1)
+tcmalloc_unittest_DEPENDENCIES = libtcmalloc.la liblogging.la \
+ $(am__DEPENDENCIES_1)
+am_thread_dealloc_unittest_OBJECTS = \
+ thread_dealloc_unittest-thread_dealloc_unittest.$(OBJEXT) \
+ thread_dealloc_unittest-testutil.$(OBJEXT)
+thread_dealloc_unittest_OBJECTS = \
+ $(am_thread_dealloc_unittest_OBJECTS)
+thread_dealloc_unittest_DEPENDENCIES = libtcmalloc_minimal.la \
+ $(am__DEPENDENCIES_1)
binSCRIPT_INSTALL = $(INSTALL_SCRIPT)
SCRIPTS = $(bin_SCRIPTS) $(noinst_SCRIPTS)
-DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/src/google/perftools
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/src
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
@@ -180,23 +279,48 @@ LTCXXCOMPILE = $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) \
CXXLD = $(CXX)
CXXLINK = $(LIBTOOL) --tag=CXX --mode=link $(CXXLD) $(AM_CXXFLAGS) \
$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
-SOURCES = $(libheapchecker_la_SOURCES) $(libheapprofiler_la_SOURCES) \
- $(libprofiler_la_SOURCES) $(libstacktrace_la_SOURCES) \
- $(libtcmalloc_la_SOURCES) $(addressmap_unittest_SOURCES) \
- $(heap_checker_unittest_SOURCES) $(malloc_unittest_SOURCES) \
+SOURCES = $(liblogging_la_SOURCES) $(libprofiler_la_SOURCES) \
+ $(libspinlock_la_SOURCES) $(libstacktrace_la_SOURCES) \
+ $(libtcmalloc_la_SOURCES) $(libtcmalloc_minimal_la_SOURCES) \
+ $(addressmap_unittest_SOURCES) $(atomicops_unittest_SOURCES) \
+ $(frag_unittest_SOURCES) \
+ $(heap_checker_death_unittest_sh_SOURCES) \
+ $(heap_checker_unittest_SOURCES) \
+ $(heap_checker_unittest_sh_SOURCES) \
+ $(heap_profiler_unittest_SOURCES) \
+ $(heap_profiler_unittest_sh_SOURCES) \
+ $(low_level_alloc_unittest_SOURCES) \
+ $(markidle_unittest_SOURCES) $(memalign_unittest_SOURCES) \
$(profiler1_unittest_SOURCES) $(profiler2_unittest_SOURCES) \
$(profiler3_unittest_SOURCES) $(profiler4_unittest_SOURCES) \
- $(ptmalloc_unittest1_SOURCES) $(ptmalloc_unittest2_SOURCES) \
- $(stacktrace_unittest_SOURCES) $(tcmalloc_unittest_SOURCES)
-DIST_SOURCES = $(libheapchecker_la_SOURCES) \
- $(libheapprofiler_la_SOURCES) $(libprofiler_la_SOURCES) \
- $(libstacktrace_la_SOURCES) $(libtcmalloc_la_SOURCES) \
- $(addressmap_unittest_SOURCES) \
- $(heap_checker_unittest_SOURCES) $(malloc_unittest_SOURCES) \
+ $(profiler_unittest_sh_SOURCES) $(ptmalloc_unittest1_SOURCES) \
+ $(ptmalloc_unittest2_SOURCES) $(stacktrace_unittest_SOURCES) \
+ $(tcmalloc_large_unittest_SOURCES) \
+ $(tcmalloc_minimal_large_unittest_SOURCES) \
+ $(tcmalloc_minimal_unittest_SOURCES) \
+ $(tcmalloc_unittest_SOURCES) \
+ $(thread_dealloc_unittest_SOURCES)
+DIST_SOURCES = $(liblogging_la_SOURCES) $(libprofiler_la_SOURCES) \
+ $(libspinlock_la_SOURCES) $(libstacktrace_la_SOURCES) \
+ $(libtcmalloc_la_SOURCES) $(libtcmalloc_minimal_la_SOURCES) \
+ $(addressmap_unittest_SOURCES) $(atomicops_unittest_SOURCES) \
+ $(frag_unittest_SOURCES) \
+ $(heap_checker_death_unittest_sh_SOURCES) \
+ $(heap_checker_unittest_SOURCES) \
+ $(heap_checker_unittest_sh_SOURCES) \
+ $(heap_profiler_unittest_SOURCES) \
+ $(heap_profiler_unittest_sh_SOURCES) \
+ $(low_level_alloc_unittest_SOURCES) \
+ $(markidle_unittest_SOURCES) $(memalign_unittest_SOURCES) \
$(profiler1_unittest_SOURCES) $(profiler2_unittest_SOURCES) \
$(profiler3_unittest_SOURCES) $(profiler4_unittest_SOURCES) \
- $(ptmalloc_unittest1_SOURCES) $(ptmalloc_unittest2_SOURCES) \
- $(stacktrace_unittest_SOURCES) $(tcmalloc_unittest_SOURCES)
+ $(profiler_unittest_sh_SOURCES) $(ptmalloc_unittest1_SOURCES) \
+ $(ptmalloc_unittest2_SOURCES) $(stacktrace_unittest_SOURCES) \
+ $(tcmalloc_large_unittest_SOURCES) \
+ $(tcmalloc_minimal_large_unittest_SOURCES) \
+ $(tcmalloc_minimal_unittest_SOURCES) \
+ $(tcmalloc_unittest_SOURCES) \
+ $(thread_dealloc_unittest_SOURCES)
man1dir = $(mandir)/man1
NROFF = nroff
MANS = $(dist_man_MANS)
@@ -245,6 +369,7 @@ ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
+EXTRA_CXXFLAGS = @EXTRA_CXXFLAGS@
F77 = @F77@
FFLAGS = @FFLAGS@
INSTALL_DATA = @INSTALL_DATA@
@@ -274,6 +399,7 @@ RANLIB = @RANLIB@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
+UNWIND_LIBS = @UNWIND_LIBS@
VERSION = @VERSION@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
@@ -325,20 +451,22 @@ ACLOCAL_AMFLAGS = -I `pwd`/../autoconf
# This is so we can #include <google/foo>
AM_CPPFLAGS = -I$(top_srcdir)/src
+# This is initialized in configure.ac (though we might add to it later)
+AM_CXXFLAGS = $(EXTRA_CXXFLAGS)
googleincludedir = $(includedir)/google
# The .h files you want to install (that is, .h files that people
# who install this package can include in their own applications.)
# We'll add to this later, on a library-by-library basis
googleinclude_HEADERS = $(SG_STACKTRACE_INCLUDES) \
- $(SG_TCMALLOC_INCLUDES) $(SG_CPU_PROFILER_INCLUDES) \
- $(SG_HEAP_PROFILER_INCLUDES) $(SG_HEAP_CHECKER_INCLUDES)
+ $(SG_TCMALLOC_MINIMAL_INCLUDES) $(SG_TCMALLOC_INCLUDES) \
+ $(SG_CPU_PROFILER_INCLUDES)
perftoolsincludedir = $(googleincludedir)/perftools
# The 'private' header files go into /usr/local/include/google/perftools.
# We'll add to this later, on a library-by-library basis
perftoolsinclude_HEADERS = $(SGP_STACKTRACE_INCLUDES) \
- $(SGP_TCMALLOC_INCLUDES) $(SGP_CPU_PROFILER_INCLUDES) \
- $(SGP_HEAP_PROFILER_INCLUDES) $(SGP_HEAP_CHECKER_INCLUDES)
-docdir = $(prefix)/doc/$(PACKAGE)-$(VERSION)
+ $(SGP_TCMALLOC_MINIMAL_INCLUDES) $(SGP_TCMALLOC_INCLUDES) \
+ $(SGP_CPU_PROFILER_INCLUDES)
+docdir = $(prefix)/share/doc/$(PACKAGE)-$(VERSION)
# This is for HTML and other documentation you want to install.
# Add your documentation files (in doc/) in addition to these
# top-level boilerplate files. Also add a TODO file if you have one.
@@ -353,18 +481,40 @@ docdir = $(prefix)/doc/$(PACKAGE)-$(VERSION)
# one day we figure it out. Regardless, installing the dot files isn't the
# end of the world.
-### Documentation
+### Documentation (above and beyond tcmalloc_minimal documentation)
### Documentation
-# TODO
dist_doc_DATA = AUTHORS COPYING ChangeLog INSTALL NEWS README TODO \
- doc/tcmalloc.html doc/overview.gif doc/pageheap.gif \
- doc/spanmap.gif doc/threadheap.gif doc/overview.dot \
+ doc/index.html doc/designstyle.css \
+ doc/pprof_remote_servers.html doc/tcmalloc.html \
+ doc/overview.gif doc/pageheap.gif doc/spanmap.gif \
+ doc/threadheap.gif doc/t-test1.times.txt \
+ doc/tcmalloc-opspercpusec.vs.threads.1024.bytes.png \
+ doc/tcmalloc-opspercpusec.vs.threads.128.bytes.png \
+ doc/tcmalloc-opspercpusec.vs.threads.131072.bytes.png \
+ doc/tcmalloc-opspercpusec.vs.threads.16384.bytes.png \
+ doc/tcmalloc-opspercpusec.vs.threads.2048.bytes.png \
+ doc/tcmalloc-opspercpusec.vs.threads.256.bytes.png \
+ doc/tcmalloc-opspercpusec.vs.threads.32768.bytes.png \
+ doc/tcmalloc-opspercpusec.vs.threads.4096.bytes.png \
+ doc/tcmalloc-opspercpusec.vs.threads.512.bytes.png \
+ doc/tcmalloc-opspercpusec.vs.threads.64.bytes.png \
+ doc/tcmalloc-opspercpusec.vs.threads.65536.bytes.png \
+ doc/tcmalloc-opspercpusec.vs.threads.8192.bytes.png \
+ doc/tcmalloc-opspersec.vs.size.1.threads.png \
+ doc/tcmalloc-opspersec.vs.size.12.threads.png \
+ doc/tcmalloc-opspersec.vs.size.16.threads.png \
+ doc/tcmalloc-opspersec.vs.size.2.threads.png \
+ doc/tcmalloc-opspersec.vs.size.20.threads.png \
+ doc/tcmalloc-opspersec.vs.size.3.threads.png \
+ doc/tcmalloc-opspersec.vs.size.4.threads.png \
+ doc/tcmalloc-opspersec.vs.size.5.threads.png \
+ doc/tcmalloc-opspersec.vs.size.8.threads.png doc/overview.dot \
doc/pageheap.dot doc/spanmap.dot doc/threadheap.dot \
- doc/cpu_profiler.html doc/pprof-test-big.gif \
- doc/pprof-test.gif doc/pprof-vsnprintf-big.gif \
- doc/pprof-vsnprintf.gif doc/heap_profiler.html \
- doc/heap-example1.png
+ doc/heapprofile.html doc/heap-example1.png \
+ doc/heap_checker.html doc/cpuprofile.html \
+ doc/pprof-test-big.gif doc/pprof-test.gif \
+ doc/pprof-vsnprintf-big.gif doc/pprof-vsnprintf.gif
# The libraries (.so's) you want to install
# We'll add to this later, on a library-by-library basis
@@ -376,109 +526,192 @@ dist_doc_DATA = AUTHORS COPYING ChangeLog INSTALL NEWS README TODO \
### Making the library
### Making the library
+lib_LTLIBRARIES = libstacktrace.la libtcmalloc_minimal.la \
+ libtcmalloc.la libprofiler.la
+# This is for 'convenience libraries' -- basically just a container for sources
-### Making the library
-lib_LTLIBRARIES = libstacktrace.la libtcmalloc.la libprofiler.la \
- libheapprofiler.la libheapchecker.la
+# This is a 'convenience library' -- it's not actually installed or anything
+noinst_LTLIBRARIES = libspinlock.la liblogging.la
# unittests you want to run when people type 'make check'.
-# TESTS is for binary unittests, check_SCRIPTS for script-based unittests.
-# TESTS_ENVIRONMENT sets environment variables for when you run unittest,
-# but it only seems to take effect for *binary* unittests (argh!)
-# We'll add to this later, on a library-by-library basis
+# Note: tests cannot take any arguments!
+# In theory, unittests that are scripts should be added to check_SCRIPTS
+# instead. But check_SCRIPTS is definitely a second-class testing mechanims:
+# it don't get TESTS_ENVIRONMENT, and it doesn't get success/failure counting
+# (in fact, a script failure aborts all the rest of the tests, even with -k).
+# So, for scripts, we add the script to tests, and also put in an empty
+# rule so automake doesn't try to build the script as a C binary.
### Unittests
### Unittests
+### Unittests
+
+# Commented out for the moment because malloc(very_big_num) is broken in
+# standard libc! At least, in some situations, some of the time.
+
# performance/unittests originally from ptmalloc2
### Unittests
+TESTS = low_level_alloc_unittest atomicops_unittest \
+ stacktrace_unittest tcmalloc_unittest \
+ tcmalloc_minimal_unittest tcmalloc_large_unittest \
+ tcmalloc_minimal_large_unittest ptmalloc_unittest1 \
+ ptmalloc_unittest2 frag_unittest markidle_unittest \
+ memalign_unittest thread_dealloc_unittest addressmap_unittest \
+ heap-profiler_unittest.sh heap-checker_unittest.sh \
+ heap-checker-death_unittest.sh profiler_unittest.sh
+# TESTS_ENVIRONMENT sets environment variables for when you run unittest.
+# We always get "srcdir" set for free.
+# We'll add to this later, on a library-by-library basis.
+
+# Let unittests find pprof if they need to run it
### Unittests
-TESTS = stacktrace_unittest malloc_unittest tcmalloc_unittest \
- ptmalloc_unittest1 ptmalloc_unittest2 addressmap_unittest \
- heap-checker_unittest
-### Unittests
-check_SCRIPTS = profiler_unittest heap-checker-death_unittest
-TESTS_ENVIRONMENT = PPROF_PATH=$(top_srcdir)/src/pprof
-# Every time you add a unittest to check_SCRIPTS, add it here too
-noinst_SCRIPTS = src/tests/profiler_unittest.sh \
- src/tests/heap-checker-death_unittest.sh
+# These unittests often need to run binaries. They're in the current dir
+TESTS_ENVIRONMENT = PPROF_PATH=$(top_srcdir)/src/pprof BINDIR=.
+# All script tests should be added her
+noinst_SCRIPTS = $(heap_profiler_unittest_sh_SOURCES) \
+ $(heap_checker_unittest_sh_SOURCES) \
+ $(heap_checker_death_unittest_sh_SOURCES) \
+ $(profiler_unittest_sh_SOURCES)
+
+### ------- library routines, in src/base
+
+# spinlock is the only code that uses atomicops.
+SPINLOCK_INCLUDES = src/base/spinlock.h \
+ src/base/atomicops.h \
+ src/base/atomicops-internals-macosx.h \
+ src/base/atomicops-internals-x86-msvc.h \
+ src/base/atomicops-internals-x86.h
+
+libspinlock_la_SOURCES = src/base/spinlock.cc \
+ src/base/atomicops-internals-x86.cc \
+ $(SPINLOCK_INCLUDES)
+
+LOGGING_INCLUDES = src/base/logging.h \
+ src/base/commandlineflags.h \
+ src/base/basictypes.h
+
+liblogging_la_SOURCES = src/base/logging.cc \
+ $(LOGGING_INCLUDES)
+
+LOW_LEVEL_ALLOC_UNITTEST_INCLUDES = src/base/low_level_alloc.h \
+ src/base/basictypes.h \
+ src/google/malloc_hook.h \
+ $(SPINLOCK_INCLUDES) \
+ $(LOGGING_INCLUDES)
+
+low_level_alloc_unittest_SOURCES = src/base/low_level_alloc.cc \
+ src/malloc_hook.cc \
+ src/tests/low_level_alloc_unittest.cc \
+ $(LOW_LEVEL_ALLOC_UNITTEST_INCLUDES)
+
+low_level_alloc_unittest_LDADD = libspinlock.la liblogging.la libstacktrace.la
+ATOMICOPS_UNITTEST_INCLUDES = src/base/atomicops.h \
+ src/base/atomicops-internals-macosx.h \
+ src/base/atomicops-internals-x86-msvc.h \
+ src/base/atomicops-internals-x86.h \
+ $(LOGGING_INCLUDES)
+
+atomicops_unittest_SOURCES = src/tests/atomicops_unittest.cc \
+ $(ATOMICOPS_UNITTEST_INCLUDES)
+
+atomicops_unittest_LDADD = libspinlock.la liblogging.la
### ------- stack trace
### The header files we use. We divide into categories based on directory
S_STACKTRACE_INCLUDES =
SG_STACKTRACE_INCLUDES = src/google/stacktrace.h
-SGP_STACKTRACE_INCLUDES = src/google/perftools/config.h
+SGP_STACKTRACE_INCLUDES = src/stacktrace_generic-inl.h \
+ src/stacktrace_libunwind-inl.h \
+ src/stacktrace_x86_64-inl.h \
+ src/stacktrace_x86-inl.h
+
STACKTRACE_INCLUDES = $(S_STACKTRACE_INCLUDES) $(SG_STACKTRACE_INCLUDES) $(SGP_STACKTRACE_INCLUDES)
libstacktrace_la_SOURCES = src/stacktrace.cc \
$(STACKTRACE_INCLUDES)
+# TODO(csilvers): only add these two things when stacktrace.cc would
+# #include "stacktrace_libunwind-inl.h"
+libstacktrace_la_LIBADD = $(UNWIND_LIBS) libspinlock.la
STACKTRACE_SYMBOLS = '(GetStackTrace)'
libstacktrace_la_LDFLAGS = -export-symbols-regex $(STACKTRACE_SYMBOLS)
-STACKTRACE_UNITTEST_INLCUDES = $(STACKTRACE_INCLUDES) \
- src/base/commandlineflags.h \
- src/base/logging.h
+STACKTRACE_UNITTEST_INLCUDES = src/base/commandlineflags.h \
+ $(STACKTRACE_INCLUDES) \
+ $(LOGGING_INCLUDES)
stacktrace_unittest_SOURCES = src/tests/stacktrace_unittest.cc \
$(STACKTRACE_UNITTEST_INLCUDES)
-stacktrace_unittest_LDADD = libstacktrace.la
+stacktrace_unittest_LDADD = libstacktrace.la liblogging.la
-### ------- tcmalloc (thread-caching malloc)
-
-### The header files we use. We divide into categories based on directory
-S_TCMALLOC_INCLUDES = src/internal_logging.h \
- src/system-alloc.h \
- src/internal_spinlock.h \
- src/base/commandlineflags.h \
- src/pagemap.h
+### ------- pprof
+bin_SCRIPTS = src/pprof
-SG_TCMALLOC_INCLUDES = src/google/malloc_hook.h \
- src/google/malloc_interface.h \
- src/google/stacktrace.h
+### Unittests
+check_SCRIPTS = pprof_unittest
-SGP_TCMALLOC_INCLUDES = src/google/perftools/config.h \
- src/google/perftools/basictypes.h \
- src/google/perftools/hash_set.h
+### Documentation
+dist_man_MANS = doc/pprof.1
-TCMALLOC_INCLUDES = $(S_TCMALLOC_INCLUDES) $(SG_TCMALLOC_INCLUDES) $(SGP_TCMALLOC_INCLUDES)
-libtcmalloc_la_SOURCES = src/internal_logging.cc \
- src/system-alloc.cc \
- src/tcmalloc.cc \
- src/malloc_hook.cc \
- src/malloc_interface.cc \
- $(TCMALLOC_INCLUDES)
+### ------- tcmalloc_minimal (thread-caching malloc)
-libtcmalloc_la_CXXFLAGS = $(PTHREAD_CFLAGS) -DNDEBUG
-TCMALLOC_SYMBOLS = '(malloc|free|realloc|calloc|cfree|memalign|valloc|pvalloc|posix_memalign|malloc_stats|MallocInterface|MallocHook)'
-libtcmalloc_la_LDFLAGS = $(PTHREAD_CFLAGS) -export-symbols-regex $(TCMALLOC_SYMBOLS)
-libtcmalloc_la_LIBADD = $(PTHREAD_LIBS) libstacktrace.la
-MALLOC_UNITEST_INCLUDES = src/google/malloc_interface.h \
- src/google/malloc_hook.h \
- src/google/perftools/basictypes.h \
- src/google/perftools/config.h \
- src/google/perftools/hash_set.h \
- src/google/malloc_interface.h
-
-malloc_unittest_SOURCES = src/tests/tcmalloc_unittest.cc \
- src/malloc_hook.cc \
- src/malloc_interface.cc \
- $(MALLOC_UNITTEST_INCLUDES)
-
-malloc_unittest_CXXFLAGS = $(PTHREAD_CFLAGS)
-malloc_unittest_LDFLAGS = $(PTHREAD_CFLAGS)
-malloc_unittest_LDADD = $(PTHREAD_LIBS)
-TCMALLOC_UNITTEST_INCLUDES = src/google/malloc_interface.h
+### The header files we use. We divide into categories based on directory
+S_TCMALLOC_MINIMAL_INCLUDES = src/internal_logging.h \
+ src/system-alloc.h \
+ $(SPINLOCK_INCLUDES) \
+ src/base/commandlineflags.h \
+ src/base/basictypes.h \
+ src/pagemap.h \
+ src/maybe_threads.h
+
+SG_TCMALLOC_MINIMAL_INCLUDES = src/google/malloc_hook.h \
+ src/google/malloc_extension.h \
+ src/google/stacktrace.h
+
+SGP_TCMALLOC_MINIMAL_INCLUDES = src/google/perftools/hash_set.h
+TCMALLOC_MINIMAL_INCLUDES = $(S_TCMALLOC_MINIMAL_INCLUDES) $(SG_TCMALLOC_MINIMAL_INCLUDES) $(SGP_TCMALLOC_MINIMAL_INCLUDES)
+libtcmalloc_minimal_la_SOURCES = src/internal_logging.cc \
+ src/system-alloc.cc \
+ src/tcmalloc.cc \
+ src/malloc_hook.cc \
+ src/malloc_extension.cc \
+ src/maybe_threads.cc \
+ $(TCMALLOC_MINIMAL_INCLUDES)
+
+libtcmalloc_minimal_la_CXXFLAGS = $(PTHREAD_CFLAGS) -DNDEBUG
+TCMALLOC_MINIMAL_SYMBOLS = '(malloc|free|realloc|calloc|cfree|memalign|valloc|pvalloc|posix_memalign|malloc_stats|MallocExtension|MallocHook)'
+libtcmalloc_minimal_la_LDFLAGS = $(PTHREAD_CFLAGS) -export-symbols-regex $(TCMALLOC_MINIMAL_SYMBOLS)
+libtcmalloc_minimal_la_LIBADD = $(PTHREAD_LIBS) \
+ libstacktrace.la libspinlock.la liblogging.la
+
+TCMALLOC_UNITTEST_INCLUDES = src/google/malloc_extension.h
tcmalloc_unittest_SOURCES = src/tests/tcmalloc_unittest.cc \
$(TCMALLOC_UNITTEST_INCLUDES)
tcmalloc_unittest_CXXFLAGS = $(PTHREAD_CFLAGS)
tcmalloc_unittest_LDFLAGS = $(PTHREAD_CFLAGS)
-tcmalloc_unittest_LDADD = libtcmalloc.la $(PTHREAD_LIBS)
+tcmalloc_unittest_LDADD = libtcmalloc.la liblogging.la $(PTHREAD_LIBS)
+tcmalloc_minimal_unittest_SOURCES = src/tests/tcmalloc_unittest.cc \
+ $(TCMALLOC_UNITTEST_INCLUDES)
+
+tcmalloc_minimal_unittest_CXXFLAGS = $(PTHREAD_CFLAGS)
+tcmalloc_minimal_unittest_LDFLAGS = $(PTHREAD_CFLAGS)
+tcmalloc_minimal_unittest_LDADD = libtcmalloc_minimal.la \
+ liblogging.la $(PTHREAD_LIBS)
+
+tcmalloc_large_unittest_SOURCES = src/tests/tcmalloc_large_unittest.cc
+tcmalloc_large_unittest_CXXFLAGS = $(PTHREAD_CFLAGS)
+tcmalloc_large_unittest_LDFLAGS = $(PTHREAD_CFLAGS)
+tcmalloc_large_unittest_LDADD = libtcmalloc.la $(PTHREAD_LIBS)
+tcmalloc_minimal_large_unittest_SOURCES = src/tests/tcmalloc_large_unittest.cc
+tcmalloc_minimal_large_unittest_CXXFLAGS = $(PTHREAD_CFLAGS)
+tcmalloc_minimal_large_unittest_LDFLAGS = $(PTHREAD_CFLAGS)
+tcmalloc_minimal_large_unittest_LDADD = libtcmalloc_minimal.la $(PTHREAD_LIBS)
PTMALLOC_UNITTEST_INCLUDES = src/tests/ptmalloc/t-test.h \
src/tests/ptmalloc/thread-m.h \
src/tests/ptmalloc/lran2.h \
@@ -488,7 +721,7 @@ PTMALLOC_UNITTEST_INCLUDES = src/tests/ptmalloc/t-test.h \
ptmalloc_unittest1_SOURCES = src/tests/ptmalloc/t-test1.c \
$(PTMALLOC_UNITTEST_INCLUDES)
-ptmalloc_unittest1_CFLAGS = $(PTHREAD_CFLAGS) -DUSE_PTHREADS
+ptmalloc_unittest1_CFLAGS = $(PTHREAD_CFLAGS) -DUSE_PTHREADS
ptmalloc_unittest1_LDFLAGS = $(PTHREAD_CFLAGS)
ptmalloc_unittest1_LDADD = $(PTHREAD_LIBS)
ptmalloc_unittest2_SOURCES = src/tests/ptmalloc/t-test2.c \
@@ -497,35 +730,139 @@ ptmalloc_unittest2_SOURCES = src/tests/ptmalloc/t-test2.c \
ptmalloc_unittest2_CFLAGS = $(PTHREAD_CFLAGS) -DUSE_PTHREADS
ptmalloc_unittest2_LDFLAGS = $(PTHREAD_CFLAGS)
ptmalloc_unittest2_LDADD = $(PTHREAD_LIBS)
+frag_unittest_SOURCES = src/tests/frag_unittest.cc
+frag_unittest_CXXFLAGS = $(PTHREAD_CFLAGS)
+frag_unittest_LDFLAGS = $(PTHREAD_CFLAGS)
+frag_unittest_LDADD = libtcmalloc_minimal.la $(PTHREAD_LIBS)
+markidle_unittest_SOURCES = src/tests/markidle_unittest.cc \
+ src/tests/testutil.h src/tests/testutil.cc
+
+markidle_unittest_CXXFLAGS = $(PTHREAD_CFLAGS)
+markidle_unittest_LDFLAGS = $(PTHREAD_CFLAGS)
+markidle_unittest_LDADD = libtcmalloc_minimal.la $(PTHREAD_LIBS)
+memalign_unittest_SOURCES = src/tests/memalign_unittest.cc
+memalign_unittest_CXXFLAGS = $(PTHREAD_CFLAGS)
+memalign_unittest_LDFLAGS = $(PTHREAD_CFLAGS)
+memalign_unittest_LDADD = libtcmalloc_minimal.la $(PTHREAD_LIBS)
+thread_dealloc_unittest_SOURCES = src/tests/thread_dealloc_unittest.cc \
+ src/tests/testutil.h src/tests/testutil.cc
+
+thread_dealloc_unittest_CXXFLAGS = $(PTHREAD_CFLAGS)
+thread_dealloc_unittest_LDFLAGS = $(PTHREAD_CFLAGS)
+thread_dealloc_unittest_LDADD = libtcmalloc_minimal.la $(PTHREAD_LIBS)
+
+### ------- tcmalloc (thread-caching malloc + heap profiler + heap checker)
+
+### The header files we use. We divide into categories based on directory
+S_TCMALLOC_INCLUDES = src/internal_logging.h \
+ src/system-alloc.h \
+ src/pagemap.h \
+ src/addressmap-inl.h \
+ src/heap-profile-table.h \
+ src/base/basictypes.h \
+ src/base/commandlineflags.h \
+ src/base/googleinit.h \
+ src/base/elfcore.h \
+ src/base/linux_syscall_support.h \
+ src/base/linuxthreads.h \
+ src/base/thread_lister.h \
+ src/base/sysinfo.h \
+ src/base/stl_allocator.h \
+ src/maybe_threads.h \
+ $(SPINLOCK_INCLUDES) \
+ $(LOGGING_INCLUDES)
+
+SG_TCMALLOC_INCLUDES = src/google/malloc_hook.h \
+ src/google/malloc_extension.h \
+ src/google/heap-profiler.h \
+ src/google/heap-checker.h \
+ src/google/stacktrace.h
+
+SGP_TCMALLOC_INCLUDES = src/google/perftools/hash_set.h
+TCMALLOC_INCLUDES = $(S_TCMALLOC_INCLUDES) $(SG_TCMALLOC_INCLUDES) $(SGP_TCMALLOC_INCLUDES)
+# Note: heap-checker-bcad is last, in hopes its global ctor will run first
+libtcmalloc_la_SOURCES = src/internal_logging.cc \
+ src/system-alloc.cc \
+ src/tcmalloc.cc \
+ src/malloc_hook.cc \
+ src/malloc_extension.cc \
+ src/maybe_threads.cc \
+ src/memory_region_map.cc \
+ src/heap-profiler.cc \
+ src/heap-profile-table.cc \
+ src/heap-checker.cc \
+ src/base/linuxthreads.c \
+ src/base/thread_lister.c \
+ src/base/sysinfo.cc \
+ src/base/low_level_alloc.cc \
+ $(TCMALLOC_INCLUDES) \
+ src/heap-checker-bcad.cc
+
+libtcmalloc_la_CXXFLAGS = $(PTHREAD_CFLAGS) -DNDEBUG
+TCMALLOC_SYMBOLS = '(malloc|free|realloc|calloc|cfree|memalign|valloc|pvalloc|posix_memalign|malloc_stats|MallocExtension|MallocHook|HeapProfilerStart|HeapProfilerStop|HeapProfilerDump|GetHeapProfile|HeapCleaner|HeapLeakChecker)'
+libtcmalloc_la_LDFLAGS = $(PTHREAD_CFLAGS) -export-symbols-regex $(TCMALLOC_SYMBOLS)
+libtcmalloc_la_LIBADD = $(PTHREAD_LIBS) \
+ libstacktrace.la libspinlock.la liblogging.la
+
+ADDRESSMAP_UNITTEST_INCLUDES = src/addressmap-inl.h \
+ src/base/commandlineflags.h \
+ $(LOGGING_INCLUDES)
+
+addressmap_unittest_SOURCES = src/tests/addressmap_unittest.cc \
+ $(ADDRESSMAP_UNITTEST_INCLUDES)
+
+addressmap_unittest_CXXFLAGS = -g
+addressmap_unittest_LDADD = liblogging.la
+heap_profiler_unittest_sh_SOURCES = src/tests/heap-profiler_unittest.sh
+HEAP_PROFILER_UNITTEST_INCLUDES = src/google/heap-profiler.h
+heap_profiler_unittest_SOURCES = src/tests/heap-profiler_unittest.cc \
+ $(HEAP_PROFILER_UNITTEST_INCLUDES)
+
+heap_profiler_unittest_CXXFLAGS = -g
+heap_profiler_unittest_LDFLAGS = -g $(PTHREAD_CFLAGS)
+heap_profiler_unittest_LDADD = libtcmalloc.la $(PTHREAD_LIBS)
+heap_checker_unittest_sh_SOURCES = src/tests/heap-checker_unittest.sh
+heap_checker_death_unittest_sh_SOURCES = src/tests/heap-checker-death_unittest.sh
+HEAP_CHECKER_UNITTEST_INCLUDES = src/memory_region_map.h \
+ src/base/commandlineflags.h \
+ src/base/googleinit.h \
+ src/google/heap-checker.h \
+ $(LOGGING_INCLUDES)
+
+heap_checker_unittest_SOURCES = src/tests/heap-checker_unittest.cc \
+ $(HEAP_CHECKER_UNITTEST_INCLUDES)
+
+heap_checker_unittest_CXXFLAGS = -g $(PTHREAD_CFLAGS)
+heap_checker_unittest_LDFLAGS = -g $(PTHREAD_CFLAGS)
+# tcmalloc has to be specified last!
+heap_checker_unittest_LDADD = $(PTHREAD_LIBS) liblogging.la -ltcmalloc
### ------- CPU profiler
### The header files we use. We divide into categories based on directory
S_CPU_PROFILER_INCLUDES = src/base/commandlineflags.h \
src/base/googleinit.h \
- src/base/logging.h
+ src/base/logging.h \
+ src/base/mutex.h \
+ $(SPINLOCK_INCLUDES) \
+ $(LOGGING_INCLUDES)
SG_CPU_PROFILER_INCLUDES = src/google/profiler.h \
src/google/stacktrace.h
-SGP_CPU_PROFILER_INCLUDES = src/google/perftools/config.h
+SGP_CPU_PROFILER_INCLUDES =
CPU_PROFILER_INCLUDES = $(S_CPU_PROFILER_INCLUDES) $(SG_CPU_PROFILER_INCLUDES) $(SGP_CPU_PROFILER_INCLUDES)
libprofiler_la_SOURCES = src/profiler.cc \
- src/stacktrace.cc \
+ src/base/mutex.cc \
$(CPU_PROFILER_INCLUDES)
+libprofiler_la_LIBADD = libspinlock.la liblogging.la libstacktrace.la
CPU_PROFILER_SYMBOLS = '(ProfilerStart|ProfilerStop|ProfilerEnable|ProfilerDisable|ProfilerFlush|ProfilerRegisterThread|ProfilerThreadState)'
libprofiler_la_LDFLAGS = -export-symbols-regex $(CPU_PROFILER_SYMBOLS)
-
-# These are sub-programs used by profiler_unittest.sh
-PROFILER_UNITTESTS = profiler1_unittest profiler2_unittest profiler3_unittest \
- profiler4_unittest
-
-PROFILER_UNITTEST_INCLUDES = src/google/perftools/config.h \
- src/google/profiler.h
-
+profiler_unittest_sh_SOURCES = src/tests/profiler_unittest.sh
+PROFILER_UNITTEST_INCLUDES = src/google/profiler.h
PROFILER_UNITTEST_SRCS = src/tests/profiler_unittest.cc \
- $(PROFILER_UNITTEST_INCLUDES)
+ $(PROFILER_UNITTEST_INCLUDES)
profiler1_unittest_SOURCES = $(PROFILER_UNITTEST_SRCS)
profiler1_unittest_CXXFLAGS = -g
@@ -541,91 +878,9 @@ profiler4_unittest_SOURCES = $(PROFILER_UNITTEST_SRCS)
profiler4_unittest_CXXFLAGS = -g $(PTHREAD_CFLAGS) -DWITH_THREADS
profiler4_unittest_LDFLAGS = $(PTHREAD_CFLAGS)
profiler4_unittest_LDADD = -lprofiler $(PTHREAD_LIBS)
-
-### Documentation
-dist_man_MANS = doc/pprof.1
-
-### ------- Heap profiler
-
-### The header files we use. We divide into categories based on directory
-S_HEAP_PROFILER_INCLUDES = src/heap-profiler-inl.h \
- src/internal_spinlock.h \
- src/addressmap-inl.h \
- src/base/commandlineflags.h \
- src/base/logging.h \
- src/base/googleinit.h
-
-SG_HEAP_PROFILER_INCLUDES = src/google/malloc_hook.h \
- src/google/heap-profiler.h \
- src/google/stacktrace.h
-
-SGP_HEAP_PROFILER_INCLUDES = src/google/perftools/config.h \
- src/google/perftools/basictypes.h \
- src/google/perftools/hash_set.h
-
-HEAP_PROFILER_INCLUDES = $(S_HEAP_PROFILER_INCLUDES) $(SG_HEAP_PROFILER_INCLUDES) $(SGP_HEAP_PROFILER_INCLUDES)
-libheapprofiler_la_SOURCES = src/heap-profiler.cc \
- src/heap-checker-bcad.cc \
- $(HEAP_PROFILER_INCLUDES)
-
-# We only need pthreads because we're linking with tcmalloc
-libheapprofiler_la_CXXFLAGS = $(PTHREAD_CFLAGS)
-# TODO: The lowercased symbols in this list are member variables of
-# HeapProfiler that the HeapLeakChecker requires access to in order to do its
-# job. We should refactor the HeapProfiler so that these are proper accessors
-# (probably protected ones)
-HEAP_PROFILER_SYMBOLS = '(HeapProfilerStart|HeapProfilerStop|HeapProfilerDump|GetHeapProfile|filename_prefix_|is_on_|dumping_|temp_disable_|dump_for_leaks_|profile_)'
-libheapprofiler_la_LDFLAGS = $(PTHREAD_CFLAGS) -export-symbols-regex $(HEAP_PROFILER_SYMBOLS)
-# We may as well depend of libtcmalloc since it is part of the same package,
-# but it is worth noting that it would be easy to break this dependency by
-# depending on a malloc_normal.cc that overrides the system malloc & friends
-# with a version that has hooks into malloc_hook.cc.
-libheapprofiler_la_LIBADD = libtcmalloc.la $(PTHREAD_LIBS)
-ADDRESSMAP_UNITTEST_INCLUDES = src/addressmap-inl.h \
- src/base/logging.h \
- src/base/commandlineflags.h
-
-addressmap_unittest_SOURCES = src/tests/addressmap_unittest.cc \
- $(ADDRESSMAP_UNITTEST_INCLUDES)
-
-addressmap_unittest_CXXFLAGS = -g
-
-### ------- Heap checker
-
-### The header files we use. We divide into categories based on directory
-S_HEAP_CHECKER_INCLUDES = src/heap-profiler-inl.h \
- src/base/commandlineflags.h \
- src/base/logging.h
-
-SG_HEAP_CHECKER_INCLUDES = src/google/heap-profiler.h \
- src/google/heap-checker.h \
- src/google/stacktrace.h
-
-SGP_HEAP_CHECKER_INCLUDES = src/google/perftools/config.h
-HEAP_CHECKER_INCLUDES = $(S_HEAP_CHECKER_INCLUDES) $(SG_HEAP_CHECKER_INCLUDES) $(SGP_HEAP_CHECKER_INCLUDES)
-libheapchecker_la_SOURCES = src/heap-checker.cc \
- src/heap-checker-bcad.cc \
- $(HEAP_CHECKER_INCLUDES)
-
-libheapchecker_la_CXXFLAGS = $(PTHREAD_CFLAGS)
-HEAP_CHECKER_SYMBOLS = '(HeapCleaner|HeapLeakChecker)'
-libheapchecker_la_LDFLAGS = $(PTHREAD_CFLAGS) -export-symbols-regex $(HEAP_CHECKER_SYMBOLS)
-libheapchecker_la_LIBADD = libheapprofiler.la $(PTHREAD_LIBS)
-HEAP_CHECKER_UNITTEST_INCLUDES = src/google/perftools/config.h \
- src/base/logging.h \
- src/base/googleinit.h \
- src/google/heap-profiler.h \
- src/google/heap-checker.h
-
-heap_checker_unittest_SOURCES = src/tests/heap-checker_unittest.cc \
- $(HEAP_CHECKER_UNITTEST_INCLUDES)
-
-heap_checker_unittest_CXXFLAGS = -g $(PTHREAD_CFLAGS)
-heap_checker_unittest_LDFLAGS = -g $(PTHREAD_CFLAGS)
-heap_checker_unittest_LDADD = libheapchecker.la $(PTHREAD_LIBS)
-bin_SCRIPTS = src/pprof
EXTRA_DIST = packages/rpm.sh packages/rpm/rpm.spec packages/deb.sh packages/deb \
- $(SCRIPTS) libtool
+ $(SCRIPTS) libtool \
+ src/solaris/libstdc++.la
DISTCLEANFILES = src/google/perftools/hash_set.h
all: all-am
@@ -666,22 +921,22 @@ $(top_srcdir)/configure: $(am__configure_deps)
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
-src/google/perftools/config.h: src/google/perftools/stamp-h1
+src/config.h: src/stamp-h1
@if test ! -f $@; then \
- rm -f src/google/perftools/stamp-h1; \
- $(MAKE) src/google/perftools/stamp-h1; \
+ rm -f src/stamp-h1; \
+ $(MAKE) src/stamp-h1; \
else :; fi
-src/google/perftools/stamp-h1: $(top_srcdir)/src/google/perftools/config.h.in $(top_builddir)/config.status
- @rm -f src/google/perftools/stamp-h1
- cd $(top_builddir) && $(SHELL) ./config.status src/google/perftools/config.h
-$(top_srcdir)/src/google/perftools/config.h.in: $(am__configure_deps)
+src/stamp-h1: $(top_srcdir)/src/config.h.in $(top_builddir)/config.status
+ @rm -f src/stamp-h1
+ cd $(top_builddir) && $(SHELL) ./config.status src/config.h
+$(top_srcdir)/src/config.h.in: $(am__configure_deps)
cd $(top_srcdir) && $(AUTOHEADER)
- rm -f src/google/perftools/stamp-h1
+ rm -f src/stamp-h1
touch $@
distclean-hdr:
- -rm -f src/google/perftools/config.h src/google/perftools/stamp-h1
+ -rm -f src/config.h src/stamp-h1
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
@$(NORMAL_INSTALL)
test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)"
@@ -709,16 +964,27 @@ clean-libLTLIBRARIES:
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
-libheapchecker.la: $(libheapchecker_la_OBJECTS) $(libheapchecker_la_DEPENDENCIES)
- $(CXXLINK) -rpath $(libdir) $(libheapchecker_la_LDFLAGS) $(libheapchecker_la_OBJECTS) $(libheapchecker_la_LIBADD) $(LIBS)
-libheapprofiler.la: $(libheapprofiler_la_OBJECTS) $(libheapprofiler_la_DEPENDENCIES)
- $(CXXLINK) -rpath $(libdir) $(libheapprofiler_la_LDFLAGS) $(libheapprofiler_la_OBJECTS) $(libheapprofiler_la_LIBADD) $(LIBS)
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+liblogging.la: $(liblogging_la_OBJECTS) $(liblogging_la_DEPENDENCIES)
+ $(CXXLINK) $(liblogging_la_LDFLAGS) $(liblogging_la_OBJECTS) $(liblogging_la_LIBADD) $(LIBS)
libprofiler.la: $(libprofiler_la_OBJECTS) $(libprofiler_la_DEPENDENCIES)
$(CXXLINK) -rpath $(libdir) $(libprofiler_la_LDFLAGS) $(libprofiler_la_OBJECTS) $(libprofiler_la_LIBADD) $(LIBS)
+libspinlock.la: $(libspinlock_la_OBJECTS) $(libspinlock_la_DEPENDENCIES)
+ $(CXXLINK) $(libspinlock_la_LDFLAGS) $(libspinlock_la_OBJECTS) $(libspinlock_la_LIBADD) $(LIBS)
libstacktrace.la: $(libstacktrace_la_OBJECTS) $(libstacktrace_la_DEPENDENCIES)
$(CXXLINK) -rpath $(libdir) $(libstacktrace_la_LDFLAGS) $(libstacktrace_la_OBJECTS) $(libstacktrace_la_LIBADD) $(LIBS)
libtcmalloc.la: $(libtcmalloc_la_OBJECTS) $(libtcmalloc_la_DEPENDENCIES)
$(CXXLINK) -rpath $(libdir) $(libtcmalloc_la_LDFLAGS) $(libtcmalloc_la_OBJECTS) $(libtcmalloc_la_LIBADD) $(LIBS)
+libtcmalloc_minimal.la: $(libtcmalloc_minimal_la_OBJECTS) $(libtcmalloc_minimal_la_DEPENDENCIES)
+ $(CXXLINK) -rpath $(libdir) $(libtcmalloc_minimal_la_LDFLAGS) $(libtcmalloc_minimal_la_OBJECTS) $(libtcmalloc_minimal_la_LIBADD) $(LIBS)
clean-noinstPROGRAMS:
@list='$(noinst_PROGRAMS)'; for p in $$list; do \
@@ -729,12 +995,27 @@ clean-noinstPROGRAMS:
addressmap_unittest$(EXEEXT): $(addressmap_unittest_OBJECTS) $(addressmap_unittest_DEPENDENCIES)
@rm -f addressmap_unittest$(EXEEXT)
$(CXXLINK) $(addressmap_unittest_LDFLAGS) $(addressmap_unittest_OBJECTS) $(addressmap_unittest_LDADD) $(LIBS)
+atomicops_unittest$(EXEEXT): $(atomicops_unittest_OBJECTS) $(atomicops_unittest_DEPENDENCIES)
+ @rm -f atomicops_unittest$(EXEEXT)
+ $(CXXLINK) $(atomicops_unittest_LDFLAGS) $(atomicops_unittest_OBJECTS) $(atomicops_unittest_LDADD) $(LIBS)
+frag_unittest$(EXEEXT): $(frag_unittest_OBJECTS) $(frag_unittest_DEPENDENCIES)
+ @rm -f frag_unittest$(EXEEXT)
+ $(CXXLINK) $(frag_unittest_LDFLAGS) $(frag_unittest_OBJECTS) $(frag_unittest_LDADD) $(LIBS)
heap-checker_unittest$(EXEEXT): $(heap_checker_unittest_OBJECTS) $(heap_checker_unittest_DEPENDENCIES)
@rm -f heap-checker_unittest$(EXEEXT)
$(CXXLINK) $(heap_checker_unittest_LDFLAGS) $(heap_checker_unittest_OBJECTS) $(heap_checker_unittest_LDADD) $(LIBS)
-malloc_unittest$(EXEEXT): $(malloc_unittest_OBJECTS) $(malloc_unittest_DEPENDENCIES)
- @rm -f malloc_unittest$(EXEEXT)
- $(CXXLINK) $(malloc_unittest_LDFLAGS) $(malloc_unittest_OBJECTS) $(malloc_unittest_LDADD) $(LIBS)
+heap-profiler_unittest$(EXEEXT): $(heap_profiler_unittest_OBJECTS) $(heap_profiler_unittest_DEPENDENCIES)
+ @rm -f heap-profiler_unittest$(EXEEXT)
+ $(CXXLINK) $(heap_profiler_unittest_LDFLAGS) $(heap_profiler_unittest_OBJECTS) $(heap_profiler_unittest_LDADD) $(LIBS)
+low_level_alloc_unittest$(EXEEXT): $(low_level_alloc_unittest_OBJECTS) $(low_level_alloc_unittest_DEPENDENCIES)
+ @rm -f low_level_alloc_unittest$(EXEEXT)
+ $(CXXLINK) $(low_level_alloc_unittest_LDFLAGS) $(low_level_alloc_unittest_OBJECTS) $(low_level_alloc_unittest_LDADD) $(LIBS)
+markidle_unittest$(EXEEXT): $(markidle_unittest_OBJECTS) $(markidle_unittest_DEPENDENCIES)
+ @rm -f markidle_unittest$(EXEEXT)
+ $(CXXLINK) $(markidle_unittest_LDFLAGS) $(markidle_unittest_OBJECTS) $(markidle_unittest_LDADD) $(LIBS)
+memalign_unittest$(EXEEXT): $(memalign_unittest_OBJECTS) $(memalign_unittest_DEPENDENCIES)
+ @rm -f memalign_unittest$(EXEEXT)
+ $(CXXLINK) $(memalign_unittest_LDFLAGS) $(memalign_unittest_OBJECTS) $(memalign_unittest_LDADD) $(LIBS)
profiler1_unittest$(EXEEXT): $(profiler1_unittest_OBJECTS) $(profiler1_unittest_DEPENDENCIES)
@rm -f profiler1_unittest$(EXEEXT)
$(CXXLINK) $(profiler1_unittest_LDFLAGS) $(profiler1_unittest_OBJECTS) $(profiler1_unittest_LDADD) $(LIBS)
@@ -756,9 +1037,21 @@ ptmalloc_unittest2$(EXEEXT): $(ptmalloc_unittest2_OBJECTS) $(ptmalloc_unittest2_
stacktrace_unittest$(EXEEXT): $(stacktrace_unittest_OBJECTS) $(stacktrace_unittest_DEPENDENCIES)
@rm -f stacktrace_unittest$(EXEEXT)
$(CXXLINK) $(stacktrace_unittest_LDFLAGS) $(stacktrace_unittest_OBJECTS) $(stacktrace_unittest_LDADD) $(LIBS)
+tcmalloc_large_unittest$(EXEEXT): $(tcmalloc_large_unittest_OBJECTS) $(tcmalloc_large_unittest_DEPENDENCIES)
+ @rm -f tcmalloc_large_unittest$(EXEEXT)
+ $(CXXLINK) $(tcmalloc_large_unittest_LDFLAGS) $(tcmalloc_large_unittest_OBJECTS) $(tcmalloc_large_unittest_LDADD) $(LIBS)
+tcmalloc_minimal_large_unittest$(EXEEXT): $(tcmalloc_minimal_large_unittest_OBJECTS) $(tcmalloc_minimal_large_unittest_DEPENDENCIES)
+ @rm -f tcmalloc_minimal_large_unittest$(EXEEXT)
+ $(CXXLINK) $(tcmalloc_minimal_large_unittest_LDFLAGS) $(tcmalloc_minimal_large_unittest_OBJECTS) $(tcmalloc_minimal_large_unittest_LDADD) $(LIBS)
+tcmalloc_minimal_unittest$(EXEEXT): $(tcmalloc_minimal_unittest_OBJECTS) $(tcmalloc_minimal_unittest_DEPENDENCIES)
+ @rm -f tcmalloc_minimal_unittest$(EXEEXT)
+ $(CXXLINK) $(tcmalloc_minimal_unittest_LDFLAGS) $(tcmalloc_minimal_unittest_OBJECTS) $(tcmalloc_minimal_unittest_LDADD) $(LIBS)
tcmalloc_unittest$(EXEEXT): $(tcmalloc_unittest_OBJECTS) $(tcmalloc_unittest_DEPENDENCIES)
@rm -f tcmalloc_unittest$(EXEEXT)
$(CXXLINK) $(tcmalloc_unittest_LDFLAGS) $(tcmalloc_unittest_OBJECTS) $(tcmalloc_unittest_LDADD) $(LIBS)
+thread_dealloc_unittest$(EXEEXT): $(thread_dealloc_unittest_OBJECTS) $(thread_dealloc_unittest_DEPENDENCIES)
+ @rm -f thread_dealloc_unittest$(EXEEXT)
+ $(CXXLINK) $(thread_dealloc_unittest_LDFLAGS) $(thread_dealloc_unittest_OBJECTS) $(thread_dealloc_unittest_LDADD) $(LIBS)
install-binSCRIPTS: $(bin_SCRIPTS)
@$(NORMAL_INSTALL)
test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)"
@@ -786,19 +1079,39 @@ distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/addressmap_unittest-addressmap_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atomicops-internals-x86.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atomicops_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/frag_unittest-frag_unittest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/heap_checker_unittest-heap-checker_unittest.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libheapchecker_la-heap-checker-bcad.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libheapchecker_la-heap-checker.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libheapprofiler_la-heap-checker-bcad.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libheapprofiler_la-heap-profiler.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/heap_profiler_unittest-heap-profiler_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_la-heap-checker-bcad.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_la-heap-checker.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_la-heap-profile-table.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_la-heap-profiler.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_la-internal_logging.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_la-low_level_alloc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_la-malloc_extension.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_la-malloc_hook.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_la-malloc_interface.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_la-maybe_threads.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_la-memory_region_map.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_la-sysinfo.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_la-system-alloc.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_la-tcmalloc.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/malloc_unittest-malloc_hook.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/malloc_unittest-malloc_interface.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/malloc_unittest-tcmalloc_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_minimal_la-internal_logging.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_minimal_la-malloc_extension.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_minimal_la-malloc_hook.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_minimal_la-maybe_threads.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_minimal_la-system-alloc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libtcmalloc_minimal_la-tcmalloc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/linuxthreads.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/logging.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/low_level_alloc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/low_level_alloc_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/malloc_hook.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/markidle_unittest-markidle_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/markidle_unittest-testutil.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/memalign_unittest-memalign_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mutex.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/profiler.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/profiler1_unittest-profiler_unittest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/profiler2_unittest-profiler_unittest.Po@am__quote@
@@ -806,9 +1119,16 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/profiler4_unittest-profiler_unittest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ptmalloc_unittest1-t-test1.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ptmalloc_unittest2-t-test2.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spinlock.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stacktrace.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stacktrace_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcmalloc_large_unittest-tcmalloc_large_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcmalloc_minimal_large_unittest-tcmalloc_large_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcmalloc_minimal_unittest-tcmalloc_unittest.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcmalloc_unittest-tcmalloc_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/thread_dealloc_unittest-testutil.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/thread_dealloc_unittest-thread_dealloc_unittest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/thread_lister.Plo@am__quote@
.c.o:
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
@@ -831,6 +1151,20 @@ distclean-compile:
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+linuxthreads.lo: src/base/linuxthreads.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT linuxthreads.lo -MD -MP -MF "$(DEPDIR)/linuxthreads.Tpo" -c -o linuxthreads.lo `test -f 'src/base/linuxthreads.c' || echo '$(srcdir)/'`src/base/linuxthreads.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/linuxthreads.Tpo" "$(DEPDIR)/linuxthreads.Plo"; else rm -f "$(DEPDIR)/linuxthreads.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='src/base/linuxthreads.c' object='linuxthreads.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o linuxthreads.lo `test -f 'src/base/linuxthreads.c' || echo '$(srcdir)/'`src/base/linuxthreads.c
+
+thread_lister.lo: src/base/thread_lister.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT thread_lister.lo -MD -MP -MF "$(DEPDIR)/thread_lister.Tpo" -c -o thread_lister.lo `test -f 'src/base/thread_lister.c' || echo '$(srcdir)/'`src/base/thread_lister.c; \
+@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/thread_lister.Tpo" "$(DEPDIR)/thread_lister.Plo"; else rm -f "$(DEPDIR)/thread_lister.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='src/base/thread_lister.c' object='thread_lister.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o thread_lister.lo `test -f 'src/base/thread_lister.c' || echo '$(srcdir)/'`src/base/thread_lister.c
+
ptmalloc_unittest1-t-test1.o: src/tests/ptmalloc/t-test1.c
@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ptmalloc_unittest1_CFLAGS) $(CFLAGS) -MT ptmalloc_unittest1-t-test1.o -MD -MP -MF "$(DEPDIR)/ptmalloc_unittest1-t-test1.Tpo" -c -o ptmalloc_unittest1-t-test1.o `test -f 'src/tests/ptmalloc/t-test1.c' || echo '$(srcdir)/'`src/tests/ptmalloc/t-test1.c; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/ptmalloc_unittest1-t-test1.Tpo" "$(DEPDIR)/ptmalloc_unittest1-t-test1.Po"; else rm -f "$(DEPDIR)/ptmalloc_unittest1-t-test1.Tpo"; exit 1; fi
@@ -880,40 +1214,40 @@ ptmalloc_unittest2-t-test2.obj: src/tests/ptmalloc/t-test2.c
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $<
-libheapchecker_la-heap-checker.lo: src/heap-checker.cc
-@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libheapchecker_la_CXXFLAGS) $(CXXFLAGS) -MT libheapchecker_la-heap-checker.lo -MD -MP -MF "$(DEPDIR)/libheapchecker_la-heap-checker.Tpo" -c -o libheapchecker_la-heap-checker.lo `test -f 'src/heap-checker.cc' || echo '$(srcdir)/'`src/heap-checker.cc; \
-@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libheapchecker_la-heap-checker.Tpo" "$(DEPDIR)/libheapchecker_la-heap-checker.Plo"; else rm -f "$(DEPDIR)/libheapchecker_la-heap-checker.Tpo"; exit 1; fi
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/heap-checker.cc' object='libheapchecker_la-heap-checker.lo' libtool=yes @AMDEPBACKSLASH@
+logging.lo: src/base/logging.cc
+@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT logging.lo -MD -MP -MF "$(DEPDIR)/logging.Tpo" -c -o logging.lo `test -f 'src/base/logging.cc' || echo '$(srcdir)/'`src/base/logging.cc; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/logging.Tpo" "$(DEPDIR)/logging.Plo"; else rm -f "$(DEPDIR)/logging.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/base/logging.cc' object='logging.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libheapchecker_la_CXXFLAGS) $(CXXFLAGS) -c -o libheapchecker_la-heap-checker.lo `test -f 'src/heap-checker.cc' || echo '$(srcdir)/'`src/heap-checker.cc
+@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o logging.lo `test -f 'src/base/logging.cc' || echo '$(srcdir)/'`src/base/logging.cc
-libheapchecker_la-heap-checker-bcad.lo: src/heap-checker-bcad.cc
-@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libheapchecker_la_CXXFLAGS) $(CXXFLAGS) -MT libheapchecker_la-heap-checker-bcad.lo -MD -MP -MF "$(DEPDIR)/libheapchecker_la-heap-checker-bcad.Tpo" -c -o libheapchecker_la-heap-checker-bcad.lo `test -f 'src/heap-checker-bcad.cc' || echo '$(srcdir)/'`src/heap-checker-bcad.cc; \
-@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libheapchecker_la-heap-checker-bcad.Tpo" "$(DEPDIR)/libheapchecker_la-heap-checker-bcad.Plo"; else rm -f "$(DEPDIR)/libheapchecker_la-heap-checker-bcad.Tpo"; exit 1; fi
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/heap-checker-bcad.cc' object='libheapchecker_la-heap-checker-bcad.lo' libtool=yes @AMDEPBACKSLASH@
+profiler.lo: src/profiler.cc
+@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT profiler.lo -MD -MP -MF "$(DEPDIR)/profiler.Tpo" -c -o profiler.lo `test -f 'src/profiler.cc' || echo '$(srcdir)/'`src/profiler.cc; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/profiler.Tpo" "$(DEPDIR)/profiler.Plo"; else rm -f "$(DEPDIR)/profiler.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/profiler.cc' object='profiler.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libheapchecker_la_CXXFLAGS) $(CXXFLAGS) -c -o libheapchecker_la-heap-checker-bcad.lo `test -f 'src/heap-checker-bcad.cc' || echo '$(srcdir)/'`src/heap-checker-bcad.cc
+@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o profiler.lo `test -f 'src/profiler.cc' || echo '$(srcdir)/'`src/profiler.cc
-libheapprofiler_la-heap-profiler.lo: src/heap-profiler.cc
-@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libheapprofiler_la_CXXFLAGS) $(CXXFLAGS) -MT libheapprofiler_la-heap-profiler.lo -MD -MP -MF "$(DEPDIR)/libheapprofiler_la-heap-profiler.Tpo" -c -o libheapprofiler_la-heap-profiler.lo `test -f 'src/heap-profiler.cc' || echo '$(srcdir)/'`src/heap-profiler.cc; \
-@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libheapprofiler_la-heap-profiler.Tpo" "$(DEPDIR)/libheapprofiler_la-heap-profiler.Plo"; else rm -f "$(DEPDIR)/libheapprofiler_la-heap-profiler.Tpo"; exit 1; fi
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/heap-profiler.cc' object='libheapprofiler_la-heap-profiler.lo' libtool=yes @AMDEPBACKSLASH@
+mutex.lo: src/base/mutex.cc
+@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT mutex.lo -MD -MP -MF "$(DEPDIR)/mutex.Tpo" -c -o mutex.lo `test -f 'src/base/mutex.cc' || echo '$(srcdir)/'`src/base/mutex.cc; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/mutex.Tpo" "$(DEPDIR)/mutex.Plo"; else rm -f "$(DEPDIR)/mutex.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/base/mutex.cc' object='mutex.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libheapprofiler_la_CXXFLAGS) $(CXXFLAGS) -c -o libheapprofiler_la-heap-profiler.lo `test -f 'src/heap-profiler.cc' || echo '$(srcdir)/'`src/heap-profiler.cc
+@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o mutex.lo `test -f 'src/base/mutex.cc' || echo '$(srcdir)/'`src/base/mutex.cc
-libheapprofiler_la-heap-checker-bcad.lo: src/heap-checker-bcad.cc
-@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libheapprofiler_la_CXXFLAGS) $(CXXFLAGS) -MT libheapprofiler_la-heap-checker-bcad.lo -MD -MP -MF "$(DEPDIR)/libheapprofiler_la-heap-checker-bcad.Tpo" -c -o libheapprofiler_la-heap-checker-bcad.lo `test -f 'src/heap-checker-bcad.cc' || echo '$(srcdir)/'`src/heap-checker-bcad.cc; \
-@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libheapprofiler_la-heap-checker-bcad.Tpo" "$(DEPDIR)/libheapprofiler_la-heap-checker-bcad.Plo"; else rm -f "$(DEPDIR)/libheapprofiler_la-heap-checker-bcad.Tpo"; exit 1; fi
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/heap-checker-bcad.cc' object='libheapprofiler_la-heap-checker-bcad.lo' libtool=yes @AMDEPBACKSLASH@
+spinlock.lo: src/base/spinlock.cc
+@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT spinlock.lo -MD -MP -MF "$(DEPDIR)/spinlock.Tpo" -c -o spinlock.lo `test -f 'src/base/spinlock.cc' || echo '$(srcdir)/'`src/base/spinlock.cc; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/spinlock.Tpo" "$(DEPDIR)/spinlock.Plo"; else rm -f "$(DEPDIR)/spinlock.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/base/spinlock.cc' object='spinlock.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libheapprofiler_la_CXXFLAGS) $(CXXFLAGS) -c -o libheapprofiler_la-heap-checker-bcad.lo `test -f 'src/heap-checker-bcad.cc' || echo '$(srcdir)/'`src/heap-checker-bcad.cc
+@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o spinlock.lo `test -f 'src/base/spinlock.cc' || echo '$(srcdir)/'`src/base/spinlock.cc
-profiler.lo: src/profiler.cc
-@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT profiler.lo -MD -MP -MF "$(DEPDIR)/profiler.Tpo" -c -o profiler.lo `test -f 'src/profiler.cc' || echo '$(srcdir)/'`src/profiler.cc; \
-@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/profiler.Tpo" "$(DEPDIR)/profiler.Plo"; else rm -f "$(DEPDIR)/profiler.Tpo"; exit 1; fi
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/profiler.cc' object='profiler.lo' libtool=yes @AMDEPBACKSLASH@
+atomicops-internals-x86.lo: src/base/atomicops-internals-x86.cc
+@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT atomicops-internals-x86.lo -MD -MP -MF "$(DEPDIR)/atomicops-internals-x86.Tpo" -c -o atomicops-internals-x86.lo `test -f 'src/base/atomicops-internals-x86.cc' || echo '$(srcdir)/'`src/base/atomicops-internals-x86.cc; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/atomicops-internals-x86.Tpo" "$(DEPDIR)/atomicops-internals-x86.Plo"; else rm -f "$(DEPDIR)/atomicops-internals-x86.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/base/atomicops-internals-x86.cc' object='atomicops-internals-x86.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o profiler.lo `test -f 'src/profiler.cc' || echo '$(srcdir)/'`src/profiler.cc
+@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o atomicops-internals-x86.lo `test -f 'src/base/atomicops-internals-x86.cc' || echo '$(srcdir)/'`src/base/atomicops-internals-x86.cc
stacktrace.lo: src/stacktrace.cc
@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT stacktrace.lo -MD -MP -MF "$(DEPDIR)/stacktrace.Tpo" -c -o stacktrace.lo `test -f 'src/stacktrace.cc' || echo '$(srcdir)/'`src/stacktrace.cc; \
@@ -950,12 +1284,110 @@ libtcmalloc_la-malloc_hook.lo: src/malloc_hook.cc
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_la-malloc_hook.lo `test -f 'src/malloc_hook.cc' || echo '$(srcdir)/'`src/malloc_hook.cc
-libtcmalloc_la-malloc_interface.lo: src/malloc_interface.cc
-@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_la-malloc_interface.lo -MD -MP -MF "$(DEPDIR)/libtcmalloc_la-malloc_interface.Tpo" -c -o libtcmalloc_la-malloc_interface.lo `test -f 'src/malloc_interface.cc' || echo '$(srcdir)/'`src/malloc_interface.cc; \
-@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libtcmalloc_la-malloc_interface.Tpo" "$(DEPDIR)/libtcmalloc_la-malloc_interface.Plo"; else rm -f "$(DEPDIR)/libtcmalloc_la-malloc_interface.Tpo"; exit 1; fi
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/malloc_interface.cc' object='libtcmalloc_la-malloc_interface.lo' libtool=yes @AMDEPBACKSLASH@
+libtcmalloc_la-malloc_extension.lo: src/malloc_extension.cc
+@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_la-malloc_extension.lo -MD -MP -MF "$(DEPDIR)/libtcmalloc_la-malloc_extension.Tpo" -c -o libtcmalloc_la-malloc_extension.lo `test -f 'src/malloc_extension.cc' || echo '$(srcdir)/'`src/malloc_extension.cc; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libtcmalloc_la-malloc_extension.Tpo" "$(DEPDIR)/libtcmalloc_la-malloc_extension.Plo"; else rm -f "$(DEPDIR)/libtcmalloc_la-malloc_extension.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/malloc_extension.cc' object='libtcmalloc_la-malloc_extension.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_la-malloc_extension.lo `test -f 'src/malloc_extension.cc' || echo '$(srcdir)/'`src/malloc_extension.cc
+
+libtcmalloc_la-maybe_threads.lo: src/maybe_threads.cc
+@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_la-maybe_threads.lo -MD -MP -MF "$(DEPDIR)/libtcmalloc_la-maybe_threads.Tpo" -c -o libtcmalloc_la-maybe_threads.lo `test -f 'src/maybe_threads.cc' || echo '$(srcdir)/'`src/maybe_threads.cc; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libtcmalloc_la-maybe_threads.Tpo" "$(DEPDIR)/libtcmalloc_la-maybe_threads.Plo"; else rm -f "$(DEPDIR)/libtcmalloc_la-maybe_threads.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/maybe_threads.cc' object='libtcmalloc_la-maybe_threads.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_la-maybe_threads.lo `test -f 'src/maybe_threads.cc' || echo '$(srcdir)/'`src/maybe_threads.cc
+
+libtcmalloc_la-memory_region_map.lo: src/memory_region_map.cc
+@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_la-memory_region_map.lo -MD -MP -MF "$(DEPDIR)/libtcmalloc_la-memory_region_map.Tpo" -c -o libtcmalloc_la-memory_region_map.lo `test -f 'src/memory_region_map.cc' || echo '$(srcdir)/'`src/memory_region_map.cc; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libtcmalloc_la-memory_region_map.Tpo" "$(DEPDIR)/libtcmalloc_la-memory_region_map.Plo"; else rm -f "$(DEPDIR)/libtcmalloc_la-memory_region_map.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/memory_region_map.cc' object='libtcmalloc_la-memory_region_map.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_la-memory_region_map.lo `test -f 'src/memory_region_map.cc' || echo '$(srcdir)/'`src/memory_region_map.cc
+
+libtcmalloc_la-heap-profiler.lo: src/heap-profiler.cc
+@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_la-heap-profiler.lo -MD -MP -MF "$(DEPDIR)/libtcmalloc_la-heap-profiler.Tpo" -c -o libtcmalloc_la-heap-profiler.lo `test -f 'src/heap-profiler.cc' || echo '$(srcdir)/'`src/heap-profiler.cc; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libtcmalloc_la-heap-profiler.Tpo" "$(DEPDIR)/libtcmalloc_la-heap-profiler.Plo"; else rm -f "$(DEPDIR)/libtcmalloc_la-heap-profiler.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/heap-profiler.cc' object='libtcmalloc_la-heap-profiler.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_la-heap-profiler.lo `test -f 'src/heap-profiler.cc' || echo '$(srcdir)/'`src/heap-profiler.cc
+
+libtcmalloc_la-heap-profile-table.lo: src/heap-profile-table.cc
+@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_la-heap-profile-table.lo -MD -MP -MF "$(DEPDIR)/libtcmalloc_la-heap-profile-table.Tpo" -c -o libtcmalloc_la-heap-profile-table.lo `test -f 'src/heap-profile-table.cc' || echo '$(srcdir)/'`src/heap-profile-table.cc; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libtcmalloc_la-heap-profile-table.Tpo" "$(DEPDIR)/libtcmalloc_la-heap-profile-table.Plo"; else rm -f "$(DEPDIR)/libtcmalloc_la-heap-profile-table.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/heap-profile-table.cc' object='libtcmalloc_la-heap-profile-table.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_la-heap-profile-table.lo `test -f 'src/heap-profile-table.cc' || echo '$(srcdir)/'`src/heap-profile-table.cc
+
+libtcmalloc_la-heap-checker.lo: src/heap-checker.cc
+@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_la-heap-checker.lo -MD -MP -MF "$(DEPDIR)/libtcmalloc_la-heap-checker.Tpo" -c -o libtcmalloc_la-heap-checker.lo `test -f 'src/heap-checker.cc' || echo '$(srcdir)/'`src/heap-checker.cc; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libtcmalloc_la-heap-checker.Tpo" "$(DEPDIR)/libtcmalloc_la-heap-checker.Plo"; else rm -f "$(DEPDIR)/libtcmalloc_la-heap-checker.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/heap-checker.cc' object='libtcmalloc_la-heap-checker.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_la-heap-checker.lo `test -f 'src/heap-checker.cc' || echo '$(srcdir)/'`src/heap-checker.cc
+
+libtcmalloc_la-sysinfo.lo: src/base/sysinfo.cc
+@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_la-sysinfo.lo -MD -MP -MF "$(DEPDIR)/libtcmalloc_la-sysinfo.Tpo" -c -o libtcmalloc_la-sysinfo.lo `test -f 'src/base/sysinfo.cc' || echo '$(srcdir)/'`src/base/sysinfo.cc; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libtcmalloc_la-sysinfo.Tpo" "$(DEPDIR)/libtcmalloc_la-sysinfo.Plo"; else rm -f "$(DEPDIR)/libtcmalloc_la-sysinfo.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/base/sysinfo.cc' object='libtcmalloc_la-sysinfo.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_la-sysinfo.lo `test -f 'src/base/sysinfo.cc' || echo '$(srcdir)/'`src/base/sysinfo.cc
+
+libtcmalloc_la-low_level_alloc.lo: src/base/low_level_alloc.cc
+@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_la-low_level_alloc.lo -MD -MP -MF "$(DEPDIR)/libtcmalloc_la-low_level_alloc.Tpo" -c -o libtcmalloc_la-low_level_alloc.lo `test -f 'src/base/low_level_alloc.cc' || echo '$(srcdir)/'`src/base/low_level_alloc.cc; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libtcmalloc_la-low_level_alloc.Tpo" "$(DEPDIR)/libtcmalloc_la-low_level_alloc.Plo"; else rm -f "$(DEPDIR)/libtcmalloc_la-low_level_alloc.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/base/low_level_alloc.cc' object='libtcmalloc_la-low_level_alloc.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_la-low_level_alloc.lo `test -f 'src/base/low_level_alloc.cc' || echo '$(srcdir)/'`src/base/low_level_alloc.cc
+
+libtcmalloc_la-heap-checker-bcad.lo: src/heap-checker-bcad.cc
+@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_la-heap-checker-bcad.lo -MD -MP -MF "$(DEPDIR)/libtcmalloc_la-heap-checker-bcad.Tpo" -c -o libtcmalloc_la-heap-checker-bcad.lo `test -f 'src/heap-checker-bcad.cc' || echo '$(srcdir)/'`src/heap-checker-bcad.cc; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libtcmalloc_la-heap-checker-bcad.Tpo" "$(DEPDIR)/libtcmalloc_la-heap-checker-bcad.Plo"; else rm -f "$(DEPDIR)/libtcmalloc_la-heap-checker-bcad.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/heap-checker-bcad.cc' object='libtcmalloc_la-heap-checker-bcad.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_la-heap-checker-bcad.lo `test -f 'src/heap-checker-bcad.cc' || echo '$(srcdir)/'`src/heap-checker-bcad.cc
+
+libtcmalloc_minimal_la-internal_logging.lo: src/internal_logging.cc
+@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_minimal_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_minimal_la-internal_logging.lo -MD -MP -MF "$(DEPDIR)/libtcmalloc_minimal_la-internal_logging.Tpo" -c -o libtcmalloc_minimal_la-internal_logging.lo `test -f 'src/internal_logging.cc' || echo '$(srcdir)/'`src/internal_logging.cc; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libtcmalloc_minimal_la-internal_logging.Tpo" "$(DEPDIR)/libtcmalloc_minimal_la-internal_logging.Plo"; else rm -f "$(DEPDIR)/libtcmalloc_minimal_la-internal_logging.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/internal_logging.cc' object='libtcmalloc_minimal_la-internal_logging.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_minimal_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_minimal_la-internal_logging.lo `test -f 'src/internal_logging.cc' || echo '$(srcdir)/'`src/internal_logging.cc
+
+libtcmalloc_minimal_la-system-alloc.lo: src/system-alloc.cc
+@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_minimal_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_minimal_la-system-alloc.lo -MD -MP -MF "$(DEPDIR)/libtcmalloc_minimal_la-system-alloc.Tpo" -c -o libtcmalloc_minimal_la-system-alloc.lo `test -f 'src/system-alloc.cc' || echo '$(srcdir)/'`src/system-alloc.cc; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libtcmalloc_minimal_la-system-alloc.Tpo" "$(DEPDIR)/libtcmalloc_minimal_la-system-alloc.Plo"; else rm -f "$(DEPDIR)/libtcmalloc_minimal_la-system-alloc.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/system-alloc.cc' object='libtcmalloc_minimal_la-system-alloc.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_minimal_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_minimal_la-system-alloc.lo `test -f 'src/system-alloc.cc' || echo '$(srcdir)/'`src/system-alloc.cc
+
+libtcmalloc_minimal_la-tcmalloc.lo: src/tcmalloc.cc
+@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_minimal_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_minimal_la-tcmalloc.lo -MD -MP -MF "$(DEPDIR)/libtcmalloc_minimal_la-tcmalloc.Tpo" -c -o libtcmalloc_minimal_la-tcmalloc.lo `test -f 'src/tcmalloc.cc' || echo '$(srcdir)/'`src/tcmalloc.cc; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libtcmalloc_minimal_la-tcmalloc.Tpo" "$(DEPDIR)/libtcmalloc_minimal_la-tcmalloc.Plo"; else rm -f "$(DEPDIR)/libtcmalloc_minimal_la-tcmalloc.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/tcmalloc.cc' object='libtcmalloc_minimal_la-tcmalloc.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_la-malloc_interface.lo `test -f 'src/malloc_interface.cc' || echo '$(srcdir)/'`src/malloc_interface.cc
+@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_minimal_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_minimal_la-tcmalloc.lo `test -f 'src/tcmalloc.cc' || echo '$(srcdir)/'`src/tcmalloc.cc
+
+libtcmalloc_minimal_la-malloc_hook.lo: src/malloc_hook.cc
+@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_minimal_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_minimal_la-malloc_hook.lo -MD -MP -MF "$(DEPDIR)/libtcmalloc_minimal_la-malloc_hook.Tpo" -c -o libtcmalloc_minimal_la-malloc_hook.lo `test -f 'src/malloc_hook.cc' || echo '$(srcdir)/'`src/malloc_hook.cc; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libtcmalloc_minimal_la-malloc_hook.Tpo" "$(DEPDIR)/libtcmalloc_minimal_la-malloc_hook.Plo"; else rm -f "$(DEPDIR)/libtcmalloc_minimal_la-malloc_hook.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/malloc_hook.cc' object='libtcmalloc_minimal_la-malloc_hook.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_minimal_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_minimal_la-malloc_hook.lo `test -f 'src/malloc_hook.cc' || echo '$(srcdir)/'`src/malloc_hook.cc
+
+libtcmalloc_minimal_la-malloc_extension.lo: src/malloc_extension.cc
+@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_minimal_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_minimal_la-malloc_extension.lo -MD -MP -MF "$(DEPDIR)/libtcmalloc_minimal_la-malloc_extension.Tpo" -c -o libtcmalloc_minimal_la-malloc_extension.lo `test -f 'src/malloc_extension.cc' || echo '$(srcdir)/'`src/malloc_extension.cc; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libtcmalloc_minimal_la-malloc_extension.Tpo" "$(DEPDIR)/libtcmalloc_minimal_la-malloc_extension.Plo"; else rm -f "$(DEPDIR)/libtcmalloc_minimal_la-malloc_extension.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/malloc_extension.cc' object='libtcmalloc_minimal_la-malloc_extension.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_minimal_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_minimal_la-malloc_extension.lo `test -f 'src/malloc_extension.cc' || echo '$(srcdir)/'`src/malloc_extension.cc
+
+libtcmalloc_minimal_la-maybe_threads.lo: src/maybe_threads.cc
+@am__fastdepCXX_TRUE@ if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_minimal_la_CXXFLAGS) $(CXXFLAGS) -MT libtcmalloc_minimal_la-maybe_threads.lo -MD -MP -MF "$(DEPDIR)/libtcmalloc_minimal_la-maybe_threads.Tpo" -c -o libtcmalloc_minimal_la-maybe_threads.lo `test -f 'src/maybe_threads.cc' || echo '$(srcdir)/'`src/maybe_threads.cc; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/libtcmalloc_minimal_la-maybe_threads.Tpo" "$(DEPDIR)/libtcmalloc_minimal_la-maybe_threads.Plo"; else rm -f "$(DEPDIR)/libtcmalloc_minimal_la-maybe_threads.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/maybe_threads.cc' object='libtcmalloc_minimal_la-maybe_threads.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libtcmalloc_minimal_la_CXXFLAGS) $(CXXFLAGS) -c -o libtcmalloc_minimal_la-maybe_threads.lo `test -f 'src/maybe_threads.cc' || echo '$(srcdir)/'`src/maybe_threads.cc
addressmap_unittest-addressmap_unittest.o: src/tests/addressmap_unittest.cc
@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(addressmap_unittest_CXXFLAGS) $(CXXFLAGS) -MT addressmap_unittest-addressmap_unittest.o -MD -MP -MF "$(DEPDIR)/addressmap_unittest-addressmap_unittest.Tpo" -c -o addressmap_unittest-addressmap_unittest.o `test -f 'src/tests/addressmap_unittest.cc' || echo '$(srcdir)/'`src/tests/addressmap_unittest.cc; \
@@ -971,6 +1403,34 @@ addressmap_unittest-addressmap_unittest.obj: src/tests/addressmap_unittest.cc
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(addressmap_unittest_CXXFLAGS) $(CXXFLAGS) -c -o addressmap_unittest-addressmap_unittest.obj `if test -f 'src/tests/addressmap_unittest.cc'; then $(CYGPATH_W) 'src/tests/addressmap_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/addressmap_unittest.cc'; fi`
+atomicops_unittest.o: src/tests/atomicops_unittest.cc
+@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT atomicops_unittest.o -MD -MP -MF "$(DEPDIR)/atomicops_unittest.Tpo" -c -o atomicops_unittest.o `test -f 'src/tests/atomicops_unittest.cc' || echo '$(srcdir)/'`src/tests/atomicops_unittest.cc; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/atomicops_unittest.Tpo" "$(DEPDIR)/atomicops_unittest.Po"; else rm -f "$(DEPDIR)/atomicops_unittest.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/tests/atomicops_unittest.cc' object='atomicops_unittest.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o atomicops_unittest.o `test -f 'src/tests/atomicops_unittest.cc' || echo '$(srcdir)/'`src/tests/atomicops_unittest.cc
+
+atomicops_unittest.obj: src/tests/atomicops_unittest.cc
+@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT atomicops_unittest.obj -MD -MP -MF "$(DEPDIR)/atomicops_unittest.Tpo" -c -o atomicops_unittest.obj `if test -f 'src/tests/atomicops_unittest.cc'; then $(CYGPATH_W) 'src/tests/atomicops_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/atomicops_unittest.cc'; fi`; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/atomicops_unittest.Tpo" "$(DEPDIR)/atomicops_unittest.Po"; else rm -f "$(DEPDIR)/atomicops_unittest.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/tests/atomicops_unittest.cc' object='atomicops_unittest.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o atomicops_unittest.obj `if test -f 'src/tests/atomicops_unittest.cc'; then $(CYGPATH_W) 'src/tests/atomicops_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/atomicops_unittest.cc'; fi`
+
+frag_unittest-frag_unittest.o: src/tests/frag_unittest.cc
+@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(frag_unittest_CXXFLAGS) $(CXXFLAGS) -MT frag_unittest-frag_unittest.o -MD -MP -MF "$(DEPDIR)/frag_unittest-frag_unittest.Tpo" -c -o frag_unittest-frag_unittest.o `test -f 'src/tests/frag_unittest.cc' || echo '$(srcdir)/'`src/tests/frag_unittest.cc; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/frag_unittest-frag_unittest.Tpo" "$(DEPDIR)/frag_unittest-frag_unittest.Po"; else rm -f "$(DEPDIR)/frag_unittest-frag_unittest.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/tests/frag_unittest.cc' object='frag_unittest-frag_unittest.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(frag_unittest_CXXFLAGS) $(CXXFLAGS) -c -o frag_unittest-frag_unittest.o `test -f 'src/tests/frag_unittest.cc' || echo '$(srcdir)/'`src/tests/frag_unittest.cc
+
+frag_unittest-frag_unittest.obj: src/tests/frag_unittest.cc
+@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(frag_unittest_CXXFLAGS) $(CXXFLAGS) -MT frag_unittest-frag_unittest.obj -MD -MP -MF "$(DEPDIR)/frag_unittest-frag_unittest.Tpo" -c -o frag_unittest-frag_unittest.obj `if test -f 'src/tests/frag_unittest.cc'; then $(CYGPATH_W) 'src/tests/frag_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/frag_unittest.cc'; fi`; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/frag_unittest-frag_unittest.Tpo" "$(DEPDIR)/frag_unittest-frag_unittest.Po"; else rm -f "$(DEPDIR)/frag_unittest-frag_unittest.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/tests/frag_unittest.cc' object='frag_unittest-frag_unittest.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(frag_unittest_CXXFLAGS) $(CXXFLAGS) -c -o frag_unittest-frag_unittest.obj `if test -f 'src/tests/frag_unittest.cc'; then $(CYGPATH_W) 'src/tests/frag_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/frag_unittest.cc'; fi`
+
heap_checker_unittest-heap-checker_unittest.o: src/tests/heap-checker_unittest.cc
@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(heap_checker_unittest_CXXFLAGS) $(CXXFLAGS) -MT heap_checker_unittest-heap-checker_unittest.o -MD -MP -MF "$(DEPDIR)/heap_checker_unittest-heap-checker_unittest.Tpo" -c -o heap_checker_unittest-heap-checker_unittest.o `test -f 'src/tests/heap-checker_unittest.cc' || echo '$(srcdir)/'`src/tests/heap-checker_unittest.cc; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/heap_checker_unittest-heap-checker_unittest.Tpo" "$(DEPDIR)/heap_checker_unittest-heap-checker_unittest.Po"; else rm -f "$(DEPDIR)/heap_checker_unittest-heap-checker_unittest.Tpo"; exit 1; fi
@@ -985,47 +1445,103 @@ heap_checker_unittest-heap-checker_unittest.obj: src/tests/heap-checker_unittest
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(heap_checker_unittest_CXXFLAGS) $(CXXFLAGS) -c -o heap_checker_unittest-heap-checker_unittest.obj `if test -f 'src/tests/heap-checker_unittest.cc'; then $(CYGPATH_W) 'src/tests/heap-checker_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/heap-checker_unittest.cc'; fi`
-malloc_unittest-tcmalloc_unittest.o: src/tests/tcmalloc_unittest.cc
-@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(malloc_unittest_CXXFLAGS) $(CXXFLAGS) -MT malloc_unittest-tcmalloc_unittest.o -MD -MP -MF "$(DEPDIR)/malloc_unittest-tcmalloc_unittest.Tpo" -c -o malloc_unittest-tcmalloc_unittest.o `test -f 'src/tests/tcmalloc_unittest.cc' || echo '$(srcdir)/'`src/tests/tcmalloc_unittest.cc; \
-@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/malloc_unittest-tcmalloc_unittest.Tpo" "$(DEPDIR)/malloc_unittest-tcmalloc_unittest.Po"; else rm -f "$(DEPDIR)/malloc_unittest-tcmalloc_unittest.Tpo"; exit 1; fi
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/tests/tcmalloc_unittest.cc' object='malloc_unittest-tcmalloc_unittest.o' libtool=no @AMDEPBACKSLASH@
+heap_profiler_unittest-heap-profiler_unittest.o: src/tests/heap-profiler_unittest.cc
+@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(heap_profiler_unittest_CXXFLAGS) $(CXXFLAGS) -MT heap_profiler_unittest-heap-profiler_unittest.o -MD -MP -MF "$(DEPDIR)/heap_profiler_unittest-heap-profiler_unittest.Tpo" -c -o heap_profiler_unittest-heap-profiler_unittest.o `test -f 'src/tests/heap-profiler_unittest.cc' || echo '$(srcdir)/'`src/tests/heap-profiler_unittest.cc; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/heap_profiler_unittest-heap-profiler_unittest.Tpo" "$(DEPDIR)/heap_profiler_unittest-heap-profiler_unittest.Po"; else rm -f "$(DEPDIR)/heap_profiler_unittest-heap-profiler_unittest.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/tests/heap-profiler_unittest.cc' object='heap_profiler_unittest-heap-profiler_unittest.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(heap_profiler_unittest_CXXFLAGS) $(CXXFLAGS) -c -o heap_profiler_unittest-heap-profiler_unittest.o `test -f 'src/tests/heap-profiler_unittest.cc' || echo '$(srcdir)/'`src/tests/heap-profiler_unittest.cc
+
+heap_profiler_unittest-heap-profiler_unittest.obj: src/tests/heap-profiler_unittest.cc
+@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(heap_profiler_unittest_CXXFLAGS) $(CXXFLAGS) -MT heap_profiler_unittest-heap-profiler_unittest.obj -MD -MP -MF "$(DEPDIR)/heap_profiler_unittest-heap-profiler_unittest.Tpo" -c -o heap_profiler_unittest-heap-profiler_unittest.obj `if test -f 'src/tests/heap-profiler_unittest.cc'; then $(CYGPATH_W) 'src/tests/heap-profiler_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/heap-profiler_unittest.cc'; fi`; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/heap_profiler_unittest-heap-profiler_unittest.Tpo" "$(DEPDIR)/heap_profiler_unittest-heap-profiler_unittest.Po"; else rm -f "$(DEPDIR)/heap_profiler_unittest-heap-profiler_unittest.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/tests/heap-profiler_unittest.cc' object='heap_profiler_unittest-heap-profiler_unittest.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(heap_profiler_unittest_CXXFLAGS) $(CXXFLAGS) -c -o heap_profiler_unittest-heap-profiler_unittest.obj `if test -f 'src/tests/heap-profiler_unittest.cc'; then $(CYGPATH_W) 'src/tests/heap-profiler_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/heap-profiler_unittest.cc'; fi`
+
+low_level_alloc.o: src/base/low_level_alloc.cc
+@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT low_level_alloc.o -MD -MP -MF "$(DEPDIR)/low_level_alloc.Tpo" -c -o low_level_alloc.o `test -f 'src/base/low_level_alloc.cc' || echo '$(srcdir)/'`src/base/low_level_alloc.cc; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/low_level_alloc.Tpo" "$(DEPDIR)/low_level_alloc.Po"; else rm -f "$(DEPDIR)/low_level_alloc.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/base/low_level_alloc.cc' object='low_level_alloc.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o low_level_alloc.o `test -f 'src/base/low_level_alloc.cc' || echo '$(srcdir)/'`src/base/low_level_alloc.cc
+
+low_level_alloc.obj: src/base/low_level_alloc.cc
+@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT low_level_alloc.obj -MD -MP -MF "$(DEPDIR)/low_level_alloc.Tpo" -c -o low_level_alloc.obj `if test -f 'src/base/low_level_alloc.cc'; then $(CYGPATH_W) 'src/base/low_level_alloc.cc'; else $(CYGPATH_W) '$(srcdir)/src/base/low_level_alloc.cc'; fi`; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/low_level_alloc.Tpo" "$(DEPDIR)/low_level_alloc.Po"; else rm -f "$(DEPDIR)/low_level_alloc.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/base/low_level_alloc.cc' object='low_level_alloc.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o low_level_alloc.obj `if test -f 'src/base/low_level_alloc.cc'; then $(CYGPATH_W) 'src/base/low_level_alloc.cc'; else $(CYGPATH_W) '$(srcdir)/src/base/low_level_alloc.cc'; fi`
+
+malloc_hook.o: src/malloc_hook.cc
+@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT malloc_hook.o -MD -MP -MF "$(DEPDIR)/malloc_hook.Tpo" -c -o malloc_hook.o `test -f 'src/malloc_hook.cc' || echo '$(srcdir)/'`src/malloc_hook.cc; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/malloc_hook.Tpo" "$(DEPDIR)/malloc_hook.Po"; else rm -f "$(DEPDIR)/malloc_hook.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/malloc_hook.cc' object='malloc_hook.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o malloc_hook.o `test -f 'src/malloc_hook.cc' || echo '$(srcdir)/'`src/malloc_hook.cc
+
+malloc_hook.obj: src/malloc_hook.cc
+@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT malloc_hook.obj -MD -MP -MF "$(DEPDIR)/malloc_hook.Tpo" -c -o malloc_hook.obj `if test -f 'src/malloc_hook.cc'; then $(CYGPATH_W) 'src/malloc_hook.cc'; else $(CYGPATH_W) '$(srcdir)/src/malloc_hook.cc'; fi`; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/malloc_hook.Tpo" "$(DEPDIR)/malloc_hook.Po"; else rm -f "$(DEPDIR)/malloc_hook.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/malloc_hook.cc' object='malloc_hook.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(malloc_unittest_CXXFLAGS) $(CXXFLAGS) -c -o malloc_unittest-tcmalloc_unittest.o `test -f 'src/tests/tcmalloc_unittest.cc' || echo '$(srcdir)/'`src/tests/tcmalloc_unittest.cc
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o malloc_hook.obj `if test -f 'src/malloc_hook.cc'; then $(CYGPATH_W) 'src/malloc_hook.cc'; else $(CYGPATH_W) '$(srcdir)/src/malloc_hook.cc'; fi`
-malloc_unittest-tcmalloc_unittest.obj: src/tests/tcmalloc_unittest.cc
-@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(malloc_unittest_CXXFLAGS) $(CXXFLAGS) -MT malloc_unittest-tcmalloc_unittest.obj -MD -MP -MF "$(DEPDIR)/malloc_unittest-tcmalloc_unittest.Tpo" -c -o malloc_unittest-tcmalloc_unittest.obj `if test -f 'src/tests/tcmalloc_unittest.cc'; then $(CYGPATH_W) 'src/tests/tcmalloc_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/tcmalloc_unittest.cc'; fi`; \
-@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/malloc_unittest-tcmalloc_unittest.Tpo" "$(DEPDIR)/malloc_unittest-tcmalloc_unittest.Po"; else rm -f "$(DEPDIR)/malloc_unittest-tcmalloc_unittest.Tpo"; exit 1; fi
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/tests/tcmalloc_unittest.cc' object='malloc_unittest-tcmalloc_unittest.obj' libtool=no @AMDEPBACKSLASH@
+low_level_alloc_unittest.o: src/tests/low_level_alloc_unittest.cc
+@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT low_level_alloc_unittest.o -MD -MP -MF "$(DEPDIR)/low_level_alloc_unittest.Tpo" -c -o low_level_alloc_unittest.o `test -f 'src/tests/low_level_alloc_unittest.cc' || echo '$(srcdir)/'`src/tests/low_level_alloc_unittest.cc; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/low_level_alloc_unittest.Tpo" "$(DEPDIR)/low_level_alloc_unittest.Po"; else rm -f "$(DEPDIR)/low_level_alloc_unittest.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/tests/low_level_alloc_unittest.cc' object='low_level_alloc_unittest.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(malloc_unittest_CXXFLAGS) $(CXXFLAGS) -c -o malloc_unittest-tcmalloc_unittest.obj `if test -f 'src/tests/tcmalloc_unittest.cc'; then $(CYGPATH_W) 'src/tests/tcmalloc_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/tcmalloc_unittest.cc'; fi`
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o low_level_alloc_unittest.o `test -f 'src/tests/low_level_alloc_unittest.cc' || echo '$(srcdir)/'`src/tests/low_level_alloc_unittest.cc
-malloc_unittest-malloc_hook.o: src/malloc_hook.cc
-@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(malloc_unittest_CXXFLAGS) $(CXXFLAGS) -MT malloc_unittest-malloc_hook.o -MD -MP -MF "$(DEPDIR)/malloc_unittest-malloc_hook.Tpo" -c -o malloc_unittest-malloc_hook.o `test -f 'src/malloc_hook.cc' || echo '$(srcdir)/'`src/malloc_hook.cc; \
-@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/malloc_unittest-malloc_hook.Tpo" "$(DEPDIR)/malloc_unittest-malloc_hook.Po"; else rm -f "$(DEPDIR)/malloc_unittest-malloc_hook.Tpo"; exit 1; fi
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/malloc_hook.cc' object='malloc_unittest-malloc_hook.o' libtool=no @AMDEPBACKSLASH@
+low_level_alloc_unittest.obj: src/tests/low_level_alloc_unittest.cc
+@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT low_level_alloc_unittest.obj -MD -MP -MF "$(DEPDIR)/low_level_alloc_unittest.Tpo" -c -o low_level_alloc_unittest.obj `if test -f 'src/tests/low_level_alloc_unittest.cc'; then $(CYGPATH_W) 'src/tests/low_level_alloc_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/low_level_alloc_unittest.cc'; fi`; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/low_level_alloc_unittest.Tpo" "$(DEPDIR)/low_level_alloc_unittest.Po"; else rm -f "$(DEPDIR)/low_level_alloc_unittest.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/tests/low_level_alloc_unittest.cc' object='low_level_alloc_unittest.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(malloc_unittest_CXXFLAGS) $(CXXFLAGS) -c -o malloc_unittest-malloc_hook.o `test -f 'src/malloc_hook.cc' || echo '$(srcdir)/'`src/malloc_hook.cc
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o low_level_alloc_unittest.obj `if test -f 'src/tests/low_level_alloc_unittest.cc'; then $(CYGPATH_W) 'src/tests/low_level_alloc_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/low_level_alloc_unittest.cc'; fi`
-malloc_unittest-malloc_hook.obj: src/malloc_hook.cc
-@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(malloc_unittest_CXXFLAGS) $(CXXFLAGS) -MT malloc_unittest-malloc_hook.obj -MD -MP -MF "$(DEPDIR)/malloc_unittest-malloc_hook.Tpo" -c -o malloc_unittest-malloc_hook.obj `if test -f 'src/malloc_hook.cc'; then $(CYGPATH_W) 'src/malloc_hook.cc'; else $(CYGPATH_W) '$(srcdir)/src/malloc_hook.cc'; fi`; \
-@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/malloc_unittest-malloc_hook.Tpo" "$(DEPDIR)/malloc_unittest-malloc_hook.Po"; else rm -f "$(DEPDIR)/malloc_unittest-malloc_hook.Tpo"; exit 1; fi
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/malloc_hook.cc' object='malloc_unittest-malloc_hook.obj' libtool=no @AMDEPBACKSLASH@
+markidle_unittest-markidle_unittest.o: src/tests/markidle_unittest.cc
+@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(markidle_unittest_CXXFLAGS) $(CXXFLAGS) -MT markidle_unittest-markidle_unittest.o -MD -MP -MF "$(DEPDIR)/markidle_unittest-markidle_unittest.Tpo" -c -o markidle_unittest-markidle_unittest.o `test -f 'src/tests/markidle_unittest.cc' || echo '$(srcdir)/'`src/tests/markidle_unittest.cc; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/markidle_unittest-markidle_unittest.Tpo" "$(DEPDIR)/markidle_unittest-markidle_unittest.Po"; else rm -f "$(DEPDIR)/markidle_unittest-markidle_unittest.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/tests/markidle_unittest.cc' object='markidle_unittest-markidle_unittest.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(malloc_unittest_CXXFLAGS) $(CXXFLAGS) -c -o malloc_unittest-malloc_hook.obj `if test -f 'src/malloc_hook.cc'; then $(CYGPATH_W) 'src/malloc_hook.cc'; else $(CYGPATH_W) '$(srcdir)/src/malloc_hook.cc'; fi`
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(markidle_unittest_CXXFLAGS) $(CXXFLAGS) -c -o markidle_unittest-markidle_unittest.o `test -f 'src/tests/markidle_unittest.cc' || echo '$(srcdir)/'`src/tests/markidle_unittest.cc
-malloc_unittest-malloc_interface.o: src/malloc_interface.cc
-@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(malloc_unittest_CXXFLAGS) $(CXXFLAGS) -MT malloc_unittest-malloc_interface.o -MD -MP -MF "$(DEPDIR)/malloc_unittest-malloc_interface.Tpo" -c -o malloc_unittest-malloc_interface.o `test -f 'src/malloc_interface.cc' || echo '$(srcdir)/'`src/malloc_interface.cc; \
-@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/malloc_unittest-malloc_interface.Tpo" "$(DEPDIR)/malloc_unittest-malloc_interface.Po"; else rm -f "$(DEPDIR)/malloc_unittest-malloc_interface.Tpo"; exit 1; fi
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/malloc_interface.cc' object='malloc_unittest-malloc_interface.o' libtool=no @AMDEPBACKSLASH@
+markidle_unittest-markidle_unittest.obj: src/tests/markidle_unittest.cc
+@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(markidle_unittest_CXXFLAGS) $(CXXFLAGS) -MT markidle_unittest-markidle_unittest.obj -MD -MP -MF "$(DEPDIR)/markidle_unittest-markidle_unittest.Tpo" -c -o markidle_unittest-markidle_unittest.obj `if test -f 'src/tests/markidle_unittest.cc'; then $(CYGPATH_W) 'src/tests/markidle_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/markidle_unittest.cc'; fi`; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/markidle_unittest-markidle_unittest.Tpo" "$(DEPDIR)/markidle_unittest-markidle_unittest.Po"; else rm -f "$(DEPDIR)/markidle_unittest-markidle_unittest.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/tests/markidle_unittest.cc' object='markidle_unittest-markidle_unittest.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(malloc_unittest_CXXFLAGS) $(CXXFLAGS) -c -o malloc_unittest-malloc_interface.o `test -f 'src/malloc_interface.cc' || echo '$(srcdir)/'`src/malloc_interface.cc
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(markidle_unittest_CXXFLAGS) $(CXXFLAGS) -c -o markidle_unittest-markidle_unittest.obj `if test -f 'src/tests/markidle_unittest.cc'; then $(CYGPATH_W) 'src/tests/markidle_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/markidle_unittest.cc'; fi`
-malloc_unittest-malloc_interface.obj: src/malloc_interface.cc
-@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(malloc_unittest_CXXFLAGS) $(CXXFLAGS) -MT malloc_unittest-malloc_interface.obj -MD -MP -MF "$(DEPDIR)/malloc_unittest-malloc_interface.Tpo" -c -o malloc_unittest-malloc_interface.obj `if test -f 'src/malloc_interface.cc'; then $(CYGPATH_W) 'src/malloc_interface.cc'; else $(CYGPATH_W) '$(srcdir)/src/malloc_interface.cc'; fi`; \
-@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/malloc_unittest-malloc_interface.Tpo" "$(DEPDIR)/malloc_unittest-malloc_interface.Po"; else rm -f "$(DEPDIR)/malloc_unittest-malloc_interface.Tpo"; exit 1; fi
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/malloc_interface.cc' object='malloc_unittest-malloc_interface.obj' libtool=no @AMDEPBACKSLASH@
+markidle_unittest-testutil.o: src/tests/testutil.cc
+@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(markidle_unittest_CXXFLAGS) $(CXXFLAGS) -MT markidle_unittest-testutil.o -MD -MP -MF "$(DEPDIR)/markidle_unittest-testutil.Tpo" -c -o markidle_unittest-testutil.o `test -f 'src/tests/testutil.cc' || echo '$(srcdir)/'`src/tests/testutil.cc; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/markidle_unittest-testutil.Tpo" "$(DEPDIR)/markidle_unittest-testutil.Po"; else rm -f "$(DEPDIR)/markidle_unittest-testutil.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/tests/testutil.cc' object='markidle_unittest-testutil.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(malloc_unittest_CXXFLAGS) $(CXXFLAGS) -c -o malloc_unittest-malloc_interface.obj `if test -f 'src/malloc_interface.cc'; then $(CYGPATH_W) 'src/malloc_interface.cc'; else $(CYGPATH_W) '$(srcdir)/src/malloc_interface.cc'; fi`
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(markidle_unittest_CXXFLAGS) $(CXXFLAGS) -c -o markidle_unittest-testutil.o `test -f 'src/tests/testutil.cc' || echo '$(srcdir)/'`src/tests/testutil.cc
+
+markidle_unittest-testutil.obj: src/tests/testutil.cc
+@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(markidle_unittest_CXXFLAGS) $(CXXFLAGS) -MT markidle_unittest-testutil.obj -MD -MP -MF "$(DEPDIR)/markidle_unittest-testutil.Tpo" -c -o markidle_unittest-testutil.obj `if test -f 'src/tests/testutil.cc'; then $(CYGPATH_W) 'src/tests/testutil.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/testutil.cc'; fi`; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/markidle_unittest-testutil.Tpo" "$(DEPDIR)/markidle_unittest-testutil.Po"; else rm -f "$(DEPDIR)/markidle_unittest-testutil.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/tests/testutil.cc' object='markidle_unittest-testutil.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(markidle_unittest_CXXFLAGS) $(CXXFLAGS) -c -o markidle_unittest-testutil.obj `if test -f 'src/tests/testutil.cc'; then $(CYGPATH_W) 'src/tests/testutil.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/testutil.cc'; fi`
+
+memalign_unittest-memalign_unittest.o: src/tests/memalign_unittest.cc
+@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memalign_unittest_CXXFLAGS) $(CXXFLAGS) -MT memalign_unittest-memalign_unittest.o -MD -MP -MF "$(DEPDIR)/memalign_unittest-memalign_unittest.Tpo" -c -o memalign_unittest-memalign_unittest.o `test -f 'src/tests/memalign_unittest.cc' || echo '$(srcdir)/'`src/tests/memalign_unittest.cc; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/memalign_unittest-memalign_unittest.Tpo" "$(DEPDIR)/memalign_unittest-memalign_unittest.Po"; else rm -f "$(DEPDIR)/memalign_unittest-memalign_unittest.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/tests/memalign_unittest.cc' object='memalign_unittest-memalign_unittest.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memalign_unittest_CXXFLAGS) $(CXXFLAGS) -c -o memalign_unittest-memalign_unittest.o `test -f 'src/tests/memalign_unittest.cc' || echo '$(srcdir)/'`src/tests/memalign_unittest.cc
+
+memalign_unittest-memalign_unittest.obj: src/tests/memalign_unittest.cc
+@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memalign_unittest_CXXFLAGS) $(CXXFLAGS) -MT memalign_unittest-memalign_unittest.obj -MD -MP -MF "$(DEPDIR)/memalign_unittest-memalign_unittest.Tpo" -c -o memalign_unittest-memalign_unittest.obj `if test -f 'src/tests/memalign_unittest.cc'; then $(CYGPATH_W) 'src/tests/memalign_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/memalign_unittest.cc'; fi`; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/memalign_unittest-memalign_unittest.Tpo" "$(DEPDIR)/memalign_unittest-memalign_unittest.Po"; else rm -f "$(DEPDIR)/memalign_unittest-memalign_unittest.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/tests/memalign_unittest.cc' object='memalign_unittest-memalign_unittest.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(memalign_unittest_CXXFLAGS) $(CXXFLAGS) -c -o memalign_unittest-memalign_unittest.obj `if test -f 'src/tests/memalign_unittest.cc'; then $(CYGPATH_W) 'src/tests/memalign_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/memalign_unittest.cc'; fi`
profiler1_unittest-profiler_unittest.o: src/tests/profiler_unittest.cc
@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(profiler1_unittest_CXXFLAGS) $(CXXFLAGS) -MT profiler1_unittest-profiler_unittest.o -MD -MP -MF "$(DEPDIR)/profiler1_unittest-profiler_unittest.Tpo" -c -o profiler1_unittest-profiler_unittest.o `test -f 'src/tests/profiler_unittest.cc' || echo '$(srcdir)/'`src/tests/profiler_unittest.cc; \
@@ -1097,6 +1613,48 @@ stacktrace_unittest.obj: src/tests/stacktrace_unittest.cc
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o stacktrace_unittest.obj `if test -f 'src/tests/stacktrace_unittest.cc'; then $(CYGPATH_W) 'src/tests/stacktrace_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/stacktrace_unittest.cc'; fi`
+tcmalloc_large_unittest-tcmalloc_large_unittest.o: src/tests/tcmalloc_large_unittest.cc
+@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_large_unittest_CXXFLAGS) $(CXXFLAGS) -MT tcmalloc_large_unittest-tcmalloc_large_unittest.o -MD -MP -MF "$(DEPDIR)/tcmalloc_large_unittest-tcmalloc_large_unittest.Tpo" -c -o tcmalloc_large_unittest-tcmalloc_large_unittest.o `test -f 'src/tests/tcmalloc_large_unittest.cc' || echo '$(srcdir)/'`src/tests/tcmalloc_large_unittest.cc; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/tcmalloc_large_unittest-tcmalloc_large_unittest.Tpo" "$(DEPDIR)/tcmalloc_large_unittest-tcmalloc_large_unittest.Po"; else rm -f "$(DEPDIR)/tcmalloc_large_unittest-tcmalloc_large_unittest.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/tests/tcmalloc_large_unittest.cc' object='tcmalloc_large_unittest-tcmalloc_large_unittest.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_large_unittest_CXXFLAGS) $(CXXFLAGS) -c -o tcmalloc_large_unittest-tcmalloc_large_unittest.o `test -f 'src/tests/tcmalloc_large_unittest.cc' || echo '$(srcdir)/'`src/tests/tcmalloc_large_unittest.cc
+
+tcmalloc_large_unittest-tcmalloc_large_unittest.obj: src/tests/tcmalloc_large_unittest.cc
+@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_large_unittest_CXXFLAGS) $(CXXFLAGS) -MT tcmalloc_large_unittest-tcmalloc_large_unittest.obj -MD -MP -MF "$(DEPDIR)/tcmalloc_large_unittest-tcmalloc_large_unittest.Tpo" -c -o tcmalloc_large_unittest-tcmalloc_large_unittest.obj `if test -f 'src/tests/tcmalloc_large_unittest.cc'; then $(CYGPATH_W) 'src/tests/tcmalloc_large_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/tcmalloc_large_unittest.cc'; fi`; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/tcmalloc_large_unittest-tcmalloc_large_unittest.Tpo" "$(DEPDIR)/tcmalloc_large_unittest-tcmalloc_large_unittest.Po"; else rm -f "$(DEPDIR)/tcmalloc_large_unittest-tcmalloc_large_unittest.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/tests/tcmalloc_large_unittest.cc' object='tcmalloc_large_unittest-tcmalloc_large_unittest.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_large_unittest_CXXFLAGS) $(CXXFLAGS) -c -o tcmalloc_large_unittest-tcmalloc_large_unittest.obj `if test -f 'src/tests/tcmalloc_large_unittest.cc'; then $(CYGPATH_W) 'src/tests/tcmalloc_large_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/tcmalloc_large_unittest.cc'; fi`
+
+tcmalloc_minimal_large_unittest-tcmalloc_large_unittest.o: src/tests/tcmalloc_large_unittest.cc
+@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_minimal_large_unittest_CXXFLAGS) $(CXXFLAGS) -MT tcmalloc_minimal_large_unittest-tcmalloc_large_unittest.o -MD -MP -MF "$(DEPDIR)/tcmalloc_minimal_large_unittest-tcmalloc_large_unittest.Tpo" -c -o tcmalloc_minimal_large_unittest-tcmalloc_large_unittest.o `test -f 'src/tests/tcmalloc_large_unittest.cc' || echo '$(srcdir)/'`src/tests/tcmalloc_large_unittest.cc; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/tcmalloc_minimal_large_unittest-tcmalloc_large_unittest.Tpo" "$(DEPDIR)/tcmalloc_minimal_large_unittest-tcmalloc_large_unittest.Po"; else rm -f "$(DEPDIR)/tcmalloc_minimal_large_unittest-tcmalloc_large_unittest.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/tests/tcmalloc_large_unittest.cc' object='tcmalloc_minimal_large_unittest-tcmalloc_large_unittest.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_minimal_large_unittest_CXXFLAGS) $(CXXFLAGS) -c -o tcmalloc_minimal_large_unittest-tcmalloc_large_unittest.o `test -f 'src/tests/tcmalloc_large_unittest.cc' || echo '$(srcdir)/'`src/tests/tcmalloc_large_unittest.cc
+
+tcmalloc_minimal_large_unittest-tcmalloc_large_unittest.obj: src/tests/tcmalloc_large_unittest.cc
+@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_minimal_large_unittest_CXXFLAGS) $(CXXFLAGS) -MT tcmalloc_minimal_large_unittest-tcmalloc_large_unittest.obj -MD -MP -MF "$(DEPDIR)/tcmalloc_minimal_large_unittest-tcmalloc_large_unittest.Tpo" -c -o tcmalloc_minimal_large_unittest-tcmalloc_large_unittest.obj `if test -f 'src/tests/tcmalloc_large_unittest.cc'; then $(CYGPATH_W) 'src/tests/tcmalloc_large_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/tcmalloc_large_unittest.cc'; fi`; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/tcmalloc_minimal_large_unittest-tcmalloc_large_unittest.Tpo" "$(DEPDIR)/tcmalloc_minimal_large_unittest-tcmalloc_large_unittest.Po"; else rm -f "$(DEPDIR)/tcmalloc_minimal_large_unittest-tcmalloc_large_unittest.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/tests/tcmalloc_large_unittest.cc' object='tcmalloc_minimal_large_unittest-tcmalloc_large_unittest.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_minimal_large_unittest_CXXFLAGS) $(CXXFLAGS) -c -o tcmalloc_minimal_large_unittest-tcmalloc_large_unittest.obj `if test -f 'src/tests/tcmalloc_large_unittest.cc'; then $(CYGPATH_W) 'src/tests/tcmalloc_large_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/tcmalloc_large_unittest.cc'; fi`
+
+tcmalloc_minimal_unittest-tcmalloc_unittest.o: src/tests/tcmalloc_unittest.cc
+@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_minimal_unittest_CXXFLAGS) $(CXXFLAGS) -MT tcmalloc_minimal_unittest-tcmalloc_unittest.o -MD -MP -MF "$(DEPDIR)/tcmalloc_minimal_unittest-tcmalloc_unittest.Tpo" -c -o tcmalloc_minimal_unittest-tcmalloc_unittest.o `test -f 'src/tests/tcmalloc_unittest.cc' || echo '$(srcdir)/'`src/tests/tcmalloc_unittest.cc; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/tcmalloc_minimal_unittest-tcmalloc_unittest.Tpo" "$(DEPDIR)/tcmalloc_minimal_unittest-tcmalloc_unittest.Po"; else rm -f "$(DEPDIR)/tcmalloc_minimal_unittest-tcmalloc_unittest.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/tests/tcmalloc_unittest.cc' object='tcmalloc_minimal_unittest-tcmalloc_unittest.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_minimal_unittest_CXXFLAGS) $(CXXFLAGS) -c -o tcmalloc_minimal_unittest-tcmalloc_unittest.o `test -f 'src/tests/tcmalloc_unittest.cc' || echo '$(srcdir)/'`src/tests/tcmalloc_unittest.cc
+
+tcmalloc_minimal_unittest-tcmalloc_unittest.obj: src/tests/tcmalloc_unittest.cc
+@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_minimal_unittest_CXXFLAGS) $(CXXFLAGS) -MT tcmalloc_minimal_unittest-tcmalloc_unittest.obj -MD -MP -MF "$(DEPDIR)/tcmalloc_minimal_unittest-tcmalloc_unittest.Tpo" -c -o tcmalloc_minimal_unittest-tcmalloc_unittest.obj `if test -f 'src/tests/tcmalloc_unittest.cc'; then $(CYGPATH_W) 'src/tests/tcmalloc_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/tcmalloc_unittest.cc'; fi`; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/tcmalloc_minimal_unittest-tcmalloc_unittest.Tpo" "$(DEPDIR)/tcmalloc_minimal_unittest-tcmalloc_unittest.Po"; else rm -f "$(DEPDIR)/tcmalloc_minimal_unittest-tcmalloc_unittest.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/tests/tcmalloc_unittest.cc' object='tcmalloc_minimal_unittest-tcmalloc_unittest.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_minimal_unittest_CXXFLAGS) $(CXXFLAGS) -c -o tcmalloc_minimal_unittest-tcmalloc_unittest.obj `if test -f 'src/tests/tcmalloc_unittest.cc'; then $(CYGPATH_W) 'src/tests/tcmalloc_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/tcmalloc_unittest.cc'; fi`
+
tcmalloc_unittest-tcmalloc_unittest.o: src/tests/tcmalloc_unittest.cc
@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_unittest_CXXFLAGS) $(CXXFLAGS) -MT tcmalloc_unittest-tcmalloc_unittest.o -MD -MP -MF "$(DEPDIR)/tcmalloc_unittest-tcmalloc_unittest.Tpo" -c -o tcmalloc_unittest-tcmalloc_unittest.o `test -f 'src/tests/tcmalloc_unittest.cc' || echo '$(srcdir)/'`src/tests/tcmalloc_unittest.cc; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/tcmalloc_unittest-tcmalloc_unittest.Tpo" "$(DEPDIR)/tcmalloc_unittest-tcmalloc_unittest.Po"; else rm -f "$(DEPDIR)/tcmalloc_unittest-tcmalloc_unittest.Tpo"; exit 1; fi
@@ -1111,6 +1669,34 @@ tcmalloc_unittest-tcmalloc_unittest.obj: src/tests/tcmalloc_unittest.cc
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tcmalloc_unittest_CXXFLAGS) $(CXXFLAGS) -c -o tcmalloc_unittest-tcmalloc_unittest.obj `if test -f 'src/tests/tcmalloc_unittest.cc'; then $(CYGPATH_W) 'src/tests/tcmalloc_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/tcmalloc_unittest.cc'; fi`
+thread_dealloc_unittest-thread_dealloc_unittest.o: src/tests/thread_dealloc_unittest.cc
+@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(thread_dealloc_unittest_CXXFLAGS) $(CXXFLAGS) -MT thread_dealloc_unittest-thread_dealloc_unittest.o -MD -MP -MF "$(DEPDIR)/thread_dealloc_unittest-thread_dealloc_unittest.Tpo" -c -o thread_dealloc_unittest-thread_dealloc_unittest.o `test -f 'src/tests/thread_dealloc_unittest.cc' || echo '$(srcdir)/'`src/tests/thread_dealloc_unittest.cc; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/thread_dealloc_unittest-thread_dealloc_unittest.Tpo" "$(DEPDIR)/thread_dealloc_unittest-thread_dealloc_unittest.Po"; else rm -f "$(DEPDIR)/thread_dealloc_unittest-thread_dealloc_unittest.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/tests/thread_dealloc_unittest.cc' object='thread_dealloc_unittest-thread_dealloc_unittest.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(thread_dealloc_unittest_CXXFLAGS) $(CXXFLAGS) -c -o thread_dealloc_unittest-thread_dealloc_unittest.o `test -f 'src/tests/thread_dealloc_unittest.cc' || echo '$(srcdir)/'`src/tests/thread_dealloc_unittest.cc
+
+thread_dealloc_unittest-thread_dealloc_unittest.obj: src/tests/thread_dealloc_unittest.cc
+@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(thread_dealloc_unittest_CXXFLAGS) $(CXXFLAGS) -MT thread_dealloc_unittest-thread_dealloc_unittest.obj -MD -MP -MF "$(DEPDIR)/thread_dealloc_unittest-thread_dealloc_unittest.Tpo" -c -o thread_dealloc_unittest-thread_dealloc_unittest.obj `if test -f 'src/tests/thread_dealloc_unittest.cc'; then $(CYGPATH_W) 'src/tests/thread_dealloc_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/thread_dealloc_unittest.cc'; fi`; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/thread_dealloc_unittest-thread_dealloc_unittest.Tpo" "$(DEPDIR)/thread_dealloc_unittest-thread_dealloc_unittest.Po"; else rm -f "$(DEPDIR)/thread_dealloc_unittest-thread_dealloc_unittest.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/tests/thread_dealloc_unittest.cc' object='thread_dealloc_unittest-thread_dealloc_unittest.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(thread_dealloc_unittest_CXXFLAGS) $(CXXFLAGS) -c -o thread_dealloc_unittest-thread_dealloc_unittest.obj `if test -f 'src/tests/thread_dealloc_unittest.cc'; then $(CYGPATH_W) 'src/tests/thread_dealloc_unittest.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/thread_dealloc_unittest.cc'; fi`
+
+thread_dealloc_unittest-testutil.o: src/tests/testutil.cc
+@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(thread_dealloc_unittest_CXXFLAGS) $(CXXFLAGS) -MT thread_dealloc_unittest-testutil.o -MD -MP -MF "$(DEPDIR)/thread_dealloc_unittest-testutil.Tpo" -c -o thread_dealloc_unittest-testutil.o `test -f 'src/tests/testutil.cc' || echo '$(srcdir)/'`src/tests/testutil.cc; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/thread_dealloc_unittest-testutil.Tpo" "$(DEPDIR)/thread_dealloc_unittest-testutil.Po"; else rm -f "$(DEPDIR)/thread_dealloc_unittest-testutil.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/tests/testutil.cc' object='thread_dealloc_unittest-testutil.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(thread_dealloc_unittest_CXXFLAGS) $(CXXFLAGS) -c -o thread_dealloc_unittest-testutil.o `test -f 'src/tests/testutil.cc' || echo '$(srcdir)/'`src/tests/testutil.cc
+
+thread_dealloc_unittest-testutil.obj: src/tests/testutil.cc
+@am__fastdepCXX_TRUE@ if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(thread_dealloc_unittest_CXXFLAGS) $(CXXFLAGS) -MT thread_dealloc_unittest-testutil.obj -MD -MP -MF "$(DEPDIR)/thread_dealloc_unittest-testutil.Tpo" -c -o thread_dealloc_unittest-testutil.obj `if test -f 'src/tests/testutil.cc'; then $(CYGPATH_W) 'src/tests/testutil.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/testutil.cc'; fi`; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/thread_dealloc_unittest-testutil.Tpo" "$(DEPDIR)/thread_dealloc_unittest-testutil.Po"; else rm -f "$(DEPDIR)/thread_dealloc_unittest-testutil.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='src/tests/testutil.cc' object='thread_dealloc_unittest-testutil.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(thread_dealloc_unittest_CXXFLAGS) $(CXXFLAGS) -c -o thread_dealloc_unittest-testutil.obj `if test -f 'src/tests/testutil.cc'; then $(CYGPATH_W) 'src/tests/testutil.cc'; else $(CYGPATH_W) '$(srcdir)/src/tests/testutil.cc'; fi`
+
mostlyclean-libtool:
-rm -f *.lo
@@ -1341,7 +1927,7 @@ check-TESTS: $(TESTS)
distdir: $(DISTFILES)
$(am__remove_distdir)
mkdir $(distdir)
- $(mkdir_p) $(distdir)/doc $(distdir)/packages $(distdir)/packages/rpm $(distdir)/src $(distdir)/src/google $(distdir)/src/google/perftools $(distdir)/src/tests
+ $(mkdir_p) $(distdir)/doc $(distdir)/packages $(distdir)/packages/rpm $(distdir)/src $(distdir)/src/google $(distdir)/src/google/perftools $(distdir)/src/solaris $(distdir)/src/tests
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
@@ -1503,7 +2089,7 @@ maintainer-clean-generic:
clean: clean-am
clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
- clean-noinstPROGRAMS mostlyclean-am
+ clean-noinstLTLIBRARIES clean-noinstPROGRAMS mostlyclean-am
distclean: distclean-am
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
@@ -1562,12 +2148,12 @@ uninstall-man: uninstall-man1
.PHONY: CTAGS GTAGS all all-am am--refresh check check-TESTS check-am \
clean clean-generic clean-libLTLIBRARIES clean-libtool \
- clean-noinstPROGRAMS ctags dist dist-all dist-bzip2 dist-gzip \
- dist-shar dist-tarZ dist-zip distcheck distclean \
- distclean-compile distclean-generic distclean-hdr \
- distclean-libtool distclean-tags distcleancheck distdir \
- distuninstallcheck dvi dvi-am html html-am info info-am \
- install install-am install-binSCRIPTS install-data \
+ clean-noinstLTLIBRARIES clean-noinstPROGRAMS ctags dist \
+ dist-all dist-bzip2 dist-gzip dist-shar dist-tarZ dist-zip \
+ distcheck distclean distclean-compile distclean-generic \
+ distclean-hdr distclean-libtool distclean-tags distcleancheck \
+ distdir distuninstallcheck dvi dvi-am html html-am info \
+ info-am install install-am install-binSCRIPTS install-data \
install-data-am install-dist_docDATA install-exec \
install-exec-am install-googleincludeHEADERS install-info \
install-info-am install-libLTLIBRARIES install-man \
@@ -1580,10 +2166,16 @@ uninstall-man: uninstall-man1
uninstall-info-am uninstall-libLTLIBRARIES uninstall-man \
uninstall-man1 uninstall-perftoolsincludeHEADERS
-profiler_unittest: $(PROFILER_UNITTESTS)
- $(top_srcdir)/src/tests/profiler_unittest.sh . $(top_srcdir)/src
-heap-checker-death_unittest:
- PPROF_PATH=$(top_srcdir)/src/pprof sh $(top_srcdir)/src/tests/heap-checker-death_unittest.sh
+pprof_unittest: $(top_srcdir)/src/pprof
+ $< -test
+heap-profiler_unittest.sh: $(heap_profiler_unittest_sh_SOURCES)
+ cp -a $(heap_profiler_unittest_sh_SOURCES) $@
+heap-checker_unittest.sh: $(heap_checker_unittest_sh_SOURCES)
+ cp -a $(heap_checker_unittest_sh_SOURCES) $@
+heap-checker-death_unittest.sh: $(heap_checker_death_unittest_sh_SOURCES)
+ cp -a $(heap_checker_death_unittest_sh_SOURCES) $@
+profiler_unittest.sh: $(profiler_unittest_sh_SOURCES)
+ cp -a $(profiler_unittest_sh_SOURCES) $@
rpm: dist-gzip packages/rpm.sh packages/rpm/rpm.spec
@cd packages && ./rpm.sh ${PACKAGE} ${VERSION}
diff --git a/README b/README
index ea7edea..c4471d4 100644
--- a/README
+++ b/README
@@ -1,3 +1,9 @@
+IMPORTANT NOTE FOR 64-BIT USERS
+-------------------------------
+There are known issues with some perftools functionality on x86_64
+systems. See 64-BIT ISSUES, below.
+
+
CPU PROFILER
------------
See doc/cpu-profiler.html for information about how to use the CPU
@@ -68,13 +74,6 @@ Other values for HEAPCHECK: normal (equivalent to "1"), strict, draconian
You can also use LD_PRELOAD to heap-check an executable that you
didn't compile.
-IMPORTANT NOTE: pthreads handling is currently incomplete. Heap leak
-checks will fail with bogus leaks if there are pthreads live at
-construction or leak checking time. One solution, for global
-heap-checking, is to make sure all threads but the main thread have
-exited at program-end time. We hope (as of March 2005) to have a fix
-soon.
-
ENVIRONMENT VARIABLES
---------------------
@@ -87,6 +86,8 @@ The easiest way to turn them on is by setting the appropriate
environment variables. We have several variables that let you
enable/disable features as well as tweak parameters.
+Here are some of the most important variables:
+
CPUPROFILE=<file> -- turns on cpu profiling and dumps data to this file.
PROFILESELECTED=1 -- if set, cpu-profiler will only profile regions of code
surrounded with ProfilerEnable()/ProfilerDisable().
@@ -98,5 +99,80 @@ HEAPCHECK=<type> -- turns on heap checking with strictness 'type'
TCMALLOC_DEBUG=<level> -- the higher level, the more messages malloc emits
MALLOCSTATS=<level> -- prints memory-use stats at program-exit
+For a full list of variables, see the documentation pages:
+ doc/cpuprofile.html
+ doc/heapprofile.html
+ doc/heap_checker.html
+
+
+COMPILING ON NON-LINUX SYSTEMS
+------------------------------
+
+Perftools was developed and tested on x86 Linux systems, and it works
+in its full generality only on those systems. However, we've
+successfully built and tested the core tcmalloc library
+(tcmalloc_minimal) on both FreeBSD and Solaris x86. See INSTALL for
+details.
+
+
+64-BIT ISSUES
+-------------
+
+There are two issues that can cause program hangs or crashes on x86_64
+64-bit systems, which use the libunwind library to get stack-traces.
+Neither issue should affect the core tcmalloc library; they both
+affect the perftools tools such as cpu-profiler, heap-checker, and
+heap-profiler.
+
+1) Some libc's -- at least glibc 2.4 on x86_64 -- have a bug where the
+libc function dl_iterate_phdr() acquires its locks in the wrong
+order. This bug should not affect tcmalloc, but may cause occasional
+deadlock with the cpu-profiler, heap-profiler, and heap-checker.
+Its likeliness increases the more dlopen() commands an executable has.
+Most executables don't have any, though several library routines like
+getgrgid() call dlopen() behind the scnees.
+
+2) On x86-64 64-bit systems, while tcmalloc itself works fine, the
+cpu-profiler tool is unreliable: it will sometimes work, but sometimes
+cause a segfault. I'll explain the problem first, and then some
+workarounds.
+
+Note that this only affects the cpu-profiler, which is a
+google-perftools featuure you must turn on manually by setting the
+CPUPROFILE environment variable. If you do not turn on cpu-profiling,
+you shouldn't see any crashes due to perftools.
+
+The gory details: The underlying problem is in the backtrace()
+function, which is a built-in function in libc. (However, we
+*strongly* recommend for x86-64, that you use the libunwind
+functionality for backtraces instead; see the top of INSTALL.)
+Backtracing is fairly straightforward in the normal case, but can run
+into problems when having to backtrace across a signal frame.
+Unfortunately, the cpu-profiler uses signals in order to register a
+profiling event, so every backtrace that the profiler does crosses a
+signal frame.
+
+In our experience, the only time there is trouble is when the signal
+fires in the middle of pthread_mutex_lock. pthread_mutex_lock is
+called quite a bit from system libraries, particular at program
+startup and when creating a new thread.
+
+The solution: The dwarf debugging format has support for 'cfi
+annotations', which make it easy to recognize a signal frame. Some OS
+distributions, such as Fedora and gentoo 2007.0, already have added
+cfi annotations to their libc. A future version of libunwind should
+recognize these annotations; these systems should not see any
+crashses.
+
+Workarounds: If you see problems with crashes when running the
+cpu-profiler, consider inserting ProfilerStart()/ProfilerStop() into
+your code, rather than setting CPUPROFILE. This will profile only
+those sections of the codebase. Though we haven't done much testing,
+in theory this should reduce the chance of crashes by limiting the
+signal generation to only a small part of the codebase. Ideally, you
+would not use ProfilerStart()/ProfilerStop() around code that spawns
+new threads, or is otherwise likely to cause a call to
+pthread_mutex_lock!
+
---
-16 March 2005
+12 April 2007
diff --git a/TODO b/TODO
index 929f802..9a6457e 100644
--- a/TODO
+++ b/TODO
@@ -8,8 +8,7 @@ HEAP PROFILER
see object-level leaks.
2) Remove dependency on tcmalloc?
3) Port to non-linux O/Ses (right now code uses /proc for library info)
-4) Port to non-x86 architectures (locking code in internal_spinlock is
- x86-specific)
+4) Port to non-x86 architectures (locking code in spinlock is x86-specific)
5) Port to C?
6) Figure out how to get setenv() to work properly before main() in
shared libaries, and get rid of the profile-naming hack once we
@@ -18,11 +17,9 @@ HEAP PROFILER
HEAP CHECKER
-[1) Uses heap profiler, so its TODOs apply here as well]
-2) Remove requirement that the heap-checker must be linked last into
+1) Remove requirement that the heap-checker must be linked last into
an application (hard! -- it needs its global constructor to run
first)
-3) Improve heap_checker.html documentation.
TCMALLOC
@@ -32,12 +29,15 @@ TCMALLOC
3) Return memory to the system when requirements drop
4) Explore coloring allocated objects to avoid cache conflicts
5) Explore biasing reclamation to larger addresses
+6) Add contention stats to a synchronization.cc (can do spinlocks,
+ but threads? -- may have to provide our own thread implementation)
CPU PROFILER
1) Figure out how to get setenv() to work properly before main() in
shared libaries(), and get rid of the profile-naming hack once we
- do. (See ProfileData::ProfileData().)
+ do. (See Profiler::GetUniquePathFromEnv().)
+2) Resolve crashing problems on x86_64 (see README)
STACKTRACE
@@ -45,4 +45,4 @@ STACKTRACE
2) Remove dependency on linux/x86
---
-20 May 2005
+4 April 2007
diff --git a/aclocal.m4 b/aclocal.m4
index d98f614..0f44a4e 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -1,7 +1,7 @@
-# aclocal.m4 generated automatically by aclocal 1.6.3 -*- Autoconf -*-
+# generated automatically by aclocal 1.9.6 -*- Autoconf -*-
-# Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002
-# Free Software Foundation, Inc.
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+# 2005 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@@ -11,832 +11,9 @@
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
-# Do all the work for Automake. -*- Autoconf -*-
-
-# This macro actually does too much some checks are only needed if
-# your package does certain things. But this isn't really a big deal.
-
-# Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002
-# Free Software Foundation, Inc.
-
-# 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 Free Software Foundation; either version 2, or (at your option)
-# any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-# 02111-1307, USA.
-
-# serial 8
-
-# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
-# written in clear, in which case automake, when reading aclocal.m4,
-# will think it sees a *use*, and therefore will trigger all it's
-# C support machinery. Also note that it means that autoscan, seeing
-# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
-
-
-AC_PREREQ([2.52])
-
-# Autoconf 2.50 wants to disallow AM_ names. We explicitly allow
-# the ones we care about.
-m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
-
-# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
-# AM_INIT_AUTOMAKE([OPTIONS])
-# -----------------------------------------------
-# The call with PACKAGE and VERSION arguments is the old style
-# call (pre autoconf-2.50), which is being phased out. PACKAGE
-# and VERSION should now be passed to AC_INIT and removed from
-# the call to AM_INIT_AUTOMAKE.
-# We support both call styles for the transition. After
-# the next Automake release, Autoconf can make the AC_INIT
-# arguments mandatory, and then we can depend on a new Autoconf
-# release and drop the old call support.
-AC_DEFUN([AM_INIT_AUTOMAKE],
-[AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
- AC_REQUIRE([AC_PROG_INSTALL])dnl
-# test to see if srcdir already configured
-if test "`cd $srcdir && pwd`" != "`pwd`" &&
- test -f $srcdir/config.status; then
- AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
-fi
-
-# Define the identity of the package.
-dnl Distinguish between old-style and new-style calls.
-m4_ifval([$2],
-[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
- AC_SUBST([PACKAGE], [$1])dnl
- AC_SUBST([VERSION], [$2])],
-[_AM_SET_OPTIONS([$1])dnl
- AC_SUBST([PACKAGE], [AC_PACKAGE_TARNAME])dnl
- AC_SUBST([VERSION], [AC_PACKAGE_VERSION])])dnl
-
-_AM_IF_OPTION([no-define],,
-[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
- AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
-
-# Some tools Automake needs.
-AC_REQUIRE([AM_SANITY_CHECK])dnl
-AC_REQUIRE([AC_ARG_PROGRAM])dnl
-AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
-AM_MISSING_PROG(AUTOCONF, autoconf)
-AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
-AM_MISSING_PROG(AUTOHEADER, autoheader)
-AM_MISSING_PROG(MAKEINFO, makeinfo)
-AM_MISSING_PROG(AMTAR, tar)
-AM_PROG_INSTALL_SH
-AM_PROG_INSTALL_STRIP
-# We need awk for the "check" target. The system "awk" is bad on
-# some platforms.
-AC_REQUIRE([AC_PROG_AWK])dnl
-AC_REQUIRE([AC_PROG_MAKE_SET])dnl
-
-_AM_IF_OPTION([no-dependencies],,
-[AC_PROVIDE_IFELSE([AC_PROG_][CC],
- [_AM_DEPENDENCIES(CC)],
- [define([AC_PROG_][CC],
- defn([AC_PROG_][CC])[_AM_DEPENDENCIES(CC)])])dnl
-AC_PROVIDE_IFELSE([AC_PROG_][CXX],
- [_AM_DEPENDENCIES(CXX)],
- [define([AC_PROG_][CXX],
- defn([AC_PROG_][CXX])[_AM_DEPENDENCIES(CXX)])])dnl
-])
-])
-
-# Copyright 2002 Free Software Foundation, Inc.
-
-# 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 Free Software Foundation; either version 2, or (at your option)
-# any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-
-# AM_AUTOMAKE_VERSION(VERSION)
-# ----------------------------
-# Automake X.Y traces this macro to ensure aclocal.m4 has been
-# generated from the m4 files accompanying Automake X.Y.
-AC_DEFUN([AM_AUTOMAKE_VERSION],[am__api_version="1.6"])
-
-# AM_SET_CURRENT_AUTOMAKE_VERSION
-# -------------------------------
-# Call AM_AUTOMAKE_VERSION so it can be traced.
-# This function is AC_REQUIREd by AC_INIT_AUTOMAKE.
-AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
- [AM_AUTOMAKE_VERSION([1.6.3])])
-
-# Helper functions for option handling. -*- Autoconf -*-
-
-# Copyright 2001, 2002 Free Software Foundation, Inc.
-
-# 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 Free Software Foundation; either version 2, or (at your option)
-# any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-# 02111-1307, USA.
-
-# serial 2
-
-# _AM_MANGLE_OPTION(NAME)
-# -----------------------
-AC_DEFUN([_AM_MANGLE_OPTION],
-[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
-
-# _AM_SET_OPTION(NAME)
-# ------------------------------
-# Set option NAME. Presently that only means defining a flag for this option.
-AC_DEFUN([_AM_SET_OPTION],
-[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
-
-# _AM_SET_OPTIONS(OPTIONS)
-# ----------------------------------
-# OPTIONS is a space-separated list of Automake options.
-AC_DEFUN([_AM_SET_OPTIONS],
-[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
-
-# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
-# -------------------------------------------
-# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
-AC_DEFUN([_AM_IF_OPTION],
-[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
-
-#
-# Check to make sure that the build environment is sane.
-#
-
-# Copyright 1996, 1997, 2000, 2001 Free Software Foundation, Inc.
-
-# 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 Free Software Foundation; either version 2, or (at your option)
-# any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-# 02111-1307, USA.
-
-# serial 3
-
-# AM_SANITY_CHECK
-# ---------------
-AC_DEFUN([AM_SANITY_CHECK],
-[AC_MSG_CHECKING([whether build environment is sane])
-# Just in case
-sleep 1
-echo timestamp > conftest.file
-# Do `set' in a subshell so we don't clobber the current shell's
-# arguments. Must try -L first in case configure is actually a
-# symlink; some systems play weird games with the mod time of symlinks
-# (eg FreeBSD returns the mod time of the symlink's containing
-# directory).
-if (
- set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null`
- if test "$[*]" = "X"; then
- # -L didn't work.
- set X `ls -t $srcdir/configure conftest.file`
- fi
- rm -f conftest.file
- if test "$[*]" != "X $srcdir/configure conftest.file" \
- && test "$[*]" != "X conftest.file $srcdir/configure"; then
-
- # If neither matched, then we have a broken ls. This can happen
- # if, for instance, CONFIG_SHELL is bash and it inherits a
- # broken ls alias from the environment. This has actually
- # happened. Such a system could not be considered "sane".
- AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
-alias in your environment])
- fi
-
- test "$[2]" = conftest.file
- )
-then
- # Ok.
- :
-else
- AC_MSG_ERROR([newly created file is older than distributed files!
-Check your system clock])
-fi
-AC_MSG_RESULT(yes)])
-
-# -*- Autoconf -*-
-
-
-# Copyright 1997, 1999, 2000, 2001 Free Software Foundation, Inc.
-
-# 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 Free Software Foundation; either version 2, or (at your option)
-# any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-# 02111-1307, USA.
-
-# serial 3
-
-# AM_MISSING_PROG(NAME, PROGRAM)
-# ------------------------------
-AC_DEFUN([AM_MISSING_PROG],
-[AC_REQUIRE([AM_MISSING_HAS_RUN])
-$1=${$1-"${am_missing_run}$2"}
-AC_SUBST($1)])
-
-
-# AM_MISSING_HAS_RUN
-# ------------------
-# Define MISSING if not defined so far and test if it supports --run.
-# If it does, set am_missing_run to use it, otherwise, to nothing.
-AC_DEFUN([AM_MISSING_HAS_RUN],
-[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
-test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing"
-# Use eval to expand $SHELL
-if eval "$MISSING --run true"; then
- am_missing_run="$MISSING --run "
-else
- am_missing_run=
- AC_MSG_WARN([`missing' script is too old or missing])
-fi
-])
-
-# AM_AUX_DIR_EXPAND
-
-# Copyright 2001 Free Software Foundation, Inc.
-
-# 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 Free Software Foundation; either version 2, or (at your option)
-# any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-# 02111-1307, USA.
-
-# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
-# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
-# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
-#
-# Of course, Automake must honor this variable whenever it calls a
-# tool from the auxiliary directory. The problem is that $srcdir (and
-# therefore $ac_aux_dir as well) can be either absolute or relative,
-# depending on how configure is run. This is pretty annoying, since
-# it makes $ac_aux_dir quite unusable in subdirectories: in the top
-# source directory, any form will work fine, but in subdirectories a
-# relative path needs to be adjusted first.
-#
-# $ac_aux_dir/missing
-# fails when called from a subdirectory if $ac_aux_dir is relative
-# $top_srcdir/$ac_aux_dir/missing
-# fails if $ac_aux_dir is absolute,
-# fails when called from a subdirectory in a VPATH build with
-# a relative $ac_aux_dir
-#
-# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
-# are both prefixed by $srcdir. In an in-source build this is usually
-# harmless because $srcdir is `.', but things will broke when you
-# start a VPATH build or use an absolute $srcdir.
-#
-# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
-# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
-# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
-# and then we would define $MISSING as
-# MISSING="\${SHELL} $am_aux_dir/missing"
-# This will work as long as MISSING is not called from configure, because
-# unfortunately $(top_srcdir) has no meaning in configure.
-# However there are other variables, like CC, which are often used in
-# configure, and could therefore not use this "fixed" $ac_aux_dir.
-#
-# Another solution, used here, is to always expand $ac_aux_dir to an
-# absolute PATH. The drawback is that using absolute paths prevent a
-# configured tree to be moved without reconfiguration.
-
-# Rely on autoconf to set up CDPATH properly.
-AC_PREREQ([2.50])
-
-AC_DEFUN([AM_AUX_DIR_EXPAND], [
-# expand $ac_aux_dir to an absolute path
-am_aux_dir=`cd $ac_aux_dir && pwd`
-])
-
-# AM_PROG_INSTALL_SH
-# ------------------
-# Define $install_sh.
-
-# Copyright 2001 Free Software Foundation, Inc.
-
-# 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 Free Software Foundation; either version 2, or (at your option)
-# any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-# 02111-1307, USA.
-
-AC_DEFUN([AM_PROG_INSTALL_SH],
-[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
-install_sh=${install_sh-"$am_aux_dir/install-sh"}
-AC_SUBST(install_sh)])
-
-# AM_PROG_INSTALL_STRIP
-
-# Copyright 2001 Free Software Foundation, Inc.
-
-# 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 Free Software Foundation; either version 2, or (at your option)
-# any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-# 02111-1307, USA.
-
-# One issue with vendor `install' (even GNU) is that you can't
-# specify the program used to strip binaries. This is especially
-# annoying in cross-compiling environments, where the build's strip
-# is unlikely to handle the host's binaries.
-# Fortunately install-sh will honor a STRIPPROG variable, so we
-# always use install-sh in `make install-strip', and initialize
-# STRIPPROG with the value of the STRIP variable (set by the user).
-AC_DEFUN([AM_PROG_INSTALL_STRIP],
-[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
-# Installed binaries are usually stripped using `strip' when the user
-# run `make install-strip'. However `strip' might not be the right
-# tool to use in cross-compilation environments, therefore Automake
-# will honor the `STRIP' environment variable to overrule this program.
-dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
-if test "$cross_compiling" != no; then
- AC_CHECK_TOOL([STRIP], [strip], :)
-fi
-INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s"
-AC_SUBST([INSTALL_STRIP_PROGRAM])])
-
-# serial 4 -*- Autoconf -*-
-
-# Copyright 1999, 2000, 2001 Free Software Foundation, Inc.
-
-# 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 Free Software Foundation; either version 2, or (at your option)
-# any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-# 02111-1307, USA.
-
-
-# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
-# written in clear, in which case automake, when reading aclocal.m4,
-# will think it sees a *use*, and therefore will trigger all it's
-# C support machinery. Also note that it means that autoscan, seeing
-# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
-
-
-
-# _AM_DEPENDENCIES(NAME)
-# ----------------------
-# See how the compiler implements dependency checking.
-# NAME is "CC", "CXX", "GCJ", or "OBJC".
-# We try a few techniques and use that to set a single cache variable.
-#
-# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
-# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
-# dependency, and given that the user is not expected to run this macro,
-# just rely on AC_PROG_CC.
-AC_DEFUN([_AM_DEPENDENCIES],
-[AC_REQUIRE([AM_SET_DEPDIR])dnl
-AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
-AC_REQUIRE([AM_MAKE_INCLUDE])dnl
-AC_REQUIRE([AM_DEP_TRACK])dnl
-
-ifelse([$1], CC, [depcc="$CC" am_compiler_list=],
- [$1], CXX, [depcc="$CXX" am_compiler_list=],
- [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
- [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
- [depcc="$$1" am_compiler_list=])
-
-AC_CACHE_CHECK([dependency style of $depcc],
- [am_cv_$1_dependencies_compiler_type],
-[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
- # We make a subdir and do the tests there. Otherwise we can end up
- # making bogus files that we don't know about and never remove. For
- # instance it was reported that on HP-UX the gcc test will end up
- # making a dummy file named `D' -- because `-MD' means `put the output
- # in D'.
- mkdir conftest.dir
- # Copy depcomp to subdir because otherwise we won't find it if we're
- # using a relative directory.
- cp "$am_depcomp" conftest.dir
- cd conftest.dir
-
- am_cv_$1_dependencies_compiler_type=none
- if test "$am_compiler_list" = ""; then
- am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
- fi
- for depmode in $am_compiler_list; do
- # We need to recreate these files for each test, as the compiler may
- # overwrite some of them when testing with obscure command lines.
- # This happens at least with the AIX C compiler.
- echo '#include "conftest.h"' > conftest.c
- echo 'int i;' > conftest.h
- echo "${am__include} ${am__quote}conftest.Po${am__quote}" > confmf
-
- case $depmode in
- nosideeffect)
- # after this tag, mechanisms are not by side-effect, so they'll
- # only be used when explicitly requested
- if test "x$enable_dependency_tracking" = xyes; then
- continue
- else
- break
- fi
- ;;
- none) break ;;
- esac
- # We check with `-c' and `-o' for the sake of the "dashmstdout"
- # mode. It turns out that the SunPro C++ compiler does not properly
- # handle `-M -o', and we need to detect this.
- if depmode=$depmode \
- source=conftest.c object=conftest.o \
- depfile=conftest.Po tmpdepfile=conftest.TPo \
- $SHELL ./depcomp $depcc -c conftest.c -o conftest.o >/dev/null 2>&1 &&
- grep conftest.h conftest.Po > /dev/null 2>&1 &&
- ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
- am_cv_$1_dependencies_compiler_type=$depmode
- break
- fi
- done
-
- cd ..
- rm -rf conftest.dir
-else
- am_cv_$1_dependencies_compiler_type=none
-fi
-])
-AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
-])
-
-
-# AM_SET_DEPDIR
-# -------------
-# Choose a directory name for dependency files.
-# This macro is AC_REQUIREd in _AM_DEPENDENCIES
-AC_DEFUN([AM_SET_DEPDIR],
-[rm -f .deps 2>/dev/null
-mkdir .deps 2>/dev/null
-if test -d .deps; then
- DEPDIR=.deps
-else
- # MS-DOS does not allow filenames that begin with a dot.
- DEPDIR=_deps
-fi
-rmdir .deps 2>/dev/null
-AC_SUBST([DEPDIR])
-])
-
-
-# AM_DEP_TRACK
-# ------------
-AC_DEFUN([AM_DEP_TRACK],
-[AC_ARG_ENABLE(dependency-tracking,
-[ --disable-dependency-tracking Speeds up one-time builds
- --enable-dependency-tracking Do not reject slow dependency extractors])
-if test "x$enable_dependency_tracking" != xno; then
- am_depcomp="$ac_aux_dir/depcomp"
- AMDEPBACKSLASH='\'
-fi
-AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
-AC_SUBST([AMDEPBACKSLASH])
-])
-
-# Generate code to set up dependency tracking. -*- Autoconf -*-
-
-# Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
-
-# 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 Free Software Foundation; either version 2, or (at your option)
-# any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-# 02111-1307, USA.
-
-#serial 2
-
-# _AM_OUTPUT_DEPENDENCY_COMMANDS
-# ------------------------------
-AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
-[for mf in $CONFIG_FILES; do
- # Strip MF so we end up with the name of the file.
- mf=`echo "$mf" | sed -e 's/:.*$//'`
- # Check whether this is an Automake generated Makefile or not.
- # We used to match only the files named `Makefile.in', but
- # some people rename them; so instead we look at the file content.
- # Grep'ing the first line is not enough: some people post-process
- # each Makefile.in and add a new line on top of each file to say so.
- # So let's grep whole file.
- if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then
- dirpart=`AS_DIRNAME("$mf")`
- else
- continue
- fi
- grep '^DEP_FILES *= *[[^ @%:@]]' < "$mf" > /dev/null || continue
- # Extract the definition of DEP_FILES from the Makefile without
- # running `make'.
- DEPDIR=`sed -n -e '/^DEPDIR = / s///p' < "$mf"`
- test -z "$DEPDIR" && continue
- # When using ansi2knr, U may be empty or an underscore; expand it
- U=`sed -n -e '/^U = / s///p' < "$mf"`
- test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR"
- # We invoke sed twice because it is the simplest approach to
- # changing $(DEPDIR) to its actual value in the expansion.
- for file in `sed -n -e '
- /^DEP_FILES = .*\\\\$/ {
- s/^DEP_FILES = //
- :loop
- s/\\\\$//
- p
- n
- /\\\\$/ b loop
- p
- }
- /^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \
- sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
- # Make sure the directory exists.
- test -f "$dirpart/$file" && continue
- fdir=`AS_DIRNAME(["$file"])`
- AS_MKDIR_P([$dirpart/$fdir])
- # echo "creating $dirpart/$file"
- echo '# dummy' > "$dirpart/$file"
- done
-done
-])# _AM_OUTPUT_DEPENDENCY_COMMANDS
-
-
-# AM_OUTPUT_DEPENDENCY_COMMANDS
-# -----------------------------
-# This macro should only be invoked once -- use via AC_REQUIRE.
-#
-# This code is only required when automatic dependency tracking
-# is enabled. FIXME. This creates each `.P' file that we will
-# need in order to bootstrap the dependency handling code.
-AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
-[AC_CONFIG_COMMANDS([depfiles],
- [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
- [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
-])
-
-# Copyright 2001 Free Software Foundation, Inc. -*- Autoconf -*-
-
-# 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 Free Software Foundation; either version 2, or (at your option)
-# any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-# 02111-1307, USA.
-
-# serial 2
-
-# AM_MAKE_INCLUDE()
-# -----------------
-# Check to see how make treats includes.
-AC_DEFUN([AM_MAKE_INCLUDE],
-[am_make=${MAKE-make}
-cat > confinc << 'END'
-doit:
- @echo done
-END
-# If we don't find an include directive, just comment out the code.
-AC_MSG_CHECKING([for style of include used by $am_make])
-am__include="#"
-am__quote=
-_am_result=none
-# First try GNU make style include.
-echo "include confinc" > confmf
-# We grep out `Entering directory' and `Leaving directory'
-# messages which can occur if `w' ends up in MAKEFLAGS.
-# In particular we don't look at `^make:' because GNU make might
-# be invoked under some other name (usually "gmake"), in which
-# case it prints its new name instead of `make'.
-if test "`$am_make -s -f confmf 2> /dev/null | fgrep -v 'ing directory'`" = "done"; then
- am__include=include
- am__quote=
- _am_result=GNU
-fi
-# Now try BSD make style include.
-if test "$am__include" = "#"; then
- echo '.include "confinc"' > confmf
- if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then
- am__include=.include
- am__quote="\""
- _am_result=BSD
- fi
-fi
-AC_SUBST(am__include)
-AC_SUBST(am__quote)
-AC_MSG_RESULT($_am_result)
-rm -f confinc confmf
-])
-
-# AM_CONDITIONAL -*- Autoconf -*-
-
-# Copyright 1997, 2000, 2001 Free Software Foundation, Inc.
-
-# 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 Free Software Foundation; either version 2, or (at your option)
-# any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-# 02111-1307, USA.
-
-# serial 5
-
-AC_PREREQ(2.52)
-
-# AM_CONDITIONAL(NAME, SHELL-CONDITION)
-# -------------------------------------
-# Define a conditional.
-AC_DEFUN([AM_CONDITIONAL],
-[ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
- [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
-AC_SUBST([$1_TRUE])
-AC_SUBST([$1_FALSE])
-if $2; then
- $1_TRUE=
- $1_FALSE='#'
-else
- $1_TRUE='#'
- $1_FALSE=
-fi
-AC_CONFIG_COMMANDS_PRE(
-[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
- AC_MSG_ERROR([conditional \"$1\" was never defined.
-Usually this means the macro was only invoked conditionally.])
-fi])])
-
-# Like AC_CONFIG_HEADER, but automatically create stamp file. -*- Autoconf -*-
-
-# Copyright 1996, 1997, 2000, 2001 Free Software Foundation, Inc.
-
-# 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 Free Software Foundation; either version 2, or (at your option)
-# any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-# 02111-1307, USA.
-
-AC_PREREQ([2.52])
-
-# serial 6
-
-# When config.status generates a header, we must update the stamp-h file.
-# This file resides in the same directory as the config header
-# that is generated. We must strip everything past the first ":",
-# and everything past the last "/".
-
-# _AM_DIRNAME(PATH)
-# -----------------
-# Like AS_DIRNAME, only do it during macro expansion
-AC_DEFUN([_AM_DIRNAME],
- [m4_if(regexp([$1], [^.*[^/]//*[^/][^/]*/*$]), -1,
- m4_if(regexp([$1], [^//\([^/]\|$\)]), -1,
- m4_if(regexp([$1], [^/.*]), -1,
- [.],
- patsubst([$1], [^\(/\).*], [\1])),
- patsubst([$1], [^\(//\)\([^/].*\|$\)], [\1])),
- patsubst([$1], [^\(.*[^/]\)//*[^/][^/]*/*$], [\1]))[]dnl
-])# _AM_DIRNAME
-
-
-# The stamp files are numbered to have different names.
-# We could number them on a directory basis, but that's additional
-# complications, let's have a unique counter.
-m4_define([_AM_STAMP_Count], [0])
-
-
-# _AM_STAMP(HEADER)
-# -----------------
-# The name of the stamp file for HEADER.
-AC_DEFUN([_AM_STAMP],
-[m4_define([_AM_STAMP_Count], m4_incr(_AM_STAMP_Count))dnl
-AS_ESCAPE(_AM_DIRNAME(patsubst([$1],
- [:.*])))/stamp-h[]_AM_STAMP_Count])
-
-
-# _AM_CONFIG_HEADER(HEADER[:SOURCES], COMMANDS, INIT-COMMANDS)
-# ------------------------------------------------------------
-# We used to try to get a real timestamp in stamp-h. But the fear is that
-# that will cause unnecessary cvs conflicts.
-AC_DEFUN([_AM_CONFIG_HEADER],
-[# Add the stamp file to the list of files AC keeps track of,
-# along with our hook.
-AC_CONFIG_HEADERS([$1],
- [# update the timestamp
-echo 'timestamp for $1' >"_AM_STAMP([$1])"
-$2],
- [$3])
-])# _AM_CONFIG_HEADER
-
-
-# AM_CONFIG_HEADER(HEADER[:SOURCES]..., COMMANDS, INIT-COMMANDS)
-# --------------------------------------------------------------
-AC_DEFUN([AM_CONFIG_HEADER],
-[AC_FOREACH([_AM_File], [$1], [_AM_CONFIG_HEADER(_AM_File, [$2], [$3])])
-])# AM_CONFIG_HEADER
-
# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
-# serial 47 AC_PROG_LIBTOOL
+# serial 48 Debian 1.5.22-2 AC_PROG_LIBTOOL
# AC_PROVIDE_IFELSE(MACRO-NAME, IF-PROVIDED, IF-NOT-PROVIDED)
@@ -946,7 +123,7 @@ esac
# Sed substitution that helps us do robust quoting. It backslashifies
# metacharacters that are still active within double-quoted strings.
-Xsed='sed -e s/^X//'
+Xsed='sed -e 1s/^X//'
[sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g']
# Same as above, but do not quote variable references.
@@ -966,7 +143,7 @@ rm="rm -f"
default_ofile=libtool
can_build_shared=yes
-# All known linkers require a `.a' archive for static linking (except M$VC,
+# All known linkers require a `.a' archive for static linking (except MSVC,
# which needs '.lib').
libext=a
ltmain="$ac_aux_dir/ltmain.sh"
@@ -986,6 +163,7 @@ test -z "$AR_FLAGS" && AR_FLAGS=cru
test -z "$AS" && AS=as
test -z "$CC" && CC=cc
test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
test -z "$DLLTOOL" && DLLTOOL=dlltool
test -z "$LD" && LD=ld
test -z "$LN_S" && LN_S="ln -s"
@@ -1005,15 +183,17 @@ old_postuninstall_cmds=
if test -n "$RANLIB"; then
case $host_os in
openbsd*)
- old_postinstall_cmds="\$RANLIB -t \$oldlib~$old_postinstall_cmds"
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib"
;;
*)
- old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds"
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib"
;;
esac
old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
fi
+_LT_CC_BASENAME([$compiler])
+
# Only perform the check for file, if the check method requires it
case $deplibs_check_method in
file_magic*)
@@ -1054,11 +234,56 @@ AC_DEFUN([_LT_AC_SYS_COMPILER],
# If no C compiler was specified, use CC.
LTCC=${LTCC-"$CC"}
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
# Allow CC to be a program name with arguments.
compiler=$CC
])# _LT_AC_SYS_COMPILER
+# _LT_CC_BASENAME(CC)
+# -------------------
+# Calculate cc_basename. Skip known compiler wrappers and cross-prefix.
+AC_DEFUN([_LT_CC_BASENAME],
+[for cc_temp in $1""; do
+ case $cc_temp in
+ compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;;
+ distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+done
+cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
+])
+
+
+# _LT_COMPILER_BOILERPLATE
+# ------------------------
+# Check for compiler boilerplate output or warnings with
+# the simple compiler test code.
+AC_DEFUN([_LT_COMPILER_BOILERPLATE],
+[ac_outfile=conftest.$ac_objext
+printf "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$rm conftest*
+])# _LT_COMPILER_BOILERPLATE
+
+
+# _LT_LINKER_BOILERPLATE
+# ----------------------
+# Check for linker boilerplate output or warnings with
+# the simple link test code.
+AC_DEFUN([_LT_LINKER_BOILERPLATE],
+[ac_outfile=conftest.$ac_objext
+printf "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$rm conftest*
+])# _LT_LINKER_BOILERPLATE
+
+
# _LT_AC_SYS_LIBPATH_AIX
# ----------------------
# Links a minimal program and checks the executable
@@ -1131,15 +356,15 @@ fi
# The HP-UX ksh and POSIX shell print the target directory to stdout
# if CDPATH is set.
-if test "X${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
if test -z "$ECHO"; then
if test "X${echo_test_string+set}" != Xset; then
# find a string as large as possible, as long as the shell can cope with it
for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do
# expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
- if (echo_test_string="`eval $cmd`") 2>/dev/null &&
- echo_test_string="`eval $cmd`" &&
+ if (echo_test_string=`eval $cmd`) 2>/dev/null &&
+ echo_test_string=`eval $cmd` &&
(test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null
then
break
@@ -1308,13 +533,13 @@ x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*)
# Find out which ABI we are using.
echo 'int i;' > conftest.$ac_ext
if AC_TRY_EVAL(ac_compile); then
- case "`/usr/bin/file conftest.o`" in
+ case `/usr/bin/file conftest.o` in
*32-bit*)
case $host in
x86_64-*linux*)
LD="${LD-ld} -m elf_i386"
;;
- ppc64-*linux*)
+ ppc64-*linux*|powerpc64-*linux*)
LD="${LD-ld} -m elf32ppclinux"
;;
s390x-*linux*)
@@ -1359,6 +584,22 @@ x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*)
CFLAGS="$SAVE_CFLAGS"
fi
;;
+sparc*-*solaris*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case `/usr/bin/file conftest.o` in
+ *64-bit*)
+ case $lt_cv_prog_gnu_ld in
+ yes*) LD="${LD-ld} -m elf64_sparc" ;;
+ *) LD="${LD-ld} -64" ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL],
[*-*-cygwin* | *-*-mingw* | *-*-pw32*)
AC_CHECK_TOOL(DLLTOOL, dlltool, false)
@@ -1378,7 +619,8 @@ need_locks="$enable_libtool_lock"
# ----------------------------------------------------------------
# Check whether the given compiler option works
AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION],
-[AC_CACHE_CHECK([$1], [$2],
+[AC_REQUIRE([LT_AC_PROG_SED])
+AC_CACHE_CHECK([$1], [$2],
[$2=no
ifelse([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4])
printf "$lt_simple_compile_test_code" > conftest.$ac_ext
@@ -1389,7 +631,7 @@ AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION],
# with a dollar sign (not a hyphen), so the echo should work correctly.
# The option is referenced via a variable to avoid confusing sed.
lt_compile=`echo "$ac_compile" | $SED \
- -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
@@ -1399,8 +641,10 @@ AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION],
echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
- # So say no if there are warnings
- if test ! -s conftest.err; then
+ # So say no if there are warnings other than the usual output.
+ $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
$2=yes
fi
fi
@@ -1426,11 +670,16 @@ AC_DEFUN([AC_LIBTOOL_LINKER_OPTION],
LDFLAGS="$LDFLAGS $3"
printf "$lt_simple_link_test_code" > conftest.$ac_ext
if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
- # The compiler can only warn and ignore the option if not recognized
+ # The linker can only warn and ignore the option if not recognized
# So say no if there are warnings
if test -s conftest.err; then
# Append any errors to the config.log.
cat conftest.err 1>&AS_MESSAGE_LOG_FD
+ $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ $2=yes
+ fi
else
$2=yes
fi
@@ -1454,7 +703,7 @@ AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN],
AC_MSG_CHECKING([the maximum length of command line arguments])
AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
i=0
- testring="ABCD"
+ teststring="ABCD"
case $build_os in
msdosdjgpp*)
@@ -1483,20 +732,70 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
lt_cv_sys_max_cmd_len=8192;
;;
- *)
+ amigaos*)
+ # On AmigaOS with pdksh, this test takes hours, literally.
+ # So we just punt and use a minimum line length of 8192.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
+ # This has been around since 386BSD, at least. Likely further.
+ if test -x /sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+ elif test -x /usr/sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+ else
+ lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs
+ fi
+ # And add a safety zone
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ ;;
+
+ interix*)
+ # We know the value 262144 and hardcode it with a safety zone (like BSD)
+ lt_cv_sys_max_cmd_len=196608
+ ;;
+
+ osf*)
+ # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+ # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+ # nice to cause kernel panics so lets avoid the loop below.
+ # First set a reasonable default.
+ lt_cv_sys_max_cmd_len=16384
+ #
+ if test -x /sbin/sysconfig; then
+ case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+ *1*) lt_cv_sys_max_cmd_len=-1 ;;
+ esac
+ fi
+ ;;
+ sco3.2v5*)
+ lt_cv_sys_max_cmd_len=102400
+ ;;
+ sysv5* | sco5v6* | sysv4.2uw2*)
+ kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+ if test -n "$kargmax"; then
+ lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'`
+ else
+ lt_cv_sys_max_cmd_len=32768
+ fi
+ ;;
+ *)
# If test is not a shell built-in, we'll probably end up computing a
# maximum length that is only half of the actual maximum length, but
# we can't tell.
- while (test "X"`$CONFIG_SHELL [$]0 --fallback-echo "X$testring" 2>/dev/null` \
- = "XX$testring") >/dev/null 2>&1 &&
- new_result=`expr "X$testring" : ".*" 2>&1` &&
+ SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+ while (test "X"`$SHELL [$]0 --fallback-echo "X$teststring" 2>/dev/null` \
+ = "XX$teststring") >/dev/null 2>&1 &&
+ new_result=`expr "X$teststring" : ".*" 2>&1` &&
lt_cv_sys_max_cmd_len=$new_result &&
test $i != 17 # 1/2 MB should be enough
do
i=`expr $i + 1`
- testring=$testring$testring
+ teststring=$teststring$teststring
done
- testring=
+ teststring=
# Add a significant safety factor because C++ compilers can tack on massive
# amounts of additional arguments before passing them to the linker.
# It appears as though 1/2 is a usable value.
@@ -1513,7 +812,7 @@ fi
# _LT_AC_CHECK_DLFCN
-# --------------------
+# ------------------
AC_DEFUN([_LT_AC_CHECK_DLFCN],
[AC_CHECK_HEADERS(dlfcn.h)dnl
])# _LT_AC_CHECK_DLFCN
@@ -1521,7 +820,7 @@ AC_DEFUN([_LT_AC_CHECK_DLFCN],
# _LT_AC_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE,
# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING)
-# ------------------------------------------------------------------
+# ---------------------------------------------------------------------
AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF],
[AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl
if test "$cross_compiling" = yes; then :
@@ -1587,17 +886,19 @@ int main ()
else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
/* dlclose (self); */
}
+ else
+ puts (dlerror ());
exit (status);
}]
EOF
if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then
- (./conftest; exit; ) 2>/dev/null
+ (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null
lt_status=$?
case x$lt_status in
x$lt_dlno_uscore) $1 ;;
x$lt_dlneed_uscore) $2 ;;
- x$lt_unknown|x*) $3 ;;
+ x$lt_dlunknown|x*) $3 ;;
esac
else :
# compilation failed
@@ -1609,7 +910,7 @@ rm -fr conftest*
# AC_LIBTOOL_DLOPEN_SELF
-# -------------------
+# ----------------------
AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF],
[AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl
if test "x$enable_dlopen" != xyes; then
@@ -1646,7 +947,7 @@ else
lt_cv_dlopen_self=yes
])
;;
-
+
*)
AC_CHECK_FUNC([shl_load],
[lt_cv_dlopen="shl_load"],
@@ -1680,7 +981,7 @@ else
test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
save_LDFLAGS="$LDFLAGS"
- eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
save_LIBS="$LIBS"
LIBS="$lt_cv_dlopen_libs $LIBS"
@@ -1693,7 +994,7 @@ else
])
if test "x$lt_cv_dlopen_self" = xyes; then
- LDFLAGS="$LDFLAGS $link_static_flag"
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
AC_CACHE_CHECK([whether a statically linked program can dlopen itself],
lt_cv_dlopen_self_static, [dnl
_LT_AC_TRY_DLOPEN_SELF(
@@ -1735,20 +1036,13 @@ AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext],
mkdir out
printf "$lt_simple_compile_test_code" > conftest.$ac_ext
- # According to Tom Tromey, Ian Lance Taylor reported there are C compilers
- # that will create temporary files in the current directory regardless of
- # the output directory. Thus, making CWD read-only will cause this test
- # to fail, enabling locking or at least warning the user not to do parallel
- # builds.
- chmod -w .
-
lt_compiler_flag="-o out/conftest2.$ac_objext"
# Insert the option either (1) after the last *FLAGS variable, or
# (2) before a word containing "conftest.", or (3) at the end.
# Note that $ac_compile itself does not contain backslashes and begins
# with a dollar sign (not a hyphen), so the echo should work correctly.
lt_compile=`echo "$ac_compile" | $SED \
- -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
@@ -1760,13 +1054,18 @@ AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext],
then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings
- if test ! -s out/conftest.err; then
+ $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
fi
fi
- chmod u+w .
- $rm conftest* out/*
- rmdir out
+ chmod u+w . 2>&AS_MESSAGE_LOG_FD
+ $rm conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files
+ $rm out/* && rmdir out
cd ..
rmdir conftest
$rm conftest*
@@ -1825,8 +1124,8 @@ AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH],
[AC_MSG_CHECKING([how to hardcode library paths into programs])
_LT_AC_TAGVAR(hardcode_action, $1)=
if test -n "$_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)" || \
- test -n "$_LT_AC_TAGVAR(runpath_var $1)" || \
- test "X$_LT_AC_TAGVAR(hardcode_automatic, $1)"="Xyes" ; then
+ test -n "$_LT_AC_TAGVAR(runpath_var, $1)" || \
+ test "X$_LT_AC_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then
# We can hardcode non-existant directories.
if test "$_LT_AC_TAGVAR(hardcode_direct, $1)" != no &&
@@ -1883,7 +1182,7 @@ fi
*)
AC_MSG_RESULT([no])
;;
- esac
+ esac
fi
])# AC_LIBTOOL_SYS_LIB_STRIP
@@ -1896,7 +1195,7 @@ AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER],
library_names_spec=
libname_spec='lib$name'
soname_spec=
-shrext=".so"
+shrext_cmds=".so"
postinstall_cmds=
postuninstall_cmds=
finish_cmds=
@@ -1984,7 +1283,7 @@ aix4* | aix5*)
amigaos*)
library_names_spec='$libname.ixlibrary $libname.a'
# Create ${libname}_ixlibrary.a entries in /sys/libs.
- finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "(cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a)"; (cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a) || exit 1; done'
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
;;
beos*)
@@ -1993,7 +1292,7 @@ beos*)
shlibpath_var=LIBRARY_PATH
;;
-bsdi4*)
+bsdi[[45]]*)
version_type=linux
need_version=no
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
@@ -2009,7 +1308,7 @@ bsdi4*)
cygwin* | mingw* | pw32*)
version_type=windows
- shrext=".dll"
+ shrext_cmds=".dll"
need_version=no
need_lib_prefix=no
@@ -2021,7 +1320,8 @@ cygwin* | mingw* | pw32*)
dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~
dldir=$destdir/`dirname \$dlpath`~
test -d \$dldir || mkdir -p \$dldir~
- $install_prog $dir/$dlname \$dldir/$dlname'
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname'
postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
dlpath=$dir/\$dldll~
$rm \$dlpath'
@@ -2031,7 +1331,7 @@ cygwin* | mingw* | pw32*)
cygwin*)
# Cygwin DLLs use 'cyg' prefix rather than 'lib'
soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
- sys_lib_search_path_spec="/lib /lib/w32api /usr/lib /usr/local/lib"
+ sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
;;
mingw*)
# MinGW DLLs use traditional 'lib' prefix
@@ -2051,7 +1351,7 @@ cygwin* | mingw* | pw32*)
;;
pw32*)
# pw32 DLLs use 'pw' prefix rather than 'lib'
- library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+ library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
;;
esac
;;
@@ -2070,17 +1370,16 @@ darwin* | rhapsody*)
version_type=darwin
need_lib_prefix=no
need_version=no
- # FIXME: Relying on posixy $() will cause problems for
- # cross-compilation, but unfortunately the echo tests do not
- # yet detect zsh echo's removal of \ escapes.
library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext'
soname_spec='${libname}${release}${major}$shared_ext'
shlibpath_overrides_runpath=yes
shlibpath_var=DYLD_LIBRARY_PATH
- shrext='$(test .$module = .yes && echo .so || echo .dylib)'
+ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
# Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same.
- if $CC -v 2>&1 | grep 'Apple' >/dev/null ; then
- sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"`
+ if test "$GCC" = yes; then
+ sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"`
+ else
+ sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib'
fi
sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
;;
@@ -2098,8 +1397,29 @@ freebsd1*)
dynamic_linker=no
;;
-freebsd*)
- objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout`
+kfreebsd*-gnu)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='GNU ld.so'
+ ;;
+
+freebsd* | dragonfly*)
+ # DragonFly does not have aout. When/if they implement a new
+ # versioning mechanism, adjust this.
+ if test -x /usr/bin/objformat; then
+ objformat=`/usr/bin/objformat`
+ else
+ case $host_os in
+ freebsd[[123]]*) objformat=aout ;;
+ *) objformat=elf ;;
+ esac
+ fi
version_type=freebsd-$objformat
case $version_type in
freebsd-elf*)
@@ -2117,14 +1437,19 @@ freebsd*)
freebsd2*)
shlibpath_overrides_runpath=yes
;;
- freebsd3.[01]* | freebsdelf3.[01]*)
+ freebsd3.[[01]]* | freebsdelf3.[[01]]*)
shlibpath_overrides_runpath=yes
hardcode_into_libs=yes
;;
- *) # from 3.2 on
+ freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \
+ freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1)
shlibpath_overrides_runpath=no
hardcode_into_libs=yes
;;
+ freebsd*) # from 4.6 on
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
esac
;;
@@ -2144,9 +1469,9 @@ hpux9* | hpux10* | hpux11*)
version_type=sunos
need_lib_prefix=no
need_version=no
- case "$host_cpu" in
+ case $host_cpu in
ia64*)
- shrext='.so'
+ shrext_cmds='.so'
hardcode_into_libs=yes
dynamic_linker="$host_os dld.so"
shlibpath_var=LD_LIBRARY_PATH
@@ -2161,7 +1486,7 @@ hpux9* | hpux10* | hpux11*)
sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
;;
hppa*64*)
- shrext='.sl'
+ shrext_cmds='.sl'
hardcode_into_libs=yes
dynamic_linker="$host_os dld.sl"
shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
@@ -2172,7 +1497,7 @@ hpux9* | hpux10* | hpux11*)
sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
;;
*)
- shrext='.sl'
+ shrext_cmds='.sl'
dynamic_linker="$host_os dld.sl"
shlibpath_var=SHLIB_PATH
shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
@@ -2184,6 +1509,18 @@ hpux9* | hpux10* | hpux11*)
postinstall_cmds='chmod 555 $lib'
;;
+interix3*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
irix5* | irix6* | nonstopux*)
case $host_os in
nonstopux*) version_type=nonstopux ;;
@@ -2241,6 +1578,12 @@ linux*)
# before this can be enabled.
hardcode_into_libs=yes
+ # Append ld.so.conf contents to the search path
+ if test -f /etc/ld.so.conf; then
+ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
+ sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+ fi
+
# We used to test for /lib/ld.so.1 and disable shared libraries on
# powerpc, because MkLinux only supported shared libraries with the
# GNU dynamic linker. Since this was broken with cross compilers,
@@ -2248,26 +1591,30 @@ linux*)
# people can always --disable-shared, the test was removed, and we
# assume the GNU/Linux dynamic linker is in use.
dynamic_linker='GNU/Linux ld.so'
+ ;;
- # Find out which ABI we are using (multilib Linux x86_64 hack).
- libsuff=
- case "$host_cpu" in
- x86_64*|s390x*)
- echo '[#]line __oline__ "configure"' > conftest.$ac_ext
- if AC_TRY_EVAL(ac_compile); then
- case `/usr/bin/file conftest.$ac_objext` in
- *64-bit*)
- libsuff=64
- ;;
- esac
- fi
- rm -rf conftest*
- ;;
- *)
- ;;
- esac
- sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff}"
- sys_lib_search_path_spec="/lib${libsuff} /usr/lib${libsuff} /usr/local/lib${libsuff}"
+netbsdelf*-gnu)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='NetBSD ld.elf_so'
+ ;;
+
+knetbsd*-gnu)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='GNU ld.so'
;;
netbsd*)
@@ -2279,7 +1626,7 @@ netbsd*)
finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
dynamic_linker='NetBSD (a.out) ld.so'
else
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} ${libname}${shared_ext}'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
soname_spec='${libname}${release}${shared_ext}$major'
dynamic_linker='NetBSD ld.elf_so'
fi
@@ -2295,7 +1642,7 @@ newsos6)
shlibpath_overrides_runpath=yes
;;
-nto-qnx)
+nto-qnx*)
version_type=linux
need_lib_prefix=no
need_version=no
@@ -2307,8 +1654,13 @@ nto-qnx)
openbsd*)
version_type=sunos
+ sys_lib_dlsearch_path_spec="/usr/lib"
need_lib_prefix=no
- need_version=no
+ # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+ case $host_os in
+ openbsd3.3 | openbsd3.3.*) need_version=yes ;;
+ *) need_version=no ;;
+ esac
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
shlibpath_var=LD_LIBRARY_PATH
@@ -2328,7 +1680,7 @@ openbsd*)
os2*)
libname_spec='$name'
- shrext=".dll"
+ shrext_cmds=".dll"
need_lib_prefix=no
library_names_spec='$libname${shared_ext} $libname.a'
dynamic_linker='OS/2 ld.exe'
@@ -2346,13 +1698,6 @@ osf3* | osf4* | osf5*)
sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
;;
-sco3.2v5*)
- version_type=osf
- soname_spec='${libname}${release}${shared_ext}$major'
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- ;;
-
solaris*)
version_type=linux
need_lib_prefix=no
@@ -2378,7 +1723,7 @@ sunos4*)
need_version=yes
;;
-sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+sysv4 | sysv4.3*)
version_type=linux
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
soname_spec='${libname}${release}${shared_ext}$major'
@@ -2411,6 +1756,29 @@ sysv4*MP*)
fi
;;
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ version_type=freebsd-elf
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ hardcode_into_libs=yes
+ if test "$with_gnu_ld" = yes; then
+ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+ shlibpath_overrides_runpath=no
+ else
+ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+ shlibpath_overrides_runpath=yes
+ case $host_os in
+ sco3.2v5*)
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+ ;;
+ esac
+ fi
+ sys_lib_dlsearch_path_spec='/usr/lib'
+ ;;
+
uts4*)
version_type=linux
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
@@ -2424,6 +1792,11 @@ uts4*)
esac
AC_MSG_RESULT([$dynamic_linker])
test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
])# AC_LIBTOOL_SYS_DYNAMIC_LINKER
@@ -2448,6 +1821,9 @@ if test -f "$ltmain" && test -n "$tagnames"; then
AC_MSG_WARN([using `LTCC=$LTCC', extracted from `$ofile'])
fi
fi
+ if test -z "$LTCFLAGS"; then
+ eval "`$SHELL ${ofile} --config | grep '^LTCFLAGS='`"
+ fi
# Extract list of available tagged configurations in $ofile.
# Note that this assumes the entire list is on one line.
@@ -2474,7 +1850,9 @@ if test -f "$ltmain" && test -n "$tagnames"; then
case $tagname in
CXX)
- if test -n "$CXX" && test "X$CXX" != "Xno"; then
+ if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
+ ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
+ (test "X$CXX" != "Xg++"))) ; then
AC_LIBTOOL_LANG_CXX_CONFIG
else
tagname=""
@@ -2536,7 +1914,7 @@ AC_DEFUN([AC_LIBTOOL_DLOPEN],
# AC_LIBTOOL_WIN32_DLL
# --------------------
-# declare package support for building win32 dll's
+# declare package support for building win32 DLLs
AC_DEFUN([AC_LIBTOOL_WIN32_DLL],
[AC_BEFORE([$0], [AC_LIBTOOL_SETUP])
])# AC_LIBTOOL_WIN32_DLL
@@ -2574,7 +1952,7 @@ AC_ARG_ENABLE([shared],
# AC_DISABLE_SHARED
# -----------------
-#- set the default shared flag to --disable-shared
+# set the default shared flag to --disable-shared
AC_DEFUN([AC_DISABLE_SHARED],
[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
AC_ENABLE_SHARED(no)
@@ -2710,7 +2088,7 @@ dnl not every word. This closes a longstanding sh security hole.
if test -n "$file_magic_test_file"; then
case $deplibs_check_method in
"file_magic "*)
- file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`"
+ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
$EGREP "$file_magic_regex" > /dev/null; then
@@ -2764,7 +2142,7 @@ fi
# AC_PROG_LD
# ----------
-# find the path to the GNU or non-GNU linker
+# find the pathname to the GNU or non-GNU linker
AC_DEFUN([AC_PROG_LD],
[AC_ARG_WITH([gnu-ld],
[AC_HELP_STRING([--with-gnu-ld],
@@ -2790,7 +2168,7 @@ if test "$GCC" = yes; then
# Accept absolute paths.
[[\\/]]* | ?:[[\\/]]*)
re_direlt='/[[^/]][[^/]]*/\.\./'
- # Canonicalize the path of ld
+ # Canonicalize the pathname of ld
ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'`
while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"`
@@ -2820,7 +2198,7 @@ AC_CACHE_VAL(lt_cv_path_LD,
if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
lt_cv_path_LD="$ac_dir/$ac_prog"
# Check to see if the program is GNU ld. I'd rather use --version,
- # but apparently some GNU ld's only accept -v.
+ # but apparently some variants of GNU ld only accept -v.
# Break only if it was the GNU/non-GNU ld that we prefer.
case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
*GNU* | *'with BFD'*)
@@ -2852,7 +2230,7 @@ AC_PROG_LD_GNU
AC_DEFUN([AC_PROG_LD_GNU],
[AC_REQUIRE([AC_PROG_EGREP])dnl
AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld,
-[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+[# I'd rather use --version here, but apparently some GNU lds only accept -v.
case `$LD -v 2>&1 </dev/null` in
*GNU* | *'with BFD'*)
lt_cv_prog_gnu_ld=yes
@@ -2879,6 +2257,15 @@ case $reload_flag in
*) reload_flag=" $reload_flag" ;;
esac
reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+ darwin*)
+ if test "$GCC" = yes; then
+ reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
+ else
+ reload_cmds='$LD$reload_flag -o $output$reload_objs'
+ fi
+ ;;
+esac
])# AC_PROG_LD_RELOAD_FLAG
@@ -2912,40 +2299,36 @@ beos*)
lt_cv_deplibs_check_method=pass_all
;;
-bsdi4*)
+bsdi[[45]]*)
lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)'
lt_cv_file_magic_cmd='/usr/bin/file -L'
lt_cv_file_magic_test_file=/shlib/libc.so
;;
-cygwin* | mingw* | pw32*)
- # win32_libid is a shell function defined in ltmain.sh
+cygwin*)
+ # func_win32_libid is a shell function defined in ltmain.sh
lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
- lt_cv_file_magic_cmd='win32_libid'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ ;;
+
+mingw* | pw32*)
+ # Base MSYS/MinGW do not provide the 'file' command needed by
+ # func_win32_libid shell function, so use a weaker test based on 'objdump'.
+ lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
;;
darwin* | rhapsody*)
- # this will be overwritten by pass_all, but leave it in just in case
- lt_cv_deplibs_check_method='file_magic Mach-O dynamically linked shared library'
- lt_cv_file_magic_cmd='/usr/bin/file -L'
- case "$host_os" in
- rhapsody* | darwin1.[[012]])
- lt_cv_file_magic_test_file=`/System/Library/Frameworks/System.framework/System`
- ;;
- *) # Darwin 1.3 on
- lt_cv_file_magic_test_file='/usr/lib/libSystem.dylib'
- ;;
- esac
lt_cv_deplibs_check_method=pass_all
;;
-freebsd*)
+freebsd* | kfreebsd*-gnu | dragonfly*)
if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
case $host_cpu in
i*86 )
# Not sure whether the presence of OpenBSD here was a mistake.
# Let's accept both of them until this is cleared up.
- lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD)/i[[3-9]]86 (compact )?demand paged shared library'
+ lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library'
lt_cv_file_magic_cmd=/usr/bin/file
lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
;;
@@ -2961,7 +2344,7 @@ gnu*)
hpux10.20* | hpux11*)
lt_cv_file_magic_cmd=/usr/bin/file
- case "$host_cpu" in
+ case $host_cpu in
ia64*)
lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64'
lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
@@ -2977,40 +2360,27 @@ hpux10.20* | hpux11*)
esac
;;
+interix3*)
+ # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$'
+ ;;
+
irix5* | irix6* | nonstopux*)
- case $host_os in
- irix5* | nonstopux*)
- # this will be overridden with pass_all, but let us keep it just in case
- lt_cv_deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1"
- ;;
- *)
- case $LD in
- *-32|*"-32 ") libmagic=32-bit;;
- *-n32|*"-n32 ") libmagic=N32;;
- *-64|*"-64 ") libmagic=64-bit;;
- *) libmagic=never-match;;
- esac
- # this will be overridden with pass_all, but let us keep it just in case
- lt_cv_deplibs_check_method="file_magic ELF ${libmagic} MSB mips-[[1234]] dynamic lib MIPS - version 1"
- ;;
+ case $LD in
+ *-32|*"-32 ") libmagic=32-bit;;
+ *-n32|*"-n32 ") libmagic=N32;;
+ *-64|*"-64 ") libmagic=64-bit;;
+ *) libmagic=never-match;;
esac
- lt_cv_file_magic_test_file=`echo /lib${libsuff}/libc.so*`
lt_cv_deplibs_check_method=pass_all
;;
# This must be Linux ELF.
linux*)
- case $host_cpu in
- alpha* | hppa* | i*86 | ia64* | m68* | mips | mipsel | powerpc* | sparc* | s390* | sh* | x86_64*)
- lt_cv_deplibs_check_method=pass_all ;;
- *)
- # glibc up to 2.1.1 does not perform some relocations on ARM
- lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ;;
- esac
- lt_cv_file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so`
+ lt_cv_deplibs_check_method=pass_all
;;
-netbsd*)
+netbsd* | netbsdelf*-gnu | knetbsd*-gnu)
if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
else
@@ -3024,37 +2394,27 @@ newos6*)
lt_cv_file_magic_test_file=/usr/lib/libnls.so
;;
-nto-qnx)
+nto-qnx*)
lt_cv_deplibs_check_method=unknown
;;
openbsd*)
- lt_cv_file_magic_cmd=/usr/bin/file
- lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
- lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB shared object'
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$'
else
- lt_cv_deplibs_check_method='file_magic OpenBSD.* shared library'
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
fi
;;
osf3* | osf4* | osf5*)
- # this will be overridden with pass_all, but let us keep it just in case
- lt_cv_deplibs_check_method='file_magic COFF format alpha shared library'
- lt_cv_file_magic_test_file=/shlib/libc.so
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-sco3.2v5*)
lt_cv_deplibs_check_method=pass_all
;;
solaris*)
lt_cv_deplibs_check_method=pass_all
- lt_cv_file_magic_test_file=/lib/libc.so
;;
-sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+sysv4 | sysv4.3*)
case $host_vendor in
motorola)
lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]'
@@ -3075,10 +2435,13 @@ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
siemens)
lt_cv_deplibs_check_method=pass_all
;;
+ pc)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
esac
;;
-sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[[78]]* | unixware7* | sysv4*uw2*)
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
lt_cv_deplibs_check_method=pass_all
;;
esac
@@ -3091,43 +2454,50 @@ test -z "$deplibs_check_method" && deplibs_check_method=unknown
# AC_PROG_NM
# ----------
-# find the path to a BSD-compatible name lister
+# find the pathname to a BSD-compatible name lister
AC_DEFUN([AC_PROG_NM],
[AC_CACHE_CHECK([for BSD-compatible nm], lt_cv_path_NM,
[if test -n "$NM"; then
# Let the user override the test.
lt_cv_path_NM="$NM"
else
- lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
- for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
- IFS="$lt_save_ifs"
- test -z "$ac_dir" && ac_dir=.
- tmp_nm="$ac_dir/${ac_tool_prefix}nm"
- if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
- # Check to see if the nm accepts a BSD-compat flag.
- # Adding the `sed 1q' prevents false positives on HP-UX, which says:
- # nm: unknown option "B" ignored
- # Tru64's nm complains that /dev/null is an invalid object file
- case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
- */dev/null* | *'Invalid file or object type'*)
- lt_cv_path_NM="$tmp_nm -B"
- break
- ;;
- *)
- case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
- */dev/null*)
- lt_cv_path_NM="$tmp_nm -p"
+ lt_nm_to_check="${ac_tool_prefix}nm"
+ if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+ lt_nm_to_check="$lt_nm_to_check nm"
+ fi
+ for lt_tmp_nm in $lt_nm_to_check; do
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ tmp_nm="$ac_dir/$lt_tmp_nm"
+ if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ # Tru64's nm complains that /dev/null is an invalid object file
+ case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+ */dev/null* | *'Invalid file or object type'*)
+ lt_cv_path_NM="$tmp_nm -B"
break
;;
*)
- lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
- continue # so that we can try to find one that supports BSD flags
+ case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+ */dev/null*)
+ lt_cv_path_NM="$tmp_nm -p"
+ break
+ ;;
+ *)
+ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ ;;
+ esac
;;
esac
- esac
- fi
+ fi
+ done
+ IFS="$lt_save_ifs"
done
- IFS="$lt_save_ifs"
test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm
fi])
NM="$lt_cv_path_NM"
@@ -3159,13 +2529,13 @@ esac
# -----------------------------------
# sets LIBLTDL to the link flags for the libltdl convenience library and
# LTDLINCL to the include flags for the libltdl header and adds
-# --enable-ltdl-convenience to the configure arguments. Note that LIBLTDL
-# and LTDLINCL are not AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called. If
-# DIRECTORY is not provided, it is assumed to be `libltdl'. LIBLTDL will
-# be prefixed with '${top_builddir}/' and LTDLINCL will be prefixed with
-# '${top_srcdir}/' (note the single quotes!). If your package is not
-# flat and you're not using automake, define top_builddir and
-# top_srcdir appropriately in the Makefiles.
+# --enable-ltdl-convenience to the configure arguments. Note that
+# AC_CONFIG_SUBDIRS is not called here. If DIRECTORY is not provided,
+# it is assumed to be `libltdl'. LIBLTDL will be prefixed with
+# '${top_builddir}/' and LTDLINCL will be prefixed with '${top_srcdir}/'
+# (note the single quotes!). If your package is not flat and you're not
+# using automake, define top_builddir and top_srcdir appropriately in
+# the Makefiles.
AC_DEFUN([AC_LIBLTDL_CONVENIENCE],
[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
case $enable_ltdl_convenience in
@@ -3184,13 +2554,13 @@ AC_DEFUN([AC_LIBLTDL_CONVENIENCE],
# -----------------------------------
# sets LIBLTDL to the link flags for the libltdl installable library and
# LTDLINCL to the include flags for the libltdl header and adds
-# --enable-ltdl-install to the configure arguments. Note that LIBLTDL
-# and LTDLINCL are not AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called. If
-# DIRECTORY is not provided and an installed libltdl is not found, it is
-# assumed to be `libltdl'. LIBLTDL will be prefixed with '${top_builddir}/'
-# and LTDLINCL will be prefixed with '${top_srcdir}/' (note the single
-# quotes!). If your package is not flat and you're not using automake,
-# define top_builddir and top_srcdir appropriately in the Makefiles.
+# --enable-ltdl-install to the configure arguments. Note that
+# AC_CONFIG_SUBDIRS is not called here. If DIRECTORY is not provided,
+# and an installed libltdl is not found, it is assumed to be `libltdl'.
+# LIBLTDL will be prefixed with '${top_builddir}/'# and LTDLINCL with
+# '${top_srcdir}/' (note the single quotes!). If your package is not
+# flat and you're not using automake, define top_builddir and top_srcdir
+# appropriately in the Makefiles.
# In the future, this macro may have to be called after AC_PROG_LIBTOOL.
AC_DEFUN([AC_LIBLTDL_INSTALLABLE],
[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
@@ -3228,10 +2598,21 @@ AC_DEFUN([AC_LIBTOOL_CXX],
# ---------------
AC_DEFUN([_LT_AC_LANG_CXX],
[AC_REQUIRE([AC_PROG_CXX])
-AC_REQUIRE([AC_PROG_CXXCPP])
-_LT_AC_SHELL_INIT([tagnames=`echo "$tagnames,CXX" | sed 's/^,//'`])
+AC_REQUIRE([_LT_AC_PROG_CXXCPP])
+_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}CXX])
])# _LT_AC_LANG_CXX
+# _LT_AC_PROG_CXXCPP
+# ------------------
+AC_DEFUN([_LT_AC_PROG_CXXCPP],
+[
+AC_REQUIRE([AC_PROG_CXX])
+if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
+ ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
+ (test "X$CXX" != "Xg++"))) ; then
+ AC_PROG_CXXCPP
+fi
+])# _LT_AC_PROG_CXXCPP
# AC_LIBTOOL_F77
# --------------
@@ -3245,7 +2626,7 @@ AC_DEFUN([AC_LIBTOOL_F77],
# ---------------
AC_DEFUN([_LT_AC_LANG_F77],
[AC_REQUIRE([AC_PROG_F77])
-_LT_AC_SHELL_INIT([tagnames=`echo "$tagnames,F77" | sed 's/^,//'`])
+_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}F77])
])# _LT_AC_LANG_F77
@@ -3266,16 +2647,16 @@ AC_DEFUN([_LT_AC_LANG_GCJ],
[ifdef([AC_PROG_GCJ],[AC_REQUIRE([AC_PROG_GCJ])],
[ifdef([A][M_PROG_GCJ],[AC_REQUIRE([A][M_PROG_GCJ])],
[AC_REQUIRE([A][C_PROG_GCJ_OR_A][M_PROG_GCJ])])])])])])
-_LT_AC_SHELL_INIT([tagnames=`echo "$tagnames,GCJ" | sed 's/^,//'`])
+_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}GCJ])
])# _LT_AC_LANG_GCJ
# AC_LIBTOOL_RC
-# --------------
+# -------------
# enable support for Windows resource files
AC_DEFUN([AC_LIBTOOL_RC],
[AC_REQUIRE([LT_AC_PROG_RC])
-_LT_AC_SHELL_INIT([tagnames=`echo "$tagnames,RC" | sed 's/^,//'`])
+_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}RC])
])# AC_LIBTOOL_RC
@@ -3304,48 +2685,21 @@ lt_simple_link_test_code='int main(){return(0);}\n'
_LT_AC_SYS_COMPILER
-#
-# Check for any special shared library compilation flags.
-#
-_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)=
-if test "$GCC" = no; then
- case $host_os in
- sco3.2v5*)
- _LT_AC_TAGVAR(lt_prog_cc_shlib, $1)='-belf'
- ;;
- esac
-fi
-if test -n "$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)"; then
- AC_MSG_WARN([`$CC' requires `$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)' to build shared libraries])
- if echo "$old_CC $old_CFLAGS " | grep "[[ ]]$]_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)[[[ ]]" >/dev/null; then :
- else
- AC_MSG_WARN([add `$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)' to the CC or CFLAGS env variable and reconfigure])
- _LT_AC_TAGVAR(lt_cv_prog_cc_can_build_shared, $1)=no
- fi
-fi
-
-
-#
-# Check to make sure the static flag actually works.
-#
-AC_LIBTOOL_LINKER_OPTION([if $compiler static flag $_LT_AC_TAGVAR(lt_prog_compiler_static, $1) works],
- _LT_AC_TAGVAR(lt_prog_compiler_static_works, $1),
- $_LT_AC_TAGVAR(lt_prog_compiler_static, $1),
- [],
- [_LT_AC_TAGVAR(lt_prog_compiler_static, $1)=])
-
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
AC_LIBTOOL_PROG_COMPILER_NO_RTTI($1)
AC_LIBTOOL_PROG_COMPILER_PIC($1)
AC_LIBTOOL_PROG_CC_C_O($1)
AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1)
AC_LIBTOOL_PROG_LD_SHLIBS($1)
+AC_LIBTOOL_SYS_DYNAMIC_LINKER($1)
AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1)
AC_LIBTOOL_SYS_LIB_STRIP
-AC_LIBTOOL_SYS_DYNAMIC_LINKER($1)
-AC_LIBTOOL_DLOPEN_SELF($1)
+AC_LIBTOOL_DLOPEN_SELF
-# Report which librarie types wil actually be built
+# Report which library types will actually be built
AC_MSG_CHECKING([if libtool supports shared libraries])
AC_MSG_RESULT([$can_build_shared])
@@ -3354,7 +2708,7 @@ test "$can_build_shared" = "no" && enable_shared=no
# On AIX, shared libraries and static libraries use the same namespace, and
# are all built from PIC.
-case "$host_os" in
+case $host_os in
aix3*)
test "$enable_shared" = yes && enable_static=no
if test -n "$RANLIB"; then
@@ -3363,39 +2717,11 @@ aix3*)
fi
;;
-aix4*)
+aix4* | aix5*)
if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
test "$enable_shared" = yes && enable_static=no
fi
- ;;
- darwin* | rhapsody*)
- if $CC -v 2>&1 | grep 'Apple' >/dev/null ; then
- _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
- case "$host_os" in
- rhapsody* | darwin1.[[012]])
- _LT_AC_TAGVAR(allow_undefined_flag, $1)='-undefined suppress'
- ;;
- *) # Darwin 1.3 on
- test -z ${LD_TWOLEVEL_NAMESPACE} && _LT_AC_TAGVAR(allow_undefined_flag, $1)='-flat_namespace -undefined suppress'
- ;;
- esac
- # FIXME: Relying on posixy $() will cause problems for
- # cross-compilation, but unfortunately the echo tests do not
- # yet detect zsh echo's removal of \ escapes. Also zsh mangles
- # `"' quotes if we put them in here... so don't!
- output_verbose_link_cmd='echo'
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs$compiler_flags -install_name $rpath/$soname $verstring'
- _LT_AC_TAGVAR(module_cmds, $1)='$CC -bundle $allow_undefined_flag -o $lib $libobjs $deplibs$compiler_flags'
- # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs$compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
- _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -bundle $allow_undefined_flag -o $lib $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
- _LT_AC_TAGVAR(hardcode_direct, $1)=no
- _LT_AC_TAGVAR(hardcode_automatic, $1)=yes
- _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
- _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-all_load $convenience'
- _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
- fi
- ;;
+ ;;
esac
AC_MSG_RESULT([$enable_shared])
@@ -3420,7 +2746,7 @@ AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG], [_LT_AC_LANG_CXX_CONFIG(CXX)])
AC_DEFUN([_LT_AC_LANG_CXX_CONFIG],
[AC_LANG_PUSH(C++)
AC_REQUIRE([AC_PROG_CXX])
-AC_REQUIRE([AC_PROG_CXXCPP])
+AC_REQUIRE([_LT_AC_PROG_CXXCPP])
_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
_LT_AC_TAGVAR(allow_undefined_flag, $1)=
@@ -3432,6 +2758,7 @@ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=
_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
_LT_AC_TAGVAR(hardcode_libdir_separator, $1)=
_LT_AC_TAGVAR(hardcode_minus_L, $1)=no
+_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
_LT_AC_TAGVAR(hardcode_automatic, $1)=no
_LT_AC_TAGVAR(module_cmds, $1)=
_LT_AC_TAGVAR(module_expsym_cmds, $1)=
@@ -3449,7 +2776,7 @@ _LT_AC_TAGVAR(postdeps, $1)=
_LT_AC_TAGVAR(compiler_lib_search_path, $1)=
# Source file extension for C++ test sources.
-ac_ext=cc
+ac_ext=cpp
# Object file extension for compiled C++ test sources.
objext=o
@@ -3459,11 +2786,15 @@ _LT_AC_TAGVAR(objext, $1)=$objext
lt_simple_compile_test_code="int some_variable = 0;\n"
# Code to be used in simple link tests
-lt_simple_link_test_code='int main(int, char *[]) { return(0); }\n'
+lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }\n'
# ltmain only uses $CC for tagged configurations so make sure $CC is set.
_LT_AC_SYS_COMPILER
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
# Allow CC to be a program name with arguments.
lt_save_CC=$CC
lt_save_LD=$LD
@@ -3474,18 +2805,18 @@ lt_save_path_LD=$lt_cv_path_LD
if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
else
- unset lt_cv_prog_gnu_ld
+ $as_unset lt_cv_prog_gnu_ld
fi
if test -n "${lt_cv_path_LDCXX+set}"; then
lt_cv_path_LD=$lt_cv_path_LDCXX
else
- unset lt_cv_path_LD
+ $as_unset lt_cv_path_LD
fi
test -z "${LDCXX+set}" || LD=$LDCXX
CC=${CXX-"c++"}
compiler=$CC
_LT_AC_TAGVAR(compiler, $1)=$CC
-cc_basename=`$echo X"$compiler" | $Xsed -e 's%^.*/%%'`
+_LT_CC_BASENAME([$compiler])
# We don't want -fno-exception wen compiling C++ code, so set the
# no_builtin_flag separately
@@ -3574,6 +2905,7 @@ case $host_os in
;;
esac
done
+ ;;
esac
exp_sym_flag='-bexport'
@@ -3592,7 +2924,7 @@ case $host_os in
_LT_AC_TAGVAR(link_all_deplibs, $1)=yes
if test "$GXX" = yes; then
- case $host_os in aix4.[012]|aix4.[012].*)
+ case $host_os in aix4.[[012]]|aix4.[[012]].*)
# We only want to do this on AIX 4.2 and lower, the check
# below for broken collect2 doesn't work under 4.3+
collect2name=`${CC} -print-prog-name=collect2`
@@ -3611,8 +2943,12 @@ case $host_os in
_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
_LT_AC_TAGVAR(hardcode_libdir_separator, $1)=
fi
+ ;;
esac
shared_flag='-shared'
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag="$shared_flag "'${wl}-G'
+ fi
else
# not using gcc
if test "$host_cpu" = ia64; then
@@ -3639,12 +2975,12 @@ case $host_os in
_LT_AC_SYS_LIBPATH_AIX
_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
else
if test "$host_cpu" = ia64; then
_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
_LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
else
# Determine the default libpath from the value encoded in an empty executable.
_LT_AC_SYS_LIBPATH_AIX
@@ -3653,16 +2989,26 @@ case $host_os in
# -berok will link without error, but may produce a broken library.
_LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
_LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
- # -bexpall does not export symbols beginning with underscore (_)
- _LT_AC_TAGVAR(always_export_symbols, $1)=yes
# Exported symbols can be pulled into shared objects from archives
- _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=' '
+ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes
- # This is similar to how AIX traditionally builds it's shared libraries.
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+ # This is similar to how AIX traditionally builds its shared libraries.
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
fi
fi
;;
+
+ beos*)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ else
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
chorus*)
case $cc_basename in
*)
@@ -3681,7 +3027,7 @@ case $host_os in
_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib'
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
# If the export-symbols file already is a .def file (1st line
# is EXPORTS), use it as is; otherwise, prepend...
_LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
@@ -3690,57 +3036,81 @@ case $host_os in
echo EXPORTS > $output_objdir/$soname.def;
cat $export_symbols >> $output_objdir/$soname.def;
fi~
- $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib'
+ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
else
_LT_AC_TAGVAR(ld_shlibs, $1)=no
fi
;;
+ darwin* | rhapsody*)
+ case $host_os in
+ rhapsody* | darwin1.[[012]])
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}suppress'
+ ;;
+ *) # Darwin 1.3 on
+ if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
+ else
+ case ${MACOSX_DEPLOYMENT_TARGET} in
+ 10.[[012]])
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
+ ;;
+ 10.*)
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}dynamic_lookup'
+ ;;
+ esac
+ fi
+ ;;
+ esac
+ _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_AC_TAGVAR(hardcode_direct, $1)=no
+ _LT_AC_TAGVAR(hardcode_automatic, $1)=yes
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=''
+ _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
- darwin* | rhapsody*)
- if $CC -v 2>&1 | grep 'Apple' >/dev/null ; then
- _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
- case "$host_os" in
- rhapsody* | darwin1.[[012]])
- _LT_AC_TAGVAR(allow_undefined_flag, $1)='-undefined suppress'
- ;;
- *) # Darwin 1.3 on
- test -z ${LD_TWOLEVEL_NAMESPACE} && _LT_AC_TAGVAR(allow_undefined_flag, $1)='-flat_namespace -undefined suppress'
- ;;
- esac
- lt_int_apple_cc_single_mod=no
- output_verbose_link_cmd='echo'
- if $CC -dumpspecs 2>&1 | grep 'single_module' >/dev/null ; then
- lt_int_apple_cc_single_mod=yes
- fi
- if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
- else
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+ if test "$GXX" = yes ; then
+ lt_int_apple_cc_single_mod=no
+ output_verbose_link_cmd='echo'
+ if $CC -dumpspecs 2>&1 | $EGREP 'single_module' >/dev/null ; then
+ lt_int_apple_cc_single_mod=yes
fi
- _LT_AC_TAGVAR(module_cmds, $1)='$CC -bundle ${wl}-bind_at_load $allow_undefined_flag -o $lib $libobjs $deplibs$compiler_flags'
-
- # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's
if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+ else
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+ fi
+ _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+ # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
+ if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ else
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ fi
+ _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
else
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ case $cc_basename in
+ xlc*)
+ output_verbose_link_cmd='echo'
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring'
+ _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+ # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ ;;
+ *)
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
fi
- _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -bundle $allow_undefined_flag -o $lib $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
- _LT_AC_TAGVAR(hardcode_direct, $1)=no
- _LT_AC_TAGVAR(hardcode_automatic, $1)=yes
- _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
- _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-all_load $convenience'
- _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
- fi
- ;;
+ ;;
dgux*)
case $cc_basename in
- ec++)
+ ec++*)
# FIXME: insert proper C++ library support
_LT_AC_TAGVAR(ld_shlibs, $1)=no
;;
- ghcx)
+ ghcx*)
# Green Hills C++ Compiler
# FIXME: insert proper C++ library support
_LT_AC_TAGVAR(ld_shlibs, $1)=no
@@ -3751,14 +3121,14 @@ case $host_os in
;;
esac
;;
- freebsd[12]*)
+ freebsd[[12]]*)
# C++ shared libraries reported to be fairly broken before switch to ELF
_LT_AC_TAGVAR(ld_shlibs, $1)=no
;;
freebsd-elf*)
_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
;;
- freebsd*)
+ freebsd* | kfreebsd*-gnu | dragonfly*)
# FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
# conventions
_LT_AC_TAGVAR(ld_shlibs, $1)=yes
@@ -3775,11 +3145,11 @@ case $host_os in
# location of the library.
case $cc_basename in
- CC)
+ CC*)
# FIXME: insert proper C++ library support
_LT_AC_TAGVAR(ld_shlibs, $1)=no
;;
- aCC)
+ aCC*)
_LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
@@ -3789,7 +3159,7 @@ case $host_os in
# explicitly linking system object files so we need to strip them
# from the output so that they don't get included in the library
# dependencies.
- output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | egrep "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "[[-]]L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
;;
*)
if test "$GXX" = yes; then
@@ -3803,34 +3173,23 @@ case $host_os in
;;
hpux10*|hpux11*)
if test $with_gnu_ld = no; then
- case "$host_cpu" in
- hppa*64*)
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir'
- _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
- ;;
- ia64*)
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
;;
*)
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
- _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
;;
esac
fi
- case "$host_cpu" in
- hppa*64*)
+ case $host_cpu in
+ hppa*64*|ia64*)
_LT_AC_TAGVAR(hardcode_direct, $1)=no
_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
;;
- ia64*)
- _LT_AC_TAGVAR(hardcode_direct, $1)=no
- _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
- _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
- # but as the default
- # location of the library.
- ;;
*)
_LT_AC_TAGVAR(hardcode_direct, $1)=yes
_LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
@@ -3840,14 +3199,17 @@ case $host_os in
esac
case $cc_basename in
- CC)
+ CC*)
# FIXME: insert proper C++ library support
_LT_AC_TAGVAR(ld_shlibs, $1)=no
;;
- aCC)
- case "$host_cpu" in
- hppa*64*|ia64*)
- _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs'
+ aCC*)
+ case $host_cpu in
+ hppa*64*)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ ia64*)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
*)
_LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
@@ -3866,9 +3228,12 @@ case $host_os in
*)
if test "$GXX" = yes; then
if test $with_gnu_ld = no; then
- case "$host_cpu" in
- ia64*|hppa*64*)
- _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs'
+ case $host_cpu in
+ hppa*64*)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ ia64*)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
*)
_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
@@ -3882,11 +3247,25 @@ case $host_os in
;;
esac
;;
+ interix3*)
+ _LT_AC_TAGVAR(hardcode_direct, $1)=no
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
irix5* | irix6*)
case $cc_basename in
- CC)
+ CC*)
# SGI C++
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib'
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
# Archives containing C++ object files must be created using
# "CC -ar", where "CC" is the IRIX C++ compiler. This is
@@ -3897,7 +3276,7 @@ case $host_os in
*)
if test "$GXX" = yes; then
if test "$with_gnu_ld" = no; then
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib'
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
else
_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` -o $lib'
fi
@@ -3910,7 +3289,7 @@ case $host_os in
;;
linux*)
case $cc_basename in
- KCC)
+ KCC*)
# Kuck and Associates, Inc. (KAI) C++ Compiler
# KCC will only create a shared library if the output file
@@ -3935,17 +3314,41 @@ case $host_os in
# "CC -Bstatic", where "CC" is the KAI C++ compiler.
_LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs'
;;
- icpc)
+ icpc*)
# Intel C++
with_gnu_ld=yes
+ # version 8.0 and above of icpc choke on multiply defined symbols
+ # if we add $predep_objects and $postdep_objects, however 7.1 and
+ # earlier do not add the objects themselves.
+ case `$CC -V 2>&1` in
+ *"Version 7."*)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ *) # Version 8.0 or newer
+ tmp_idyn=
+ case $host_cpu in
+ ia64*) tmp_idyn=' -i_dynamic';;
+ esac
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ esac
_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
_LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
;;
- cxx)
+ pgCC*)
+ # Portland Group C++ compiler
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'
+ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
+ ;;
+ cxx*)
# Compaq C++
_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols'
@@ -3976,7 +3379,7 @@ case $host_os in
;;
mvs*)
case $cc_basename in
- cxx)
+ cxx*)
# FIXME: insert proper C++ library support
_LT_AC_TAGVAR(ld_shlibs, $1)=no
;;
@@ -3986,7 +3389,7 @@ case $host_os in
;;
esac
;;
- netbsd*)
+ netbsd* | netbsdelf*-gnu | knetbsd*-gnu)
if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
_LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
wlarc=
@@ -3997,9 +3400,25 @@ case $host_os in
# Workaround some broken pre-1.5 toolchains
output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'
;;
+ openbsd2*)
+ # C++ shared libraries are fairly broken
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ openbsd*)
+ _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'
+ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ fi
+ output_verbose_link_cmd='echo'
+ ;;
osf3*)
case $cc_basename in
- KCC)
+ KCC*)
# Kuck and Associates, Inc. (KAI) C++ Compiler
# KCC will only create a shared library if the output file
@@ -4015,14 +3434,14 @@ case $host_os in
_LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs'
;;
- RCC)
+ RCC*)
# Rational C++ 2.4.1
# FIXME: insert proper C++ library support
_LT_AC_TAGVAR(ld_shlibs, $1)=no
;;
- cxx)
+ cxx*)
_LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && echo ${wl}-set_version $verstring` -update_registry ${objdir}/so_locations -o $lib'
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && echo ${wl}-set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
_LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
@@ -4040,7 +3459,7 @@ case $host_os in
*)
if test "$GXX" = yes && test "$with_gnu_ld" = no; then
_LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib'
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
_LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
@@ -4059,7 +3478,7 @@ case $host_os in
;;
osf4* | osf5*)
case $cc_basename in
- KCC)
+ KCC*)
# Kuck and Associates, Inc. (KAI) C++ Compiler
# KCC will only create a shared library if the output file
@@ -4074,17 +3493,17 @@ case $host_os in
# the KAI C++ compiler.
_LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs'
;;
- RCC)
+ RCC*)
# Rational C++ 2.4.1
# FIXME: insert proper C++ library support
_LT_AC_TAGVAR(ld_shlibs, $1)=no
;;
- cxx)
+ cxx*)
_LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib'
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
_LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
echo "-hidden">> $lib.exp~
- $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname -Wl,-input -Wl,$lib.exp `test -n "$verstring" && echo -set_version $verstring` -update_registry $objdir/so_locations -o $lib~
+ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname -Wl,-input -Wl,$lib.exp `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~
$rm $lib.exp'
_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
@@ -4103,7 +3522,7 @@ case $host_os in
*)
if test "$GXX" = yes && test "$with_gnu_ld" = no; then
_LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib'
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
_LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
@@ -4124,27 +3543,14 @@ case $host_os in
# FIXME: insert proper C++ library support
_LT_AC_TAGVAR(ld_shlibs, $1)=no
;;
- sco*)
- _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
- case $cc_basename in
- CC)
- # FIXME: insert proper C++ library support
- _LT_AC_TAGVAR(ld_shlibs, $1)=no
- ;;
- *)
- # FIXME: insert proper C++ library support
- _LT_AC_TAGVAR(ld_shlibs, $1)=no
- ;;
- esac
- ;;
sunos4*)
case $cc_basename in
- CC)
+ CC*)
# Sun C++ 4.x
# FIXME: insert proper C++ library support
_LT_AC_TAGVAR(ld_shlibs, $1)=no
;;
- lcc)
+ lcc*)
# Lucid
# FIXME: insert proper C++ library support
_LT_AC_TAGVAR(ld_shlibs, $1)=no
@@ -4157,36 +3563,33 @@ case $host_os in
;;
solaris*)
case $cc_basename in
- CC)
+ CC*)
# Sun C++ 4.2, 5.x and Centerline C++
+ _LT_AC_TAGVAR(archive_cmds_need_lc,$1)=yes
_LT_AC_TAGVAR(no_undefined_flag, $1)=' -zdefs'
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -nolib -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
- $CC -G${allow_undefined_flag} -nolib ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp'
+ $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp'
_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
case $host_os in
- solaris2.[0-5] | solaris2.[0-5].*) ;;
+ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
*)
# The C++ compiler is used as linker so we must use $wl
# flag to pass the commands to the underlying system
- # linker.
+ # linker. We must also pass each convience library through
+ # to the system linker between allextract/defaultextract.
+ # The C++ compiler will combine linker options so we
+ # cannot just pass the convience library names through
+ # without $wl.
# Supported since Solaris 2.6 (maybe 2.5.1?)
- _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract'
;;
esac
_LT_AC_TAGVAR(link_all_deplibs, $1)=yes
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- #
- # There doesn't appear to be a way to prevent this compiler from
- # explicitly linking system object files so we need to strip them
- # from the output so that they don't get included in the library
- # dependencies.
- output_verbose_link_cmd='templist=`$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep "\-[[LR]]"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+ output_verbose_link_cmd='echo'
# Archives containing C++ object files must be created using
# "CC -xar", where "CC" is the Sun C++ compiler. This is
@@ -4194,7 +3597,7 @@ case $host_os in
# in the archive.
_LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
;;
- gcx)
+ gcx*)
# Green Hills C++ Compiler
_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
@@ -4232,12 +3635,63 @@ case $host_os in
;;
esac
;;
- sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[[78]]* | unixware7*)
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+ _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+ runpath_var='LD_RUN_PATH'
+
+ case $cc_basename in
+ CC*)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ ;;
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We can NOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ # For security reasons, it is highly recommended that you always
+ # use absolute paths for naming shared libraries, and exclude the
+ # DT_RUNPATH tag from executables and libraries. But doing so
+ # requires that you compile everything twice, which is a pain.
+ # So that behaviour is only enabled if SCOABSPATH is set to a
+ # non-empty value in the environment. Most likely only useful for
+ # creating official distributions of packages.
+ # This is a hack until libtool officially supports absolute path
+ # names for shared libraries.
+ _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
+ _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
+ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ case $cc_basename in
+ CC*)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
;;
tandem*)
case $cc_basename in
- NCC)
+ NCC*)
# NonStop-UX NCC 3.20
# FIXME: insert proper C++ library support
_LT_AC_TAGVAR(ld_shlibs, $1)=no
@@ -4268,10 +3722,8 @@ AC_LIBTOOL_PROG_COMPILER_PIC($1)
AC_LIBTOOL_PROG_CC_C_O($1)
AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1)
AC_LIBTOOL_PROG_LD_SHLIBS($1)
-AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1)
-AC_LIBTOOL_SYS_LIB_STRIP
AC_LIBTOOL_SYS_DYNAMIC_LINKER($1)
-AC_LIBTOOL_DLOPEN_SELF($1)
+AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1)
AC_LIBTOOL_CONFIG($1)
@@ -4289,7 +3741,7 @@ lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
])# AC_LIBTOOL_LANG_CXX_CONFIG
# AC_LIBTOOL_POSTDEP_PREDEP([TAGNAME])
-# ------------------------
+# ------------------------------------
# Figure out "hidden" library dependencies from verbose
# compiler output when linking a shared library.
# Parse the compiler output and extract the necessary
@@ -4343,7 +3795,7 @@ if AC_TRY_EVAL(ac_compile); then
# The `*' in the case matches for architectures that use `case' in
# $output_verbose_cmd can trigger glob expansion during the loop
# eval without this substitution.
- output_verbose_link_cmd="`$echo \"X$output_verbose_link_cmd\" | $Xsed -e \"$no_glob_subst\"`"
+ output_verbose_link_cmd=`$echo "X$output_verbose_link_cmd" | $Xsed -e "$no_glob_subst"`
for p in `eval $output_verbose_link_cmd`; do
case $p in
@@ -4419,13 +3871,37 @@ fi
$rm -f confest.$objext
+# PORTME: override above test on systems where it is broken
+ifelse([$1],[CXX],
+[case $host_os in
+interix3*)
+ # Interix 3.5 installs completely hosed .la files for C++, so rather than
+ # hack all around it, let's just trust "g++" to DTRT.
+ _LT_AC_TAGVAR(predep_objects,$1)=
+ _LT_AC_TAGVAR(postdep_objects,$1)=
+ _LT_AC_TAGVAR(postdeps,$1)=
+ ;;
+
+solaris*)
+ case $cc_basename in
+ CC*)
+ # Adding this requires a known-good setup of shared libraries for
+ # Sun compiler versions before 5.6, else PIC objects from an old
+ # archive will be linked into the output, leading to subtle bugs.
+ _LT_AC_TAGVAR(postdeps,$1)='-lCstd -lCrun'
+ ;;
+ esac
+ ;;
+esac
+])
+
case " $_LT_AC_TAGVAR(postdeps, $1) " in
*" -lc "*) _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no ;;
esac
])# AC_LIBTOOL_POSTDEP_PREDEP
# AC_LIBTOOL_LANG_F77_CONFIG
-# ------------------------
+# --------------------------
# Ensure that the configuration vars for the C compiler are
# suitably defined. Those variables are subsequently used by
# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'.
@@ -4469,12 +3945,16 @@ lt_simple_link_test_code=" program t\n end\n"
# ltmain only uses $CC for tagged configurations so make sure $CC is set.
_LT_AC_SYS_COMPILER
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
# Allow CC to be a program name with arguments.
lt_save_CC="$CC"
CC=${F77-"f77"}
compiler=$CC
_LT_AC_TAGVAR(compiler, $1)=$CC
-cc_basename=`$echo X"$compiler" | $Xsed -e 's%^.*/%%'`
+_LT_CC_BASENAME([$compiler])
AC_MSG_CHECKING([if libtool supports shared libraries])
AC_MSG_RESULT([$can_build_shared])
@@ -4484,7 +3964,7 @@ test "$can_build_shared" = "no" && enable_shared=no
# On AIX, shared libraries and static libraries use the same namespace, and
# are all built from PIC.
-case "$host_os" in
+case $host_os in
aix3*)
test "$enable_shared" = yes && enable_static=no
if test -n "$RANLIB"; then
@@ -4492,8 +3972,10 @@ aix3*)
postinstall_cmds='$RANLIB $lib'
fi
;;
-aix4*)
- test "$enable_shared" = yes && enable_static=no
+aix4* | aix5*)
+ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+ test "$enable_shared" = yes && enable_static=no
+ fi
;;
esac
AC_MSG_RESULT([$enable_shared])
@@ -4503,8 +3985,6 @@ AC_MSG_CHECKING([whether to build static libraries])
test "$enable_shared" = yes || enable_static=yes
AC_MSG_RESULT([$enable_static])
-test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
-
_LT_AC_TAGVAR(GCC, $1)="$G77"
_LT_AC_TAGVAR(LD, $1)="$LD"
@@ -4512,9 +3992,8 @@ AC_LIBTOOL_PROG_COMPILER_PIC($1)
AC_LIBTOOL_PROG_CC_C_O($1)
AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1)
AC_LIBTOOL_PROG_LD_SHLIBS($1)
-AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1)
-AC_LIBTOOL_SYS_LIB_STRIP
AC_LIBTOOL_SYS_DYNAMIC_LINKER($1)
+AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1)
AC_LIBTOOL_CONFIG($1)
@@ -4543,29 +4022,34 @@ _LT_AC_TAGVAR(objext, $1)=$objext
lt_simple_compile_test_code="class foo {}\n"
# Code to be used in simple link tests
-lt_simple_link_test_code='public class conftest { public static void main(String[] argv) {}; }\n'
+lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }\n'
# ltmain only uses $CC for tagged configurations so make sure $CC is set.
_LT_AC_SYS_COMPILER
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
# Allow CC to be a program name with arguments.
lt_save_CC="$CC"
CC=${GCJ-"gcj"}
compiler=$CC
_LT_AC_TAGVAR(compiler, $1)=$CC
+_LT_CC_BASENAME([$compiler])
# GCJ did not exist at the time GCC didn't implicitly link libc in.
_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_AC_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+
AC_LIBTOOL_PROG_COMPILER_NO_RTTI($1)
AC_LIBTOOL_PROG_COMPILER_PIC($1)
AC_LIBTOOL_PROG_CC_C_O($1)
AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1)
AC_LIBTOOL_PROG_LD_SHLIBS($1)
-AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1)
-AC_LIBTOOL_SYS_LIB_STRIP
AC_LIBTOOL_SYS_DYNAMIC_LINKER($1)
-AC_LIBTOOL_DLOPEN_SELF($1)
+AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1)
AC_LIBTOOL_CONFIG($1)
@@ -4575,7 +4059,7 @@ CC="$lt_save_CC"
# AC_LIBTOOL_LANG_RC_CONFIG
-# --------------------------
+# -------------------------
# Ensure that the configuration vars for the Windows resource compiler are
# suitably defined. Those variables are subsequently used by
# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'.
@@ -4599,11 +4083,16 @@ lt_simple_link_test_code="$lt_simple_compile_test_code"
# ltmain only uses $CC for tagged configurations so make sure $CC is set.
_LT_AC_SYS_COMPILER
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
# Allow CC to be a program name with arguments.
lt_save_CC="$CC"
CC=${RC-"windres"}
compiler=$CC
_LT_AC_TAGVAR(compiler, $1)=$CC
+_LT_CC_BASENAME([$compiler])
_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
AC_LIBTOOL_CONFIG($1)
@@ -4629,11 +4118,12 @@ if test -f "$ltmain"; then
# without removal of \ escapes.
if test -n "${ZSH_VERSION+set}" ; then
setopt NO_GLOB_SUBST
- fi
+ fi
# Now quote all the things that may contain metacharacters while being
# careful not to overquote the AC_SUBSTed values. We take copies of the
# variables and quote the copies for generation of the libtool script.
- for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC NM SED SHELL \
+ for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \
+ SED SHELL STRIP \
libname_spec library_names_spec soname_spec extract_expsyms_cmds \
old_striplib striplib file_magic_cmd finish_cmds finish_eval \
deplibs_check_method reload_flag reload_cmds need_locks \
@@ -4683,7 +4173,7 @@ if test -f "$ltmain"; then
_LT_AC_TAGVAR(archive_cmds, $1) | \
_LT_AC_TAGVAR(archive_expsym_cmds, $1) | \
_LT_AC_TAGVAR(module_cmds, $1) | \
- _LT_AC_TAGVAR(module_expsym_cmds, $1) | \
+ _LT_AC_TAGVAR(module_expsym_cmds, $1) | \
_LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1) | \
_LT_AC_TAGVAR(export_symbols_cmds, $1) | \
extract_expsyms_cmds | reload_cmds | finish_cmds | \
@@ -4738,7 +4228,7 @@ ifelse([$1], [],
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
@@ -4749,11 +4239,11 @@ ifelse([$1], [],
SED=$lt_SED
# Sed that helps us avoid accidentally triggering echo(1) options like -n.
-Xsed="$SED -e s/^X//"
+Xsed="$SED -e 1s/^X//"
# The HP-UX ksh and POSIX shell print the target directory to stdout
# if CDPATH is set.
-if test "X\${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
# The names of the tagged configurations supported by this script.
available_tags=
@@ -4784,6 +4274,12 @@ fast_install=$enable_fast_install
# The host system.
host_alias=$host_alias
host=$host
+host_os=$host_os
+
+# The build system.
+build_alias=$build_alias
+build=$build
+build_os=$build_os
# An echo program that does not interpret backslashes.
echo=$lt_echo
@@ -4795,6 +4291,9 @@ AR_FLAGS=$lt_AR_FLAGS
# A C compiler.
LTCC=$lt_LTCC
+# LTCC compiler flags.
+LTCFLAGS=$lt_LTCFLAGS
+
# A language-specific compiler.
CC=$lt_[]_LT_AC_TAGVAR(compiler, $1)
@@ -4814,7 +4313,7 @@ LN_S=$lt_LN_S
NM=$lt_NM
# A symbol stripping program
-STRIP=$STRIP
+STRIP=$lt_STRIP
# Used to examine libraries when file_magic_cmd begins "file"
MAGIC_CMD=$MAGIC_CMD
@@ -4845,7 +4344,7 @@ objext="$ac_objext"
libext="$libext"
# Shared library suffix (normally ".so").
-shrext='$shrext'
+shrext_cmds='$shrext_cmds'
# Executable file suffix (normally "").
exeext="$exeext"
@@ -4860,7 +4359,7 @@ max_cmd_len=$lt_cv_sys_max_cmd_len
# Does compiler simultaneously support -c and -o options?
compiler_c_o=$lt_[]_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)
-# Must we lock files when doing compilation ?
+# Must we lock files when doing compilation?
need_locks=$lt_need_locks
# Do we need the lib prefix for modules?
@@ -5089,7 +4588,10 @@ else
# If there is no Makefile yet, we rely on a make rule to execute
# `config.status --recheck' to rerun these tests and create the
# libtool script then.
- test -f Makefile && make "$ltmain"
+ ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'`
+ if test -f "$ltmain_in"; then
+ test -f Makefile && make "$ltmain"
+ fi
fi
])# AC_LIBTOOL_CONFIG
@@ -5131,9 +4633,6 @@ symcode='[[BCDEGRST]]'
# Regexp to match symbols that can be accessed directly from C.
sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)'
-# Transform the above into a raw symbol and a C symbol.
-symxfrm='\1 \2\3 \3'
-
# Transform an extracted symbol line into a proper C declaration
lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern int \1;/p'"
@@ -5155,15 +4654,31 @@ hpux*) # Its linker distinguishes data from code symbols
lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'"
;;
+linux*)
+ if test "$host_cpu" = ia64; then
+ symcode='[[ABCDGIRSTW]]'
+ lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+ lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'"
+ fi
+ ;;
irix* | nonstopux*)
symcode='[[BCDEGRST]]'
;;
osf*)
symcode='[[BCDEGQRST]]'
;;
-solaris* | sysv5*)
+solaris*)
symcode='[[BDRT]]'
;;
+sco3.2v5*)
+ symcode='[[DT]]'
+ ;;
+sysv4.2uw2*)
+ symcode='[[DT]]'
+ ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+ symcode='[[ABDT]]'
+ ;;
sysv4)
symcode='[[DFNSTU]]'
;;
@@ -5186,8 +4701,11 @@ esac
# Try without a prefix undercore, then with it.
for ac_symprfx in "" "_"; do
+ # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+ symxfrm="\\1 $ac_symprfx\\2 \\2"
+
# Write the raw and C identifiers.
- lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*\($ac_symprfx\)$sympat$opt_cr$/$symxfrm/p'"
+ lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
# Check to see that the pipe works correctly.
pipe_works=no
@@ -5343,6 +4861,10 @@ AC_MSG_CHECKING([for $compiler option to produce PIC])
# DJGPP does not support shared libraries at all
_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
;;
+ interix3*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
sysv4*MP*)
if test -d /usr/nec; then
_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
@@ -5351,7 +4873,7 @@ AC_MSG_CHECKING([for $compiler option to produce PIC])
hpux*)
# PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
# not for PA HP-UX.
- case "$host_cpu" in
+ case $host_cpu in
hppa*64*|ia64*)
;;
*)
@@ -5376,18 +4898,28 @@ AC_MSG_CHECKING([for $compiler option to produce PIC])
;;
chorus*)
case $cc_basename in
- cxch68)
+ cxch68*)
# Green Hills C++ Compiler
# _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"
;;
esac
;;
+ darwin*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ case $cc_basename in
+ xlc*)
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-qnocommon'
+ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ ;;
+ esac
+ ;;
dgux*)
case $cc_basename in
- ec++)
+ ec++*)
_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
;;
- ghcx)
+ ghcx*)
# Green Hills C++ Compiler
_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
;;
@@ -5395,22 +4927,22 @@ AC_MSG_CHECKING([for $compiler option to produce PIC])
;;
esac
;;
- freebsd*)
+ freebsd* | kfreebsd*-gnu | dragonfly*)
# FreeBSD uses GNU C++
;;
hpux9* | hpux10* | hpux11*)
case $cc_basename in
- CC)
+ CC*)
_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive"
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
if test "$host_cpu" != ia64; then
_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
fi
;;
- aCC)
+ aCC*)
_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
- _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive"
- case "$host_cpu" in
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+ case $host_cpu in
hppa*64*|ia64*)
# +Z the default
;;
@@ -5423,9 +4955,13 @@ AC_MSG_CHECKING([for $compiler option to produce PIC])
;;
esac
;;
+ interix*)
+ # This is c89, which is MS Visual C++ (no shared libs)
+ # Anyone wants to do a port?
+ ;;
irix5* | irix6* | nonstopux*)
case $cc_basename in
- CC)
+ CC*)
_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
_LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
# CC pic flag -KPIC is the default.
@@ -5436,18 +4972,24 @@ AC_MSG_CHECKING([for $compiler option to produce PIC])
;;
linux*)
case $cc_basename in
- KCC)
+ KCC*)
# KAI C++ Compiler
_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
;;
- icpc)
+ icpc* | ecpc*)
# Intel C++
_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
_LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static'
- ;;
- cxx)
+ ;;
+ pgCC*)
+ # Portland Group C++ compiler.
+ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ cxx*)
# Compaq C++
# Make sure the PIC flag is empty. It appears that all Alpha
# Linux and Compaq Tru64 Unix objects are PIC.
@@ -5464,25 +5006,25 @@ AC_MSG_CHECKING([for $compiler option to produce PIC])
;;
mvs*)
case $cc_basename in
- cxx)
+ cxx*)
_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall'
;;
*)
;;
esac
;;
- netbsd*)
+ netbsd* | netbsdelf*-gnu | knetbsd*-gnu)
;;
osf3* | osf4* | osf5*)
case $cc_basename in
- KCC)
+ KCC*)
_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
;;
- RCC)
+ RCC*)
# Rational C++ 2.4.1
_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
;;
- cxx)
+ cxx*)
# Digital/Compaq C++
_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
# Make sure the PIC flag is empty. It appears that all Alpha
@@ -5496,24 +5038,15 @@ AC_MSG_CHECKING([for $compiler option to produce PIC])
;;
psos*)
;;
- sco*)
- case $cc_basename in
- CC)
- _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
- ;;
- *)
- ;;
- esac
- ;;
solaris*)
case $cc_basename in
- CC)
+ CC*)
# Sun C++ 4.2, 5.x and Centerline C++
_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
_LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
;;
- gcx)
+ gcx*)
# Green Hills C++ Compiler
_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
;;
@@ -5523,12 +5056,12 @@ AC_MSG_CHECKING([for $compiler option to produce PIC])
;;
sunos4*)
case $cc_basename in
- CC)
+ CC*)
# Sun C++ 4.x
_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
_LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
;;
- lcc)
+ lcc*)
# Lucid
_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
;;
@@ -5538,7 +5071,7 @@ AC_MSG_CHECKING([for $compiler option to produce PIC])
;;
tandem*)
case $cc_basename in
- NCC)
+ NCC*)
# NonStop-UX NCC 3.20
_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
;;
@@ -5546,7 +5079,14 @@ AC_MSG_CHECKING([for $compiler option to produce PIC])
;;
esac
;;
- unixware*)
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ case $cc_basename in
+ CC*)
+ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ esac
;;
vxworks*)
;;
@@ -5593,6 +5133,11 @@ AC_MSG_CHECKING([for $compiler option to produce PIC])
_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
;;
+ interix3*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+
msdosdjgpp*)
# Just because we use GCC doesn't mean we suddenly get shared libraries
# on systems that don't support them.
@@ -5609,7 +5154,7 @@ AC_MSG_CHECKING([for $compiler option to produce PIC])
hpux*)
# PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
# not for PA HP-UX.
- case "$host_cpu" in
+ case $host_cpu in
hppa*64*|ia64*)
# +Z the default
;;
@@ -5635,6 +5180,16 @@ AC_MSG_CHECKING([for $compiler option to produce PIC])
_LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
fi
;;
+ darwin*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ case $cc_basename in
+ xlc*)
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-qnocommon'
+ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ ;;
+ esac
+ ;;
mingw* | pw32* | os2*)
# This hack is so that the source file can tell whether it is being
@@ -5646,7 +5201,7 @@ AC_MSG_CHECKING([for $compiler option to produce PIC])
_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
# PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
# not for PA HP-UX.
- case "$host_cpu" in
+ case $host_cpu in
hppa*64*|ia64*)
# +Z the default
;;
@@ -5670,13 +5225,20 @@ AC_MSG_CHECKING([for $compiler option to produce PIC])
;;
linux*)
- case $CC in
- icc|ecc)
+ case $cc_basename in
+ icc* | ecc*)
_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
_LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static'
;;
- ccc)
+ pgcc* | pgf77* | pgf90* | pgf95*)
+ # Portland Group compilers (*not* the Pentium gcc compiler,
+ # which looks to be a dead project)
+ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ ccc*)
_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
# All Alpha code is PIC.
_LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
@@ -5690,15 +5252,15 @@ AC_MSG_CHECKING([for $compiler option to produce PIC])
_LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
;;
- sco3.2v5*)
- _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-Kpic'
- _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-dn'
- ;;
-
solaris*)
- _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
_LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ case $cc_basename in
+ f77* | f90* | f95*)
+ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';;
+ *)
+ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';;
+ esac
;;
sunos4*)
@@ -5707,7 +5269,7 @@ AC_MSG_CHECKING([for $compiler option to produce PIC])
_LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
;;
- sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ sysv4 | sysv4.2uw2* | sysv4.3*)
_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
_LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
@@ -5720,6 +5282,17 @@ AC_MSG_CHECKING([for $compiler option to produce PIC])
fi
;;
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ unicos*)
+ _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ ;;
+
uts4*)
_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
_LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
@@ -5747,7 +5320,7 @@ if test -n "$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)"; then
[_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
_LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no])
fi
-case "$host_os" in
+case $host_os in
# For platforms which do not support PIC, -DPIC is meaningless:
*djgpp*)
_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
@@ -5756,6 +5329,16 @@ case "$host_os" in
_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])"
;;
esac
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_AC_TAGVAR(lt_prog_compiler_static, $1)\"
+AC_LIBTOOL_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works],
+ _LT_AC_TAGVAR(lt_prog_compiler_static_works, $1),
+ $lt_tmp_static_flag,
+ [],
+ [_LT_AC_TAGVAR(lt_prog_compiler_static, $1)=])
])
@@ -5780,7 +5363,13 @@ ifelse([$1],[CXX],[
_LT_AC_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds"
;;
cygwin* | mingw*)
- _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGS]] /s/.* \([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols'
+ _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]] /s/.* \([[^ ]]*\)/\1 DATA/;/^.* __nm__/s/^.* __nm__\([[^ ]]*\) [[^ ]]*/\1 DATA/;/^I /d;/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols'
+ ;;
+ kfreebsd*-gnu)
+ _LT_AC_TAGVAR(link_all_deplibs, $1)=no
+ ;;
+ linux*)
+ _LT_AC_TAGVAR(link_all_deplibs, $1)=no
;;
*)
_LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
@@ -5806,7 +5395,7 @@ ifelse([$1],[CXX],[
_LT_AC_TAGVAR(link_all_deplibs, $1)=unknown
_LT_AC_TAGVAR(hardcode_automatic, $1)=no
_LT_AC_TAGVAR(module_cmds, $1)=
- _LT_AC_TAGVAR(module_expsym_cmds, $1)=
+ _LT_AC_TAGVAR(module_expsym_cmds, $1)=
_LT_AC_TAGVAR(always_export_symbols, $1)=no
_LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
# include_expsyms should be a list of space-separated symbols to be *always*
@@ -5823,7 +5412,8 @@ ifelse([$1],[CXX],[
# rely on this symbol name, it's probably fine to never include it in
# preloaded symbol tables.
extract_expsyms_cmds=
-
+ # Just being paranoid about ensuring that cc_basename is set.
+ _LT_CC_BASENAME([$compiler])
case $host_os in
cygwin* | mingw* | pw32*)
# FIXME: the MSVC++ port hasn't been tested in a loooong time
@@ -5833,6 +5423,10 @@ ifelse([$1],[CXX],[
with_gnu_ld=no
fi
;;
+ interix*)
+ # we just hope/assume this is gcc and not c89 (= MSVC++)
+ with_gnu_ld=yes
+ ;;
openbsd*)
with_gnu_ld=no
;;
@@ -5843,6 +5437,27 @@ ifelse([$1],[CXX],[
# If archive_cmds runs LD, not CC, wlarc should be empty
wlarc='${wl}'
+ # Set some defaults for GNU ld with shared library support. These
+ # are reset later if shared libraries are not supported. Putting them
+ # here allows them to be overridden if necessary.
+ runpath_var=LD_RUN_PATH
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'
+ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then
+ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ else
+ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=
+ fi
+ supports_anon_versioning=no
+ case `$LD -v 2>/dev/null` in
+ *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11
+ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+ *\ 2.11.*) ;; # other 2.11 versions
+ *) supports_anon_versioning=yes ;;
+ esac
+
# See if GNU ld supports shared libraries.
case $host_os in
aix3* | aix4* | aix5*)
@@ -5893,10 +5508,10 @@ EOF
_LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
_LT_AC_TAGVAR(always_export_symbols, $1)=no
_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
- _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGS]] /s/.* \([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols'
+ _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]] /s/.* \([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols'
if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib'
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
# If the export-symbols file already is a .def file (1st line
# is EXPORTS), use it as is; otherwise, prepend...
_LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
@@ -5905,13 +5520,60 @@ EOF
echo EXPORTS > $output_objdir/$soname.def;
cat $export_symbols >> $output_objdir/$soname.def;
fi~
- $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib'
+ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ interix3*)
+ _LT_AC_TAGVAR(hardcode_direct, $1)=no
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+
+ linux*)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ tmp_addflag=
+ case $cc_basename,$host_cpu in
+ pgcc*) # Portland Group C compiler
+ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
+ tmp_addflag=' $pic_flag'
+ ;;
+ pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers
+ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
+ tmp_addflag=' $pic_flag -Mnomain' ;;
+ ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
+ tmp_addflag=' -i_dynamic' ;;
+ efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64
+ tmp_addflag=' -i_dynamic -nofor_main' ;;
+ ifc* | ifort*) # Intel Fortran compiler
+ tmp_addflag=' -nofor_main' ;;
+ esac
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+
+ if test $supports_anon_versioning = yes; then
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ $echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+ fi
+ _LT_AC_TAGVAR(link_all_deplibs, $1)=no
else
- ld_shlibs=no
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
fi
;;
- netbsd*)
+ netbsd* | netbsdelf*-gnu | knetbsd*-gnu)
if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
_LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
wlarc=
@@ -5921,7 +5583,7 @@ EOF
fi
;;
- solaris* | sysv5*)
+ solaris*)
if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
_LT_AC_TAGVAR(ld_shlibs, $1)=no
cat <<EOF 1>&2
@@ -5942,6 +5604,33 @@ EOF
fi
;;
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+ case `$LD -v 2>&1` in
+ *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*)
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ ;;
+ *)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`'
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib'
+ else
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
sunos4*)
_LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
wlarc=
@@ -5949,31 +5638,6 @@ EOF
_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
;;
- linux*)
- if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
- tmp_archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- _LT_AC_TAGVAR(archive_cmds, $1)="$tmp_archive_cmds"
- supports_anon_versioning=no
- case `$LD -v 2>/dev/null` in
- *\ [01].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11
- *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
- *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
- *\ 2.11.*) ;; # other 2.11 versions
- *) supports_anon_versioning=yes ;;
- esac
- if test $supports_anon_versioning = yes; then
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $output_objdir/$libname.ver~
-cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
-$echo "local: *; };" >> $output_objdir/$libname.ver~
- $CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
- else
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)="$tmp_archive_cmds"
- fi
- else
- _LT_AC_TAGVAR(ld_shlibs, $1)=no
- fi
- ;;
-
*)
if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
@@ -5984,16 +5648,11 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~
;;
esac
- if test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = yes; then
- runpath_var=LD_RUN_PATH
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'
- _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
- # ancient GNU ld didn't support --whole-archive et. al.
- if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then
- _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
- else
- _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=
- fi
+ if test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no; then
+ runpath_var=
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=
+ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=
+ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=
fi
else
# PORTME fill in a description of your system's linker (not GNU ld)
@@ -6005,7 +5664,7 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~
# Note: this linker hardcodes the directories in LIBPATH if there
# are no directories specified by -L.
_LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
- if test "$GCC" = yes && test -z "$link_static_flag"; then
+ if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
# Neither direct hardcoding nor static linking is supported with a
# broken collect2.
_LT_AC_TAGVAR(hardcode_direct, $1)=unsupported
@@ -6039,6 +5698,7 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~
break
fi
done
+ ;;
esac
exp_sym_flag='-bexport'
@@ -6057,7 +5717,7 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~
_LT_AC_TAGVAR(link_all_deplibs, $1)=yes
if test "$GCC" = yes; then
- case $host_os in aix4.[012]|aix4.[012].*)
+ case $host_os in aix4.[[012]]|aix4.[[012]].*)
# We only want to do this on AIX 4.2 and lower, the check
# below for broken collect2 doesn't work under 4.3+
collect2name=`${CC} -print-prog-name=collect2`
@@ -6076,8 +5736,12 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~
_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
_LT_AC_TAGVAR(hardcode_libdir_separator, $1)=
fi
+ ;;
esac
shared_flag='-shared'
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag="$shared_flag "'${wl}-G'
+ fi
else
# not using gcc
if test "$host_cpu" = ia64; then
@@ -6085,11 +5749,11 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~
# chokes on -Wl,-G. The following line is correct:
shared_flag='-G'
else
- if test "$aix_use_runtimelinking" = yes; then
+ if test "$aix_use_runtimelinking" = yes; then
shared_flag='${wl}-G'
else
shared_flag='${wl}-bM:SRE'
- fi
+ fi
fi
fi
@@ -6103,12 +5767,12 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~
# Determine the default libpath from the value encoded in an empty executable.
_LT_AC_SYS_LIBPATH_AIX
_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
else
if test "$host_cpu" = ia64; then
_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
_LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
else
# Determine the default libpath from the value encoded in an empty executable.
_LT_AC_SYS_LIBPATH_AIX
@@ -6117,13 +5781,11 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~
# -berok will link without error, but may produce a broken library.
_LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
_LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
- # -bexpall does not export symbols beginning with underscore (_)
- _LT_AC_TAGVAR(always_export_symbols, $1)=yes
# Exported symbols can be pulled into shared objects from archives
- _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=' '
+ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes
- # This is similar to how AIX traditionally builds it's shared libraries.
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+ # This is similar to how AIX traditionally builds its shared libraries.
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
fi
fi
;;
@@ -6136,7 +5798,7 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~
_LT_AC_TAGVAR(ld_shlibs, $1)=no
;;
- bsdi4*)
+ bsdi[[45]]*)
_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic
;;
@@ -6150,56 +5812,65 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~
# Tell ltmain to make .lib files, not .a files.
libext=lib
# Tell ltmain to make .dll files, not .so files.
- shrext=".dll"
+ shrext_cmds=".dll"
# FIXME: Setting linknames here is a bad hack.
_LT_AC_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames='
# The linker will automatically build a .lib file if we build a DLL.
_LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='true'
# FIXME: Should let the user specify the lib program.
_LT_AC_TAGVAR(old_archive_cmds, $1)='lib /OUT:$oldlib$oldobjs$old_deplibs'
- fix_srcfile_path='`cygpath -w "$srcfile"`'
+ _LT_AC_TAGVAR(fix_srcfile_path, $1)='`cygpath -w "$srcfile"`'
_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
;;
darwin* | rhapsody*)
- if $CC -v 2>&1 | grep 'Apple' >/dev/null ; then
- _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
- case "$host_os" in
- rhapsody* | darwin1.[[012]])
- _LT_AC_TAGVAR(allow_undefined_flag, $1)='-undefined suppress'
- ;;
- *) # Darwin 1.3 on
- test -z ${LD_TWOLEVEL_NAMESPACE} && _LT_AC_TAGVAR(allow_undefined_flag, $1)='-flat_namespace -undefined suppress'
- ;;
+ case $host_os in
+ rhapsody* | darwin1.[[012]])
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}suppress'
+ ;;
+ *) # Darwin 1.3 on
+ if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
+ else
+ case ${MACOSX_DEPLOYMENT_TARGET} in
+ 10.[[012]])
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
+ ;;
+ 10.*)
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}dynamic_lookup'
+ ;;
+ esac
+ fi
+ ;;
esac
- # FIXME: Relying on posixy $() will cause problems for
- # cross-compilation, but unfortunately the echo tests do not
- # yet detect zsh echo's removal of \ escapes. Also zsh mangles
- # `"' quotes if we put them in here... so don't!
- lt_int_apple_cc_single_mod=no
- output_verbose_link_cmd='echo'
- if $CC -dumpspecs 2>&1 | grep 'single_module' >/dev/null ; then
- lt_int_apple_cc_single_mod=yes
- fi
- if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
- else
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
- fi
- _LT_AC_TAGVAR(module_cmds, $1)='$CC -bundle ${wl}-bind_at_load $allow_undefined_flag -o $lib $libobjs $deplibs$compiler_flags'
- # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's
- if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
- else
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
- fi
- _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -bundle $allow_undefined_flag -o $lib $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
_LT_AC_TAGVAR(hardcode_direct, $1)=no
_LT_AC_TAGVAR(hardcode_automatic, $1)=yes
_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
- _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-all_load $convenience'
+ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=''
_LT_AC_TAGVAR(link_all_deplibs, $1)=yes
- fi
+ if test "$GCC" = yes ; then
+ output_verbose_link_cmd='echo'
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+ _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+ # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ else
+ case $cc_basename in
+ xlc*)
+ output_verbose_link_cmd='echo'
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring'
+ _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+ # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ ;;
+ *)
+ _LT_AC_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ fi
;;
dgux*)
@@ -6232,12 +5903,21 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~
;;
# FreeBSD 3 and greater uses gcc -shared to do shared libraries.
- freebsd*)
+ freebsd* | dragonfly*)
_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
_LT_AC_TAGVAR(hardcode_direct, $1)=yes
_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
;;
+
+ # GNU/kFreeBSD uses gcc -shared to do shared libraries.
+ kfreebsd*-gnu)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+ _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_AC_TAGVAR(link_all_deplibs, $1)=no
+ ;;
hpux9*)
if test "$GCC" = yes; then
@@ -6255,47 +5935,62 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~
_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
;;
- hpux10* | hpux11*)
+ hpux10*)
if test "$GCC" = yes -a "$with_gnu_ld" = no; then
- case "$host_cpu" in
- hppa*64*|ia64*)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ if test "$with_gnu_ld" = no; then
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+ fi
+ ;;
+
+ hpux11*)
+ if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+ case $host_cpu in
+ hppa*64*)
_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
;;
+ ia64*)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
*)
_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
;;
esac
else
- case "$host_cpu" in
- hppa*64*|ia64*)
- _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $libobjs $deplibs $linker_flags'
+ case $host_cpu in
+ hppa*64*)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
*)
- _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
;;
esac
fi
if test "$with_gnu_ld" = no; then
- case "$host_cpu" in
- hppa*64*)
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir'
- _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
_LT_AC_TAGVAR(hardcode_direct, $1)=no
_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
;;
- ia64*)
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
- _LT_AC_TAGVAR(hardcode_direct, $1)=no
- _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
-
- # hardcode_minus_L: Not really in the search PATH,
- # but as the default location of the library.
- _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
- ;;
*)
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
- _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
_LT_AC_TAGVAR(hardcode_direct, $1)=yes
_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
@@ -6319,7 +6014,7 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~
_LT_AC_TAGVAR(link_all_deplibs, $1)=yes
;;
- netbsd*)
+ netbsd* | netbsdelf*-gnu | knetbsd*-gnu)
if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
_LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
else
@@ -6343,6 +6038,7 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~
_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
else
@@ -6388,7 +6084,7 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~
_LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
_LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
_LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~
- $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib~$rm $lib.exp'
+ $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp'
# Both c and cxx compiler support -rpath directly
_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
@@ -6396,21 +6092,15 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~
_LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
;;
- sco3.2v5*)
- _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
- _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
- runpath_var=LD_RUN_PATH
- hardcode_runpath_var=yes
- ;;
-
solaris*)
_LT_AC_TAGVAR(no_undefined_flag, $1)=' -z text'
if test "$GCC" = yes; then
+ wlarc='${wl}'
_LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
$CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp'
else
+ wlarc=''
_LT_AC_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
_LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
$LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
@@ -6419,8 +6109,18 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~
_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
case $host_os in
solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
- *) # Supported since Solaris 2.6 (maybe 2.5.1?)
- _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;;
+ *)
+ # The compiler driver will combine linker options so we
+ # cannot just pass the convience library names through
+ # without $wl, iff we do not link with $LD.
+ # Luckily, gcc supports the same syntax we need for Sun Studio.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ case $wlarc in
+ '')
+ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;;
+ *)
+ _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;;
+ esac ;;
esac
_LT_AC_TAGVAR(link_all_deplibs, $1)=yes
;;
@@ -6477,36 +6177,45 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~
fi
;;
- sysv4.2uw2*)
- _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags'
- _LT_AC_TAGVAR(hardcode_direct, $1)=yes
- _LT_AC_TAGVAR(hardcode_minus_L, $1)=no
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7*)
+ _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+ _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
- hardcode_runpath_var=yes
- runpath_var=LD_RUN_PATH
- ;;
+ runpath_var='LD_RUN_PATH'
- sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[[78]]* | unixware7*)
- _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z ${wl}text'
if test "$GCC" = yes; then
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
else
- _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
fi
- runpath_var='LD_RUN_PATH'
- _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
;;
- sysv5*)
- _LT_AC_TAGVAR(no_undefined_flag, $1)=' -z text'
- # $CC -shared without GNU ld will not create a library from C++
- # object files and a static libstdc++, better avoid it by now
- _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
- _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
- $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
- _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We can NOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+ _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
+ _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
+ _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
runpath_var='LD_RUN_PATH'
+
+ if test "$GCC" = yes; then
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
;;
uts4*)
@@ -6524,11 +6233,6 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~
AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)])
test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
-variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
-if test "$GCC" = yes; then
- variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
-fi
-
#
# Do we need to explicitly link libc?
#
@@ -6549,13 +6253,14 @@ x|xyes)
AC_MSG_CHECKING([whether -lc should be explicitly linked in])
$rm conftest*
printf "$lt_simple_compile_test_code" > conftest.$ac_ext
-
+
if AC_TRY_EVAL(ac_compile) 2>conftest.err; then
soname=conftest
lib=conftest
libobjs=conftest.$ac_objext
deplibs=
wl=$_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)
+ pic_flag=$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)
compiler_flags=-v
linker_flags=-v
verstring=
@@ -6681,7 +6386,7 @@ lt_ac_count=0
# Add /usr/xpg4/bin/sed as it is typically found on Solaris
# along with /bin/sed that truncates output.
for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
- test ! -f $lt_ac_sed && break
+ test ! -f $lt_ac_sed && continue
cat /dev/null > conftest.in
lt_ac_count=0
echo $ECHO_N "0123456789$ECHO_C" >conftest.in
@@ -6706,21 +6411,868 @@ for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
fi
done
done
-SED=$lt_cv_path_SED
])
+SED=$lt_cv_path_SED
AC_MSG_RESULT([$SED])
])
+# Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_AUTOMAKE_VERSION(VERSION)
+# ----------------------------
+# Automake X.Y traces this macro to ensure aclocal.m4 has been
+# generated from the m4 files accompanying Automake X.Y.
+AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.9"])
+
+# AM_SET_CURRENT_AUTOMAKE_VERSION
+# -------------------------------
+# Call AM_AUTOMAKE_VERSION so it can be traced.
+# This function is AC_REQUIREd by AC_INIT_AUTOMAKE.
+AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
+ [AM_AUTOMAKE_VERSION([1.9.6])])
+
+# AM_AUX_DIR_EXPAND -*- Autoconf -*-
+
+# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
+# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
+# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
+#
+# Of course, Automake must honor this variable whenever it calls a
+# tool from the auxiliary directory. The problem is that $srcdir (and
+# therefore $ac_aux_dir as well) can be either absolute or relative,
+# depending on how configure is run. This is pretty annoying, since
+# it makes $ac_aux_dir quite unusable in subdirectories: in the top
+# source directory, any form will work fine, but in subdirectories a
+# relative path needs to be adjusted first.
+#
+# $ac_aux_dir/missing
+# fails when called from a subdirectory if $ac_aux_dir is relative
+# $top_srcdir/$ac_aux_dir/missing
+# fails if $ac_aux_dir is absolute,
+# fails when called from a subdirectory in a VPATH build with
+# a relative $ac_aux_dir
+#
+# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
+# are both prefixed by $srcdir. In an in-source build this is usually
+# harmless because $srcdir is `.', but things will broke when you
+# start a VPATH build or use an absolute $srcdir.
+#
+# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
+# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
+# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
+# and then we would define $MISSING as
+# MISSING="\${SHELL} $am_aux_dir/missing"
+# This will work as long as MISSING is not called from configure, because
+# unfortunately $(top_srcdir) has no meaning in configure.
+# However there are other variables, like CC, which are often used in
+# configure, and could therefore not use this "fixed" $ac_aux_dir.
+#
+# Another solution, used here, is to always expand $ac_aux_dir to an
+# absolute PATH. The drawback is that using absolute paths prevent a
+# configured tree to be moved without reconfiguration.
+
+AC_DEFUN([AM_AUX_DIR_EXPAND],
+[dnl Rely on autoconf to set up CDPATH properly.
+AC_PREREQ([2.50])dnl
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+])
+
+# AM_CONDITIONAL -*- Autoconf -*-
+
+# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 7
+
+# AM_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[AC_PREREQ(2.52)dnl
+ ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
+ [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
+AC_SUBST([$1_TRUE])
+AC_SUBST([$1_FALSE])
+if $2; then
+ $1_TRUE=
+ $1_FALSE='#'
+else
+ $1_TRUE='#'
+ $1_FALSE=
+fi
+AC_CONFIG_COMMANDS_PRE(
+[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
+ AC_MSG_ERROR([[conditional "$1" was never defined.
+Usually this means the macro was only invoked conditionally.]])
+fi])])
+
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 8
+
+# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
+# written in clear, in which case automake, when reading aclocal.m4,
+# will think it sees a *use*, and therefore will trigger all it's
+# C support machinery. Also note that it means that autoscan, seeing
+# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
+
+
+# _AM_DEPENDENCIES(NAME)
+# ----------------------
+# See how the compiler implements dependency checking.
+# NAME is "CC", "CXX", "GCJ", or "OBJC".
+# We try a few techniques and use that to set a single cache variable.
+#
+# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
+# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
+# dependency, and given that the user is not expected to run this macro,
+# just rely on AC_PROG_CC.
+AC_DEFUN([_AM_DEPENDENCIES],
+[AC_REQUIRE([AM_SET_DEPDIR])dnl
+AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
+AC_REQUIRE([AM_MAKE_INCLUDE])dnl
+AC_REQUIRE([AM_DEP_TRACK])dnl
+
+ifelse([$1], CC, [depcc="$CC" am_compiler_list=],
+ [$1], CXX, [depcc="$CXX" am_compiler_list=],
+ [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+ [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
+ [depcc="$$1" am_compiler_list=])
+
+AC_CACHE_CHECK([dependency style of $depcc],
+ [am_cv_$1_dependencies_compiler_type],
+[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named `D' -- because `-MD' means `put the output
+ # in D'.
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_$1_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
+ fi
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+ # Solaris 8's {/usr,}/bin/sh.
+ touch sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ case $depmode in
+ nosideeffect)
+ # after this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ none) break ;;
+ esac
+ # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle `-M -o', and we need to detect this.
+ if depmode=$depmode \
+ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_$1_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_$1_dependencies_compiler_type=none
+fi
+])
+AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
+AM_CONDITIONAL([am__fastdep$1], [
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_$1_dependencies_compiler_type" = gcc3])
+])
+
+
+# AM_SET_DEPDIR
+# -------------
+# Choose a directory name for dependency files.
+# This macro is AC_REQUIREd in _AM_DEPENDENCIES
+AC_DEFUN([AM_SET_DEPDIR],
+[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
+])
+
+
+# AM_DEP_TRACK
+# ------------
+AC_DEFUN([AM_DEP_TRACK],
+[AC_ARG_ENABLE(dependency-tracking,
+[ --disable-dependency-tracking speeds up one-time build
+ --enable-dependency-tracking do not reject slow dependency extractors])
+if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
+fi
+AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
+AC_SUBST([AMDEPBACKSLASH])
+])
+
+# Generate code to set up dependency tracking. -*- Autoconf -*-
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+#serial 3
+
+# _AM_OUTPUT_DEPENDENCY_COMMANDS
+# ------------------------------
+AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
+[for mf in $CONFIG_FILES; do
+ # Strip MF so we end up with the name of the file.
+ mf=`echo "$mf" | sed -e 's/:.*$//'`
+ # Check whether this is an Automake generated Makefile or not.
+ # We used to match only the files named `Makefile.in', but
+ # some people rename them; so instead we look at the file content.
+ # Grep'ing the first line is not enough: some people post-process
+ # each Makefile.in and add a new line on top of each file to say so.
+ # So let's grep whole file.
+ if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then
+ dirpart=`AS_DIRNAME("$mf")`
+ else
+ continue
+ fi
+ # Extract the definition of DEPDIR, am__include, and am__quote
+ # from the Makefile without running `make'.
+ DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+ test -z "$DEPDIR" && continue
+ am__include=`sed -n 's/^am__include = //p' < "$mf"`
+ test -z "am__include" && continue
+ am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+ # When using ansi2knr, U may be empty or an underscore; expand it
+ U=`sed -n 's/^U = //p' < "$mf"`
+ # Find all dependency output files, they are included files with
+ # $(DEPDIR) in their names. We invoke sed twice because it is the
+ # simplest approach to changing $(DEPDIR) to its actual value in the
+ # expansion.
+ for file in `sed -n "
+ s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+ # Make sure the directory exists.
+ test -f "$dirpart/$file" && continue
+ fdir=`AS_DIRNAME(["$file"])`
+ AS_MKDIR_P([$dirpart/$fdir])
+ # echo "creating $dirpart/$file"
+ echo '# dummy' > "$dirpart/$file"
+ done
+done
+])# _AM_OUTPUT_DEPENDENCY_COMMANDS
+
+
+# AM_OUTPUT_DEPENDENCY_COMMANDS
+# -----------------------------
+# This macro should only be invoked once -- use via AC_REQUIRE.
+#
+# This code is only required when automatic dependency tracking
+# is enabled. FIXME. This creates each `.P' file that we will
+# need in order to bootstrap the dependency handling code.
+AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
+[AC_CONFIG_COMMANDS([depfiles],
+ [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
+ [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
+])
+
+# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 8
+
+# AM_CONFIG_HEADER is obsolete. It has been replaced by AC_CONFIG_HEADERS.
+AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)])
+
+# Do all the work for Automake. -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 12
+
+# This macro actually does too much. Some checks are only needed if
+# your package does certain things. But this isn't really a big deal.
+
+# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
+# AM_INIT_AUTOMAKE([OPTIONS])
+# -----------------------------------------------
+# The call with PACKAGE and VERSION arguments is the old style
+# call (pre autoconf-2.50), which is being phased out. PACKAGE
+# and VERSION should now be passed to AC_INIT and removed from
+# the call to AM_INIT_AUTOMAKE.
+# We support both call styles for the transition. After
+# the next Automake release, Autoconf can make the AC_INIT
+# arguments mandatory, and then we can depend on a new Autoconf
+# release and drop the old call support.
+AC_DEFUN([AM_INIT_AUTOMAKE],
+[AC_PREREQ([2.58])dnl
+dnl Autoconf wants to disallow AM_ names. We explicitly allow
+dnl the ones we care about.
+m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
+AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
+AC_REQUIRE([AC_PROG_INSTALL])dnl
+# test to see if srcdir already configured
+if test "`cd $srcdir && pwd`" != "`pwd`" &&
+ test -f $srcdir/config.status; then
+ AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+AC_SUBST([CYGPATH_W])
+
+# Define the identity of the package.
+dnl Distinguish between old-style and new-style calls.
+m4_ifval([$2],
+[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
+ AC_SUBST([PACKAGE], [$1])dnl
+ AC_SUBST([VERSION], [$2])],
+[_AM_SET_OPTIONS([$1])dnl
+ AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
+ AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
+
+_AM_IF_OPTION([no-define],,
+[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+ AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
+
+# Some tools Automake needs.
+AC_REQUIRE([AM_SANITY_CHECK])dnl
+AC_REQUIRE([AC_ARG_PROGRAM])dnl
+AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
+AM_MISSING_PROG(AUTOCONF, autoconf)
+AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
+AM_MISSING_PROG(AUTOHEADER, autoheader)
+AM_MISSING_PROG(MAKEINFO, makeinfo)
+AM_PROG_INSTALL_SH
+AM_PROG_INSTALL_STRIP
+AC_REQUIRE([AM_PROG_MKDIR_P])dnl
+# We need awk for the "check" target. The system "awk" is bad on
+# some platforms.
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
+ [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
+ [_AM_PROG_TAR([v7])])])
+_AM_IF_OPTION([no-dependencies],,
+[AC_PROVIDE_IFELSE([AC_PROG_CC],
+ [_AM_DEPENDENCIES(CC)],
+ [define([AC_PROG_CC],
+ defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_CXX],
+ [_AM_DEPENDENCIES(CXX)],
+ [define([AC_PROG_CXX],
+ defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
+])
+])
+
+
+# When config.status generates a header, we must update the stamp-h file.
+# This file resides in the same directory as the config header
+# that is generated. The stamp files are numbered to have different names.
+
+# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
+# loop where config.status creates the headers, so we can generate
+# our stamp files there.
+AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
+[# Compute $1's index in $config_headers.
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+ case $_am_header in
+ $1 | $1:* )
+ break ;;
+ * )
+ _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+ esac
+done
+echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count])
+
+# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_SH
+# ------------------
+# Define $install_sh.
+AC_DEFUN([AM_PROG_INSTALL_SH],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+install_sh=${install_sh-"$am_aux_dir/install-sh"}
+AC_SUBST(install_sh)])
+
+# Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 2
+
+# Check whether the underlying file-system supports filenames
+# with a leading dot. For instance MS-DOS doesn't.
+AC_DEFUN([AM_SET_LEADING_DOT],
+[rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+ am__leading_dot=.
+else
+ am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+AC_SUBST([am__leading_dot])])
+
+# Check to see how 'make' treats includes. -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 3
+
+# AM_MAKE_INCLUDE()
+# -----------------
+# Check to see how make treats includes.
+AC_DEFUN([AM_MAKE_INCLUDE],
+[am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+ @echo done
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+AC_MSG_CHECKING([for style of include used by $am_make])
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# We grep out `Entering directory' and `Leaving directory'
+# messages which can occur if `w' ends up in MAKEFLAGS.
+# In particular we don't look at `^make:' because GNU make might
+# be invoked under some other name (usually "gmake"), in which
+# case it prints its new name instead of `make'.
+if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then
+ am__include=include
+ am__quote=
+ _am_result=GNU
+fi
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+ echo '.include "confinc"' > confmf
+ if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then
+ am__include=.include
+ am__quote="\""
+ _am_result=BSD
+ fi
+fi
+AC_SUBST([am__include])
+AC_SUBST([am__quote])
+AC_MSG_RESULT([$_am_result])
+rm -f confinc confmf
+])
+
+# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
+
+# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 4
+
+# AM_MISSING_PROG(NAME, PROGRAM)
+# ------------------------------
+AC_DEFUN([AM_MISSING_PROG],
+[AC_REQUIRE([AM_MISSING_HAS_RUN])
+$1=${$1-"${am_missing_run}$2"}
+AC_SUBST($1)])
+
+
+# AM_MISSING_HAS_RUN
+# ------------------
+# Define MISSING if not defined so far and test if it supports --run.
+# If it does, set am_missing_run to use it, otherwise, to nothing.
+AC_DEFUN([AM_MISSING_HAS_RUN],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing"
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+ am_missing_run="$MISSING --run "
+else
+ am_missing_run=
+ AC_MSG_WARN([`missing' script is too old or missing])
+fi
+])
+
+# Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_MKDIR_P
+# ---------------
+# Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise.
+#
+# Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories
+# created by `make install' are always world readable, even if the
+# installer happens to have an overly restrictive umask (e.g. 077).
+# This was a mistake. There are at least two reasons why we must not
+# use `-m 0755':
+# - it causes special bits like SGID to be ignored,
+# - it may be too restrictive (some setups expect 775 directories).
+#
+# Do not use -m 0755 and let people choose whatever they expect by
+# setting umask.
+#
+# We cannot accept any implementation of `mkdir' that recognizes `-p'.
+# Some implementations (such as Solaris 8's) are not thread-safe: if a
+# parallel make tries to run `mkdir -p a/b' and `mkdir -p a/c'
+# concurrently, both version can detect that a/ is missing, but only
+# one can create it and the other will error out. Consequently we
+# restrict ourselves to GNU make (using the --version option ensures
+# this.)
+AC_DEFUN([AM_PROG_MKDIR_P],
+[if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
+ # We used to keeping the `.' as first argument, in order to
+ # allow $(mkdir_p) to be used without argument. As in
+ # $(mkdir_p) $(somedir)
+ # where $(somedir) is conditionally defined. However this is wrong
+ # for two reasons:
+ # 1. if the package is installed by a user who cannot write `.'
+ # make install will fail,
+ # 2. the above comment should most certainly read
+ # $(mkdir_p) $(DESTDIR)$(somedir)
+ # so it does not work when $(somedir) is undefined and
+ # $(DESTDIR) is not.
+ # To support the latter case, we have to write
+ # test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir),
+ # so the `.' trick is pointless.
+ mkdir_p='mkdir -p --'
+else
+ # On NextStep and OpenStep, the `mkdir' command does not
+ # recognize any option. It will interpret all options as
+ # directories to create, and then abort because `.' already
+ # exists.
+ for d in ./-p ./--version;
+ do
+ test -d $d && rmdir $d
+ done
+ # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists.
+ if test -f "$ac_aux_dir/mkinstalldirs"; then
+ mkdir_p='$(mkinstalldirs)'
+ else
+ mkdir_p='$(install_sh) -d'
+ fi
+fi
+AC_SUBST([mkdir_p])])
+
+# Helper functions for option handling. -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 3
+
+# _AM_MANGLE_OPTION(NAME)
+# -----------------------
+AC_DEFUN([_AM_MANGLE_OPTION],
+[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
+
+# _AM_SET_OPTION(NAME)
+# ------------------------------
+# Set option NAME. Presently that only means defining a flag for this option.
+AC_DEFUN([_AM_SET_OPTION],
+[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
+
+# _AM_SET_OPTIONS(OPTIONS)
+# ----------------------------------
+# OPTIONS is a space-separated list of Automake options.
+AC_DEFUN([_AM_SET_OPTIONS],
+[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
+
+# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
+# -------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+AC_DEFUN([_AM_IF_OPTION],
+[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
+
+# Check to make sure that the build environment is sane. -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 4
+
+# AM_SANITY_CHECK
+# ---------------
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null`
+ if test "$[*]" = "X"; then
+ # -L didn't work.
+ set X `ls -t $srcdir/configure conftest.file`
+ fi
+ rm -f conftest.file
+ if test "$[*]" != "X $srcdir/configure conftest.file" \
+ && test "$[*]" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
+alias in your environment])
+ fi
+
+ test "$[2]" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+AC_MSG_RESULT(yes)])
+
+# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_STRIP
+# ---------------------
+# One issue with vendor `install' (even GNU) is that you can't
+# specify the program used to strip binaries. This is especially
+# annoying in cross-compiling environments, where the build's strip
+# is unlikely to handle the host's binaries.
+# Fortunately install-sh will honor a STRIPPROG variable, so we
+# always use install-sh in `make install-strip', and initialize
+# STRIPPROG with the value of the STRIP variable (set by the user).
+AC_DEFUN([AM_PROG_INSTALL_STRIP],
+[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'. However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
+if test "$cross_compiling" != no; then
+ AC_CHECK_TOOL([STRIP], [strip], :)
+fi
+INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s"
+AC_SUBST([INSTALL_STRIP_PROGRAM])])
+
+# Check how to create a tarball. -*- Autoconf -*-
+
+# Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 2
+
+# _AM_PROG_TAR(FORMAT)
+# --------------------
+# Check how to create a tarball in format FORMAT.
+# FORMAT should be one of `v7', `ustar', or `pax'.
+#
+# Substitute a variable $(am__tar) that is a command
+# writing to stdout a FORMAT-tarball containing the directory
+# $tardir.
+# tardir=directory && $(am__tar) > result.tar
+#
+# Substitute a variable $(am__untar) that extract such
+# a tarball read from stdin.
+# $(am__untar) < result.tar
+AC_DEFUN([_AM_PROG_TAR],
+[# Always define AMTAR for backward compatibility.
+AM_MISSING_PROG([AMTAR], [tar])
+m4_if([$1], [v7],
+ [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'],
+ [m4_case([$1], [ustar],, [pax],,
+ [m4_fatal([Unknown tar format])])
+AC_MSG_CHECKING([how to create a $1 tar archive])
+# Loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
+_am_tools=${am_cv_prog_tar_$1-$_am_tools}
+# Do not fold the above two line into one, because Tru64 sh and
+# Solaris sh will not grok spaces in the rhs of `-'.
+for _am_tool in $_am_tools
+do
+ case $_am_tool in
+ gnutar)
+ for _am_tar in tar gnutar gtar;
+ do
+ AM_RUN_LOG([$_am_tar --version]) && break
+ done
+ am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
+ am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
+ am__untar="$_am_tar -xf -"
+ ;;
+ plaintar)
+ # Must skip GNU tar: if it does not support --format= it doesn't create
+ # ustar tarball either.
+ (tar --version) >/dev/null 2>&1 && continue
+ am__tar='tar chf - "$$tardir"'
+ am__tar_='tar chf - "$tardir"'
+ am__untar='tar xf -'
+ ;;
+ pax)
+ am__tar='pax -L -x $1 -w "$$tardir"'
+ am__tar_='pax -L -x $1 -w "$tardir"'
+ am__untar='pax -r'
+ ;;
+ cpio)
+ am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
+ am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
+ am__untar='cpio -i -H $1 -d'
+ ;;
+ none)
+ am__tar=false
+ am__tar_=false
+ am__untar=false
+ ;;
+ esac
+
+ # If the value was cached, stop now. We just wanted to have am__tar
+ # and am__untar set.
+ test -n "${am_cv_prog_tar_$1}" && break
+
+ # tar/untar a dummy directory, and stop if the command works
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ echo GrepMe > conftest.dir/file
+ AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
+ rm -rf conftest.dir
+ if test -s conftest.tar; then
+ AM_RUN_LOG([$am__untar <conftest.tar])
+ grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
+ fi
+done
+rm -rf conftest.dir
+
+AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
+AC_MSG_RESULT([$am_cv_prog_tar_$1])])
+AC_SUBST([am__tar])
+AC_SUBST([am__untar])
+]) # _AM_PROG_TAR
+
AC_DEFUN([AX_C___ATTRIBUTE__], [
AC_MSG_CHECKING(for __attribute__)
AC_CACHE_VAL(ac_cv___attribute__, [
AC_TRY_COMPILE(
- [#include <stdlib.h>],
- [static void foo(void) __attribute__ ((unused));
- static void
- foo(void) {
- exit(1);
- }],
+ [#include <stdlib.h>
+ static void foo(void) __attribute__ ((unused));
+ void foo(void) { exit(1); }],
+ [],
ac_cv___attribute__=yes,
ac_cv___attribute__=no
)])
@@ -6730,26 +7282,6 @@ AC_DEFUN([AX_C___ATTRIBUTE__], [
AC_MSG_RESULT($ac_cv___attribute__)
])
-# Check compiler characteristics (e.g. type sizes, PRIxx macros, ...)
-
-# If types $1 and $2 are compatible, perform action $3
-AC_DEFUN([AC_TYPES_COMPATIBLE],
- [AC_TRY_COMPILE([#include <stddef.h>], [$1 v1 = 0; $2 v2 = 0; return (&v1 - &v2)], $3)])
-
-define(AC_PRIUS_COMMENT, [printf format code for printing a size_t])
-
-AC_DEFUN([AC_COMPILER_CHARACTERISTICS],
- [AC_CACHE_CHECK(AC_PRIUS_COMMENT, ac_cv_formatting_prius,
- [AC_TYPES_COMPATIBLE(unsigned int, size_t, ac_cv_formatting_prius=u)
- AC_TYPES_COMPATIBLE(unsigned long, size_t, ac_cv_formatting_prius=lu)
- AC_TYPES_COMPATIBLE(unsigned long long, size_t, ac_cv_formatting_prius=llu)])
- if test -z "$ac_cv_formatting_prius"; then
- ac_cv_formatting_prius=zu;
- fi
- AC_DEFINE_UNQUOTED(PRIuS, "$ac_cv_formatting_prius", AC_PRIUS_COMMENT)
-])
-
-
# This was retrieved from
# http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/common/acx_pthread.m4?rev=1220
# See also (perhaps for new versions?)
@@ -7099,58 +7631,40 @@ fi
AC_LANG_RESTORE
])dnl ACX_PTHREAD
-# We check what namespace stl code like vector expects to be executed in
+# Check compiler characteristics (e.g. type sizes, PRIxx macros, ...)
-AC_DEFUN([AC_CXX_STL_NAMESPACE],
- [AC_CACHE_CHECK(
- what namespace STL code is in,
- ac_cv_cxx_stl_namespace,
- [AC_REQUIRE([AC_CXX_NAMESPACES])
- AC_LANG_SAVE
- AC_LANG_CPLUSPLUS
- AC_TRY_COMPILE([#include <vector>],
- [vector<int> t; return 0;],
- ac_cv_cxx_stl_namespace=none)
- AC_TRY_COMPILE([#include <vector>],
- [std::vector<int> t; return 0;],
- ac_cv_cxx_stl_namespace=std)
- AC_LANG_RESTORE])
- if test "$ac_cv_cxx_stl_namespace" = none; then
- AC_DEFINE(STL_NAMESPACE,,
- [the namespace where STL code like vector<> is defined])
- fi
- if test "$ac_cv_cxx_stl_namespace" = std; then
- AC_DEFINE(STL_NAMESPACE,std,
- [the namespace where STL code like vector<> is defined])
- fi
-])
+# If types $1 and $2 are compatible, perform action $3
+AC_DEFUN([AC_TYPES_COMPATIBLE],
+ [AC_TRY_COMPILE([#include <stddef.h>], [$1 v1 = 0; $2 v2 = 0; return (&v1 - &v2)], $3)])
-dnl @synopsis AC_CXX_NAMESPACES
-dnl
-dnl If the compiler can prevent names clashes using namespaces, define
-dnl HAVE_NAMESPACES.
-dnl
-dnl @category Cxx
-dnl @author Todd Veldhuizen
-dnl @author Luc Maisonobe <luc@spaceroots.org>
-dnl @version 2004-02-04
-dnl @license AllPermissive
+define(AC_PRIUS_COMMENT, [printf format code for printing a size_t and ssize_t])
-AC_DEFUN([AC_CXX_NAMESPACES],
-[AC_CACHE_CHECK(whether the compiler implements namespaces,
-ac_cv_cxx_namespaces,
-[AC_LANG_SAVE
- AC_LANG_CPLUSPLUS
- AC_TRY_COMPILE([namespace Outer { namespace Inner { int i = 0; }}],
- [using namespace Outer::Inner; return i;],
- ac_cv_cxx_namespaces=yes, ac_cv_cxx_namespaces=no)
- AC_LANG_RESTORE
-])
-if test "$ac_cv_cxx_namespaces" = yes; then
- AC_DEFINE(HAVE_NAMESPACES,,[define if the compiler implements namespaces])
-fi
+AC_DEFUN([AC_COMPILER_CHARACTERISTICS],
+ [AC_CACHE_CHECK(AC_PRIUS_COMMENT, ac_cv_formatting_prius_prefix,
+ [AC_TYPES_COMPATIBLE(unsigned int, size_t,
+ ac_cv_formatting_prius_prefix=; ac_cv_prius_defined=1)
+ AC_TYPES_COMPATIBLE(unsigned long, size_t,
+ ac_cv_formatting_prius_prefix=l; ac_cv_prius_defined=1)
+ AC_TYPES_COMPATIBLE(unsigned long long, size_t,
+ ac_cv_formatting_prius_prefix=ll; ac_cv_prius_defined=1
+ )])
+ if test -z "$ac_cv_formatting_prius_defined"; then
+ ac_cv_formatting_prius_prefix=z;
+ fi
+ AC_DEFINE_UNQUOTED(PRIuS, "${ac_cv_formatting_prius_prefix}u", AC_PRIUS_COMMENT)
+ AC_DEFINE_UNQUOTED(PRIxS, "${ac_cv_formatting_prius_prefix}x", AC_PRIUS_COMMENT)
+ AC_DEFINE_UNQUOTED(PRIdS, "${ac_cv_formatting_prius_prefix}d", AC_PRIUS_COMMENT)
])
+AC_DEFUN([AC_INSTALL_PREFIX],
+ [ac_cv_install_prefix="$prefix";
+ if test x"$ac_cv_install_prefix" == x"NONE" ; then
+ ac_cv_install_prefix="$ac_default_prefix";
+ fi
+ AC_DEFINE_UNQUOTED(INSTALL_PREFIX, "$ac_cv_install_prefix",
+ [prefix where we look for installed files])
+ ])
+
# Figures out where hash_set is defined, and then writes out the
# location to the file specified in $1. The output file also
# #defines the namespace that hash_set is in HASH_NAMESPACE.
@@ -7175,6 +7689,38 @@ EOF
AC_MSG_RESULT([$1])
])
+# Checks whether the compiler implements namespaces
+AC_DEFUN([AC_CXX_NAMESPACES],
+ [AC_CACHE_CHECK(whether the compiler implements namespaces,
+ ac_cv_cxx_namespaces,
+ [AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ AC_TRY_COMPILE([namespace Outer {
+ namespace Inner { int i = 0; }}],
+ [using namespace Outer::Inner; return i;],
+ ac_cv_cxx_namespaces=yes,
+ ac_cv_cxx_namespaces=no)
+ AC_LANG_RESTORE])
+ if test "$ac_cv_cxx_namespaces" = yes; then
+ AC_DEFINE(HAVE_NAMESPACES, 1, [define if the compiler implements namespaces])
+ fi])
+
+AC_DEFUN([AC_PROGRAM_INVOCATION_NAME],
+ [AC_CACHE_CHECK(
+ for program_invocation_name,
+ ac_cv_have_program_invocation_name,
+ AC_TRY_LINK([extern char* program_invocation_name;],
+ [char c = *program_invocation_name; return 0; ],
+ [ac_cv_have_program_invocation_name=yes],
+ [ac_cv_have_program_invocation_name=no])
+ )
+ if test "$ac_cv_have_program_invocation_name" = "yes"; then
+ AC_DEFINE(HAVE_PROGRAM_INVOCATION_NAME, 1,
+ [define if libc has program_invocation_name])
+ fi
+ ])
+
+
# We check two things: where the include file is for hash_map, and
# what namespace hash_map lives in within that include file. We
# include AC_TRY_COMPILE for all the combinations we've seen in the
@@ -7239,28 +7785,29 @@ AC_DEFUN([AC_CXX_STL_HASH],
fi
])
-AC_DEFUN([AC_PROGRAM_INVOCATION_NAME],
+# We check what namespace stl code like vector expects to be executed in
+
+AC_DEFUN([AC_CXX_STL_NAMESPACE],
[AC_CACHE_CHECK(
- for program_invocation_name,
- ac_cv_have_program_invocation_name,
- AC_TRY_LINK([extern char* program_invocation_name;],
- [char c = *program_invocation_name; return 0; ],
- [ac_cv_have_program_invocation_name=yes],
- [ac_cv_have_program_invocation_name=no])
- )
- if test "$ac_cv_have_program_invocation_name" = "yes"; then
- AC_DEFINE(HAVE_PROGRAM_INVOCATION_NAME, 1,
- [define if libc has program_invocation_name])
+ what namespace STL code is in,
+ ac_cv_cxx_stl_namespace,
+ [AC_REQUIRE([AC_CXX_NAMESPACES])
+ AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ AC_TRY_COMPILE([#include <vector>],
+ [vector<int> t; return 0;],
+ ac_cv_cxx_stl_namespace=none)
+ AC_TRY_COMPILE([#include <vector>],
+ [std::vector<int> t; return 0;],
+ ac_cv_cxx_stl_namespace=std)
+ AC_LANG_RESTORE])
+ if test "$ac_cv_cxx_stl_namespace" = none; then
+ AC_DEFINE(STL_NAMESPACE,,
+ [the namespace where STL code like vector<> is defined])
fi
- ])
-
-
-AC_DEFUN([AC_INSTALL_PREFIX],
- [ac_cv_install_prefix="$prefix";
- if test x"$ac_cv_install_prefix" == x"NONE" ; then
- ac_cv_install_prefix="$ac_default_prefix";
+ if test "$ac_cv_cxx_stl_namespace" = std; then
+ AC_DEFINE(STL_NAMESPACE,std,
+ [the namespace where STL code like vector<> is defined])
fi
- AC_DEFINE_UNQUOTED(INSTALL_PREFIX, "$ac_cv_install_prefix",
- [prefix where we look for installed files])
- ])
+])
diff --git a/config.guess b/config.guess
index dff9e48..ad5281e 100755
--- a/config.guess
+++ b/config.guess
@@ -1,9 +1,9 @@
#! /bin/sh
# Attempt to guess a canonical system name.
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
-# Free Software Foundation, Inc.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
-timestamp='2001-09-04'
+timestamp='2005-08-03'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -17,15 +17,18 @@ timestamp='2001-09-04'
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
-# Written by Per Bothner <bothner@cygnus.com>.
-# Please send patches to <config-patches@gnu.org>.
+
+# Originally written by Per Bothner <per@bothner.com>.
+# Please send patches to <config-patches@gnu.org>. Submit a context
+# diff and a properly formatted ChangeLog entry.
#
# This script attempts to guess a canonical system name similar to
# config.sub. If it succeeds, it prints the system name on stdout, and
@@ -52,7 +55,7 @@ version="\
GNU config.guess ($timestamp)
Originally written by Per Bothner.
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
@@ -65,11 +68,11 @@ Try \`$me --help' for more information."
while test $# -gt 0 ; do
case $1 in
--time-stamp | --time* | -t )
- echo "$timestamp" ; exit 0 ;;
+ echo "$timestamp" ; exit ;;
--version | -v )
- echo "$version" ; exit 0 ;;
+ echo "$version" ; exit ;;
--help | --h* | -h )
- echo "$usage"; exit 0 ;;
+ echo "$usage"; exit ;;
-- ) # Stop option processing
shift; break ;;
- ) # Use stdin as input.
@@ -87,30 +90,42 @@ if test $# != 0; then
exit 1
fi
+trap 'exit 1' 1 2 15
-dummy=dummy-$$
-trap 'rm -f $dummy.c $dummy.o $dummy.rel $dummy; exit 1' 1 2 15
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
-# CC_FOR_BUILD -- compiler used by this script.
# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
# use `HOST_CC' if defined, but it is deprecated.
-set_cc_for_build='case $CC_FOR_BUILD,$HOST_CC,$CC in
- ,,) echo "int dummy(){}" > $dummy.c ;
- for c in cc gcc c89 ; do
- ($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1 ;
- if test $? = 0 ; then
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,) echo "int x;" > $dummy.c ;
+ for c in cc gcc c89 c99 ; do
+ if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
CC_FOR_BUILD="$c"; break ;
fi ;
done ;
- rm -f $dummy.c $dummy.o $dummy.rel ;
if test x"$CC_FOR_BUILD" = x ; then
CC_FOR_BUILD=no_compiler_found ;
fi
;;
,,*) CC_FOR_BUILD=$CC ;;
,*,*) CC_FOR_BUILD=$HOST_CC ;;
-esac'
+esac ; set_cc_for_build= ;'
# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
# (ghazi@noc.rutgers.edu 1994-08-24)
@@ -127,29 +142,30 @@ UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
*:NetBSD:*:*)
- # Netbsd (nbsd) targets should (where applicable) match one or
+ # NetBSD (nbsd) targets should (where applicable) match one or
# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
# *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
# switched to ELF, *-*-netbsd* would select the old
# object file format. This provides both forward
# compatibility and a consistent mechanism for selecting the
# object file format.
- # Determine the machine/vendor (is the vendor relevant).
- case "${UNAME_MACHINE}" in
- amiga) machine=m68k-unknown ;;
- arm32) machine=arm-unknown ;;
- atari*) machine=m68k-atari ;;
- sun3*) machine=m68k-sun ;;
- mac68k) machine=m68k-apple ;;
- macppc) machine=powerpc-apple ;;
- hp3[0-9][05]) machine=m68k-hp ;;
- ibmrt|romp-ibm) machine=romp-ibm ;;
- *) machine=${UNAME_MACHINE}-unknown ;;
+ #
+ # Note: NetBSD doesn't particularly care about the vendor
+ # portion of the name. We always set it to "unknown".
+ sysctl="sysctl -n hw.machine_arch"
+ UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+ /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+ case "${UNAME_MACHINE_ARCH}" in
+ armeb) machine=armeb-unknown ;;
+ arm*) machine=arm-unknown ;;
+ sh3el) machine=shl-unknown ;;
+ sh3eb) machine=sh-unknown ;;
+ *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
esac
# The Operating System including object format, if it has switched
# to ELF recently, or will in the future.
- case "${UNAME_MACHINE}" in
- i386|sparc|amiga|arm*|hp300|mvme68k|vax|atari|luna68k|mac68k|news68k|next68k|pc532|sun3*|x68k)
+ case "${UNAME_MACHINE_ARCH}" in
+ arm*|i386|m68k|ns32k|sh3*|sparc|vax)
eval $set_cc_for_build
if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep __ELF__ >/dev/null
@@ -166,120 +182,125 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
;;
esac
# The OS release
- release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ # Debian GNU/NetBSD machines have a different userland, and
+ # thus, need a distinct triplet. However, they do not need
+ # kernel version information, so it can be replaced with a
+ # suitable tag, in the style of linux-gnu.
+ case "${UNAME_VERSION}" in
+ Debian*)
+ release='-gnu'
+ ;;
+ *)
+ release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ ;;
+ esac
# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
# contains redundant information, the shorter form:
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
echo "${machine}-${os}${release}"
- exit 0 ;;
+ exit ;;
+ *:OpenBSD:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+ echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+ exit ;;
+ *:ekkoBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+ exit ;;
+ macppc:MirBSD:*:*)
+ echo powerppc-unknown-mirbsd${UNAME_RELEASE}
+ exit ;;
+ *:MirBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+ exit ;;
alpha:OSF1:*:*)
- if test $UNAME_RELEASE = "V4.0"; then
+ case $UNAME_RELEASE in
+ *4.0)
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
- fi
+ ;;
+ *5.*)
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+ ;;
+ esac
+ # According to Compaq, /usr/sbin/psrinfo has been available on
+ # OSF/1 and Tru64 systems produced since 1995. I hope that
+ # covers most systems running today. This code pipes the CPU
+ # types through head -n 1, so we only detect the type of CPU 0.
+ ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+ case "$ALPHA_CPU_TYPE" in
+ "EV4 (21064)")
+ UNAME_MACHINE="alpha" ;;
+ "EV4.5 (21064)")
+ UNAME_MACHINE="alpha" ;;
+ "LCA4 (21066/21068)")
+ UNAME_MACHINE="alpha" ;;
+ "EV5 (21164)")
+ UNAME_MACHINE="alphaev5" ;;
+ "EV5.6 (21164A)")
+ UNAME_MACHINE="alphaev56" ;;
+ "EV5.6 (21164PC)")
+ UNAME_MACHINE="alphapca56" ;;
+ "EV5.7 (21164PC)")
+ UNAME_MACHINE="alphapca57" ;;
+ "EV6 (21264)")
+ UNAME_MACHINE="alphaev6" ;;
+ "EV6.7 (21264A)")
+ UNAME_MACHINE="alphaev67" ;;
+ "EV6.8CB (21264C)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.8AL (21264B)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.8CX (21264D)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.9A (21264/EV69A)")
+ UNAME_MACHINE="alphaev69" ;;
+ "EV7 (21364)")
+ UNAME_MACHINE="alphaev7" ;;
+ "EV7.9 (21364A)")
+ UNAME_MACHINE="alphaev79" ;;
+ esac
+ # A Pn.n version is a patched version.
# A Vn.n version is a released version.
# A Tn.n version is a released field test version.
# A Xn.n version is an unreleased experimental baselevel.
# 1.2 uses "1.2" for uname -r.
- cat <<EOF >$dummy.s
- .data
-\$Lformat:
- .byte 37,100,45,37,120,10,0 # "%d-%x\n"
-
- .text
- .globl main
- .align 4
- .ent main
-main:
- .frame \$30,16,\$26,0
- ldgp \$29,0(\$27)
- .prologue 1
- .long 0x47e03d80 # implver \$0
- lda \$2,-1
- .long 0x47e20c21 # amask \$2,\$1
- lda \$16,\$Lformat
- mov \$0,\$17
- not \$1,\$18
- jsr \$26,printf
- ldgp \$29,0(\$26)
- mov 0,\$16
- jsr \$26,exit
- .end main
-EOF
- eval $set_cc_for_build
- $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
- if test "$?" = 0 ; then
- case `./$dummy` in
- 0-0)
- UNAME_MACHINE="alpha"
- ;;
- 1-0)
- UNAME_MACHINE="alphaev5"
- ;;
- 1-1)
- UNAME_MACHINE="alphaev56"
- ;;
- 1-101)
- UNAME_MACHINE="alphapca56"
- ;;
- 2-303)
- UNAME_MACHINE="alphaev6"
- ;;
- 2-307)
- UNAME_MACHINE="alphaev67"
- ;;
- 2-1307)
- UNAME_MACHINE="alphaev68"
- ;;
- esac
- fi
- rm -f $dummy.s $dummy
- echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
- exit 0 ;;
+ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ exit ;;
Alpha\ *:Windows_NT*:*)
# How do we know it's Interix rather than the generic POSIX subsystem?
# Should we change UNAME_MACHINE based on the output of uname instead
# of the specific Alpha model?
echo alpha-pc-interix
- exit 0 ;;
+ exit ;;
21064:Windows_NT:50:3)
echo alpha-dec-winnt3.5
- exit 0 ;;
+ exit ;;
Amiga*:UNIX_System_V:4.0:*)
echo m68k-unknown-sysv4
- exit 0;;
- amiga:OpenBSD:*:*)
- echo m68k-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
*:[Aa]miga[Oo][Ss]:*:*)
echo ${UNAME_MACHINE}-unknown-amigaos
- exit 0 ;;
- arc64:OpenBSD:*:*)
- echo mips64el-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- arc:OpenBSD:*:*)
- echo mipsel-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- hkmips:OpenBSD:*:*)
- echo mips-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- pmax:OpenBSD:*:*)
- echo mipsel-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- sgi:OpenBSD:*:*)
- echo mips-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- wgrisc:OpenBSD:*:*)
- echo mipsel-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
+ *:[Mm]orph[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-morphos
+ exit ;;
*:OS/390:*:*)
echo i370-ibm-openedition
- exit 0 ;;
+ exit ;;
+ *:z/VM:*:*)
+ echo s390-ibm-zvmoe
+ exit ;;
+ *:OS400:*:*)
+ echo powerpc-ibm-os400
+ exit ;;
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
echo arm-acorn-riscix${UNAME_RELEASE}
- exit 0;;
+ exit ;;
+ arm:riscos:*:*|arm:RISCOS:*:*)
+ echo arm-unknown-riscos
+ exit ;;
SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
echo hppa1.1-hitachi-hiuxmpp
- exit 0;;
+ exit ;;
Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
if test "`(/bin/universe) 2>/dev/null`" = att ; then
@@ -287,25 +308,32 @@ EOF
else
echo pyramid-pyramid-bsd
fi
- exit 0 ;;
+ exit ;;
NILE*:*:*:dcosx)
echo pyramid-pyramid-svr4
- exit 0 ;;
+ exit ;;
+ DRS?6000:unix:4.0:6*)
+ echo sparc-icl-nx6
+ exit ;;
+ DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+ case `/usr/bin/uname -p` in
+ sparc) echo sparc-icl-nx7; exit ;;
+ esac ;;
sun4H:SunOS:5.*:*)
echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit 0 ;;
+ exit ;;
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit 0 ;;
+ exit ;;
i86pc:SunOS:5.*:*)
echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit 0 ;;
+ exit ;;
sun4*:SunOS:6*:*)
# According to config.sub, this is the proper way to canonicalize
# SunOS6. Hard to guess exactly what SunOS6 will be like, but
# it's likely to be more like Solaris than SunOS4.
echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit 0 ;;
+ exit ;;
sun4*:SunOS:*:*)
case "`/usr/bin/arch -k`" in
Series*|S4*)
@@ -314,12 +342,12 @@ EOF
esac
# Japanese Language versions have a version number like `4.1.3-JL'.
echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
- exit 0 ;;
+ exit ;;
sun3*:SunOS:*:*)
echo m68k-sun-sunos${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
sun*:*:4.2BSD:*)
- UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+ UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
case "`/bin/arch`" in
sun3)
@@ -329,16 +357,10 @@ EOF
echo sparc-sun-sunos${UNAME_RELEASE}
;;
esac
- exit 0 ;;
+ exit ;;
aushp:SunOS:*:*)
echo sparc-auspex-sunos${UNAME_RELEASE}
- exit 0 ;;
- sparc*:NetBSD:*)
- echo `uname -p`-unknown-netbsd${UNAME_RELEASE}
- exit 0 ;;
- atari*:OpenBSD:*:*)
- echo m68k-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
# The situation for MiNT is a little confusing. The machine name
# can be virtually everything (everything which is not
# "atarist" or "atariste" at least should have a processor
@@ -349,49 +371,40 @@ EOF
# be no problem.
atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
echo m68k-atari-mint${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
echo m68k-atari-mint${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
*falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
echo m68k-atari-mint${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
echo m68k-milan-mint${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
echo m68k-hades-mint${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
*:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
echo m68k-unknown-mint${UNAME_RELEASE}
- exit 0 ;;
- sun3*:OpenBSD:*:*)
- echo m68k-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- mac68k:OpenBSD:*:*)
- echo m68k-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- mvme68k:OpenBSD:*:*)
- echo m68k-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
- mvme88k:OpenBSD:*:*)
- echo m88k-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
+ m68k:machten:*:*)
+ echo m68k-apple-machten${UNAME_RELEASE}
+ exit ;;
powerpc:machten:*:*)
echo powerpc-apple-machten${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
RISC*:Mach:*:*)
echo mips-dec-mach_bsd4.3
- exit 0 ;;
+ exit ;;
RISC*:ULTRIX:*:*)
echo mips-dec-ultrix${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
VAX*:ULTRIX*:*:*)
echo vax-dec-ultrix${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
2020:CLIX:*:* | 2430:CLIX:*:*)
echo clipper-intergraph-clix${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
mips:*:*:UMIPS | mips:*:*:RISCos)
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
@@ -415,27 +428,33 @@ EOF
exit (-1);
}
EOF
- $CC_FOR_BUILD $dummy.c -o $dummy \
- && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
- && rm -f $dummy.c $dummy && exit 0
- rm -f $dummy.c $dummy
+ $CC_FOR_BUILD -o $dummy $dummy.c &&
+ dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+ SYSTEM_NAME=`$dummy $dummyarg` &&
+ { echo "$SYSTEM_NAME"; exit; }
echo mips-mips-riscos${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
Motorola:PowerMAX_OS:*:*)
echo powerpc-motorola-powermax
- exit 0 ;;
+ exit ;;
+ Motorola:*:4.3:PL8-*)
+ echo powerpc-harris-powermax
+ exit ;;
+ Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+ echo powerpc-harris-powermax
+ exit ;;
Night_Hawk:Power_UNIX:*:*)
echo powerpc-harris-powerunix
- exit 0 ;;
+ exit ;;
m88k:CX/UX:7*:*)
echo m88k-harris-cxux7
- exit 0 ;;
+ exit ;;
m88k:*:4*:R4*)
echo m88k-motorola-sysv4
- exit 0 ;;
+ exit ;;
m88k:*:3*:R3*)
echo m88k-motorola-sysv3
- exit 0 ;;
+ exit ;;
AViiON:dgux:*:*)
# DG/UX returns AViiON for all architectures
UNAME_PROCESSOR=`/usr/bin/uname -p`
@@ -451,29 +470,29 @@ EOF
else
echo i586-dg-dgux${UNAME_RELEASE}
fi
- exit 0 ;;
+ exit ;;
M88*:DolphinOS:*:*) # DolphinOS (SVR3)
echo m88k-dolphin-sysv3
- exit 0 ;;
+ exit ;;
M88*:*:R3*:*)
# Delta 88k system running SVR3
echo m88k-motorola-sysv3
- exit 0 ;;
+ exit ;;
XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
echo m88k-tektronix-sysv3
- exit 0 ;;
+ exit ;;
Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
echo m68k-tektronix-bsd
- exit 0 ;;
+ exit ;;
*:IRIX*:*:*)
echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
- exit 0 ;;
+ exit ;;
????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
- echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
- exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX '
+ echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
+ exit ;; # Note that: echo "'`uname -s`'" gives 'AIX '
i*86:AIX:*:*)
echo i386-ibm-aix
- exit 0 ;;
+ exit ;;
ia64:AIX:*:*)
if [ -x /usr/bin/oslevel ] ; then
IBM_REV=`/usr/bin/oslevel`
@@ -481,7 +500,7 @@ EOF
IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
fi
echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
- exit 0 ;;
+ exit ;;
*:AIX:2:3)
if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
eval $set_cc_for_build
@@ -496,17 +515,20 @@ EOF
exit(0);
}
EOF
- $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0
- rm -f $dummy.c $dummy
- echo rs6000-ibm-aix3.2.5
+ if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+ then
+ echo "$SYSTEM_NAME"
+ else
+ echo rs6000-ibm-aix3.2.5
+ fi
elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
echo rs6000-ibm-aix3.2.4
else
echo rs6000-ibm-aix3.2
fi
- exit 0 ;;
+ exit ;;
*:AIX:*:[45])
- IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'`
+ IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
IBM_ARCH=rs6000
else
@@ -518,38 +540,36 @@ EOF
IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
fi
echo ${IBM_ARCH}-ibm-aix${IBM_REV}
- exit 0 ;;
+ exit ;;
*:AIX:*:*)
echo rs6000-ibm-aix
- exit 0 ;;
+ exit ;;
ibmrt:4.4BSD:*|romp-ibm:BSD:*)
echo romp-ibm-bsd4.4
- exit 0 ;;
+ exit ;;
ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
- exit 0 ;; # report: romp-ibm BSD 4.3
+ exit ;; # report: romp-ibm BSD 4.3
*:BOSX:*:*)
echo rs6000-bull-bosx
- exit 0 ;;
+ exit ;;
DPX/2?00:B.O.S.:*:*)
echo m68k-bull-sysv3
- exit 0 ;;
+ exit ;;
9000/[34]??:4.3bsd:1.*:*)
echo m68k-hp-bsd
- exit 0 ;;
+ exit ;;
hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
echo m68k-hp-bsd4.4
- exit 0 ;;
+ exit ;;
9000/[34678]??:HP-UX:*:*)
HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
case "${UNAME_MACHINE}" in
9000/31? ) HP_ARCH=m68000 ;;
9000/[34]?? ) HP_ARCH=m68k ;;
9000/[678][0-9][0-9])
- case "${HPUX_REV}" in
- 11.[0-9][0-9])
- if [ -x /usr/bin/getconf ]; then
- sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+ if [ -x /usr/bin/getconf ]; then
+ sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
case "${sc_cpu_version}" in
523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
@@ -558,13 +578,13 @@ EOF
case "${sc_kernel_bits}" in
32) HP_ARCH="hppa2.0n" ;;
64) HP_ARCH="hppa2.0w" ;;
+ '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
esac ;;
esac
- fi ;;
- esac
- if [ "${HP_ARCH}" = "" ]; then
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
+ fi
+ if [ "${HP_ARCH}" = "" ]; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
#define _HPUX_SOURCE
#include <stdlib.h>
@@ -597,17 +617,37 @@ EOF
exit (0);
}
EOF
- (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy`
- if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi
- rm -f $dummy.c $dummy
- fi ;;
+ (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+ test -z "$HP_ARCH" && HP_ARCH=hppa
+ fi ;;
esac
+ if [ ${HP_ARCH} = "hppa2.0w" ]
+ then
+ eval $set_cc_for_build
+
+ # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
+ # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler
+ # generating 64-bit code. GNU and HP use different nomenclature:
+ #
+ # $ CC_FOR_BUILD=cc ./config.guess
+ # => hppa2.0w-hp-hpux11.23
+ # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
+ # => hppa64-hp-hpux11.23
+
+ if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+ grep __LP64__ >/dev/null
+ then
+ HP_ARCH="hppa2.0w"
+ else
+ HP_ARCH="hppa64"
+ fi
+ fi
echo ${HP_ARCH}-hp-hpux${HPUX_REV}
- exit 0 ;;
+ exit ;;
ia64:HP-UX:*:*)
HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
echo ia64-hp-hpux${HPUX_REV}
- exit 0 ;;
+ exit ;;
3050*:HI-UX:*:*)
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
@@ -635,158 +675,213 @@ EOF
exit (0);
}
EOF
- $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0
- rm -f $dummy.c $dummy
+ $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+ { echo "$SYSTEM_NAME"; exit; }
echo unknown-hitachi-hiuxwe2
- exit 0 ;;
+ exit ;;
9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
echo hppa1.1-hp-bsd
- exit 0 ;;
+ exit ;;
9000/8??:4.3bsd:*:*)
echo hppa1.0-hp-bsd
- exit 0 ;;
+ exit ;;
*9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
echo hppa1.0-hp-mpeix
- exit 0 ;;
+ exit ;;
hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
echo hppa1.1-hp-osf
- exit 0 ;;
+ exit ;;
hp8??:OSF1:*:*)
echo hppa1.0-hp-osf
- exit 0 ;;
+ exit ;;
i*86:OSF1:*:*)
if [ -x /usr/sbin/sysversion ] ; then
echo ${UNAME_MACHINE}-unknown-osf1mk
else
echo ${UNAME_MACHINE}-unknown-osf1
fi
- exit 0 ;;
+ exit ;;
parisc*:Lites*:*:*)
echo hppa1.1-hp-lites
- exit 0 ;;
- hppa*:OpenBSD:*:*)
- echo hppa-unknown-openbsd
- exit 0 ;;
+ exit ;;
C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
echo c1-convex-bsd
- exit 0 ;;
+ exit ;;
C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
if getsysinfo -f scalar_acc
then echo c32-convex-bsd
else echo c2-convex-bsd
fi
- exit 0 ;;
+ exit ;;
C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
echo c34-convex-bsd
- exit 0 ;;
+ exit ;;
C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
echo c38-convex-bsd
- exit 0 ;;
+ exit ;;
C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
echo c4-convex-bsd
- exit 0 ;;
- CRAY*X-MP:*:*:*)
- echo xmp-cray-unicos
- exit 0 ;;
+ exit ;;
CRAY*Y-MP:*:*:*)
echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit 0 ;;
+ exit ;;
CRAY*[A-Z]90:*:*:*)
echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
-e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
-e 's/\.[^.]*$/.X/'
- exit 0 ;;
+ exit ;;
CRAY*TS:*:*:*)
echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit 0 ;;
- CRAY*T3D:*:*:*)
- echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit 0 ;;
+ exit ;;
CRAY*T3E:*:*:*)
echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit 0 ;;
+ exit ;;
CRAY*SV1:*:*:*)
echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit 0 ;;
- CRAY-2:*:*:*)
- echo cray2-cray-unicos
- exit 0 ;;
+ exit ;;
+ *:UNICOS/mp:*:*)
+ echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
- exit 0 ;;
- hp300:OpenBSD:*:*)
- echo m68k-unknown-openbsd${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
+ 5000:UNIX_System_V:4.*:*)
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+ echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
sparc*:BSD/OS:*:*)
echo sparc-unknown-bsdi${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
*:BSD/OS:*:*)
echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
*:FreeBSD:*:*)
echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
- exit 0 ;;
- *:OpenBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
- exit 0 ;;
+ exit ;;
i*:CYGWIN*:*)
echo ${UNAME_MACHINE}-pc-cygwin
- exit 0 ;;
+ exit ;;
i*:MINGW*:*)
echo ${UNAME_MACHINE}-pc-mingw32
- exit 0 ;;
+ exit ;;
+ i*:windows32*:*)
+ # uname -m includes "-pc" on this system.
+ echo ${UNAME_MACHINE}-mingw32
+ exit ;;
i*:PW*:*)
echo ${UNAME_MACHINE}-pc-pw32
- exit 0 ;;
+ exit ;;
+ x86:Interix*:[34]*)
+ echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//'
+ exit ;;
+ [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+ echo i${UNAME_MACHINE}-pc-mks
+ exit ;;
i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
# How do we know it's Interix rather than the generic POSIX subsystem?
# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
# UNAME_MACHINE based on the output of uname instead of i386?
- echo i386-pc-interix
- exit 0 ;;
+ echo i586-pc-interix
+ exit ;;
i*:UWIN*:*)
echo ${UNAME_MACHINE}-pc-uwin
- exit 0 ;;
+ exit ;;
+ amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
+ echo x86_64-unknown-cygwin
+ exit ;;
p*:CYGWIN*:*)
echo powerpcle-unknown-cygwin
- exit 0 ;;
+ exit ;;
prep*:SunOS:5.*:*)
echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit 0 ;;
+ exit ;;
*:GNU:*:*)
+ # the GNU system
echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
- exit 0 ;;
+ exit ;;
+ *:GNU/*:*:*)
+ # other systems with GNU libc and userland
+ echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
+ exit ;;
i*86:Minix:*:*)
echo ${UNAME_MACHINE}-pc-minix
- exit 0 ;;
+ exit ;;
arm*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit 0 ;;
+ exit ;;
+ cris:Linux:*:*)
+ echo cris-axis-linux-gnu
+ exit ;;
+ crisv32:Linux:*:*)
+ echo crisv32-axis-linux-gnu
+ exit ;;
+ frv:Linux:*:*)
+ echo frv-unknown-linux-gnu
+ exit ;;
ia64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux
- exit 0 ;;
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ m32r*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
m68*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit 0 ;;
+ exit ;;
mips:Linux:*:*)
- case `sed -n '/^byte/s/^.*: \(.*\) endian/\1/p' < /proc/cpuinfo` in
- big) echo mips-unknown-linux-gnu && exit 0 ;;
- little) echo mipsel-unknown-linux-gnu && exit 0 ;;
- esac
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #undef CPU
+ #undef mips
+ #undef mipsel
+ #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+ CPU=mipsel
+ #else
+ #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+ CPU=mips
+ #else
+ CPU=
+ #endif
+ #endif
+EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+ test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+ ;;
+ mips64:Linux:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #undef CPU
+ #undef mips64
+ #undef mips64el
+ #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+ CPU=mips64el
+ #else
+ #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+ CPU=mips64
+ #else
+ CPU=
+ #endif
+ #endif
+EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+ test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
;;
+ or32:Linux:*:*)
+ echo or32-unknown-linux-gnu
+ exit ;;
ppc:Linux:*:*)
echo powerpc-unknown-linux-gnu
- exit 0 ;;
+ exit ;;
ppc64:Linux:*:*)
echo powerpc64-unknown-linux-gnu
- exit 0 ;;
+ exit ;;
alpha:Linux:*:*)
case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
EV5) UNAME_MACHINE=alphaev5 ;;
@@ -800,7 +895,7 @@ EOF
objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
- exit 0 ;;
+ exit ;;
parisc:Linux:*:* | hppa:Linux:*:*)
# Look for CPU level
case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
@@ -808,27 +903,31 @@ EOF
PA8*) echo hppa2.0-unknown-linux-gnu ;;
*) echo hppa-unknown-linux-gnu ;;
esac
- exit 0 ;;
+ exit ;;
parisc64:Linux:*:* | hppa64:Linux:*:*)
echo hppa64-unknown-linux-gnu
- exit 0 ;;
+ exit ;;
s390:Linux:*:* | s390x:Linux:*:*)
echo ${UNAME_MACHINE}-ibm-linux
- exit 0 ;;
+ exit ;;
+ sh64*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
sh*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit 0 ;;
+ exit ;;
sparc:Linux:*:* | sparc64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit 0 ;;
+ exit ;;
x86_64:Linux:*:*)
echo x86_64-unknown-linux-gnu
- exit 0 ;;
+ exit ;;
i*86:Linux:*:*)
# The BFD linker knows what the default object file format is, so
# first see if it will tell us. cd to the root directory to prevent
# problems with other programs or directories called `ld' in the path.
- ld_supported_targets=`cd /; ld --help 2>&1 \
+ # Set LC_ALL=C to ensure ld outputs messages in English.
+ ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
| sed -ne '/supported targets:/!d
s/[ ][ ]*/ /g
s/.*supported targets: *//
@@ -840,52 +939,54 @@ EOF
;;
a.out-i386-linux)
echo "${UNAME_MACHINE}-pc-linux-gnuaout"
- exit 0 ;;
+ exit ;;
coff-i386)
echo "${UNAME_MACHINE}-pc-linux-gnucoff"
- exit 0 ;;
+ exit ;;
"")
# Either a pre-BFD a.out linker (linux-gnuoldld) or
# one that does not give us useful --help.
echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
- exit 0 ;;
+ exit ;;
esac
# Determine whether the default compiler is a.out or elf
eval $set_cc_for_build
- cat >$dummy.c <<EOF
-#include <features.h>
-#ifdef __cplusplus
-#include <stdio.h> /* for printf() prototype */
- int main (int argc, char *argv[]) {
-#else
- int main (argc, argv) int argc; char *argv[]; {
-#endif
-#ifdef __ELF__
-# ifdef __GLIBC__
-# if __GLIBC__ >= 2
- printf ("%s-pc-linux-gnu\n", argv[1]);
-# else
- printf ("%s-pc-linux-gnulibc1\n", argv[1]);
-# endif
-# else
- printf ("%s-pc-linux-gnulibc1\n", argv[1]);
-# endif
-#else
- printf ("%s-pc-linux-gnuaout\n", argv[1]);
-#endif
- return 0;
-}
+ sed 's/^ //' << EOF >$dummy.c
+ #include <features.h>
+ #ifdef __ELF__
+ # ifdef __GLIBC__
+ # if __GLIBC__ >= 2
+ LIBC=gnu
+ # else
+ LIBC=gnulibc1
+ # endif
+ # else
+ LIBC=gnulibc1
+ # endif
+ #else
+ #ifdef __INTEL_COMPILER
+ LIBC=gnu
+ #else
+ LIBC=gnuaout
+ #endif
+ #endif
+ #ifdef __dietlibc__
+ LIBC=dietlibc
+ #endif
EOF
- $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm -f $dummy.c $dummy && exit 0
- rm -f $dummy.c $dummy
- test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
+ test x"${LIBC}" != x && {
+ echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
+ exit
+ }
+ test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; }
;;
i*86:DYNIX/ptx:4*:*)
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
# earlier versions are messed up and put the nodename in both
# sysname and nodename.
echo i386-sequent-sysv4
- exit 0 ;;
+ exit ;;
i*86:UNIX_SV:4.2MP:2.*)
# Unixware is an offshoot of SVR4, but it has its own version
# number series starting with 2...
@@ -893,7 +994,27 @@ EOF
# I just have to hope. -- rms.
# Use sysv4.2uw... so that sysv4* matches it.
echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
- exit 0 ;;
+ exit ;;
+ i*86:OS/2:*:*)
+ # If we were able to find `uname', then EMX Unix compatibility
+ # is probably installed.
+ echo ${UNAME_MACHINE}-pc-os2-emx
+ exit ;;
+ i*86:XTS-300:*:STOP)
+ echo ${UNAME_MACHINE}-unknown-stop
+ exit ;;
+ i*86:atheos:*:*)
+ echo ${UNAME_MACHINE}-unknown-atheos
+ exit ;;
+ i*86:syllable:*:*)
+ echo ${UNAME_MACHINE}-pc-syllable
+ exit ;;
+ i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+ echo i386-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ i*86:*DOS:*:*)
+ echo ${UNAME_MACHINE}-pc-msdosdjgpp
+ exit ;;
i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
@@ -901,99 +1022,100 @@ EOF
else
echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
fi
- exit 0 ;;
- i*86:*:5:[78]*)
+ exit ;;
+ i*86:*:5:[678]*)
+ # UnixWare 7.x, OpenUNIX and OpenServer 6.
case `/bin/uname -X | grep "^Machine"` in
*486*) UNAME_MACHINE=i486 ;;
*Pentium) UNAME_MACHINE=i586 ;;
*Pent*|*Celeron) UNAME_MACHINE=i686 ;;
esac
echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
- exit 0 ;;
+ exit ;;
i*86:*:3.2:*)
if test -f /usr/options/cb.name; then
UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
elif /bin/uname -X 2>/dev/null >/dev/null ; then
- UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
- (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
- (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
+ UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+ (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+ (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
&& UNAME_MACHINE=i586
- (/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \
+ (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
&& UNAME_MACHINE=i686
- (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \
+ (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
&& UNAME_MACHINE=i686
echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
else
echo ${UNAME_MACHINE}-pc-sysv32
fi
- exit 0 ;;
- i*86:*DOS:*:*)
- echo ${UNAME_MACHINE}-pc-msdosdjgpp
- exit 0 ;;
+ exit ;;
pc:*:*:*)
# Left here for compatibility:
# uname -m prints for DJGPP always 'pc', but it prints nothing about
# the processor, so we play safe by assuming i386.
echo i386-pc-msdosdjgpp
- exit 0 ;;
+ exit ;;
Intel:Mach:3*:*)
echo i386-pc-mach3
- exit 0 ;;
+ exit ;;
paragon:*:*:*)
echo i860-intel-osf1
- exit 0 ;;
+ exit ;;
i860:*:4.*:*) # i860-SVR4
if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
else # Add other i860-SVR4 vendors below as they are discovered.
echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
fi
- exit 0 ;;
+ exit ;;
mini*:CTIX:SYS*5:*)
# "miniframe"
echo m68010-convergent-sysv
- exit 0 ;;
- M68*:*:R3V[567]*:*)
- test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
- 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0)
+ exit ;;
+ mc68k:UNIX:SYSTEM5:3.51m)
+ echo m68k-convergent-sysv
+ exit ;;
+ M680?0:D-NIX:5.3:*)
+ echo m68k-diab-dnix
+ exit ;;
+ M68*:*:R3V[5678]*:*)
+ test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
+ 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
OS_REL=''
test -r /etc/.relid \
&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
- && echo i486-ncr-sysv4.3${OS_REL} && exit 0
+ && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
- && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
- && echo i486-ncr-sysv4 && exit 0 ;;
+ && { echo i486-ncr-sysv4; exit; } ;;
m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
echo m68k-unknown-lynxos${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
mc68030:UNIX_System_V:4.*:*)
echo m68k-atari-sysv4
- exit 0 ;;
- i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
- echo i386-unknown-lynxos${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
TSUNAMI:LynxOS:2.*:*)
echo sparc-unknown-lynxos${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
rs6000:LynxOS:2.*:*)
echo rs6000-unknown-lynxos${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
echo powerpc-unknown-lynxos${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
SM[BE]S:UNIX_SV:*:*)
echo mips-dde-sysv${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
RM*:ReliantUNIX-*:*:*)
echo mips-sni-sysv4
- exit 0 ;;
+ exit ;;
RM*:SINIX-*:*:*)
echo mips-sni-sysv4
- exit 0 ;;
+ exit ;;
*:SINIX-*:*:*)
if uname -p 2>/dev/null >/dev/null ; then
UNAME_MACHINE=`(uname -p) 2>/dev/null`
@@ -1001,82 +1123,99 @@ EOF
else
echo ns32k-sni-sysv
fi
- exit 0 ;;
+ exit ;;
PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
# says <Richard.M.Bartel@ccMail.Census.GOV>
echo i586-unisys-sysv4
- exit 0 ;;
+ exit ;;
*:UNIX_System_V:4*:FTX*)
# From Gerald Hewes <hewes@openmarket.com>.
# How about differentiating between stratus architectures? -djm
echo hppa1.1-stratus-sysv4
- exit 0 ;;
+ exit ;;
*:*:*:FTX*)
# From seanf@swdc.stratus.com.
echo i860-stratus-sysv4
- exit 0 ;;
+ exit ;;
+ i*86:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo ${UNAME_MACHINE}-stratus-vos
+ exit ;;
*:VOS:*:*)
# From Paul.Green@stratus.com.
echo hppa1.1-stratus-vos
- exit 0 ;;
+ exit ;;
mc68*:A/UX:*:*)
echo m68k-apple-aux${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
news*:NEWS-OS:6*:*)
echo mips-sony-newsos6
- exit 0 ;;
+ exit ;;
R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
if [ -d /usr/nec ]; then
echo mips-nec-sysv${UNAME_RELEASE}
else
echo mips-unknown-sysv${UNAME_RELEASE}
fi
- exit 0 ;;
+ exit ;;
BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
echo powerpc-be-beos
- exit 0 ;;
+ exit ;;
BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
echo powerpc-apple-beos
- exit 0 ;;
+ exit ;;
BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
echo i586-pc-beos
- exit 0 ;;
+ exit ;;
SX-4:SUPER-UX:*:*)
echo sx4-nec-superux${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
SX-5:SUPER-UX:*:*)
echo sx5-nec-superux${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
+ SX-6:SUPER-UX:*:*)
+ echo sx6-nec-superux${UNAME_RELEASE}
+ exit ;;
Power*:Rhapsody:*:*)
echo powerpc-apple-rhapsody${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
*:Rhapsody:*:*)
echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
*:Darwin:*:*)
- echo `uname -p`-apple-darwin${UNAME_RELEASE}
- exit 0 ;;
+ UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+ case $UNAME_PROCESSOR in
+ *86) UNAME_PROCESSOR=i686 ;;
+ unknown) UNAME_PROCESSOR=powerpc ;;
+ esac
+ echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+ exit ;;
*:procnto*:*:* | *:QNX:[0123456789]*:*)
- if test "${UNAME_MACHINE}" = "x86pc"; then
+ UNAME_PROCESSOR=`uname -p`
+ if test "$UNAME_PROCESSOR" = "x86"; then
+ UNAME_PROCESSOR=i386
UNAME_MACHINE=pc
fi
- echo `uname -p`-${UNAME_MACHINE}-nto-qnx
- exit 0 ;;
+ echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+ exit ;;
*:QNX:*:4*)
echo i386-pc-qnx
- exit 0 ;;
- NSR-[KW]:NONSTOP_KERNEL:*:*)
+ exit ;;
+ NSE-?:NONSTOP_KERNEL:*:*)
+ echo nse-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ NSR-?:NONSTOP_KERNEL:*:*)
echo nsr-tandem-nsk${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
*:NonStop-UX:*:*)
echo mips-compaq-nonstopux
- exit 0 ;;
+ exit ;;
BS2000:POSIX*:*:*)
echo bs2000-siemens-sysv
- exit 0 ;;
+ exit ;;
DS/*:UNIX_System_V:*:*)
echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
- exit 0 ;;
+ exit ;;
*:Plan9:*:*)
# "uname -m" is not consistent, so use $cputype instead. 386
# is converted to i386 for consistency with other x86
@@ -1087,36 +1226,44 @@ EOF
UNAME_MACHINE="$cputype"
fi
echo ${UNAME_MACHINE}-unknown-plan9
- exit 0 ;;
- i*86:OS/2:*:*)
- # If we were able to find `uname', then EMX Unix compatibility
- # is probably installed.
- echo ${UNAME_MACHINE}-pc-os2-emx
- exit 0 ;;
+ exit ;;
*:TOPS-10:*:*)
echo pdp10-unknown-tops10
- exit 0 ;;
+ exit ;;
*:TENEX:*:*)
echo pdp10-unknown-tenex
- exit 0 ;;
+ exit ;;
KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
echo pdp10-dec-tops20
- exit 0 ;;
+ exit ;;
XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
echo pdp10-xkl-tops20
- exit 0 ;;
+ exit ;;
*:TOPS-20:*:*)
echo pdp10-unknown-tops20
- exit 0 ;;
+ exit ;;
*:ITS:*:*)
echo pdp10-unknown-its
- exit 0 ;;
- i*86:XTS-300:*:STOP)
- echo ${UNAME_MACHINE}-unknown-stop
- exit 0 ;;
- i*86:atheos:*:*)
- echo ${UNAME_MACHINE}-unknown-atheos
- exit 0 ;;
+ exit ;;
+ SEI:*:*:SEIUX)
+ echo mips-sei-seiux${UNAME_RELEASE}
+ exit ;;
+ *:DragonFly:*:*)
+ echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ exit ;;
+ *:*VMS:*:*)
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ case "${UNAME_MACHINE}" in
+ A*) echo alpha-dec-vms ; exit ;;
+ I*) echo ia64-dec-vms ; exit ;;
+ V*) echo vax-dec-vms ; exit ;;
+ esac ;;
+ *:XENIX:*:SysV)
+ echo i386-pc-xenix
+ exit ;;
+ i*86:skyos:*:*)
+ echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+ exit ;;
esac
#echo '(No uname command or uname output not recognized.)' 1>&2
@@ -1148,7 +1295,7 @@ main ()
#endif
#if defined (__arm) && defined (__acorn) && defined (__unix)
- printf ("arm-acorn-riscix"); exit (0);
+ printf ("arm-acorn-riscix\n"); exit (0);
#endif
#if defined (hp300) && !defined (hpux)
@@ -1237,12 +1384,12 @@ main ()
}
EOF
-$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm -f $dummy.c $dummy && exit 0
-rm -f $dummy.c $dummy
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
+ { echo "$SYSTEM_NAME"; exit; }
# Apollos put the system type in the environment.
-test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
# Convex versions that predate uname can use getsysinfo(1)
@@ -1251,22 +1398,22 @@ then
case `getsysinfo -f cpu_type` in
c1*)
echo c1-convex-bsd
- exit 0 ;;
+ exit ;;
c2*)
if getsysinfo -f scalar_acc
then echo c32-convex-bsd
else echo c2-convex-bsd
fi
- exit 0 ;;
+ exit ;;
c34*)
echo c34-convex-bsd
- exit 0 ;;
+ exit ;;
c38*)
echo c38-convex-bsd
- exit 0 ;;
+ exit ;;
c4*)
echo c4-convex-bsd
- exit 0 ;;
+ exit ;;
esac
fi
@@ -1277,7 +1424,9 @@ This script, last modified $timestamp, has failed to recognize
the operating system you are using. It is advised that you
download the most up to date version of the config scripts from
- ftp://ftp.gnu.org/pub/gnu/config/
+ http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess
+and
+ http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub
If the version you run ($0) is already up to date, please
send the following data and any information you think might be
diff --git a/config.sub b/config.sub
index 7cee3d6..1c366df 100755
--- a/config.sub
+++ b/config.sub
@@ -1,9 +1,9 @@
#! /bin/sh
# Configuration validation subroutine script.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-# 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
-timestamp='2003-06-18'
+timestamp='2005-07-08'
# This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software
@@ -21,14 +21,15 @@ timestamp='2003-06-18'
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330,
-# Boston, MA 02111-1307, USA.
-
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
+
# Please send patches to <config-patches@gnu.org>. Submit a context
# diff and a properly formatted ChangeLog entry.
#
@@ -70,7 +71,7 @@ Report bugs and patches to <config-patches@gnu.org>."
version="\
GNU config.sub ($timestamp)
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
@@ -83,11 +84,11 @@ Try \`$me --help' for more information."
while test $# -gt 0 ; do
case $1 in
--time-stamp | --time* | -t )
- echo "$timestamp" ; exit 0 ;;
+ echo "$timestamp" ; exit ;;
--version | -v )
- echo "$version" ; exit 0 ;;
+ echo "$version" ; exit ;;
--help | --h* | -h )
- echo "$usage"; exit 0 ;;
+ echo "$usage"; exit ;;
-- ) # Stop option processing
shift; break ;;
- ) # Use stdin as input.
@@ -99,7 +100,7 @@ while test $# -gt 0 ; do
*local*)
# First pass through any local machine types.
echo $1
- exit 0;;
+ exit ;;
* )
break ;;
@@ -118,7 +119,8 @@ esac
# Here we must recognize all the valid KERNEL-OS combinations.
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in
- nto-qnx* | linux-gnu* | freebsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*)
+ nto-qnx* | linux-gnu* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \
+ kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*)
os=-$maybe_os
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
;;
@@ -144,7 +146,7 @@ case $os in
-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
- -apple | -axis)
+ -apple | -axis | -knuth | -cray)
os=
basic_machine=$1
;;
@@ -228,14 +230,16 @@ case $basic_machine in
| a29k \
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+ | am33_2.0 \
| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
+ | bfin \
| c4x | clipper \
| d10v | d30v | dlx | dsp16xx \
| fr30 | frv \
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| i370 | i860 | i960 | ia64 \
- | ip2k \
- | m32r | m68000 | m68k | m88k | mcore \
+ | ip2k | iq2000 \
+ | m32r | m32rle | m68000 | m68k | m88k | maxq | mcore \
| mips | mipsbe | mipseb | mipsel | mipsle \
| mips16 \
| mips64 | mips64el \
@@ -244,31 +248,37 @@ case $basic_machine in
| mips64vr4100 | mips64vr4100el \
| mips64vr4300 | mips64vr4300el \
| mips64vr5000 | mips64vr5000el \
+ | mips64vr5900 | mips64vr5900el \
| mipsisa32 | mipsisa32el \
| mipsisa32r2 | mipsisa32r2el \
| mipsisa64 | mipsisa64el \
+ | mipsisa64r2 | mipsisa64r2el \
| mipsisa64sb1 | mipsisa64sb1el \
| mipsisa64sr71k | mipsisa64sr71kel \
| mipstx39 | mipstx39el \
| mn10200 | mn10300 \
+ | ms1 \
| msp430 \
| ns16k | ns32k \
- | openrisc | or32 \
+ | or32 \
| pdp10 | pdp11 | pj | pjl \
| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
| pyramid \
- | s390 | s390x \
- | sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
+ | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
| sh64 | sh64le \
- | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \
+ | sparc | sparc64 | sparc64b | sparc86x | sparclet | sparclite \
+ | sparcv8 | sparcv9 | sparcv9b \
| strongarm \
| tahoe | thumb | tic4x | tic80 | tron \
| v850 | v850e \
| we32k \
- | x86 | xscale | xstormy16 | xtensa \
+ | x86 | xscale | xscalee[bl] | xstormy16 | xtensa \
| z8k)
basic_machine=$basic_machine-unknown
;;
+ m32c)
+ basic_machine=$basic_machine-unknown
+ ;;
m6811 | m68hc11 | m6812 | m68hc12)
# Motorola 68HC11/12.
basic_machine=$basic_machine-unknown
@@ -296,19 +306,19 @@ case $basic_machine in
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
| avr-* \
- | bs2000-* \
+ | bfin-* | bs2000-* \
| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
- | clipper-* | cydra-* \
+ | clipper-* | craynv-* | cydra-* \
| d10v-* | d30v-* | dlx-* \
| elxsi-* \
| f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
| h8300-* | h8500-* \
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
| i*86-* | i860-* | i960-* | ia64-* \
- | ip2k-* \
- | m32r-* \
+ | ip2k-* | iq2000-* \
+ | m32r-* | m32rle-* \
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
- | m88110-* | m88k-* | mcore-* \
+ | m88110-* | m88k-* | maxq-* | mcore-* \
| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
| mips16-* \
| mips64-* | mips64el-* \
@@ -317,34 +327,40 @@ case $basic_machine in
| mips64vr4100-* | mips64vr4100el-* \
| mips64vr4300-* | mips64vr4300el-* \
| mips64vr5000-* | mips64vr5000el-* \
+ | mips64vr5900-* | mips64vr5900el-* \
| mipsisa32-* | mipsisa32el-* \
| mipsisa32r2-* | mipsisa32r2el-* \
| mipsisa64-* | mipsisa64el-* \
+ | mipsisa64r2-* | mipsisa64r2el-* \
| mipsisa64sb1-* | mipsisa64sb1el-* \
| mipsisa64sr71k-* | mipsisa64sr71kel-* \
| mipstx39-* | mipstx39el-* \
+ | mmix-* \
+ | ms1-* \
| msp430-* \
- | none-* | np1-* | nv1-* | ns16k-* | ns32k-* \
+ | none-* | np1-* | ns16k-* | ns32k-* \
| orion-* \
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
| pyramid-* \
| romp-* | rs6000-* \
- | s390-* | s390x-* \
- | sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \
+ | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | shbe-* \
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
- | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \
- | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
+ | sparc-* | sparc64-* | sparc64b-* | sparc86x-* | sparclet-* \
+ | sparclite-* \
+ | sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
| tahoe-* | thumb-* \
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
| tron-* \
| v850-* | v850e-* | vax-* \
| we32k-* \
- | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \
- | xtensa-* \
+ | x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \
+ | xstormy16-* | xtensa-* \
| ymp-* \
| z8k-*)
;;
+ m32c-*)
+ ;;
# Recognize the various machine names and aliases which stand
# for a CPU type and a company and sometimes even an OS.
386bsd)
@@ -361,6 +377,9 @@ case $basic_machine in
basic_machine=a29k-amd
os=-udi
;;
+ abacus)
+ basic_machine=abacus-unknown
+ ;;
adobe68k)
basic_machine=m68010-adobe
os=-scout
@@ -378,6 +397,9 @@ case $basic_machine in
amd64)
basic_machine=x86_64-pc
;;
+ amd64-*)
+ basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
amdahl)
basic_machine=580-amdahl
os=-sysv
@@ -437,12 +459,27 @@ case $basic_machine in
basic_machine=j90-cray
os=-unicos
;;
+ craynv)
+ basic_machine=craynv-cray
+ os=-unicosmp
+ ;;
+ cr16c)
+ basic_machine=cr16c-unknown
+ os=-elf
+ ;;
crds | unos)
basic_machine=m68k-crds
;;
+ crisv32 | crisv32-* | etraxfs*)
+ basic_machine=crisv32-axis
+ ;;
cris | cris-* | etrax*)
basic_machine=cris-axis
;;
+ crx)
+ basic_machine=crx-unknown
+ os=-elf
+ ;;
da30 | da30-*)
basic_machine=m68k-da30
;;
@@ -465,6 +502,10 @@ case $basic_machine in
basic_machine=m88k-motorola
os=-sysv3
;;
+ djgpp)
+ basic_machine=i586-pc
+ os=-msdosdjgpp
+ ;;
dpx20 | dpx20-*)
basic_machine=rs6000-bull
os=-bosx
@@ -643,10 +684,6 @@ case $basic_machine in
mips3*)
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
;;
- mmix*)
- basic_machine=mmix-knuth
- os=-mmixware
- ;;
monitor)
basic_machine=m68k-rom68k
os=-coff
@@ -727,10 +764,6 @@ case $basic_machine in
np1)
basic_machine=np1-gould
;;
- nv1)
- basic_machine=nv1-cray
- os=-unicosmp
- ;;
nsr-tandem)
basic_machine=nsr-tandem
;;
@@ -738,9 +771,12 @@ case $basic_machine in
basic_machine=hppa1.1-oki
os=-proelf
;;
- or32 | or32-*)
+ openrisc | openrisc-*)
basic_machine=or32-unknown
- os=-coff
+ ;;
+ os400)
+ basic_machine=powerpc-ibm
+ os=-os400
;;
OSE68000 | ose68000)
basic_machine=m68000-ericsson
@@ -833,6 +869,12 @@ case $basic_machine in
rtpc | rtpc-*)
basic_machine=romp-ibm
;;
+ s390 | s390-*)
+ basic_machine=s390-ibm
+ ;;
+ s390x | s390x-*)
+ basic_machine=s390x-ibm
+ ;;
sa29200)
basic_machine=a29k-amd
os=-udi
@@ -956,6 +998,10 @@ case $basic_machine in
tower | tower-32)
basic_machine=m68k-ncr
;;
+ tpf)
+ basic_machine=s390x-ibm
+ os=-tpf
+ ;;
udi29k)
basic_machine=a29k-amd
os=-udi
@@ -999,6 +1045,10 @@ case $basic_machine in
basic_machine=hppa1.1-winbond
os=-proelf
;;
+ xbox)
+ basic_machine=i686-pc
+ os=-mingw32
+ ;;
xps | xps100)
basic_machine=xps100-honeywell
;;
@@ -1029,6 +1079,9 @@ case $basic_machine in
romp)
basic_machine=romp-ibm
;;
+ mmix)
+ basic_machine=mmix-knuth
+ ;;
rs6000)
basic_machine=rs6000-ibm
;;
@@ -1045,13 +1098,10 @@ case $basic_machine in
we32k)
basic_machine=we32k-att
;;
- sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele)
+ sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele)
basic_machine=sh-unknown
;;
- sh64)
- basic_machine=sh64-unknown
- ;;
- sparc | sparcv9 | sparcv9b)
+ sparc | sparcv8 | sparcv9 | sparcv9b)
basic_machine=sparc-sun
;;
cydra)
@@ -1124,19 +1174,21 @@ case $os in
| -aos* \
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
- | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
- | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \
+ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
| -chorusos* | -chorusrdb* \
| -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
- | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
+ | -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
- | -powermax* | -dnix* | -nx6 | -nx7 | -sei*)
+ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+ | -skyos* | -haiku*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
-qnx*)
@@ -1154,12 +1206,15 @@ case $os in
os=`echo $os | sed -e 's|nto|nto-qnx|'`
;;
-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
- | -windows* | -osx | -abug | -netware* | -os9* | -beos* \
+ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
| -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
;;
-mac*)
os=`echo $os | sed -e 's|mac|macos|'`
;;
+ -linux-dietlibc)
+ os=-linux-dietlibc
+ ;;
-linux*)
os=`echo $os | sed -e 's|linux|linux-gnu|'`
;;
@@ -1172,6 +1227,9 @@ case $os in
-opened*)
os=-openedition
;;
+ -os400*)
+ os=-os400
+ ;;
-wince*)
os=-wince
;;
@@ -1193,6 +1251,9 @@ case $os in
-atheos*)
os=-atheos
;;
+ -syllable*)
+ os=-syllable
+ ;;
-386bsd)
os=-bsd
;;
@@ -1215,6 +1276,9 @@ case $os in
-sinix*)
os=-sysv4
;;
+ -tpf*)
+ os=-tpf
+ ;;
-triton*)
os=-sysv3
;;
@@ -1251,6 +1315,9 @@ case $os in
-kaos*)
os=-kaos
;;
+ -zvmoe)
+ os=-zvmoe
+ ;;
-none)
;;
*)
@@ -1282,9 +1349,9 @@ case $basic_machine in
arm*-semi)
os=-aout
;;
- c4x-* | tic4x-*)
- os=-coff
- ;;
+ c4x-* | tic4x-*)
+ os=-coff
+ ;;
# This must come before the *-dec entry.
pdp10-*)
os=-tops20
@@ -1328,9 +1395,15 @@ case $basic_machine in
*-be)
os=-beos
;;
+ *-haiku)
+ os=-haiku
+ ;;
*-ibm)
os=-aix
;;
+ *-knuth)
+ os=-mmixware
+ ;;
*-wec)
os=-proelf
;;
@@ -1463,9 +1536,15 @@ case $basic_machine in
-mvs* | -opened*)
vendor=ibm
;;
+ -os400*)
+ vendor=ibm
+ ;;
-ptx*)
vendor=sequent
;;
+ -tpf*)
+ vendor=ibm
+ ;;
-vxsim* | -vxworks* | -windiss*)
vendor=wrs
;;
@@ -1490,7 +1569,7 @@ case $basic_machine in
esac
echo $basic_machine$os
-exit 0
+exit
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
diff --git a/configure b/configure
index 9147d97..789e02c 100755
--- a/configure
+++ b/configure
@@ -1,11 +1,10 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.57 for google-perftools 0.8.
+# Generated by GNU Autoconf 2.59 for google-perftools 0.90.
#
# Report bugs to <opensource@google.com>.
#
-# Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002
-# Free Software Foundation, Inc.
+# Copyright (C) 2003 Free Software Foundation, Inc.
# This configure script is free software; the Free Software Foundation
# gives unlimited permission to copy, distribute and modify it.
## --------------------- ##
@@ -22,9 +21,10 @@ if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
set -o posix
fi
+DUALCASE=1; export DUALCASE # for MKS sh
# Support unset when possible.
-if (FOO=FOO; unset FOO) >/dev/null 2>&1; then
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
as_unset=unset
else
as_unset=false
@@ -43,7 +43,7 @@ for as_var in \
LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
LC_TELEPHONE LC_TIME
do
- if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then
+ if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
eval $as_var=C; export $as_var
else
$as_unset $as_var
@@ -220,16 +220,17 @@ rm -f conf$$ conf$$.exe conf$$.file
if mkdir -p . 2>/dev/null; then
as_mkdir_p=:
else
+ test -d ./-p && rmdir ./-p
as_mkdir_p=false
fi
as_executable_p="test -f"
# Sed expression to map a string onto a valid CPP name.
-as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g"
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
# Sed expression to map a string onto a valid variable name.
-as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g"
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
# IFS
@@ -279,15 +280,15 @@ fi
# The HP-UX ksh and POSIX shell print the target directory to stdout
# if CDPATH is set.
-if test "X${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
if test -z "$ECHO"; then
if test "X${echo_test_string+set}" != Xset; then
# find a string as large as possible, as long as the shell can cope with it
for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do
# expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
- if (echo_test_string="`eval $cmd`") 2>/dev/null &&
- echo_test_string="`eval $cmd`" &&
+ if (echo_test_string=`eval $cmd`) 2>/dev/null &&
+ echo_test_string=`eval $cmd` &&
(test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null
then
break
@@ -392,9 +393,9 @@ fi
-tagnames=`echo "$tagnames,CXX" | sed 's/^,//'`
+tagnames=${tagnames+${tagnames},}CXX
-tagnames=`echo "$tagnames,F77" | sed 's/^,//'`
+tagnames=${tagnames+${tagnames},}F77
# Name of the host.
# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
@@ -422,8 +423,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
# Identity of this package.
PACKAGE_NAME='google-perftools'
PACKAGE_TARNAME='google-perftools'
-PACKAGE_VERSION='0.8'
-PACKAGE_STRING='google-perftools 0.8'
+PACKAGE_VERSION='0.90'
+PACKAGE_STRING='google-perftools 0.90'
PACKAGE_BUGREPORT='opensource@google.com'
ac_unique_file="README"
@@ -464,7 +465,7 @@ ac_includes_default="\
# include <unistd.h>
#endif"
-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO AMTAR install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM AWK SET_MAKE CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE CPP CXX CXXFLAGS ac_ct_CXX CXXDEPMODE build build_cpu build_vendor build_os host host_cpu host_vendor host_os EGREP LN_S ECHO AR ac_ct_AR RANLIB ac_ct_RANLIB CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL LIBTOOL_DEPS acx_pthread_config PTHREAD_CC PTHREAD_LIBS PTHREAD_CFLAGS LIBOBJS LTLIBOBJS'
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CPP CXX CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE build build_cpu build_vendor build_os host host_cpu host_vendor host_os EGREP LN_S ECHO AR ac_ct_AR RANLIB ac_ct_RANLIB CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL LIBTOOL_DEPS UNWIND_LIBS EXTRA_CXXFLAGS acx_pthread_config PTHREAD_CC PTHREAD_LIBS PTHREAD_CFLAGS LIBOBJS LTLIBOBJS'
ac_subst_files=''
# Initialize some variables set by options.
@@ -823,7 +824,7 @@ done
# Be sure to have absolute paths.
for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
- localstatedir libdir includedir oldincludedir infodir mandir
+ localstatedir libdir includedir oldincludedir infodir mandir
do
eval ac_val=$`echo $ac_var`
case $ac_val in
@@ -863,10 +864,10 @@ if test -z "$srcdir"; then
# Try the directory containing this script, then its parent.
ac_confdir=`(dirname "$0") 2>/dev/null ||
$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$0" : 'X\(//\)[^/]' \| \
- X"$0" : 'X\(//\)$' \| \
- X"$0" : 'X\(/\)' \| \
- . : '\(.\)' 2>/dev/null ||
+ X"$0" : 'X\(//\)[^/]' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
echo X"$0" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
/^X\(\/\/\)[^/].*/{ s//\1/; q; }
@@ -953,7 +954,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures google-perftools 0.8 to adapt to many kinds of systems.
+\`configure' configures google-perftools 0.90 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -978,9 +979,9 @@ _ACEOF
cat <<_ACEOF
Installation directories:
--prefix=PREFIX install architecture-independent files in PREFIX
- [$ac_default_prefix]
+ [$ac_default_prefix]
--exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
- [PREFIX]
+ [PREFIX]
By default, \`make install' will install all the files in
\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
@@ -1019,15 +1020,15 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of google-perftools 0.8:";;
+ short | recursive ) echo "Configuration of google-perftools 0.90:";;
esac
cat <<\_ACEOF
Optional Features:
--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
- --disable-dependency-tracking Speeds up one-time builds
- --enable-dependency-tracking Do not reject slow dependency extractors
+ --disable-dependency-tracking speeds up one-time build
+ --enable-dependency-tracking do not reject slow dependency extractors
--enable-shared[=PKGS]
build shared libraries [default=yes]
--enable-static[=PKGS]
@@ -1035,6 +1036,8 @@ Optional Features:
--enable-fast-install[=PKGS]
optimize for fast installation [default=yes]
--disable-libtool-lock avoid locking (might break parallel builds)
+ --enable-frame-pointer On x86_64 systems, compile with
+ -fno-omit-frame-pointer (see INSTALL)
Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
@@ -1096,12 +1099,45 @@ case $srcdir in
ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
ac_top_srcdir=$ac_top_builddir$srcdir ;;
esac
-# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
-# absolute.
-ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
-ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd`
-ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
-ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+ case "$ac_dir" in
+ .) ac_abs_builddir=`pwd`;;
+ [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+ *) ac_abs_builddir=`pwd`/"$ac_dir";;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+ case ${ac_top_builddir}. in
+ .) ac_abs_top_builddir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+ *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+ case $ac_srcdir in
+ .) ac_abs_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+ *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+ case $ac_top_srcdir in
+ .) ac_abs_top_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+ *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+ esac;;
+esac
cd $ac_dir
# Check for guested configure; otherwise get Cygnus style configure.
@@ -1112,24 +1148,23 @@ ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
echo
$SHELL $ac_srcdir/configure --help=recursive
elif test -f $ac_srcdir/configure.ac ||
- test -f $ac_srcdir/configure.in; then
+ test -f $ac_srcdir/configure.in; then
echo
$ac_configure --help
else
echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
fi
- cd $ac_popdir
+ cd "$ac_popdir"
done
fi
test -n "$ac_init_help" && exit 0
if $ac_init_version; then
cat <<\_ACEOF
-google-perftools configure 0.8
-generated by GNU Autoconf 2.57
+google-perftools configure 0.90
+generated by GNU Autoconf 2.59
-Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002
-Free Software Foundation, Inc.
+Copyright (C) 2003 Free Software Foundation, Inc.
This configure script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it.
_ACEOF
@@ -1140,8 +1175,8 @@ cat >&5 <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by google-perftools $as_me 0.8, which was
-generated by GNU Autoconf 2.57. Invocation command line was
+It was created by google-perftools $as_me 0.90, which was
+generated by GNU Autoconf 2.59. Invocation command line was
$ $0 $@
@@ -1218,19 +1253,19 @@ do
2)
ac_configure_args1="$ac_configure_args1 '$ac_arg'"
if test $ac_must_keep_next = true; then
- ac_must_keep_next=false # Got value, back to normal.
+ ac_must_keep_next=false # Got value, back to normal.
else
- case $ac_arg in
- *=* | --config-cache | -C | -disable-* | --disable-* \
- | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
- | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
- | -with-* | --with-* | -without-* | --without-* | --x)
- case "$ac_configure_args0 " in
- "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
- esac
- ;;
- -* ) ac_must_keep_next=true ;;
- esac
+ case $ac_arg in
+ *=* | --config-cache | -C | -disable-* | --disable-* \
+ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+ | -with-* | --with-* | -without-* | --without-* | --x)
+ case "$ac_configure_args0 " in
+ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+ esac
+ ;;
+ -* ) ac_must_keep_next=true ;;
+ esac
fi
ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
# Get rid of the leading space.
@@ -1264,12 +1299,12 @@ _ASBOX
case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
*ac_space=\ *)
sed -n \
- "s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
- s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
+ "s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
;;
*)
sed -n \
- "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
;;
esac;
}
@@ -1298,7 +1333,7 @@ _ASBOX
for ac_var in $ac_subst_files
do
eval ac_val=$`echo $ac_var`
- echo "$ac_var='"'"'$ac_val'"'"'"
+ echo "$ac_var='"'"'$ac_val'"'"'"
done | sort
echo
fi
@@ -1317,7 +1352,7 @@ _ASBOX
echo "$as_me: caught signal $ac_signal"
echo "$as_me: exit $exit_status"
} >&5
- rm -f core core.* *.core &&
+ rm -f core *.core &&
rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
exit $exit_status
' 0
@@ -1397,7 +1432,7 @@ fi
# value.
ac_cache_corrupted=false
for ac_var in `(set) 2>&1 |
- sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
+ sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
eval ac_old_set=\$ac_cv_env_${ac_var}_set
eval ac_new_set=\$ac_env_${ac_var}_set
eval ac_old_val="\$ac_cv_env_${ac_var}_value"
@@ -1414,13 +1449,13 @@ echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
,);;
*)
if test "x$ac_old_val" != "x$ac_new_val"; then
- { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+ { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
- { echo "$as_me:$LINENO: former value: $ac_old_val" >&5
+ { echo "$as_me:$LINENO: former value: $ac_old_val" >&5
echo "$as_me: former value: $ac_old_val" >&2;}
- { echo "$as_me:$LINENO: current value: $ac_new_val" >&5
+ { echo "$as_me:$LINENO: current value: $ac_new_val" >&5
echo "$as_me: current value: $ac_new_val" >&2;}
- ac_cache_corrupted=:
+ ac_cache_corrupted=:
fi;;
esac
# Pass precious variables to config.status.
@@ -1479,7 +1514,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
# The argument here is just something that should be in the current directory
# (for sanity checking)
-am__api_version="1.6"
+am__api_version="1.9"
ac_aux_dir=
for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
if test -f $ac_dir/install-sh; then
@@ -1516,6 +1551,7 @@ ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure.
# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
# AFS /usr/afsws/bin/install, which mishandles nonexistent args
# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
# ./install, which can be erroneously created by make from ./install.sh.
echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
@@ -1532,6 +1568,7 @@ do
case $as_dir/ in
./ | .// | /cC/* | \
/etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+ ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \
/usr/ucb/* ) ;;
*)
# OSF1 and SCO ODT 3.0 have their own names for install.
@@ -1539,20 +1576,20 @@ case $as_dir/ in
# by default.
for ac_prog in ginstall scoinst install; do
for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
- if test $ac_prog = install &&
- grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
- # AIX install. It has an incompatible calling convention.
- :
- elif test $ac_prog = install &&
- grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
- # program-specific install script used by HP pwplus--don't use.
- :
- else
- ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
- break 3
- fi
- fi
+ if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+ if test $ac_prog = install &&
+ grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ elif test $ac_prog = install &&
+ grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # program-specific install script used by HP pwplus--don't use.
+ :
+ else
+ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+ break 3
+ fi
+ fi
done
done
;;
@@ -1640,7 +1677,6 @@ _ACEOF
program_transform_name=`echo $program_transform_name | sed -f conftest.sed`
rm conftest.sed
-
# expand $ac_aux_dir to an absolute path
am_aux_dir=`cd $ac_aux_dir && pwd`
@@ -1654,6 +1690,39 @@ else
echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;}
fi
+if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
+ # We used to keeping the `.' as first argument, in order to
+ # allow $(mkdir_p) to be used without argument. As in
+ # $(mkdir_p) $(somedir)
+ # where $(somedir) is conditionally defined. However this is wrong
+ # for two reasons:
+ # 1. if the package is installed by a user who cannot write `.'
+ # make install will fail,
+ # 2. the above comment should most certainly read
+ # $(mkdir_p) $(DESTDIR)$(somedir)
+ # so it does not work when $(somedir) is undefined and
+ # $(DESTDIR) is not.
+ # To support the latter case, we have to write
+ # test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir),
+ # so the `.' trick is pointless.
+ mkdir_p='mkdir -p --'
+else
+ # On NextStep and OpenStep, the `mkdir' command does not
+ # recognize any option. It will interpret all options as
+ # directories to create, and then abort because `.' already
+ # exists.
+ for d in ./-p ./--version;
+ do
+ test -d $d && rmdir $d
+ done
+ # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists.
+ if test -f "$ac_aux_dir/mkinstalldirs"; then
+ mkdir_p='$(mkinstalldirs)'
+ else
+ mkdir_p='$(install_sh) -d'
+ fi
+fi
+
for ac_prog in gawk mawk nawk awk
do
# Extract the first word of "$ac_prog", so it can be a program name with args.
@@ -1696,7 +1765,7 @@ done
echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5
echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6
-set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,./+-,__p_,'`
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,:./+-,___p_,'`
if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
@@ -1723,7 +1792,16 @@ echo "${ECHO_T}no" >&6
SET_MAKE="MAKE=${MAKE-make}"
fi
- # test to see if srcdir already configured
+rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+ am__leading_dot=.
+else
+ am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+
+# test to see if srcdir already configured
if test "`cd $srcdir && pwd`" != "`pwd`" &&
test -f $srcdir/config.status; then
{ { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5
@@ -1731,9 +1809,19 @@ echo "$as_me: error: source directory already configured; run \"make distclean\"
{ (exit 1); exit 1; }; }
fi
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+
+
# Define the identity of the package.
- PACKAGE=google-perftools
- VERSION=0.8
+ PACKAGE='google-perftools'
+ VERSION='0.90'
cat >>confdefs.h <<_ACEOF
@@ -1761,9 +1849,6 @@ AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
-
-AMTAR=${AMTAR-"${am_missing_run}tar"}
-
install_sh=${install_sh-"$am_aux_dir/install-sh"}
# Installed binaries are usually stripped using `strip' when the user
@@ -1856,16 +1941,19 @@ INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s"
# We need awk for the "check" target. The system "awk" is bad on
# some platforms.
+# Always define AMTAR for backward compatibility.
+AMTAR=${AMTAR-"${am_missing_run}tar"}
+am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'
-# Add the stamp file to the list of files AC keeps track of,
-# along with our hook.
- ac_config_headers="$ac_config_headers src/config.h"
+ ac_config_headers="$ac_config_headers src/config.h"
+
+
# Checks for programs.
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
@@ -2203,7 +2291,6 @@ ac_compiler=`set X $ac_compile; echo $2`
(exit $ac_status); }
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -2223,8 +2310,8 @@ ac_clean_files="$ac_clean_files a.out a.exe b.out"
# Try to create an executable without -o first, disregard a.out.
# It will help us diagnose broken compilers, and finding out an intuition
# of exeext.
-echo "$as_me:$LINENO: checking for C compiler default output" >&5
-echo $ECHO_N "checking for C compiler default output... $ECHO_C" >&6
+echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
+echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6
ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
(eval $ac_link_default) 2>&5
@@ -2244,23 +2331,23 @@ do
test -f "$ac_file" || continue
case $ac_file in
*.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
- ;;
+ ;;
conftest.$ac_ext )
- # This is the source file.
- ;;
+ # This is the source file.
+ ;;
[ab].out )
- # We found the default executable, but exeext='' is most
- # certainly right.
- break;;
+ # We found the default executable, but exeext='' is most
+ # certainly right.
+ break;;
*.* )
- ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
- # FIXME: I believe we export ac_cv_exeext for Libtool,
- # but it would be cool to find out if it's true. Does anybody
- # maintain Libtool? --akim.
- export ac_cv_exeext
- break;;
+ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ # FIXME: I believe we export ac_cv_exeext for Libtool,
+ # but it would be cool to find out if it's true. Does anybody
+ # maintain Libtool? --akim.
+ export ac_cv_exeext
+ break;;
* )
- break;;
+ break;;
esac
done
else
@@ -2334,8 +2421,8 @@ for ac_file in conftest.exe conftest conftest.*; do
case $ac_file in
*.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
*.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
- export ac_cv_exeext
- break;;
+ export ac_cv_exeext
+ break;;
* ) break;;
esac
done
@@ -2360,7 +2447,6 @@ if test "${ac_cv_objext+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -2411,7 +2497,6 @@ if test "${ac_cv_c_compiler_gnu+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -2431,11 +2516,20 @@ main ()
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -2448,7 +2542,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
ac_compiler_gnu=no
fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
ac_cv_c_compiler_gnu=$ac_compiler_gnu
fi
@@ -2464,7 +2558,6 @@ if test "${ac_cv_prog_cc_g+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -2481,11 +2574,20 @@ main ()
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -2498,7 +2600,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
ac_cv_prog_cc_g=no
fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
@@ -2525,7 +2627,6 @@ else
ac_cv_prog_cc_stdc=no
ac_save_CC=$CC
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -2553,6 +2654,16 @@ static char *f (char * (*g) (char **, int), char **p, ...)
va_end (v);
return s;
}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std1 is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std1. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
int test (int i, double x);
struct s1 {int (*f) (int a);};
struct s2 {int (*f) (double a);};
@@ -2579,11 +2690,20 @@ do
CC="$ac_save_CC $ac_arg"
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -2596,7 +2716,7 @@ else
sed 's/^/| /' conftest.$ac_ext >&5
fi
-rm -f conftest.$ac_objext
+rm -f conftest.err conftest.$ac_objext
done
rm -f conftest.$ac_ext conftest.$ac_objext
CC=$ac_save_CC
@@ -2624,19 +2744,27 @@ cat >conftest.$ac_ext <<_ACEOF
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
for ac_declaration in \
- ''\
- '#include <stdlib.h>' \
+ '' \
'extern "C" void std::exit (int) throw (); using std::exit;' \
'extern "C" void std::exit (int); using std::exit;' \
'extern "C" void exit (int) throw ();' \
@@ -2644,14 +2772,13 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
'void exit (int);'
do
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
-#include <stdlib.h>
$ac_declaration
+#include <stdlib.h>
int
main ()
{
@@ -2662,11 +2789,20 @@ exit (42);
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -2679,9 +2815,8 @@ sed 's/^/| /' conftest.$ac_ext >&5
continue
fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -2698,11 +2833,20 @@ exit (42);
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -2714,7 +2858,7 @@ else
sed 's/^/| /' conftest.$ac_ext >&5
fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
done
rm -f conftest*
if test -n "$ac_declaration"; then
@@ -2728,30 +2872,22 @@ else
sed 's/^/| /' conftest.$ac_ext >&5
fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
-rm -f .deps 2>/dev/null
-mkdir .deps 2>/dev/null
-if test -d .deps; then
- DEPDIR=.deps
-else
- # MS-DOS does not allow filenames that begin with a dot.
- DEPDIR=_deps
-fi
-rmdir .deps 2>/dev/null
-
+DEPDIR="${am__leading_dot}deps"
ac_config_commands="$ac_config_commands depfiles"
am_make=${MAKE-make}
cat > confinc << 'END'
-doit:
+am__doit:
@echo done
+.PHONY: am__doit
END
# If we don't find an include directive, just comment out the code.
echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5
@@ -2766,7 +2902,7 @@ echo "include confinc" > confmf
# In particular we don't look at `^make:' because GNU make might
# be invoked under some other name (usually "gmake"), in which
# case it prints its new name instead of `make'.
-if test "`$am_make -s -f confmf 2> /dev/null | fgrep -v 'ing directory'`" = "done"; then
+if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then
am__include=include
am__quote=
_am_result=GNU
@@ -2826,18 +2962,34 @@ else
# using a relative directory.
cp "$am_depcomp" conftest.dir
cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
am_cv_CC_dependencies_compiler_type=none
if test "$am_compiler_list" = ""; then
am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
fi
for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
# We need to recreate these files for each test, as the compiler may
# overwrite some of them when testing with obscure command lines.
# This happens at least with the AIX C compiler.
- echo '#include "conftest.h"' > conftest.c
- echo 'int i;' > conftest.h
- echo "${am__include} ${am__quote}conftest.Po${am__quote}" > confmf
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+ # Solaris 8's {/usr,}/bin/sh.
+ touch sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
case $depmode in
nosideeffect)
@@ -2855,13 +3007,25 @@ else
# mode. It turns out that the SunPro C++ compiler does not properly
# handle `-M -o', and we need to detect this.
if depmode=$depmode \
- source=conftest.c object=conftest.o \
- depfile=conftest.Po tmpdepfile=conftest.TPo \
- $SHELL ./depcomp $depcc -c conftest.c -o conftest.o >/dev/null 2>&1 &&
- grep conftest.h conftest.Po > /dev/null 2>&1 &&
+ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
${MAKE-make} -s -f confmf > /dev/null 2>&1; then
- am_cv_CC_dependencies_compiler_type=$depmode
- break
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_CC_dependencies_compiler_type=$depmode
+ break
+ fi
fi
done
@@ -2877,6 +3041,18 @@ echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6
CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
+
+if
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
+ am__fastdepCC_TRUE=
+ am__fastdepCC_FALSE='#'
+else
+ am__fastdepCC_TRUE='#'
+ am__fastdepCC_FALSE=
+fi
+
+
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -2905,7 +3081,6 @@ do
# On the NeXT, cc -E runs the code through the compiler's parser,
# not just through cpp. "Syntax error" is here to catch this case.
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -2916,7 +3091,7 @@ cat >>conftest.$ac_ext <<_ACEOF
#else
# include <assert.h>
#endif
- Syntax error
+ Syntax error
_ACEOF
if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
(eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
@@ -2928,6 +3103,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
(exit $ac_status); } >/dev/null; then
if test -s conftest.err; then
ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
else
ac_cpp_err=
fi
@@ -2948,7 +3124,6 @@ rm -f conftest.err conftest.$ac_ext
# OK, works on sane cases. Now check whether non-existent headers
# can be detected and how.
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -2966,6 +3141,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
(exit $ac_status); } >/dev/null; then
if test -s conftest.err; then
ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
else
ac_cpp_err=
fi
@@ -3012,7 +3188,6 @@ do
# On the NeXT, cc -E runs the code through the compiler's parser,
# not just through cpp. "Syntax error" is here to catch this case.
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -3023,7 +3198,7 @@ cat >>conftest.$ac_ext <<_ACEOF
#else
# include <assert.h>
#endif
- Syntax error
+ Syntax error
_ACEOF
if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
(eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
@@ -3035,6 +3210,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
(exit $ac_status); } >/dev/null; then
if test -s conftest.err; then
ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
else
ac_cpp_err=
fi
@@ -3055,7 +3231,6 @@ rm -f conftest.err conftest.$ac_ext
# OK, works on sane cases. Now check whether non-existent headers
# can be detected and how.
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -3073,6 +3248,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
(exit $ac_status); } >/dev/null; then
if test -s conftest.err; then
ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
else
ac_cpp_err=
fi
@@ -3230,7 +3406,6 @@ if test "${ac_cv_cxx_compiler_gnu+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -3250,11 +3425,20 @@ main ()
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
+ { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -3267,7 +3451,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
ac_compiler_gnu=no
fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
fi
@@ -3283,7 +3467,6 @@ if test "${ac_cv_prog_cxx_g+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -3300,11 +3483,20 @@ main ()
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
+ { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -3317,7 +3509,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
ac_cv_prog_cxx_g=no
fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5
echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6
@@ -3337,8 +3529,7 @@ else
fi
fi
for ac_declaration in \
- ''\
- '#include <stdlib.h>' \
+ '' \
'extern "C" void std::exit (int) throw (); using std::exit;' \
'extern "C" void std::exit (int); using std::exit;' \
'extern "C" void exit (int) throw ();' \
@@ -3346,14 +3537,13 @@ for ac_declaration in \
'void exit (int);'
do
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
-#include <stdlib.h>
$ac_declaration
+#include <stdlib.h>
int
main ()
{
@@ -3364,11 +3554,20 @@ exit (42);
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
+ { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -3381,9 +3580,8 @@ sed 's/^/| /' conftest.$ac_ext >&5
continue
fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -3400,11 +3598,20 @@ exit (42);
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
+ { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -3416,7 +3623,7 @@ else
sed 's/^/| /' conftest.$ac_ext >&5
fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
done
rm -f conftest*
if test -n "$ac_declaration"; then
@@ -3449,18 +3656,34 @@ else
# using a relative directory.
cp "$am_depcomp" conftest.dir
cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
am_cv_CXX_dependencies_compiler_type=none
if test "$am_compiler_list" = ""; then
am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
fi
for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
# We need to recreate these files for each test, as the compiler may
# overwrite some of them when testing with obscure command lines.
# This happens at least with the AIX C compiler.
- echo '#include "conftest.h"' > conftest.c
- echo 'int i;' > conftest.h
- echo "${am__include} ${am__quote}conftest.Po${am__quote}" > confmf
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+ # Solaris 8's {/usr,}/bin/sh.
+ touch sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
case $depmode in
nosideeffect)
@@ -3478,13 +3701,25 @@ else
# mode. It turns out that the SunPro C++ compiler does not properly
# handle `-M -o', and we need to detect this.
if depmode=$depmode \
- source=conftest.c object=conftest.o \
- depfile=conftest.Po tmpdepfile=conftest.TPo \
- $SHELL ./depcomp $depcc -c conftest.c -o conftest.o >/dev/null 2>&1 &&
- grep conftest.h conftest.Po > /dev/null 2>&1 &&
+ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
${MAKE-make} -s -f confmf > /dev/null 2>&1; then
- am_cv_CXX_dependencies_compiler_type=$depmode
- break
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_CXX_dependencies_compiler_type=$depmode
+ break
+ fi
fi
done
@@ -3501,6 +3736,18 @@ CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type
+if
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then
+ am__fastdepCXX_TRUE=
+ am__fastdepCXX_FALSE='#'
+else
+ am__fastdepCXX_TRUE='#'
+ am__fastdepCXX_FALSE=
+fi
+
+
+
# Check whether --enable-shared or --disable-shared was given.
if test "${enable_shared+set}" = set; then
enableval="$enable_shared"
@@ -3652,7 +3899,7 @@ lt_ac_count=0
# Add /usr/xpg4/bin/sed as it is typically found on Solaris
# along with /bin/sed that truncates output.
for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
- test ! -f $lt_ac_sed && break
+ test ! -f $lt_ac_sed && continue
cat /dev/null > conftest.in
lt_ac_count=0
echo $ECHO_N "0123456789$ECHO_C" >conftest.in
@@ -3677,10 +3924,10 @@ for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
fi
done
done
-SED=$lt_cv_path_SED
fi
+SED=$lt_cv_path_SED
echo "$as_me:$LINENO: result: $SED" >&5
echo "${ECHO_T}$SED" >&6
@@ -3723,7 +3970,7 @@ echo $ECHO_N "checking for ld used by $CC... $ECHO_C" >&6
# Accept absolute paths.
[\\/]* | ?:[\\/]*)
re_direlt='/[^/][^/]*/\.\./'
- # Canonicalize the path of ld
+ # Canonicalize the pathname of ld
ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'`
while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"`
@@ -3757,7 +4004,7 @@ else
if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
lt_cv_path_LD="$ac_dir/$ac_prog"
# Check to see if the program is GNU ld. I'd rather use --version,
- # but apparently some GNU ld's only accept -v.
+ # but apparently some variants of GNU ld only accept -v.
# Break only if it was the GNU/non-GNU ld that we prefer.
case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
*GNU* | *'with BFD'*)
@@ -3791,7 +4038,7 @@ echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6
if test "${lt_cv_prog_gnu_ld+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
- # I'd rather use --version here, but apparently some GNU ld's only accept -v.
+ # I'd rather use --version here, but apparently some GNU lds only accept -v.
case `$LD -v 2>&1 </dev/null` in
*GNU* | *'with BFD'*)
lt_cv_prog_gnu_ld=yes
@@ -3821,6 +4068,15 @@ case $reload_flag in
*) reload_flag=" $reload_flag" ;;
esac
reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+ darwin*)
+ if test "$GCC" = yes; then
+ reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
+ else
+ reload_cmds='$LD$reload_flag -o $output$reload_objs'
+ fi
+ ;;
+esac
echo "$as_me:$LINENO: checking for BSD-compatible nm" >&5
echo $ECHO_N "checking for BSD-compatible nm... $ECHO_C" >&6
@@ -3831,36 +4087,43 @@ else
# Let the user override the test.
lt_cv_path_NM="$NM"
else
- lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
- for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
- IFS="$lt_save_ifs"
- test -z "$ac_dir" && ac_dir=.
- tmp_nm="$ac_dir/${ac_tool_prefix}nm"
- if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
- # Check to see if the nm accepts a BSD-compat flag.
- # Adding the `sed 1q' prevents false positives on HP-UX, which says:
- # nm: unknown option "B" ignored
- # Tru64's nm complains that /dev/null is an invalid object file
- case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
- */dev/null* | *'Invalid file or object type'*)
- lt_cv_path_NM="$tmp_nm -B"
- break
- ;;
- *)
- case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
- */dev/null*)
- lt_cv_path_NM="$tmp_nm -p"
+ lt_nm_to_check="${ac_tool_prefix}nm"
+ if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+ lt_nm_to_check="$lt_nm_to_check nm"
+ fi
+ for lt_tmp_nm in $lt_nm_to_check; do
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ tmp_nm="$ac_dir/$lt_tmp_nm"
+ if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ # Tru64's nm complains that /dev/null is an invalid object file
+ case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+ */dev/null* | *'Invalid file or object type'*)
+ lt_cv_path_NM="$tmp_nm -B"
break
;;
*)
- lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
- continue # so that we can try to find one that supports BSD flags
+ case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+ */dev/null*)
+ lt_cv_path_NM="$tmp_nm -p"
+ break
+ ;;
+ *)
+ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ ;;
+ esac
;;
esac
- esac
- fi
+ fi
+ done
+ IFS="$lt_save_ifs"
done
- IFS="$lt_save_ifs"
test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm
fi
fi
@@ -3907,40 +4170,36 @@ beos*)
lt_cv_deplibs_check_method=pass_all
;;
-bsdi4*)
+bsdi[45]*)
lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
lt_cv_file_magic_cmd='/usr/bin/file -L'
lt_cv_file_magic_test_file=/shlib/libc.so
;;
-cygwin* | mingw* | pw32*)
- # win32_libid is a shell function defined in ltmain.sh
+cygwin*)
+ # func_win32_libid is a shell function defined in ltmain.sh
lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
- lt_cv_file_magic_cmd='win32_libid'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ ;;
+
+mingw* | pw32*)
+ # Base MSYS/MinGW do not provide the 'file' command needed by
+ # func_win32_libid shell function, so use a weaker test based on 'objdump'.
+ lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
;;
darwin* | rhapsody*)
- # this will be overwritten by pass_all, but leave it in just in case
- lt_cv_deplibs_check_method='file_magic Mach-O dynamically linked shared library'
- lt_cv_file_magic_cmd='/usr/bin/file -L'
- case "$host_os" in
- rhapsody* | darwin1.[012])
- lt_cv_file_magic_test_file=`/System/Library/Frameworks/System.framework/System`
- ;;
- *) # Darwin 1.3 on
- lt_cv_file_magic_test_file='/usr/lib/libSystem.dylib'
- ;;
- esac
lt_cv_deplibs_check_method=pass_all
;;
-freebsd*)
+freebsd* | kfreebsd*-gnu | dragonfly*)
if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
case $host_cpu in
i*86 )
# Not sure whether the presence of OpenBSD here was a mistake.
# Let's accept both of them until this is cleared up.
- lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD)/i[3-9]86 (compact )?demand paged shared library'
+ lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library'
lt_cv_file_magic_cmd=/usr/bin/file
lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
;;
@@ -3956,7 +4215,7 @@ gnu*)
hpux10.20* | hpux11*)
lt_cv_file_magic_cmd=/usr/bin/file
- case "$host_cpu" in
+ case $host_cpu in
ia64*)
lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64'
lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
@@ -3972,40 +4231,27 @@ hpux10.20* | hpux11*)
esac
;;
+interix3*)
+ # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$'
+ ;;
+
irix5* | irix6* | nonstopux*)
- case $host_os in
- irix5* | nonstopux*)
- # this will be overridden with pass_all, but let us keep it just in case
- lt_cv_deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1"
- ;;
- *)
- case $LD in
- *-32|*"-32 ") libmagic=32-bit;;
- *-n32|*"-n32 ") libmagic=N32;;
- *-64|*"-64 ") libmagic=64-bit;;
- *) libmagic=never-match;;
- esac
- # this will be overridden with pass_all, but let us keep it just in case
- lt_cv_deplibs_check_method="file_magic ELF ${libmagic} MSB mips-[1234] dynamic lib MIPS - version 1"
- ;;
+ case $LD in
+ *-32|*"-32 ") libmagic=32-bit;;
+ *-n32|*"-n32 ") libmagic=N32;;
+ *-64|*"-64 ") libmagic=64-bit;;
+ *) libmagic=never-match;;
esac
- lt_cv_file_magic_test_file=`echo /lib${libsuff}/libc.so*`
lt_cv_deplibs_check_method=pass_all
;;
# This must be Linux ELF.
linux*)
- case $host_cpu in
- alpha* | hppa* | i*86 | ia64* | m68* | mips | mipsel | powerpc* | sparc* | s390* | sh* | x86_64*)
- lt_cv_deplibs_check_method=pass_all ;;
- *)
- # glibc up to 2.1.1 does not perform some relocations on ARM
- lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;;
- esac
- lt_cv_file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so`
+ lt_cv_deplibs_check_method=pass_all
;;
-netbsd*)
+netbsd* | netbsdelf*-gnu | knetbsd*-gnu)
if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
else
@@ -4019,37 +4265,27 @@ newos6*)
lt_cv_file_magic_test_file=/usr/lib/libnls.so
;;
-nto-qnx)
+nto-qnx*)
lt_cv_deplibs_check_method=unknown
;;
openbsd*)
- lt_cv_file_magic_cmd=/usr/bin/file
- lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
- lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB shared object'
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$'
else
- lt_cv_deplibs_check_method='file_magic OpenBSD.* shared library'
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
fi
;;
osf3* | osf4* | osf5*)
- # this will be overridden with pass_all, but let us keep it just in case
- lt_cv_deplibs_check_method='file_magic COFF format alpha shared library'
- lt_cv_file_magic_test_file=/shlib/libc.so
- lt_cv_deplibs_check_method=pass_all
- ;;
-
-sco3.2v5*)
lt_cv_deplibs_check_method=pass_all
;;
solaris*)
lt_cv_deplibs_check_method=pass_all
- lt_cv_file_magic_test_file=/lib/libc.so
;;
-sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+sysv4 | sysv4.3*)
case $host_vendor in
motorola)
lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
@@ -4070,10 +4306,13 @@ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
siemens)
lt_cv_deplibs_check_method=pass_all
;;
+ pc)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
esac
;;
-sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[78]* | unixware7* | sysv4*uw2*)
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
lt_cv_deplibs_check_method=pass_all
;;
esac
@@ -4091,6 +4330,9 @@ test -z "$deplibs_check_method" && deplibs_check_method=unknown
# If no C compiler was specified, use CC.
LTCC=${LTCC-"$CC"}
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
# Allow CC to be a program name with arguments.
compiler=$CC
@@ -4126,7 +4368,7 @@ ia64-*-hpux*)
;;
*-*-irix6*)
# Find out which ABI we are using.
- echo '#line 4129 "configure"' > conftest.$ac_ext
+ echo '#line 4371 "configure"' > conftest.$ac_ext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
@@ -4169,13 +4411,13 @@ x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*)
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; then
- case "`/usr/bin/file conftest.o`" in
+ case `/usr/bin/file conftest.o` in
*32-bit*)
case $host in
x86_64-*linux*)
LD="${LD-ld} -m elf_i386"
;;
- ppc64-*linux*)
+ ppc64-*linux*|powerpc64-*linux*)
LD="${LD-ld} -m elf32ppclinux"
;;
s390x-*linux*)
@@ -4223,7 +4465,6 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $
ac_compiler_gnu=$ac_cv_c_compiler_gnu
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -4240,11 +4481,20 @@ main ()
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
+ (eval $ac_link) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest$ac_exeext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -4257,7 +4507,8 @@ sed 's/^/| /' conftest.$ac_ext >&5
lt_cv_cc_needs_belf=no
fi
-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -4272,6 +4523,26 @@ echo "${ECHO_T}$lt_cv_cc_needs_belf" >&6
CFLAGS="$SAVE_CFLAGS"
fi
;;
+sparc*-*solaris*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ case `/usr/bin/file conftest.o` in
+ *64-bit*)
+ case $lt_cv_prog_gnu_ld in
+ yes*) LD="${LD-ld} -m elf64_sparc" ;;
+ *) LD="${LD-ld} -64" ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
esac
@@ -4285,7 +4556,6 @@ if test "${ac_cv_header_stdc+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -4306,11 +4576,20 @@ main ()
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -4323,12 +4602,11 @@ sed 's/^/| /' conftest.$ac_ext >&5
ac_cv_header_stdc=no
fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
if test $ac_cv_header_stdc = yes; then
# SunOS 4.x string.h does not declare mem*, contrary to ANSI.
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -4350,7 +4628,6 @@ fi
if test $ac_cv_header_stdc = yes; then
# ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -4375,7 +4652,6 @@ if test $ac_cv_header_stdc = yes; then
:
else
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -4387,9 +4663,9 @@ cat >>conftest.$ac_ext <<_ACEOF
# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
#else
# define ISLOWER(c) \
- (('a' <= (c) && (c) <= 'i') \
- || ('j' <= (c) && (c) <= 'r') \
- || ('s' <= (c) && (c) <= 'z'))
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
#endif
@@ -4400,7 +4676,7 @@ main ()
int i;
for (i = 0; i < 256; i++)
if (XOR (islower (i), ISLOWER (i))
- || toupper (i) != TOUPPER (i))
+ || toupper (i) != TOUPPER (i))
exit(2);
exit (0);
}
@@ -4425,7 +4701,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
( exit $ac_status )
ac_cv_header_stdc=no
fi
-rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
fi
fi
fi
@@ -4450,7 +4726,7 @@ fi
for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
- inttypes.h stdint.h unistd.h
+ inttypes.h stdint.h unistd.h
do
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
echo "$as_me:$LINENO: checking for $ac_header" >&5
@@ -4459,7 +4735,6 @@ if eval "test \"\${$as_ac_Header+set}\" = set"; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -4471,11 +4746,20 @@ $ac_includes_default
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -4488,7 +4772,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
eval "$as_ac_Header=no"
fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
@@ -4519,7 +4803,6 @@ else
echo "$as_me:$LINENO: checking $ac_header usability" >&5
echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -4530,11 +4813,20 @@ $ac_includes_default
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -4547,7 +4839,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
ac_header_compiler=no
fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
echo "${ECHO_T}$ac_header_compiler" >&6
@@ -4555,7 +4847,6 @@ echo "${ECHO_T}$ac_header_compiler" >&6
echo "$as_me:$LINENO: checking $ac_header presence" >&5
echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -4573,6 +4864,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
(exit $ac_status); } >/dev/null; then
if test -s conftest.err; then
ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
else
ac_cpp_err=
fi
@@ -4592,32 +4884,31 @@ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
echo "${ECHO_T}$ac_header_preproc" >&6
# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc in
- yes:no )
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
{ echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
- (
- cat <<\_ASBOX
-## ------------------------------------ ##
-## Report this to bug-autoconf@gnu.org. ##
-## ------------------------------------ ##
-_ASBOX
- ) |
- sed "s/^/$as_me: WARNING: /" >&2
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
;;
- no:yes )
+ no:yes:* )
{ echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
(
cat <<\_ASBOX
## ------------------------------------ ##
-## Report this to bug-autoconf@gnu.org. ##
+## Report this to opensource@google.com ##
## ------------------------------------ ##
_ASBOX
) |
@@ -4629,7 +4920,7 @@ echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
if eval "test \"\${$as_ac_Header+set}\" = set"; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
- eval "$as_ac_Header=$ac_header_preproc"
+ eval "$as_ac_Header=\$ac_header_preproc"
fi
echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
@@ -4644,7 +4935,12 @@ fi
done
-ac_ext=cc
+
+
+if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
+ ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
+ (test "X$CXX" != "Xg++"))) ; then
+ ac_ext=cc
ac_cpp='$CXXCPP $CPPFLAGS'
ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
@@ -4668,7 +4964,6 @@ do
# On the NeXT, cc -E runs the code through the compiler's parser,
# not just through cpp. "Syntax error" is here to catch this case.
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -4679,7 +4974,7 @@ cat >>conftest.$ac_ext <<_ACEOF
#else
# include <assert.h>
#endif
- Syntax error
+ Syntax error
_ACEOF
if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
(eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
@@ -4691,6 +4986,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
(exit $ac_status); } >/dev/null; then
if test -s conftest.err; then
ac_cpp_err=$ac_cxx_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag
else
ac_cpp_err=
fi
@@ -4711,7 +5007,6 @@ rm -f conftest.err conftest.$ac_ext
# OK, works on sane cases. Now check whether non-existent headers
# can be detected and how.
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -4729,6 +5024,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
(exit $ac_status); } >/dev/null; then
if test -s conftest.err; then
ac_cpp_err=$ac_cxx_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag
else
ac_cpp_err=
fi
@@ -4775,7 +5071,6 @@ do
# On the NeXT, cc -E runs the code through the compiler's parser,
# not just through cpp. "Syntax error" is here to catch this case.
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -4786,7 +5081,7 @@ cat >>conftest.$ac_ext <<_ACEOF
#else
# include <assert.h>
#endif
- Syntax error
+ Syntax error
_ACEOF
if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
(eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
@@ -4798,6 +5093,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
(exit $ac_status); } >/dev/null; then
if test -s conftest.err; then
ac_cpp_err=$ac_cxx_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag
else
ac_cpp_err=
fi
@@ -4818,7 +5114,6 @@ rm -f conftest.err conftest.$ac_ext
# OK, works on sane cases. Now check whether non-existent headers
# can be detected and how.
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -4836,6 +5131,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
(exit $ac_status); } >/dev/null; then
if test -s conftest.err; then
ac_cpp_err=$ac_cxx_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag
else
ac_cpp_err=
fi
@@ -4874,13 +5170,15 @@ ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+fi
+
ac_ext=f
ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5'
ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_f77_compiler_gnu
if test -n "$ac_tool_prefix"; then
- for ac_prog in g77 f77 xlf frt pgf77 fl32 af77 fort77 f90 xlf90 pgf90 epcf90 f95 fort xlf95 lf95 g95
+ for ac_prog in g77 f77 xlf frt pgf77 fort77 fl32 af77 f90 xlf90 pgf90 epcf90 f95 fort xlf95 ifc efc pgf95 lf95 gfortran
do
# Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
set dummy $ac_tool_prefix$ac_prog; ac_word=$2
@@ -4922,7 +5220,7 @@ fi
fi
if test -z "$F77"; then
ac_ct_F77=$F77
- for ac_prog in g77 f77 xlf frt pgf77 fl32 af77 fort77 f90 xlf90 pgf90 epcf90 f95 fort xlf95 lf95 g95
+ for ac_prog in g77 f77 xlf frt pgf77 fort77 fl32 af77 f90 xlf90 pgf90 epcf90 f95 fort xlf95 ifc efc pgf95 lf95 gfortran
do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
@@ -4967,7 +5265,7 @@ fi
# Provide some information about the compiler.
-echo "$as_me:4970:" \
+echo "$as_me:5268:" \
"checking for Fortran 77 compiler version" >&5
ac_compiler=`set X $ac_compile; echo $2`
{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
@@ -4985,9 +5283,10 @@ ac_compiler=`set X $ac_compile; echo $2`
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }
+rm -f a.out
# If we don't use `.F' as extension, the preprocessor is not run on the
-# input file.
+# input file. (Note that this only needs to work for GNU compilers.)
ac_save_ext=$ac_ext
ac_ext=F
echo "$as_me:$LINENO: checking whether we are using the GNU Fortran 77 compiler" >&5
@@ -5005,11 +5304,20 @@ else
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
+ { ac_try='test -z "$ac_f77_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -5022,14 +5330,13 @@ sed 's/^/| /' conftest.$ac_ext >&5
ac_compiler_gnu=no
fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
ac_cv_f77_compiler_gnu=$ac_compiler_gnu
fi
echo "$as_me:$LINENO: result: $ac_cv_f77_compiler_gnu" >&5
echo "${ECHO_T}$ac_cv_f77_compiler_gnu" >&6
ac_ext=$ac_save_ext
-G77=`test $ac_compiler_gnu = yes && echo yes`
ac_test_FFLAGS=${FFLAGS+set}
ac_save_FFLAGS=$FFLAGS
FFLAGS=
@@ -5046,11 +5353,20 @@ cat >conftest.$ac_ext <<_ACEOF
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
+ { ac_try='test -z "$ac_f77_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -5063,7 +5379,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
ac_cv_prog_f77_g=no
fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: $ac_cv_prog_f77_g" >&5
@@ -5071,18 +5387,20 @@ echo "${ECHO_T}$ac_cv_prog_f77_g" >&6
if test "$ac_test_FFLAGS" = set; then
FFLAGS=$ac_save_FFLAGS
elif test $ac_cv_prog_f77_g = yes; then
- if test "$G77" = yes; then
+ if test "x$ac_cv_f77_compiler_gnu" = xyes; then
FFLAGS="-g -O2"
else
FFLAGS="-g"
fi
else
- if test "$G77" = yes; then
+ if test "x$ac_cv_f77_compiler_gnu" = xyes; then
FFLAGS="-O2"
else
FFLAGS=
fi
fi
+
+G77=`test $ac_compiler_gnu = yes && echo yes`
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -5100,7 +5418,7 @@ if test "${lt_cv_sys_max_cmd_len+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
i=0
- testring="ABCD"
+ teststring="ABCD"
case $build_os in
msdosdjgpp*)
@@ -5129,20 +5447,70 @@ else
lt_cv_sys_max_cmd_len=8192;
;;
- *)
+ amigaos*)
+ # On AmigaOS with pdksh, this test takes hours, literally.
+ # So we just punt and use a minimum line length of 8192.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
+ # This has been around since 386BSD, at least. Likely further.
+ if test -x /sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+ elif test -x /usr/sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+ else
+ lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs
+ fi
+ # And add a safety zone
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ ;;
+
+ interix*)
+ # We know the value 262144 and hardcode it with a safety zone (like BSD)
+ lt_cv_sys_max_cmd_len=196608
+ ;;
+
+ osf*)
+ # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+ # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+ # nice to cause kernel panics so lets avoid the loop below.
+ # First set a reasonable default.
+ lt_cv_sys_max_cmd_len=16384
+ #
+ if test -x /sbin/sysconfig; then
+ case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+ *1*) lt_cv_sys_max_cmd_len=-1 ;;
+ esac
+ fi
+ ;;
+ sco3.2v5*)
+ lt_cv_sys_max_cmd_len=102400
+ ;;
+ sysv5* | sco5v6* | sysv4.2uw2*)
+ kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+ if test -n "$kargmax"; then
+ lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'`
+ else
+ lt_cv_sys_max_cmd_len=32768
+ fi
+ ;;
+ *)
# If test is not a shell built-in, we'll probably end up computing a
# maximum length that is only half of the actual maximum length, but
# we can't tell.
- while (test "X"`$CONFIG_SHELL $0 --fallback-echo "X$testring" 2>/dev/null` \
- = "XX$testring") >/dev/null 2>&1 &&
- new_result=`expr "X$testring" : ".*" 2>&1` &&
+ SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+ while (test "X"`$SHELL $0 --fallback-echo "X$teststring" 2>/dev/null` \
+ = "XX$teststring") >/dev/null 2>&1 &&
+ new_result=`expr "X$teststring" : ".*" 2>&1` &&
lt_cv_sys_max_cmd_len=$new_result &&
test $i != 17 # 1/2 MB should be enough
do
i=`expr $i + 1`
- testring=$testring$testring
+ teststring=$teststring$teststring
done
- testring=
+ teststring=
# Add a significant safety factor because C++ compilers can tack on massive
# amounts of additional arguments before passing them to the linker.
# It appears as though 1/2 is a usable value.
@@ -5179,9 +5547,6 @@ symcode='[BCDEGRST]'
# Regexp to match symbols that can be accessed directly from C.
sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
-# Transform the above into a raw symbol and a C symbol.
-symxfrm='\1 \2\3 \3'
-
# Transform an extracted symbol line into a proper C declaration
lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern int \1;/p'"
@@ -5203,15 +5568,31 @@ hpux*) # Its linker distinguishes data from code symbols
lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'"
;;
+linux*)
+ if test "$host_cpu" = ia64; then
+ symcode='[ABCDGIRSTW]'
+ lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+ lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'"
+ fi
+ ;;
irix* | nonstopux*)
symcode='[BCDEGRST]'
;;
osf*)
symcode='[BCDEGQRST]'
;;
-solaris* | sysv5*)
+solaris*)
symcode='[BDRT]'
;;
+sco3.2v5*)
+ symcode='[DT]'
+ ;;
+sysv4.2uw2*)
+ symcode='[DT]'
+ ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+ symcode='[ABDT]'
+ ;;
sysv4)
symcode='[DFNSTU]'
;;
@@ -5234,8 +5615,11 @@ esac
# Try without a prefix undercore, then with it.
for ac_symprfx in "" "_"; do
+ # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+ symxfrm="\\1 $ac_symprfx\\2 \\2"
+
# Write the raw and C identifiers.
- lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*\($ac_symprfx\)$sympat$opt_cr$/$symxfrm/p'"
+ lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
# Check to see that the pipe works correctly.
pipe_works=no
@@ -5397,7 +5781,7 @@ esac
# Sed substitution that helps us do robust quoting. It backslashifies
# metacharacters that are still active within double-quoted strings.
-Xsed='sed -e s/^X//'
+Xsed='sed -e 1s/^X//'
sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g'
# Same as above, but do not quote variable references.
@@ -5417,7 +5801,7 @@ rm="rm -f"
default_ofile=libtool
can_build_shared=yes
-# All known linkers require a `.a' archive for static linking (except M$VC,
+# All known linkers require a `.a' archive for static linking (except MSVC,
# which needs '.lib').
libext=a
ltmain="$ac_aux_dir/ltmain.sh"
@@ -5674,6 +6058,7 @@ test -z "$AR_FLAGS" && AR_FLAGS=cru
test -z "$AS" && AS=as
test -z "$CC" && CC=cc
test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
test -z "$DLLTOOL" && DLLTOOL=dlltool
test -z "$LD" && LD=ld
test -z "$LN_S" && LN_S="ln -s"
@@ -5693,15 +6078,26 @@ old_postuninstall_cmds=
if test -n "$RANLIB"; then
case $host_os in
openbsd*)
- old_postinstall_cmds="\$RANLIB -t \$oldlib~$old_postinstall_cmds"
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib"
;;
*)
- old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds"
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib"
;;
esac
old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
fi
+for cc_temp in $compiler""; do
+ case $cc_temp in
+ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+done
+cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
+
+
# Only perform the check for file, if the check method requires it
case $deplibs_check_method in
file_magic*)
@@ -5727,7 +6123,7 @@ else
if test -n "$file_magic_test_file"; then
case $deplibs_check_method in
"file_magic "*)
- file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`"
+ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
$EGREP "$file_magic_regex" > /dev/null; then
@@ -5789,7 +6185,7 @@ else
if test -n "$file_magic_test_file"; then
case $deplibs_check_method in
"file_magic "*)
- file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`"
+ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
$EGREP "$file_magic_regex" > /dev/null; then
@@ -5884,68 +6280,25 @@ lt_simple_link_test_code='int main(){return(0);}\n'
# If no C compiler was specified, use CC.
LTCC=${LTCC-"$CC"}
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
# Allow CC to be a program name with arguments.
compiler=$CC
-#
-# Check for any special shared library compilation flags.
-#
-lt_prog_cc_shlib=
-if test "$GCC" = no; then
- case $host_os in
- sco3.2v5*)
- lt_prog_cc_shlib='-belf'
- ;;
- esac
-fi
-if test -n "$lt_prog_cc_shlib"; then
- { echo "$as_me:$LINENO: WARNING: \`$CC' requires \`$lt_prog_cc_shlib' to build shared libraries" >&5
-echo "$as_me: WARNING: \`$CC' requires \`$lt_prog_cc_shlib' to build shared libraries" >&2;}
- if echo "$old_CC $old_CFLAGS " | grep "[ ]$lt_prog_cc_shlib[ ]" >/dev/null; then :
- else
- { echo "$as_me:$LINENO: WARNING: add \`$lt_prog_cc_shlib' to the CC or CFLAGS env variable and reconfigure" >&5
-echo "$as_me: WARNING: add \`$lt_prog_cc_shlib' to the CC or CFLAGS env variable and reconfigure" >&2;}
- lt_cv_prog_cc_can_build_shared=no
- fi
-fi
-
-
-#
-# Check to make sure the static flag actually works.
-#
-echo "$as_me:$LINENO: checking if $compiler static flag $lt_prog_compiler_static works" >&5
-echo $ECHO_N "checking if $compiler static flag $lt_prog_compiler_static works... $ECHO_C" >&6
-if test "${lt_prog_compiler_static_works+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- lt_prog_compiler_static_works=no
- save_LDFLAGS="$LDFLAGS"
- LDFLAGS="$LDFLAGS $lt_prog_compiler_static"
- printf "$lt_simple_link_test_code" > conftest.$ac_ext
- if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
- # The compiler can only warn and ignore the option if not recognized
- # So say no if there are warnings
- if test -s conftest.err; then
- # Append any errors to the config.log.
- cat conftest.err 1>&5
- else
- lt_prog_compiler_static_works=yes
- fi
- fi
- $rm conftest*
- LDFLAGS="$save_LDFLAGS"
-
-fi
-echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works" >&5
-echo "${ECHO_T}$lt_prog_compiler_static_works" >&6
-
-if test x"$lt_prog_compiler_static_works" = xyes; then
- :
-else
- lt_prog_compiler_static=
-fi
+# save warnings/boilerplate of simple test code
+ac_outfile=conftest.$ac_objext
+printf "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$rm conftest*
+ac_outfile=conftest.$ac_objext
+printf "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$rm conftest*
@@ -5954,7 +6307,8 @@ lt_prog_compiler_no_builtin_flag=
if test "$GCC" = yes; then
lt_prog_compiler_no_builtin_flag=' -fno-builtin'
- echo "$as_me:$LINENO: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+
+echo "$as_me:$LINENO: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
echo $ECHO_N "checking if $compiler supports -fno-rtti -fno-exceptions... $ECHO_C" >&6
if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -5969,18 +6323,20 @@ else
# with a dollar sign (not a hyphen), so the echo should work correctly.
# The option is referenced via a variable to avoid confusing sed.
lt_compile=`echo "$ac_compile" | $SED \
- -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:5975: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:6329: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:5979: \$? = $ac_status" >&5
+ echo "$as_me:6333: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
- # So say no if there are warnings
- if test ! -s conftest.err; then
+ # So say no if there are warnings other than the usual output.
+ $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
lt_cv_prog_compiler_rtti_exceptions=yes
fi
fi
@@ -6041,6 +6397,11 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6
lt_prog_compiler_pic='-fno-common'
;;
+ interix3*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+
msdosdjgpp*)
# Just because we use GCC doesn't mean we suddenly get shared libraries
# on systems that don't support them.
@@ -6057,7 +6418,7 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6
hpux*)
# PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
# not for PA HP-UX.
- case "$host_cpu" in
+ case $host_cpu in
hppa*64*|ia64*)
# +Z the default
;;
@@ -6083,6 +6444,16 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6
lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp'
fi
;;
+ darwin*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ case $cc_basename in
+ xlc*)
+ lt_prog_compiler_pic='-qnocommon'
+ lt_prog_compiler_wl='-Wl,'
+ ;;
+ esac
+ ;;
mingw* | pw32* | os2*)
# This hack is so that the source file can tell whether it is being
@@ -6094,7 +6465,7 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6
lt_prog_compiler_wl='-Wl,'
# PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
# not for PA HP-UX.
- case "$host_cpu" in
+ case $host_cpu in
hppa*64*|ia64*)
# +Z the default
;;
@@ -6118,13 +6489,20 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6
;;
linux*)
- case $CC in
- icc|ecc)
+ case $cc_basename in
+ icc* | ecc*)
lt_prog_compiler_wl='-Wl,'
lt_prog_compiler_pic='-KPIC'
lt_prog_compiler_static='-static'
;;
- ccc)
+ pgcc* | pgf77* | pgf90* | pgf95*)
+ # Portland Group compilers (*not* the Pentium gcc compiler,
+ # which looks to be a dead project)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fpic'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+ ccc*)
lt_prog_compiler_wl='-Wl,'
# All Alpha code is PIC.
lt_prog_compiler_static='-non_shared'
@@ -6138,15 +6516,15 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6
lt_prog_compiler_static='-non_shared'
;;
- sco3.2v5*)
- lt_prog_compiler_pic='-Kpic'
- lt_prog_compiler_static='-dn'
- ;;
-
solaris*)
- lt_prog_compiler_wl='-Wl,'
lt_prog_compiler_pic='-KPIC'
lt_prog_compiler_static='-Bstatic'
+ case $cc_basename in
+ f77* | f90* | f95*)
+ lt_prog_compiler_wl='-Qoption ld ';;
+ *)
+ lt_prog_compiler_wl='-Wl,';;
+ esac
;;
sunos4*)
@@ -6155,7 +6533,7 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6
lt_prog_compiler_static='-Bstatic'
;;
- sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ sysv4 | sysv4.2uw2* | sysv4.3*)
lt_prog_compiler_wl='-Wl,'
lt_prog_compiler_pic='-KPIC'
lt_prog_compiler_static='-Bstatic'
@@ -6168,6 +6546,17 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6
fi
;;
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ unicos*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_can_build_shared=no
+ ;;
+
uts4*)
lt_prog_compiler_pic='-pic'
lt_prog_compiler_static='-Bstatic'
@@ -6186,7 +6575,8 @@ echo "${ECHO_T}$lt_prog_compiler_pic" >&6
# Check to make sure the PIC flag actually works.
#
if test -n "$lt_prog_compiler_pic"; then
- echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5
+
+echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5
echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic works... $ECHO_C" >&6
if test "${lt_prog_compiler_pic_works+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -6201,18 +6591,20 @@ else
# with a dollar sign (not a hyphen), so the echo should work correctly.
# The option is referenced via a variable to avoid confusing sed.
lt_compile=`echo "$ac_compile" | $SED \
- -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:6207: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:6597: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:6211: \$? = $ac_status" >&5
+ echo "$as_me:6601: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
- # So say no if there are warnings
- if test ! -s conftest.err; then
+ # So say no if there are warnings other than the usual output.
+ $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
lt_prog_compiler_pic_works=yes
fi
fi
@@ -6233,7 +6625,7 @@ else
fi
fi
-case "$host_os" in
+case $host_os in
# For platforms which do not support PIC, -DPIC is meaningless:
*djgpp*)
lt_prog_compiler_pic=
@@ -6243,6 +6635,48 @@ case "$host_os" in
;;
esac
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\"
+echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6
+if test "${lt_prog_compiler_static_works+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ lt_prog_compiler_static_works=no
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+ printf "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ lt_prog_compiler_static_works=yes
+ fi
+ else
+ lt_prog_compiler_static_works=yes
+ fi
+ fi
+ $rm conftest*
+ LDFLAGS="$save_LDFLAGS"
+
+fi
+echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works" >&5
+echo "${ECHO_T}$lt_prog_compiler_static_works" >&6
+
+if test x"$lt_prog_compiler_static_works" = xyes; then
+ :
+else
+ lt_prog_compiler_static=
+fi
+
+
echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5
echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6
if test "${lt_cv_prog_compiler_c_o+set}" = set; then
@@ -6255,38 +6689,36 @@ else
mkdir out
printf "$lt_simple_compile_test_code" > conftest.$ac_ext
- # According to Tom Tromey, Ian Lance Taylor reported there are C compilers
- # that will create temporary files in the current directory regardless of
- # the output directory. Thus, making CWD read-only will cause this test
- # to fail, enabling locking or at least warning the user not to do parallel
- # builds.
- chmod -w .
-
lt_compiler_flag="-o out/conftest2.$ac_objext"
# Insert the option either (1) after the last *FLAGS variable, or
# (2) before a word containing "conftest.", or (3) at the end.
# Note that $ac_compile itself does not contain backslashes and begins
# with a dollar sign (not a hyphen), so the echo should work correctly.
lt_compile=`echo "$ac_compile" | $SED \
- -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:6274: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:6701: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:6278: \$? = $ac_status" >&5
+ echo "$as_me:6705: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings
- if test ! -s out/conftest.err; then
+ $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
lt_cv_prog_compiler_c_o=yes
fi
fi
- chmod u+w .
- $rm conftest* out/*
- rmdir out
+ chmod u+w . 2>&5
+ $rm conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files
+ $rm out/* && rmdir out
cd ..
rmdir conftest
$rm conftest*
@@ -6357,6 +6789,16 @@ echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared librar
# rely on this symbol name, it's probably fine to never include it in
# preloaded symbol tables.
extract_expsyms_cmds=
+ # Just being paranoid about ensuring that cc_basename is set.
+ for cc_temp in $compiler""; do
+ case $cc_temp in
+ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+done
+cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
case $host_os in
cygwin* | mingw* | pw32*)
@@ -6367,6 +6809,10 @@ echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared librar
with_gnu_ld=no
fi
;;
+ interix*)
+ # we just hope/assume this is gcc and not c89 (= MSVC++)
+ with_gnu_ld=yes
+ ;;
openbsd*)
with_gnu_ld=no
;;
@@ -6377,6 +6823,27 @@ echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared librar
# If archive_cmds runs LD, not CC, wlarc should be empty
wlarc='${wl}'
+ # Set some defaults for GNU ld with shared library support. These
+ # are reset later if shared libraries are not supported. Putting them
+ # here allows them to be overridden if necessary.
+ runpath_var=LD_RUN_PATH
+ hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir'
+ export_dynamic_flag_spec='${wl}--export-dynamic'
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then
+ whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ else
+ whole_archive_flag_spec=
+ fi
+ supports_anon_versioning=no
+ case `$LD -v 2>/dev/null` in
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
+ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+ *\ 2.11.*) ;; # other 2.11 versions
+ *) supports_anon_versioning=yes ;;
+ esac
+
# See if GNU ld supports shared libraries.
case $host_os in
aix3* | aix4* | aix5*)
@@ -6427,10 +6894,10 @@ EOF
allow_undefined_flag=unsupported
always_export_symbols=no
enable_shared_with_static_runtimes=yes
- export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols'
+ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols'
if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
- archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib'
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
# If the export-symbols file already is a .def file (1st line
# is EXPORTS), use it as is; otherwise, prepend...
archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
@@ -6439,13 +6906,60 @@ EOF
echo EXPORTS > $output_objdir/$soname.def;
cat $export_symbols >> $output_objdir/$soname.def;
fi~
- $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib'
+ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ interix3*)
+ hardcode_direct=no
+ hardcode_shlibpath_var=no
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ export_dynamic_flag_spec='${wl}-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+
+ linux*)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ tmp_addflag=
+ case $cc_basename,$host_cpu in
+ pgcc*) # Portland Group C compiler
+ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
+ tmp_addflag=' $pic_flag'
+ ;;
+ pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers
+ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
+ tmp_addflag=' $pic_flag -Mnomain' ;;
+ ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
+ tmp_addflag=' -i_dynamic' ;;
+ efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64
+ tmp_addflag=' -i_dynamic -nofor_main' ;;
+ ifc* | ifort*) # Intel Fortran compiler
+ tmp_addflag=' -nofor_main' ;;
+ esac
+ archive_cmds='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+
+ if test $supports_anon_versioning = yes; then
+ archive_expsym_cmds='$echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ $echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+ fi
+ link_all_deplibs=no
else
ld_shlibs=no
fi
;;
- netbsd*)
+ netbsd* | netbsdelf*-gnu | knetbsd*-gnu)
if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
wlarc=
@@ -6455,7 +6969,7 @@ EOF
fi
;;
- solaris* | sysv5*)
+ solaris*)
if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
ld_shlibs=no
cat <<EOF 1>&2
@@ -6476,6 +6990,33 @@ EOF
fi
;;
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+ case `$LD -v 2>&1` in
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ ;;
+ *)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`'
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+ ;;
+
sunos4*)
archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
wlarc=
@@ -6483,31 +7024,6 @@ EOF
hardcode_shlibpath_var=no
;;
- linux*)
- if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
- tmp_archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_cmds="$tmp_archive_cmds"
- supports_anon_versioning=no
- case `$LD -v 2>/dev/null` in
- *\ 01.* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
- *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
- *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
- *\ 2.11.*) ;; # other 2.11 versions
- *) supports_anon_versioning=yes ;;
- esac
- if test $supports_anon_versioning = yes; then
- archive_expsym_cmds='$echo "{ global:" > $output_objdir/$libname.ver~
-cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
-$echo "local: *; };" >> $output_objdir/$libname.ver~
- $CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
- else
- archive_expsym_cmds="$tmp_archive_cmds"
- fi
- else
- ld_shlibs=no
- fi
- ;;
-
*)
if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
@@ -6518,16 +7034,11 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~
;;
esac
- if test "$ld_shlibs" = yes; then
- runpath_var=LD_RUN_PATH
- hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir'
- export_dynamic_flag_spec='${wl}--export-dynamic'
- # ancient GNU ld didn't support --whole-archive et. al.
- if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then
- whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
- else
- whole_archive_flag_spec=
- fi
+ if test "$ld_shlibs" = no; then
+ runpath_var=
+ hardcode_libdir_flag_spec=
+ export_dynamic_flag_spec=
+ whole_archive_flag_spec=
fi
else
# PORTME fill in a description of your system's linker (not GNU ld)
@@ -6539,7 +7050,7 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~
# Note: this linker hardcodes the directories in LIBPATH if there
# are no directories specified by -L.
hardcode_minus_L=yes
- if test "$GCC" = yes && test -z "$link_static_flag"; then
+ if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
# Neither direct hardcoding nor static linking is supported with a
# broken collect2.
hardcode_direct=unsupported
@@ -6573,6 +7084,7 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~
break
fi
done
+ ;;
esac
exp_sym_flag='-bexport'
@@ -6591,7 +7103,7 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~
link_all_deplibs=yes
if test "$GCC" = yes; then
- case $host_os in aix4.012|aix4.012.*)
+ case $host_os in aix4.[012]|aix4.[012].*)
# We only want to do this on AIX 4.2 and lower, the check
# below for broken collect2 doesn't work under 4.3+
collect2name=`${CC} -print-prog-name=collect2`
@@ -6610,8 +7122,12 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~
hardcode_libdir_flag_spec='-L$libdir'
hardcode_libdir_separator=
fi
+ ;;
esac
shared_flag='-shared'
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag="$shared_flag "'${wl}-G'
+ fi
else
# not using gcc
if test "$host_cpu" = ia64; then
@@ -6619,11 +7135,11 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~
# chokes on -Wl,-G. The following line is correct:
shared_flag='-G'
else
- if test "$aix_use_runtimelinking" = yes; then
+ if test "$aix_use_runtimelinking" = yes; then
shared_flag='${wl}-G'
else
shared_flag='${wl}-bM:SRE'
- fi
+ fi
fi
fi
@@ -6636,7 +7152,6 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~
allow_undefined_flag='-berok'
# Determine the default libpath from the value encoded in an empty executable.
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -6653,11 +7168,20 @@ main ()
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
+ (eval $ac_link) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest$ac_exeext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -6674,20 +7198,20 @@ else
sed 's/^/| /' conftest.$ac_ext >&5
fi
-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
- archive_expsym_cmds="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+ archive_expsym_cmds="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
else
if test "$host_cpu" = ia64; then
hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
allow_undefined_flag="-z nodefs"
- archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"
+ archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
else
# Determine the default libpath from the value encoded in an empty executable.
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -6704,11 +7228,20 @@ main ()
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
+ (eval $ac_link) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest$ac_exeext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -6725,7 +7258,8 @@ else
sed 's/^/| /' conftest.$ac_ext >&5
fi
-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
@@ -6733,13 +7267,11 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
# -berok will link without error, but may produce a broken library.
no_undefined_flag=' ${wl}-bernotok'
allow_undefined_flag=' ${wl}-berok'
- # -bexpall does not export symbols beginning with underscore (_)
- always_export_symbols=yes
# Exported symbols can be pulled into shared objects from archives
- whole_archive_flag_spec=' '
+ whole_archive_flag_spec='$convenience'
archive_cmds_need_lc=yes
- # This is similar to how AIX traditionally builds it's shared libraries.
- archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+ # This is similar to how AIX traditionally builds its shared libraries.
+ archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
fi
fi
;;
@@ -6752,7 +7284,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
ld_shlibs=no
;;
- bsdi4*)
+ bsdi[45]*)
export_dynamic_flag_spec=-rdynamic
;;
@@ -6766,7 +7298,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
# Tell ltmain to make .lib files, not .a files.
libext=lib
# Tell ltmain to make .dll files, not .so files.
- shrext=".dll"
+ shrext_cmds=".dll"
# FIXME: Setting linknames here is a bad hack.
archive_cmds='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames='
# The linker will automatically build a .lib file if we build a DLL.
@@ -6778,43 +7310,52 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
;;
darwin* | rhapsody*)
- if $CC -v 2>&1 | grep 'Apple' >/dev/null ; then
- archive_cmds_need_lc=no
- case "$host_os" in
- rhapsody* | darwin1.[012])
- allow_undefined_flag='-undefined suppress'
- ;;
- *) # Darwin 1.3 on
- test -z ${LD_TWOLEVEL_NAMESPACE} && allow_undefined_flag='-flat_namespace -undefined suppress'
- ;;
+ case $host_os in
+ rhapsody* | darwin1.[012])
+ allow_undefined_flag='${wl}-undefined ${wl}suppress'
+ ;;
+ *) # Darwin 1.3 on
+ if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then
+ allow_undefined_flag='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
+ else
+ case ${MACOSX_DEPLOYMENT_TARGET} in
+ 10.[012])
+ allow_undefined_flag='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
+ ;;
+ 10.*)
+ allow_undefined_flag='${wl}-undefined ${wl}dynamic_lookup'
+ ;;
+ esac
+ fi
+ ;;
esac
- # FIXME: Relying on posixy $() will cause problems for
- # cross-compilation, but unfortunately the echo tests do not
- # yet detect zsh echo's removal of \ escapes. Also zsh mangles
- # `"' quotes if we put them in here... so don't!
- lt_int_apple_cc_single_mod=no
- output_verbose_link_cmd='echo'
- if $CC -dumpspecs 2>&1 | grep 'single_module' >/dev/null ; then
- lt_int_apple_cc_single_mod=yes
- fi
- if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
- archive_cmds='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
- else
- archive_cmds='$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
- fi
- module_cmds='$CC -bundle ${wl}-bind_at_load $allow_undefined_flag -o $lib $libobjs $deplibs$compiler_flags'
- # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's
- if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
- archive_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
- else
- archive_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
- fi
- module_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -bundle $allow_undefined_flag -o $lib $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ archive_cmds_need_lc=no
hardcode_direct=no
hardcode_automatic=yes
hardcode_shlibpath_var=unsupported
- whole_archive_flag_spec='-all_load $convenience'
+ whole_archive_flag_spec=''
link_all_deplibs=yes
+ if test "$GCC" = yes ; then
+ output_verbose_link_cmd='echo'
+ archive_cmds='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+ module_cmds='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+ # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
+ archive_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ module_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ else
+ case $cc_basename in
+ xlc*)
+ output_verbose_link_cmd='echo'
+ archive_cmds='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring'
+ module_cmds='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+ # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
+ archive_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ module_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ ;;
+ *)
+ ld_shlibs=no
+ ;;
+ esac
fi
;;
@@ -6848,11 +7389,20 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
;;
# FreeBSD 3 and greater uses gcc -shared to do shared libraries.
- freebsd*)
+ freebsd* | dragonfly*)
+ archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # GNU/kFreeBSD uses gcc -shared to do shared libraries.
+ kfreebsd*-gnu)
archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
hardcode_libdir_flag_spec='-R$libdir'
hardcode_direct=yes
hardcode_shlibpath_var=no
+ link_all_deplibs=no
;;
hpux9*)
@@ -6871,47 +7421,62 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
export_dynamic_flag_spec='${wl}-E'
;;
- hpux10* | hpux11*)
+ hpux10*)
if test "$GCC" = yes -a "$with_gnu_ld" = no; then
- case "$host_cpu" in
- hppa*64*|ia64*)
+ archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ if test "$with_gnu_ld" = no; then
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+
+ hardcode_direct=yes
+ export_dynamic_flag_spec='${wl}-E'
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ fi
+ ;;
+
+ hpux11*)
+ if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+ case $host_cpu in
+ hppa*64*)
archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
;;
+ ia64*)
+ archive_cmds='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
*)
archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
;;
esac
else
- case "$host_cpu" in
- hppa*64*|ia64*)
- archive_cmds='$LD -b +h $soname -o $lib $libobjs $deplibs $linker_flags'
+ case $host_cpu in
+ hppa*64*)
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
*)
- archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
;;
esac
fi
if test "$with_gnu_ld" = no; then
- case "$host_cpu" in
- hppa*64*)
- hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
hardcode_libdir_flag_spec_ld='+b $libdir'
- hardcode_libdir_separator=:
- hardcode_direct=no
- hardcode_shlibpath_var=no
- ;;
- ia64*)
- hardcode_libdir_flag_spec='-L$libdir'
hardcode_direct=no
hardcode_shlibpath_var=no
-
- # hardcode_minus_L: Not really in the search PATH,
- # but as the default location of the library.
- hardcode_minus_L=yes
;;
*)
- hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
- hardcode_libdir_separator=:
hardcode_direct=yes
export_dynamic_flag_spec='${wl}-E'
@@ -6935,7 +7500,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
link_all_deplibs=yes
;;
- netbsd*)
+ netbsd* | netbsdelf*-gnu | knetbsd*-gnu)
if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
else
@@ -6959,6 +7524,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
hardcode_shlibpath_var=no
if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
export_dynamic_flag_spec='${wl}-E'
else
@@ -7004,7 +7570,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
allow_undefined_flag=' -expect_unresolved \*'
archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~
- $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib~$rm $lib.exp'
+ $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp'
# Both c and cxx compiler support -rpath directly
hardcode_libdir_flag_spec='-rpath $libdir'
@@ -7012,21 +7578,15 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
hardcode_libdir_separator=:
;;
- sco3.2v5*)
- archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_shlibpath_var=no
- export_dynamic_flag_spec='${wl}-Bexport'
- runpath_var=LD_RUN_PATH
- hardcode_runpath_var=yes
- ;;
-
solaris*)
no_undefined_flag=' -z text'
if test "$GCC" = yes; then
+ wlarc='${wl}'
archive_cmds='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
$CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp'
else
+ wlarc=''
archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
$LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
@@ -7035,8 +7595,18 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
hardcode_shlibpath_var=no
case $host_os in
solaris2.[0-5] | solaris2.[0-5].*) ;;
- *) # Supported since Solaris 2.6 (maybe 2.5.1?)
- whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;;
+ *)
+ # The compiler driver will combine linker options so we
+ # cannot just pass the convience library names through
+ # without $wl, iff we do not link with $LD.
+ # Luckily, gcc supports the same syntax we need for Sun Studio.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ case $wlarc in
+ '')
+ whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;;
+ *)
+ whole_archive_flag_spec='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;;
+ esac ;;
esac
link_all_deplibs=yes
;;
@@ -7093,36 +7663,45 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
fi
;;
- sysv4.2uw2*)
- archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'
- hardcode_direct=yes
- hardcode_minus_L=no
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7*)
+ no_undefined_flag='${wl}-z,text'
+ archive_cmds_need_lc=no
hardcode_shlibpath_var=no
- hardcode_runpath_var=yes
- runpath_var=LD_RUN_PATH
- ;;
+ runpath_var='LD_RUN_PATH'
- sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[78]* | unixware7*)
- no_undefined_flag='${wl}-z ${wl}text'
if test "$GCC" = yes; then
- archive_cmds='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
else
- archive_cmds='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
fi
- runpath_var='LD_RUN_PATH'
- hardcode_shlibpath_var=no
;;
- sysv5*)
- no_undefined_flag=' -z text'
- # $CC -shared without GNU ld will not create a library from C++
- # object files and a static libstdc++, better avoid it by now
- archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
- archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
- $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
- hardcode_libdir_flag_spec=
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We can NOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ no_undefined_flag='${wl}-z,text'
+ allow_undefined_flag='${wl}-z,nodefs'
+ archive_cmds_need_lc=no
hardcode_shlibpath_var=no
+ hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
+ hardcode_libdir_separator=':'
+ link_all_deplibs=yes
+ export_dynamic_flag_spec='${wl}-Bexport'
runpath_var='LD_RUN_PATH'
+
+ if test "$GCC" = yes; then
+ archive_cmds='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
;;
uts4*)
@@ -7141,11 +7720,6 @@ echo "$as_me:$LINENO: result: $ld_shlibs" >&5
echo "${ECHO_T}$ld_shlibs" >&6
test "$ld_shlibs" = no && can_build_shared=no
-variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
-if test "$GCC" = yes; then
- variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
-fi
-
#
# Do we need to explicitly link libc?
#
@@ -7178,6 +7752,7 @@ echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&
libobjs=conftest.$ac_objext
deplibs=
wl=$lt_prog_compiler_wl
+ pic_flag=$lt_prog_compiler_pic
compiler_flags=-v
linker_flags=-v
verstring=
@@ -7208,78 +7783,12 @@ echo "${ECHO_T}$archive_cmds_need_lc" >&6
;;
esac
-echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5
-echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6
-hardcode_action=
-if test -n "$hardcode_libdir_flag_spec" || \
- test -n "$runpath_var " || \
- test "X$hardcode_automatic"="Xyes" ; then
-
- # We can hardcode non-existant directories.
- if test "$hardcode_direct" != no &&
- # If the only mechanism to avoid hardcoding is shlibpath_var, we
- # have to relink, otherwise we might link with an installed library
- # when we should be linking with a yet-to-be-installed one
- ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, )" != no &&
- test "$hardcode_minus_L" != no; then
- # Linking always hardcodes the temporary library directory.
- hardcode_action=relink
- else
- # We can link without hardcoding, and we can hardcode nonexisting dirs.
- hardcode_action=immediate
- fi
-else
- # We cannot hardcode anything, or else we can only hardcode existing
- # directories.
- hardcode_action=unsupported
-fi
-echo "$as_me:$LINENO: result: $hardcode_action" >&5
-echo "${ECHO_T}$hardcode_action" >&6
-
-if test "$hardcode_action" = relink; then
- # Fast installation is not supported
- enable_fast_install=no
-elif test "$shlibpath_overrides_runpath" = yes ||
- test "$enable_shared" = no; then
- # Fast installation is not necessary
- enable_fast_install=needless
-fi
-
-striplib=
-old_striplib=
-echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5
-echo $ECHO_N "checking whether stripping libraries is possible... $ECHO_C" >&6
-if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then
- test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
- test -z "$striplib" && striplib="$STRIP --strip-unneeded"
- echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6
-else
-# FIXME - insert some real tests, host_os isn't really good enough
- case $host_os in
- darwin*)
- if test -n "$STRIP" ; then
- striplib="$STRIP -x"
- echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6
- else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
- ;;
- *)
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
- ;;
- esac
-fi
-
echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5
echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6
library_names_spec=
libname_spec='lib$name'
soname_spec=
-shrext=".so"
+shrext_cmds=".so"
postinstall_cmds=
postuninstall_cmds=
finish_cmds=
@@ -7367,7 +7876,7 @@ aix4* | aix5*)
amigaos*)
library_names_spec='$libname.ixlibrary $libname.a'
# Create ${libname}_ixlibrary.a entries in /sys/libs.
- finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "(cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a)"; (cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a) || exit 1; done'
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
;;
beos*)
@@ -7376,7 +7885,7 @@ beos*)
shlibpath_var=LIBRARY_PATH
;;
-bsdi4*)
+bsdi[45]*)
version_type=linux
need_version=no
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
@@ -7392,7 +7901,7 @@ bsdi4*)
cygwin* | mingw* | pw32*)
version_type=windows
- shrext=".dll"
+ shrext_cmds=".dll"
need_version=no
need_lib_prefix=no
@@ -7404,7 +7913,8 @@ cygwin* | mingw* | pw32*)
dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~
dldir=$destdir/`dirname \$dlpath`~
test -d \$dldir || mkdir -p \$dldir~
- $install_prog $dir/$dlname \$dldir/$dlname'
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname'
postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
dlpath=$dir/\$dldll~
$rm \$dlpath'
@@ -7414,7 +7924,7 @@ cygwin* | mingw* | pw32*)
cygwin*)
# Cygwin DLLs use 'cyg' prefix rather than 'lib'
soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
- sys_lib_search_path_spec="/lib /lib/w32api /usr/lib /usr/local/lib"
+ sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
;;
mingw*)
# MinGW DLLs use traditional 'lib' prefix
@@ -7434,7 +7944,7 @@ cygwin* | mingw* | pw32*)
;;
pw32*)
# pw32 DLLs use 'pw' prefix rather than 'lib'
- library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/./-/g'`${versuffix}${shared_ext}'
+ library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
;;
esac
;;
@@ -7453,17 +7963,16 @@ darwin* | rhapsody*)
version_type=darwin
need_lib_prefix=no
need_version=no
- # FIXME: Relying on posixy $() will cause problems for
- # cross-compilation, but unfortunately the echo tests do not
- # yet detect zsh echo's removal of \ escapes.
library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext'
soname_spec='${libname}${release}${major}$shared_ext'
shlibpath_overrides_runpath=yes
shlibpath_var=DYLD_LIBRARY_PATH
- shrext='$(test .$module = .yes && echo .so || echo .dylib)'
+ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
# Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same.
- if $CC -v 2>&1 | grep 'Apple' >/dev/null ; then
- sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"`
+ if test "$GCC" = yes; then
+ sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"`
+ else
+ sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib'
fi
sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
;;
@@ -7481,8 +7990,29 @@ freebsd1*)
dynamic_linker=no
;;
-freebsd*)
- objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout`
+kfreebsd*-gnu)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='GNU ld.so'
+ ;;
+
+freebsd* | dragonfly*)
+ # DragonFly does not have aout. When/if they implement a new
+ # versioning mechanism, adjust this.
+ if test -x /usr/bin/objformat; then
+ objformat=`/usr/bin/objformat`
+ else
+ case $host_os in
+ freebsd[123]*) objformat=aout ;;
+ *) objformat=elf ;;
+ esac
+ fi
version_type=freebsd-$objformat
case $version_type in
freebsd-elf*)
@@ -7500,14 +8030,19 @@ freebsd*)
freebsd2*)
shlibpath_overrides_runpath=yes
;;
- freebsd3.01* | freebsdelf3.01*)
+ freebsd3.[01]* | freebsdelf3.[01]*)
shlibpath_overrides_runpath=yes
hardcode_into_libs=yes
;;
- *) # from 3.2 on
+ freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
shlibpath_overrides_runpath=no
hardcode_into_libs=yes
;;
+ freebsd*) # from 4.6 on
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
esac
;;
@@ -7527,9 +8062,9 @@ hpux9* | hpux10* | hpux11*)
version_type=sunos
need_lib_prefix=no
need_version=no
- case "$host_cpu" in
+ case $host_cpu in
ia64*)
- shrext='.so'
+ shrext_cmds='.so'
hardcode_into_libs=yes
dynamic_linker="$host_os dld.so"
shlibpath_var=LD_LIBRARY_PATH
@@ -7544,7 +8079,7 @@ hpux9* | hpux10* | hpux11*)
sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
;;
hppa*64*)
- shrext='.sl'
+ shrext_cmds='.sl'
hardcode_into_libs=yes
dynamic_linker="$host_os dld.sl"
shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
@@ -7555,7 +8090,7 @@ hpux9* | hpux10* | hpux11*)
sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
;;
*)
- shrext='.sl'
+ shrext_cmds='.sl'
dynamic_linker="$host_os dld.sl"
shlibpath_var=SHLIB_PATH
shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
@@ -7567,6 +8102,18 @@ hpux9* | hpux10* | hpux11*)
postinstall_cmds='chmod 555 $lib'
;;
+interix3*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
irix5* | irix6* | nonstopux*)
case $host_os in
nonstopux*) version_type=nonstopux ;;
@@ -7624,6 +8171,12 @@ linux*)
# before this can be enabled.
hardcode_into_libs=yes
+ # Append ld.so.conf contents to the search path
+ if test -f /etc/ld.so.conf; then
+ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
+ sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+ fi
+
# We used to test for /lib/ld.so.1 and disable shared libraries on
# powerpc, because MkLinux only supported shared libraries with the
# GNU dynamic linker. Since this was broken with cross compilers,
@@ -7631,30 +8184,30 @@ linux*)
# people can always --disable-shared, the test was removed, and we
# assume the GNU/Linux dynamic linker is in use.
dynamic_linker='GNU/Linux ld.so'
+ ;;
- # Find out which ABI we are using (multilib Linux x86_64 hack).
- libsuff=
- case "$host_cpu" in
- x86_64*|s390x*)
- echo '#line 7639 "configure"' > conftest.$ac_ext
- if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; then
- case `/usr/bin/file conftest.$ac_objext` in
- *64-bit*)
- libsuff=64
- ;;
- esac
- fi
- rm -rf conftest*
- ;;
- *)
- ;;
- esac
- sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff}"
- sys_lib_search_path_spec="/lib${libsuff} /usr/lib${libsuff} /usr/local/lib${libsuff}"
+netbsdelf*-gnu)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='NetBSD ld.elf_so'
+ ;;
+
+knetbsd*-gnu)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='GNU ld.so'
;;
netbsd*)
@@ -7666,7 +8219,7 @@ netbsd*)
finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
dynamic_linker='NetBSD (a.out) ld.so'
else
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} ${libname}${shared_ext}'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
soname_spec='${libname}${release}${shared_ext}$major'
dynamic_linker='NetBSD ld.elf_so'
fi
@@ -7682,7 +8235,7 @@ newsos6)
shlibpath_overrides_runpath=yes
;;
-nto-qnx)
+nto-qnx*)
version_type=linux
need_lib_prefix=no
need_version=no
@@ -7694,8 +8247,13 @@ nto-qnx)
openbsd*)
version_type=sunos
+ sys_lib_dlsearch_path_spec="/usr/lib"
need_lib_prefix=no
- need_version=no
+ # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+ case $host_os in
+ openbsd3.3 | openbsd3.3.*) need_version=yes ;;
+ *) need_version=no ;;
+ esac
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
shlibpath_var=LD_LIBRARY_PATH
@@ -7715,7 +8273,7 @@ openbsd*)
os2*)
libname_spec='$name'
- shrext=".dll"
+ shrext_cmds=".dll"
need_lib_prefix=no
library_names_spec='$libname${shared_ext} $libname.a'
dynamic_linker='OS/2 ld.exe'
@@ -7733,13 +8291,6 @@ osf3* | osf4* | osf5*)
sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
;;
-sco3.2v5*)
- version_type=osf
- soname_spec='${libname}${release}${shared_ext}$major'
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- ;;
-
solaris*)
version_type=linux
need_lib_prefix=no
@@ -7765,7 +8316,7 @@ sunos4*)
need_version=yes
;;
-sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+sysv4 | sysv4.3*)
version_type=linux
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
soname_spec='${libname}${release}${shared_ext}$major'
@@ -7798,6 +8349,29 @@ sysv4*MP*)
fi
;;
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ version_type=freebsd-elf
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ hardcode_into_libs=yes
+ if test "$with_gnu_ld" = yes; then
+ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+ shlibpath_overrides_runpath=no
+ else
+ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+ shlibpath_overrides_runpath=yes
+ case $host_os in
+ sco3.2v5*)
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+ ;;
+ esac
+ fi
+ sys_lib_dlsearch_path_spec='/usr/lib'
+ ;;
+
uts4*)
version_type=linux
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
@@ -7813,6 +8387,77 @@ echo "$as_me:$LINENO: result: $dynamic_linker" >&5
echo "${ECHO_T}$dynamic_linker" >&6
test "$dynamic_linker" = no && can_build_shared=no
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5
+echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" || \
+ test -n "$runpath_var" || \
+ test "X$hardcode_automatic" = "Xyes" ; then
+
+ # We can hardcode non-existant directories.
+ if test "$hardcode_direct" != no &&
+ # If the only mechanism to avoid hardcoding is shlibpath_var, we
+ # have to relink, otherwise we might link with an installed library
+ # when we should be linking with a yet-to-be-installed one
+ ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, )" != no &&
+ test "$hardcode_minus_L" != no; then
+ # Linking always hardcodes the temporary library directory.
+ hardcode_action=relink
+ else
+ # We can link without hardcoding, and we can hardcode nonexisting dirs.
+ hardcode_action=immediate
+ fi
+else
+ # We cannot hardcode anything, or else we can only hardcode existing
+ # directories.
+ hardcode_action=unsupported
+fi
+echo "$as_me:$LINENO: result: $hardcode_action" >&5
+echo "${ECHO_T}$hardcode_action" >&6
+
+if test "$hardcode_action" = relink; then
+ # Fast installation is not supported
+ enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+ test "$enable_shared" = no; then
+ # Fast installation is not necessary
+ enable_fast_install=needless
+fi
+
+striplib=
+old_striplib=
+echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5
+echo $ECHO_N "checking whether stripping libraries is possible... $ECHO_C" >&6
+if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then
+ test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+ test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+ case $host_os in
+ darwin*)
+ if test -n "$STRIP" ; then
+ striplib="$STRIP -x"
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+ else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+ ;;
+ *)
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+ ;;
+ esac
+fi
+
if test "x$enable_dlopen" != xyes; then
enable_dlopen=unknown
enable_dlopen_self=unknown
@@ -7848,7 +8493,6 @@ else
ac_check_lib_save_LIBS=$LIBS
LIBS="-ldl $LIBS"
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -7872,11 +8516,20 @@ dlopen ();
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
+ (eval $ac_link) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest$ac_exeext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -7889,7 +8542,8 @@ sed 's/^/| /' conftest.$ac_ext >&5
ac_cv_lib_dl_dlopen=no
fi
-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5
@@ -7913,21 +8567,28 @@ if test "${ac_cv_func_shl_load+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
+/* Define shl_load to an innocuous variant, in case <limits.h> declares shl_load.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define shl_load innocuous_shl_load
+
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char shl_load (); below.
Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
<limits.h> exists even on freestanding compilers. */
+
#ifdef __STDC__
# include <limits.h>
#else
# include <assert.h>
#endif
+
+#undef shl_load
+
/* Override any gcc2 internal prototype to avoid an error. */
#ifdef __cplusplus
extern "C"
@@ -7958,11 +8619,20 @@ return f != shl_load;
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
+ (eval $ac_link) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest$ac_exeext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -7975,7 +8645,8 @@ sed 's/^/| /' conftest.$ac_ext >&5
ac_cv_func_shl_load=no
fi
-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5
echo "${ECHO_T}$ac_cv_func_shl_load" >&6
@@ -7990,7 +8661,6 @@ else
ac_check_lib_save_LIBS=$LIBS
LIBS="-ldld $LIBS"
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -8014,11 +8684,20 @@ shl_load ();
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
+ (eval $ac_link) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest$ac_exeext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -8031,7 +8710,8 @@ sed 's/^/| /' conftest.$ac_ext >&5
ac_cv_lib_dld_shl_load=no
fi
-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5
@@ -8045,21 +8725,28 @@ if test "${ac_cv_func_dlopen+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
+/* Define dlopen to an innocuous variant, in case <limits.h> declares dlopen.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define dlopen innocuous_dlopen
+
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char dlopen (); below.
Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
<limits.h> exists even on freestanding compilers. */
+
#ifdef __STDC__
# include <limits.h>
#else
# include <assert.h>
#endif
+
+#undef dlopen
+
/* Override any gcc2 internal prototype to avoid an error. */
#ifdef __cplusplus
extern "C"
@@ -8090,11 +8777,20 @@ return f != dlopen;
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
+ (eval $ac_link) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest$ac_exeext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -8107,7 +8803,8 @@ sed 's/^/| /' conftest.$ac_ext >&5
ac_cv_func_dlopen=no
fi
-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5
echo "${ECHO_T}$ac_cv_func_dlopen" >&6
@@ -8122,7 +8819,6 @@ else
ac_check_lib_save_LIBS=$LIBS
LIBS="-ldl $LIBS"
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -8146,11 +8842,20 @@ dlopen ();
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
+ (eval $ac_link) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest$ac_exeext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -8163,7 +8868,8 @@ sed 's/^/| /' conftest.$ac_ext >&5
ac_cv_lib_dl_dlopen=no
fi
-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5
@@ -8179,7 +8885,6 @@ else
ac_check_lib_save_LIBS=$LIBS
LIBS="-lsvld $LIBS"
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -8203,11 +8908,20 @@ dlopen ();
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
+ (eval $ac_link) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest$ac_exeext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -8220,7 +8934,8 @@ sed 's/^/| /' conftest.$ac_ext >&5
ac_cv_lib_svld_dlopen=no
fi
-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
echo "$as_me:$LINENO: result: $ac_cv_lib_svld_dlopen" >&5
@@ -8236,7 +8951,6 @@ else
ac_check_lib_save_LIBS=$LIBS
LIBS="-ldld $LIBS"
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -8260,11 +8974,20 @@ dld_link ();
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
+ (eval $ac_link) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest$ac_exeext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -8277,7 +9000,8 @@ sed 's/^/| /' conftest.$ac_ext >&5
ac_cv_lib_dld_dld_link=no
fi
-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
echo "$as_me:$LINENO: result: $ac_cv_lib_dld_dld_link" >&5
@@ -8316,7 +9040,7 @@ fi
test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
save_LDFLAGS="$LDFLAGS"
- eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
save_LIBS="$LIBS"
LIBS="$lt_cv_dlopen_libs $LIBS"
@@ -8332,7 +9056,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
-#line 8335 "configure"
+#line 9059 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -8389,6 +9113,8 @@ int main ()
else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
/* dlclose (self); */
}
+ else
+ puts (dlerror ());
exit (status);
}
@@ -8398,12 +9124,12 @@ EOF
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then
- (./conftest; exit; ) 2>/dev/null
+ (./conftest; exit; ) >&5 2>/dev/null
lt_status=$?
case x$lt_status in
x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;
x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;;
- x$lt_unknown|x*) lt_cv_dlopen_self=no ;;
+ x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;;
esac
else :
# compilation failed
@@ -8418,7 +9144,7 @@ echo "$as_me:$LINENO: result: $lt_cv_dlopen_self" >&5
echo "${ECHO_T}$lt_cv_dlopen_self" >&6
if test "x$lt_cv_dlopen_self" = xyes; then
- LDFLAGS="$LDFLAGS $link_static_flag"
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
echo "$as_me:$LINENO: checking whether a statically linked program can dlopen itself" >&5
echo $ECHO_N "checking whether a statically linked program can dlopen itself... $ECHO_C" >&6
if test "${lt_cv_dlopen_self_static+set}" = set; then
@@ -8430,7 +9156,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF
-#line 8433 "configure"
+#line 9159 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -8487,6 +9213,8 @@ int main ()
else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
/* dlclose (self); */
}
+ else
+ puts (dlerror ());
exit (status);
}
@@ -8496,12 +9224,12 @@ EOF
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then
- (./conftest; exit; ) 2>/dev/null
+ (./conftest; exit; ) >&5 2>/dev/null
lt_status=$?
case x$lt_status in
x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;
x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;;
- x$lt_unknown|x*) lt_cv_dlopen_self_static=no ;;
+ x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;;
esac
else :
# compilation failed
@@ -8534,7 +9262,7 @@ echo "${ECHO_T}$lt_cv_dlopen_self_static" >&6
fi
-# Report which librarie types wil actually be built
+# Report which library types will actually be built
echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5
echo $ECHO_N "checking if libtool supports shared libraries... $ECHO_C" >&6
echo "$as_me:$LINENO: result: $can_build_shared" >&5
@@ -8546,7 +9274,7 @@ test "$can_build_shared" = "no" && enable_shared=no
# On AIX, shared libraries and static libraries use the same namespace, and
# are all built from PIC.
-case "$host_os" in
+case $host_os in
aix3*)
test "$enable_shared" = yes && enable_static=no
if test -n "$RANLIB"; then
@@ -8555,38 +9283,10 @@ aix3*)
fi
;;
-aix4*)
+aix4* | aix5*)
if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
test "$enable_shared" = yes && enable_static=no
fi
- ;;
- darwin* | rhapsody*)
- if $CC -v 2>&1 | grep 'Apple' >/dev/null ; then
- archive_cmds_need_lc=no
- case "$host_os" in
- rhapsody* | darwin1.[012])
- allow_undefined_flag='-undefined suppress'
- ;;
- *) # Darwin 1.3 on
- test -z ${LD_TWOLEVEL_NAMESPACE} && allow_undefined_flag='-flat_namespace -undefined suppress'
- ;;
- esac
- # FIXME: Relying on posixy $() will cause problems for
- # cross-compilation, but unfortunately the echo tests do not
- # yet detect zsh echo's removal of \ escapes. Also zsh mangles
- # `"' quotes if we put them in here... so don't!
- output_verbose_link_cmd='echo'
- archive_cmds='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs$compiler_flags -install_name $rpath/$soname $verstring'
- module_cmds='$CC -bundle $allow_undefined_flag -o $lib $libobjs $deplibs$compiler_flags'
- # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's
- archive_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs$compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
- module_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -bundle $allow_undefined_flag -o $lib $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
- hardcode_direct=no
- hardcode_automatic=yes
- hardcode_shlibpath_var=unsupported
- whole_archive_flag_spec='-all_load $convenience'
- link_all_deplibs=yes
- fi
;;
esac
echo "$as_me:$LINENO: result: $enable_shared" >&5
@@ -8612,7 +9312,8 @@ if test -f "$ltmain"; then
# Now quote all the things that may contain metacharacters while being
# careful not to overquote the AC_SUBSTed values. We take copies of the
# variables and quote the copies for generation of the libtool script.
- for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC NM SED SHELL \
+ for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \
+ SED SHELL STRIP \
libname_spec library_names_spec soname_spec extract_expsyms_cmds \
old_striplib striplib file_magic_cmd finish_cmds finish_eval \
deplibs_check_method reload_flag reload_cmds need_locks \
@@ -8715,7 +9416,7 @@ echo "$as_me: creating $ofile" >&6;}
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
@@ -8726,11 +9427,11 @@ echo "$as_me: creating $ofile" >&6;}
SED=$lt_SED
# Sed that helps us avoid accidentally triggering echo(1) options like -n.
-Xsed="$SED -e s/^X//"
+Xsed="$SED -e 1s/^X//"
# The HP-UX ksh and POSIX shell print the target directory to stdout
# if CDPATH is set.
-if test "X\${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
# The names of the tagged configurations supported by this script.
available_tags=
@@ -8760,6 +9461,12 @@ fast_install=$enable_fast_install
# The host system.
host_alias=$host_alias
host=$host
+host_os=$host_os
+
+# The build system.
+build_alias=$build_alias
+build=$build
+build_os=$build_os
# An echo program that does not interpret backslashes.
echo=$lt_echo
@@ -8771,6 +9478,9 @@ AR_FLAGS=$lt_AR_FLAGS
# A C compiler.
LTCC=$lt_LTCC
+# LTCC compiler flags.
+LTCFLAGS=$lt_LTCFLAGS
+
# A language-specific compiler.
CC=$lt_compiler
@@ -8790,7 +9500,7 @@ LN_S=$lt_LN_S
NM=$lt_NM
# A symbol stripping program
-STRIP=$STRIP
+STRIP=$lt_STRIP
# Used to examine libraries when file_magic_cmd begins "file"
MAGIC_CMD=$MAGIC_CMD
@@ -8821,7 +9531,7 @@ objext="$ac_objext"
libext="$libext"
# Shared library suffix (normally ".so").
-shrext='$shrext'
+shrext_cmds='$shrext_cmds'
# Executable file suffix (normally "").
exeext="$exeext"
@@ -8836,7 +9546,7 @@ max_cmd_len=$lt_cv_sys_max_cmd_len
# Does compiler simultaneously support -c and -o options?
compiler_c_o=$lt_lt_cv_prog_compiler_c_o
-# Must we lock files when doing compilation ?
+# Must we lock files when doing compilation?
need_locks=$lt_need_locks
# Do we need the lib prefix for modules?
@@ -9063,7 +9773,10 @@ else
# If there is no Makefile yet, we rely on a make rule to execute
# `config.status --recheck' to rerun these tests and create the
# libtool script then.
- test -f Makefile && make "$ltmain"
+ ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'`
+ if test -f "$ltmain_in"; then
+ test -f Makefile && make "$ltmain"
+ fi
fi
@@ -9098,6 +9811,9 @@ echo "$as_me: WARNING: output file \`$ofile' does not look like a libtool script
echo "$as_me: WARNING: using \`LTCC=$LTCC', extracted from \`$ofile'" >&2;}
fi
fi
+ if test -z "$LTCFLAGS"; then
+ eval "`$SHELL ${ofile} --config | grep '^LTCFLAGS='`"
+ fi
# Extract list of available tagged configurations in $ofile.
# Note that this assumes the entire list is on one line.
@@ -9128,7 +9844,9 @@ echo "$as_me: error: tag name \"$tagname\" already exists" >&2;}
case $tagname in
CXX)
- if test -n "$CXX" && test "X$CXX" != "Xno"; then
+ if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
+ ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
+ (test "X$CXX" != "Xg++"))) ; then
ac_ext=cc
ac_cpp='$CXXCPP $CPPFLAGS'
ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -9148,6 +9866,7 @@ hardcode_libdir_flag_spec_CXX=
hardcode_libdir_flag_spec_ld_CXX=
hardcode_libdir_separator_CXX=
hardcode_minus_L_CXX=no
+hardcode_shlibpath_var_CXX=unsupported
hardcode_automatic_CXX=no
module_cmds_CXX=
module_expsym_cmds_CXX=
@@ -9165,7 +9884,7 @@ postdeps_CXX=
compiler_lib_search_path_CXX=
# Source file extension for C++ test sources.
-ac_ext=cc
+ac_ext=cpp
# Object file extension for compiled C++ test sources.
objext=o
@@ -9175,17 +9894,34 @@ objext_CXX=$objext
lt_simple_compile_test_code="int some_variable = 0;\n"
# Code to be used in simple link tests
-lt_simple_link_test_code='int main(int, char *) { return(0); }\n'
+lt_simple_link_test_code='int main(int, char *[]) { return(0); }\n'
# ltmain only uses $CC for tagged configurations so make sure $CC is set.
# If no C compiler was specified, use CC.
LTCC=${LTCC-"$CC"}
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
# Allow CC to be a program name with arguments.
compiler=$CC
+# save warnings/boilerplate of simple test code
+ac_outfile=conftest.$ac_objext
+printf "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$rm conftest*
+
+ac_outfile=conftest.$ac_objext
+printf "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$rm conftest*
+
+
# Allow CC to be a program name with arguments.
lt_save_CC=$CC
lt_save_LD=$LD
@@ -9196,18 +9932,27 @@ lt_save_path_LD=$lt_cv_path_LD
if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
else
- unset lt_cv_prog_gnu_ld
+ $as_unset lt_cv_prog_gnu_ld
fi
if test -n "${lt_cv_path_LDCXX+set}"; then
lt_cv_path_LD=$lt_cv_path_LDCXX
else
- unset lt_cv_path_LD
+ $as_unset lt_cv_path_LD
fi
test -z "${LDCXX+set}" || LD=$LDCXX
CC=${CXX-"c++"}
compiler=$CC
compiler_CXX=$CC
-cc_basename=`$echo X"$compiler" | $Xsed -e 's%^.*/%%'`
+for cc_temp in $compiler""; do
+ case $cc_temp in
+ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+done
+cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
+
# We don't want -fno-exception wen compiling C++ code, so set the
# no_builtin_flag separately
@@ -9244,7 +9989,7 @@ echo $ECHO_N "checking for ld used by $CC... $ECHO_C" >&6
# Accept absolute paths.
[\\/]* | ?:[\\/]*)
re_direlt='/[^/][^/]*/\.\./'
- # Canonicalize the path of ld
+ # Canonicalize the pathname of ld
ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'`
while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"`
@@ -9278,7 +10023,7 @@ else
if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
lt_cv_path_LD="$ac_dir/$ac_prog"
# Check to see if the program is GNU ld. I'd rather use --version,
- # but apparently some GNU ld's only accept -v.
+ # but apparently some variants of GNU ld only accept -v.
# Break only if it was the GNU/non-GNU ld that we prefer.
case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
*GNU* | *'with BFD'*)
@@ -9312,7 +10057,7 @@ echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6
if test "${lt_cv_prog_gnu_ld+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
- # I'd rather use --version here, but apparently some GNU ld's only accept -v.
+ # I'd rather use --version here, but apparently some GNU lds only accept -v.
case `$LD -v 2>&1 </dev/null` in
*GNU* | *'with BFD'*)
lt_cv_prog_gnu_ld=yes
@@ -9403,6 +10148,7 @@ case $host_os in
;;
esac
done
+ ;;
esac
exp_sym_flag='-bexport'
@@ -9421,7 +10167,7 @@ case $host_os in
link_all_deplibs_CXX=yes
if test "$GXX" = yes; then
- case $host_os in aix4.012|aix4.012.*)
+ case $host_os in aix4.[012]|aix4.[012].*)
# We only want to do this on AIX 4.2 and lower, the check
# below for broken collect2 doesn't work under 4.3+
collect2name=`${CC} -print-prog-name=collect2`
@@ -9440,8 +10186,12 @@ case $host_os in
hardcode_libdir_flag_spec_CXX='-L$libdir'
hardcode_libdir_separator_CXX=
fi
+ ;;
esac
shared_flag='-shared'
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag="$shared_flag "'${wl}-G'
+ fi
else
# not using gcc
if test "$host_cpu" = ia64; then
@@ -9466,7 +10216,6 @@ case $host_os in
allow_undefined_flag_CXX='-berok'
# Determine the default libpath from the value encoded in an empty executable.
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -9483,11 +10232,20 @@ main ()
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
+ (eval $ac_link) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest$ac_exeext'
+ { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -9504,21 +10262,21 @@ else
sed 's/^/| /' conftest.$ac_ext >&5
fi
-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath"
- archive_expsym_cmds_CXX="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+ archive_expsym_cmds_CXX="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
else
if test "$host_cpu" = ia64; then
hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib'
allow_undefined_flag_CXX="-z nodefs"
- archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"
+ archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
else
# Determine the default libpath from the value encoded in an empty executable.
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -9535,11 +10293,20 @@ main ()
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
+ (eval $ac_link) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest$ac_exeext'
+ { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -9556,7 +10323,8 @@ else
sed 's/^/| /' conftest.$ac_ext >&5
fi
-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath"
@@ -9564,16 +10332,26 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
# -berok will link without error, but may produce a broken library.
no_undefined_flag_CXX=' ${wl}-bernotok'
allow_undefined_flag_CXX=' ${wl}-berok'
- # -bexpall does not export symbols beginning with underscore (_)
- always_export_symbols_CXX=yes
# Exported symbols can be pulled into shared objects from archives
- whole_archive_flag_spec_CXX=' '
+ whole_archive_flag_spec_CXX='$convenience'
archive_cmds_need_lc_CXX=yes
- # This is similar to how AIX traditionally builds it's shared libraries.
- archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+ # This is similar to how AIX traditionally builds its shared libraries.
+ archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
fi
fi
;;
+
+ beos*)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ allow_undefined_flag_CXX=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ else
+ ld_shlibs_CXX=no
+ fi
+ ;;
+
chorus*)
case $cc_basename in
*)
@@ -9592,7 +10370,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
enable_shared_with_static_runtimes_CXX=yes
if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
- archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib'
+ archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
# If the export-symbols file already is a .def file (1st line
# is EXPORTS), use it as is; otherwise, prepend...
archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
@@ -9601,57 +10379,81 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
echo EXPORTS > $output_objdir/$soname.def;
cat $export_symbols >> $output_objdir/$soname.def;
fi~
- $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib'
+ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
else
ld_shlibs_CXX=no
fi
;;
-
- darwin* | rhapsody*)
- if $CC -v 2>&1 | grep 'Apple' >/dev/null ; then
- archive_cmds_need_lc_CXX=no
- case "$host_os" in
- rhapsody* | darwin1.[012])
- allow_undefined_flag_CXX='-undefined suppress'
- ;;
- *) # Darwin 1.3 on
- test -z ${LD_TWOLEVEL_NAMESPACE} && allow_undefined_flag_CXX='-flat_namespace -undefined suppress'
- ;;
- esac
- lt_int_apple_cc_single_mod=no
- output_verbose_link_cmd='echo'
- if $CC -dumpspecs 2>&1 | grep 'single_module' >/dev/null ; then
- lt_int_apple_cc_single_mod=yes
- fi
- if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
- archive_cmds_CXX='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
- else
- archive_cmds_CXX='$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+ darwin* | rhapsody*)
+ case $host_os in
+ rhapsody* | darwin1.[012])
+ allow_undefined_flag_CXX='${wl}-undefined ${wl}suppress'
+ ;;
+ *) # Darwin 1.3 on
+ if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then
+ allow_undefined_flag_CXX='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
+ else
+ case ${MACOSX_DEPLOYMENT_TARGET} in
+ 10.[012])
+ allow_undefined_flag_CXX='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
+ ;;
+ 10.*)
+ allow_undefined_flag_CXX='${wl}-undefined ${wl}dynamic_lookup'
+ ;;
+ esac
+ fi
+ ;;
+ esac
+ archive_cmds_need_lc_CXX=no
+ hardcode_direct_CXX=no
+ hardcode_automatic_CXX=yes
+ hardcode_shlibpath_var_CXX=unsupported
+ whole_archive_flag_spec_CXX=''
+ link_all_deplibs_CXX=yes
+
+ if test "$GXX" = yes ; then
+ lt_int_apple_cc_single_mod=no
+ output_verbose_link_cmd='echo'
+ if $CC -dumpspecs 2>&1 | $EGREP 'single_module' >/dev/null ; then
+ lt_int_apple_cc_single_mod=yes
fi
- module_cmds_CXX='$CC -bundle ${wl}-bind_at_load $allow_undefined_flag -o $lib $libobjs $deplibs$compiler_flags'
-
- # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's
if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
- archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ archive_cmds_CXX='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
else
- archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ archive_cmds_CXX='$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+ fi
+ module_cmds_CXX='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+ # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
+ if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
+ archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ else
+ archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ fi
+ module_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ else
+ case $cc_basename in
+ xlc*)
+ output_verbose_link_cmd='echo'
+ archive_cmds_CXX='$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring'
+ module_cmds_CXX='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+ # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
+ archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ module_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ ;;
+ *)
+ ld_shlibs_CXX=no
+ ;;
+ esac
fi
- module_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -bundle $allow_undefined_flag -o $lib $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
- hardcode_direct_CXX=no
- hardcode_automatic_CXX=yes
- hardcode_shlibpath_var_CXX=unsupported
- whole_archive_flag_spec_CXX='-all_load $convenience'
- link_all_deplibs_CXX=yes
- fi
- ;;
+ ;;
dgux*)
case $cc_basename in
- ec++)
+ ec++*)
# FIXME: insert proper C++ library support
ld_shlibs_CXX=no
;;
- ghcx)
+ ghcx*)
# Green Hills C++ Compiler
# FIXME: insert proper C++ library support
ld_shlibs_CXX=no
@@ -9662,14 +10464,14 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
;;
esac
;;
- freebsd12*)
+ freebsd[12]*)
# C++ shared libraries reported to be fairly broken before switch to ELF
ld_shlibs_CXX=no
;;
freebsd-elf*)
archive_cmds_need_lc_CXX=no
;;
- freebsd*)
+ freebsd* | kfreebsd*-gnu | dragonfly*)
# FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
# conventions
ld_shlibs_CXX=yes
@@ -9686,11 +10488,11 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
# location of the library.
case $cc_basename in
- CC)
+ CC*)
# FIXME: insert proper C++ library support
ld_shlibs_CXX=no
;;
- aCC)
+ aCC*)
archive_cmds_CXX='$rm $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
# Commands to make compiler produce verbose output that lists
# what "hidden" libraries, object files and flags are used when
@@ -9700,7 +10502,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
# explicitly linking system object files so we need to strip them
# from the output so that they don't get included in the library
# dependencies.
- output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | egrep "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "[-]L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
;;
*)
if test "$GXX" = yes; then
@@ -9714,33 +10516,22 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
;;
hpux10*|hpux11*)
if test $with_gnu_ld = no; then
- case "$host_cpu" in
- hppa*64*)
- hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir'
+ hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator_CXX=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
hardcode_libdir_flag_spec_ld_CXX='+b $libdir'
- hardcode_libdir_separator_CXX=:
- ;;
- ia64*)
- hardcode_libdir_flag_spec_CXX='-L$libdir'
;;
*)
- hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir'
- hardcode_libdir_separator_CXX=:
export_dynamic_flag_spec_CXX='${wl}-E'
;;
esac
fi
- case "$host_cpu" in
- hppa*64*)
- hardcode_direct_CXX=no
- hardcode_shlibpath_var_CXX=no
- ;;
- ia64*)
+ case $host_cpu in
+ hppa*64*|ia64*)
hardcode_direct_CXX=no
hardcode_shlibpath_var_CXX=no
- hardcode_minus_L_CXX=yes # Not in the search PATH,
- # but as the default
- # location of the library.
;;
*)
hardcode_direct_CXX=yes
@@ -9751,14 +10542,17 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
esac
case $cc_basename in
- CC)
+ CC*)
# FIXME: insert proper C++ library support
ld_shlibs_CXX=no
;;
- aCC)
- case "$host_cpu" in
- hppa*64*|ia64*)
- archive_cmds_CXX='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs'
+ aCC*)
+ case $host_cpu in
+ hppa*64*)
+ archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ ia64*)
+ archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
*)
archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
@@ -9777,9 +10571,12 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
*)
if test "$GXX" = yes; then
if test $with_gnu_ld = no; then
- case "$host_cpu" in
- ia64*|hppa*64*)
- archive_cmds_CXX='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs'
+ case $host_cpu in
+ hppa*64*)
+ archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ ia64*)
+ archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
;;
*)
archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
@@ -9793,11 +10590,25 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
;;
esac
;;
+ interix3*)
+ hardcode_direct_CXX=no
+ hardcode_shlibpath_var_CXX=no
+ hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+ export_dynamic_flag_spec_CXX='${wl}-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ archive_expsym_cmds_CXX='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
irix5* | irix6*)
case $cc_basename in
- CC)
+ CC*)
# SGI C++
- archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib'
+ archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
# Archives containing C++ object files must be created using
# "CC -ar", where "CC" is the IRIX C++ compiler. This is
@@ -9808,7 +10619,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
*)
if test "$GXX" = yes; then
if test "$with_gnu_ld" = no; then
- archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib'
+ archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
else
archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` -o $lib'
fi
@@ -9821,7 +10632,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
;;
linux*)
case $cc_basename in
- KCC)
+ KCC*)
# Kuck and Associates, Inc. (KAI) C++ Compiler
# KCC will only create a shared library if the output file
@@ -9846,17 +10657,41 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
# "CC -Bstatic", where "CC" is the KAI C++ compiler.
old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs'
;;
- icpc)
+ icpc*)
# Intel C++
with_gnu_ld=yes
+ # version 8.0 and above of icpc choke on multiply defined symbols
+ # if we add $predep_objects and $postdep_objects, however 7.1 and
+ # earlier do not add the objects themselves.
+ case `$CC -V 2>&1` in
+ *"Version 7."*)
+ archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ *) # Version 8.0 or newer
+ tmp_idyn=
+ case $host_cpu in
+ ia64*) tmp_idyn=' -i_dynamic';;
+ esac
+ archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ esac
archive_cmds_need_lc_CXX=no
- archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
;;
- cxx)
+ pgCC*)
+ # Portland Group C++ compiler
+ archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+ archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+
+ hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir'
+ export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+ whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
+ ;;
+ cxx*)
# Compaq C++
archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols'
@@ -9887,7 +10722,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
;;
mvs*)
case $cc_basename in
- cxx)
+ cxx*)
# FIXME: insert proper C++ library support
ld_shlibs_CXX=no
;;
@@ -9897,7 +10732,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
;;
esac
;;
- netbsd*)
+ netbsd* | netbsdelf*-gnu | knetbsd*-gnu)
if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
wlarc=
@@ -9908,9 +10743,25 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
# Workaround some broken pre-1.5 toolchains
output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'
;;
+ openbsd2*)
+ # C++ shared libraries are fairly broken
+ ld_shlibs_CXX=no
+ ;;
+ openbsd*)
+ hardcode_direct_CXX=yes
+ hardcode_shlibpath_var_CXX=no
+ archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+ hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'
+ export_dynamic_flag_spec_CXX='${wl}-E'
+ whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ fi
+ output_verbose_link_cmd='echo'
+ ;;
osf3*)
case $cc_basename in
- KCC)
+ KCC*)
# Kuck and Associates, Inc. (KAI) C++ Compiler
# KCC will only create a shared library if the output file
@@ -9926,14 +10777,14 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs'
;;
- RCC)
+ RCC*)
# Rational C++ 2.4.1
# FIXME: insert proper C++ library support
ld_shlibs_CXX=no
;;
- cxx)
+ cxx*)
allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*'
- archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && echo ${wl}-set_version $verstring` -update_registry ${objdir}/so_locations -o $lib'
+ archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && echo ${wl}-set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
hardcode_libdir_separator_CXX=:
@@ -9951,7 +10802,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
*)
if test "$GXX" = yes && test "$with_gnu_ld" = no; then
allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*'
- archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib'
+ archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
hardcode_libdir_separator_CXX=:
@@ -9970,7 +10821,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
;;
osf4* | osf5*)
case $cc_basename in
- KCC)
+ KCC*)
# Kuck and Associates, Inc. (KAI) C++ Compiler
# KCC will only create a shared library if the output file
@@ -9985,17 +10836,17 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
# the KAI C++ compiler.
old_archive_cmds_CXX='$CC -o $oldlib $oldobjs'
;;
- RCC)
+ RCC*)
# Rational C++ 2.4.1
# FIXME: insert proper C++ library support
ld_shlibs_CXX=no
;;
- cxx)
+ cxx*)
allow_undefined_flag_CXX=' -expect_unresolved \*'
- archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib'
+ archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
echo "-hidden">> $lib.exp~
- $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname -Wl,-input -Wl,$lib.exp `test -n "$verstring" && echo -set_version $verstring` -update_registry $objdir/so_locations -o $lib~
+ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname -Wl,-input -Wl,$lib.exp `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~
$rm $lib.exp'
hardcode_libdir_flag_spec_CXX='-rpath $libdir'
@@ -10014,7 +10865,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
*)
if test "$GXX" = yes && test "$with_gnu_ld" = no; then
allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*'
- archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib'
+ archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
hardcode_libdir_separator_CXX=:
@@ -10035,27 +10886,14 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
# FIXME: insert proper C++ library support
ld_shlibs_CXX=no
;;
- sco*)
- archive_cmds_need_lc_CXX=no
- case $cc_basename in
- CC)
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- *)
- # FIXME: insert proper C++ library support
- ld_shlibs_CXX=no
- ;;
- esac
- ;;
sunos4*)
case $cc_basename in
- CC)
+ CC*)
# Sun C++ 4.x
# FIXME: insert proper C++ library support
ld_shlibs_CXX=no
;;
- lcc)
+ lcc*)
# Lucid
# FIXME: insert proper C++ library support
ld_shlibs_CXX=no
@@ -10068,36 +10906,33 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
;;
solaris*)
case $cc_basename in
- CC)
+ CC*)
# Sun C++ 4.2, 5.x and Centerline C++
+ archive_cmds_need_lc_CXX=yes
no_undefined_flag_CXX=' -zdefs'
- archive_cmds_CXX='$CC -G${allow_undefined_flag} -nolib -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
- $CC -G${allow_undefined_flag} -nolib ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp'
+ $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp'
hardcode_libdir_flag_spec_CXX='-R$libdir'
hardcode_shlibpath_var_CXX=no
case $host_os in
- solaris2.0-5 | solaris2.0-5.*) ;;
+ solaris2.[0-5] | solaris2.[0-5].*) ;;
*)
# The C++ compiler is used as linker so we must use $wl
# flag to pass the commands to the underlying system
- # linker.
+ # linker. We must also pass each convience library through
+ # to the system linker between allextract/defaultextract.
+ # The C++ compiler will combine linker options so we
+ # cannot just pass the convience library names through
+ # without $wl.
# Supported since Solaris 2.6 (maybe 2.5.1?)
- whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+ whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract'
;;
esac
link_all_deplibs_CXX=yes
- # Commands to make compiler produce verbose output that lists
- # what "hidden" libraries, object files and flags are used when
- # linking a shared library.
- #
- # There doesn't appear to be a way to prevent this compiler from
- # explicitly linking system object files so we need to strip them
- # from the output so that they don't get included in the library
- # dependencies.
- output_verbose_link_cmd='templist=`$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep "\-[LR]"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+ output_verbose_link_cmd='echo'
# Archives containing C++ object files must be created using
# "CC -xar", where "CC" is the Sun C++ compiler. This is
@@ -10105,7 +10940,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
# in the archive.
old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs'
;;
- gcx)
+ gcx*)
# Green Hills C++ Compiler
archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
@@ -10143,12 +10978,63 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
;;
esac
;;
- sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[78]* | unixware7*)
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+ no_undefined_flag_CXX='${wl}-z,text'
archive_cmds_need_lc_CXX=no
+ hardcode_shlibpath_var_CXX=no
+ runpath_var='LD_RUN_PATH'
+
+ case $cc_basename in
+ CC*)
+ archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ ;;
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We can NOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ # For security reasons, it is highly recommended that you always
+ # use absolute paths for naming shared libraries, and exclude the
+ # DT_RUNPATH tag from executables and libraries. But doing so
+ # requires that you compile everything twice, which is a pain.
+ # So that behaviour is only enabled if SCOABSPATH is set to a
+ # non-empty value in the environment. Most likely only useful for
+ # creating official distributions of packages.
+ # This is a hack until libtool officially supports absolute path
+ # names for shared libraries.
+ no_undefined_flag_CXX='${wl}-z,text'
+ allow_undefined_flag_CXX='${wl}-z,nodefs'
+ archive_cmds_need_lc_CXX=no
+ hardcode_shlibpath_var_CXX=no
+ hardcode_libdir_flag_spec_CXX='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
+ hardcode_libdir_separator_CXX=':'
+ link_all_deplibs_CXX=yes
+ export_dynamic_flag_spec_CXX='${wl}-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ case $cc_basename in
+ CC*)
+ archive_cmds_CXX='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ archive_cmds_CXX='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
;;
tandem*)
case $cc_basename in
- NCC)
+ NCC*)
# NonStop-UX NCC 3.20
# FIXME: insert proper C++ library support
ld_shlibs_CXX=no
@@ -10201,7 +11087,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
# The `*' in the case matches for architectures that use `case' in
# $output_verbose_cmd can trigger glob expansion during the loop
# eval without this substitution.
- output_verbose_link_cmd="`$echo \"X$output_verbose_link_cmd\" | $Xsed -e \"$no_glob_subst\"`"
+ output_verbose_link_cmd=`$echo "X$output_verbose_link_cmd" | $Xsed -e "$no_glob_subst"`
for p in `eval $output_verbose_link_cmd`; do
case $p in
@@ -10277,6 +11163,29 @@ fi
$rm -f confest.$objext
+# PORTME: override above test on systems where it is broken
+case $host_os in
+interix3*)
+ # Interix 3.5 installs completely hosed .la files for C++, so rather than
+ # hack all around it, let's just trust "g++" to DTRT.
+ predep_objects_CXX=
+ postdep_objects_CXX=
+ postdeps_CXX=
+ ;;
+
+solaris*)
+ case $cc_basename in
+ CC*)
+ # Adding this requires a known-good setup of shared libraries for
+ # Sun compiler versions before 5.6, else PIC objects from an old
+ # archive will be linked into the output, leading to subtle bugs.
+ postdeps_CXX='-lCstd -lCrun'
+ ;;
+ esac
+ ;;
+esac
+
+
case " $postdeps_CXX " in
*" -lc "*) archive_cmds_need_lc_CXX=no ;;
esac
@@ -10324,6 +11233,10 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6
# DJGPP does not support shared libraries at all
lt_prog_compiler_pic_CXX=
;;
+ interix3*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
sysv4*MP*)
if test -d /usr/nec; then
lt_prog_compiler_pic_CXX=-Kconform_pic
@@ -10332,7 +11245,7 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6
hpux*)
# PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
# not for PA HP-UX.
- case "$host_cpu" in
+ case $host_cpu in
hppa*64*|ia64*)
;;
*)
@@ -10357,18 +11270,28 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6
;;
chorus*)
case $cc_basename in
- cxch68)
+ cxch68*)
# Green Hills C++ Compiler
# _LT_AC_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"
;;
esac
;;
+ darwin*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ case $cc_basename in
+ xlc*)
+ lt_prog_compiler_pic_CXX='-qnocommon'
+ lt_prog_compiler_wl_CXX='-Wl,'
+ ;;
+ esac
+ ;;
dgux*)
case $cc_basename in
- ec++)
+ ec++*)
lt_prog_compiler_pic_CXX='-KPIC'
;;
- ghcx)
+ ghcx*)
# Green Hills C++ Compiler
lt_prog_compiler_pic_CXX='-pic'
;;
@@ -10376,22 +11299,22 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6
;;
esac
;;
- freebsd*)
+ freebsd* | kfreebsd*-gnu | dragonfly*)
# FreeBSD uses GNU C++
;;
hpux9* | hpux10* | hpux11*)
case $cc_basename in
- CC)
+ CC*)
lt_prog_compiler_wl_CXX='-Wl,'
- lt_prog_compiler_static_CXX="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive"
+ lt_prog_compiler_static_CXX='${wl}-a ${wl}archive'
if test "$host_cpu" != ia64; then
lt_prog_compiler_pic_CXX='+Z'
fi
;;
- aCC)
+ aCC*)
lt_prog_compiler_wl_CXX='-Wl,'
- lt_prog_compiler_static_CXX="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive"
- case "$host_cpu" in
+ lt_prog_compiler_static_CXX='${wl}-a ${wl}archive'
+ case $host_cpu in
hppa*64*|ia64*)
# +Z the default
;;
@@ -10404,9 +11327,13 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6
;;
esac
;;
+ interix*)
+ # This is c89, which is MS Visual C++ (no shared libs)
+ # Anyone wants to do a port?
+ ;;
irix5* | irix6* | nonstopux*)
case $cc_basename in
- CC)
+ CC*)
lt_prog_compiler_wl_CXX='-Wl,'
lt_prog_compiler_static_CXX='-non_shared'
# CC pic flag -KPIC is the default.
@@ -10417,18 +11344,24 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6
;;
linux*)
case $cc_basename in
- KCC)
+ KCC*)
# KAI C++ Compiler
lt_prog_compiler_wl_CXX='--backend -Wl,'
lt_prog_compiler_pic_CXX='-fPIC'
;;
- icpc)
+ icpc* | ecpc*)
# Intel C++
lt_prog_compiler_wl_CXX='-Wl,'
lt_prog_compiler_pic_CXX='-KPIC'
lt_prog_compiler_static_CXX='-static'
;;
- cxx)
+ pgCC*)
+ # Portland Group C++ compiler.
+ lt_prog_compiler_wl_CXX='-Wl,'
+ lt_prog_compiler_pic_CXX='-fpic'
+ lt_prog_compiler_static_CXX='-Bstatic'
+ ;;
+ cxx*)
# Compaq C++
# Make sure the PIC flag is empty. It appears that all Alpha
# Linux and Compaq Tru64 Unix objects are PIC.
@@ -10445,25 +11378,25 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6
;;
mvs*)
case $cc_basename in
- cxx)
+ cxx*)
lt_prog_compiler_pic_CXX='-W c,exportall'
;;
*)
;;
esac
;;
- netbsd*)
+ netbsd* | netbsdelf*-gnu | knetbsd*-gnu)
;;
osf3* | osf4* | osf5*)
case $cc_basename in
- KCC)
+ KCC*)
lt_prog_compiler_wl_CXX='--backend -Wl,'
;;
- RCC)
+ RCC*)
# Rational C++ 2.4.1
lt_prog_compiler_pic_CXX='-pic'
;;
- cxx)
+ cxx*)
# Digital/Compaq C++
lt_prog_compiler_wl_CXX='-Wl,'
# Make sure the PIC flag is empty. It appears that all Alpha
@@ -10477,24 +11410,15 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6
;;
psos*)
;;
- sco*)
- case $cc_basename in
- CC)
- lt_prog_compiler_pic_CXX='-fPIC'
- ;;
- *)
- ;;
- esac
- ;;
solaris*)
case $cc_basename in
- CC)
+ CC*)
# Sun C++ 4.2, 5.x and Centerline C++
lt_prog_compiler_pic_CXX='-KPIC'
lt_prog_compiler_static_CXX='-Bstatic'
lt_prog_compiler_wl_CXX='-Qoption ld '
;;
- gcx)
+ gcx*)
# Green Hills C++ Compiler
lt_prog_compiler_pic_CXX='-PIC'
;;
@@ -10504,12 +11428,12 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6
;;
sunos4*)
case $cc_basename in
- CC)
+ CC*)
# Sun C++ 4.x
lt_prog_compiler_pic_CXX='-pic'
lt_prog_compiler_static_CXX='-Bstatic'
;;
- lcc)
+ lcc*)
# Lucid
lt_prog_compiler_pic_CXX='-pic'
;;
@@ -10519,7 +11443,7 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6
;;
tandem*)
case $cc_basename in
- NCC)
+ NCC*)
# NonStop-UX NCC 3.20
lt_prog_compiler_pic_CXX='-KPIC'
;;
@@ -10527,7 +11451,14 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6
;;
esac
;;
- unixware*)
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ case $cc_basename in
+ CC*)
+ lt_prog_compiler_wl_CXX='-Wl,'
+ lt_prog_compiler_pic_CXX='-KPIC'
+ lt_prog_compiler_static_CXX='-Bstatic'
+ ;;
+ esac
;;
vxworks*)
;;
@@ -10544,7 +11475,8 @@ echo "${ECHO_T}$lt_prog_compiler_pic_CXX" >&6
# Check to make sure the PIC flag actually works.
#
if test -n "$lt_prog_compiler_pic_CXX"; then
- echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5
+
+echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5
echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... $ECHO_C" >&6
if test "${lt_prog_compiler_pic_works_CXX+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -10559,18 +11491,20 @@ else
# with a dollar sign (not a hyphen), so the echo should work correctly.
# The option is referenced via a variable to avoid confusing sed.
lt_compile=`echo "$ac_compile" | $SED \
- -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:10565: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:11497: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:10569: \$? = $ac_status" >&5
+ echo "$as_me:11501: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
- # So say no if there are warnings
- if test ! -s conftest.err; then
+ # So say no if there are warnings other than the usual output.
+ $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
lt_prog_compiler_pic_works_CXX=yes
fi
fi
@@ -10591,7 +11525,7 @@ else
fi
fi
-case "$host_os" in
+case $host_os in
# For platforms which do not support PIC, -DPIC is meaningless:
*djgpp*)
lt_prog_compiler_pic_CXX=
@@ -10601,6 +11535,48 @@ case "$host_os" in
;;
esac
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\"
+echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6
+if test "${lt_prog_compiler_static_works_CXX+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ lt_prog_compiler_static_works_CXX=no
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+ printf "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ lt_prog_compiler_static_works_CXX=yes
+ fi
+ else
+ lt_prog_compiler_static_works_CXX=yes
+ fi
+ fi
+ $rm conftest*
+ LDFLAGS="$save_LDFLAGS"
+
+fi
+echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works_CXX" >&5
+echo "${ECHO_T}$lt_prog_compiler_static_works_CXX" >&6
+
+if test x"$lt_prog_compiler_static_works_CXX" = xyes; then
+ :
+else
+ lt_prog_compiler_static_CXX=
+fi
+
+
echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5
echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6
if test "${lt_cv_prog_compiler_c_o_CXX+set}" = set; then
@@ -10613,38 +11589,36 @@ else
mkdir out
printf "$lt_simple_compile_test_code" > conftest.$ac_ext
- # According to Tom Tromey, Ian Lance Taylor reported there are C compilers
- # that will create temporary files in the current directory regardless of
- # the output directory. Thus, making CWD read-only will cause this test
- # to fail, enabling locking or at least warning the user not to do parallel
- # builds.
- chmod -w .
-
lt_compiler_flag="-o out/conftest2.$ac_objext"
# Insert the option either (1) after the last *FLAGS variable, or
# (2) before a word containing "conftest.", or (3) at the end.
# Note that $ac_compile itself does not contain backslashes and begins
# with a dollar sign (not a hyphen), so the echo should work correctly.
lt_compile=`echo "$ac_compile" | $SED \
- -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:10632: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:11601: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:10636: \$? = $ac_status" >&5
+ echo "$as_me:11605: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings
- if test ! -s out/conftest.err; then
+ $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
lt_cv_prog_compiler_c_o_CXX=yes
fi
fi
- chmod u+w .
- $rm conftest* out/*
- rmdir out
+ chmod u+w . 2>&5
+ $rm conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files
+ $rm out/* && rmdir out
cd ..
rmdir conftest
$rm conftest*
@@ -10694,7 +11668,13 @@ echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared librar
export_symbols_cmds_CXX="$ltdll_cmds"
;;
cygwin* | mingw*)
- export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols'
+ export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS] /s/.* \([^ ]*\)/\1 DATA/;/^.* __nm__/s/^.* __nm__\([^ ]*\) [^ ]*/\1 DATA/;/^I /d;/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols'
+ ;;
+ kfreebsd*-gnu)
+ link_all_deplibs_CXX=no
+ ;;
+ linux*)
+ link_all_deplibs_CXX=no
;;
*)
export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
@@ -10705,11 +11685,6 @@ echo "$as_me:$LINENO: result: $ld_shlibs_CXX" >&5
echo "${ECHO_T}$ld_shlibs_CXX" >&6
test "$ld_shlibs_CXX" = no && can_build_shared=no
-variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
-if test "$GCC" = yes; then
- variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
-fi
-
#
# Do we need to explicitly link libc?
#
@@ -10742,6 +11717,7 @@ echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&
libobjs=conftest.$ac_objext
deplibs=
wl=$lt_prog_compiler_wl_CXX
+ pic_flag=$lt_prog_compiler_pic_CXX
compiler_flags=-v
linker_flags=-v
verstring=
@@ -10772,78 +11748,12 @@ echo "${ECHO_T}$archive_cmds_need_lc_CXX" >&6
;;
esac
-echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5
-echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6
-hardcode_action_CXX=
-if test -n "$hardcode_libdir_flag_spec_CXX" || \
- test -n "$runpath_var CXX" || \
- test "X$hardcode_automatic_CXX"="Xyes" ; then
-
- # We can hardcode non-existant directories.
- if test "$hardcode_direct_CXX" != no &&
- # If the only mechanism to avoid hardcoding is shlibpath_var, we
- # have to relink, otherwise we might link with an installed library
- # when we should be linking with a yet-to-be-installed one
- ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, CXX)" != no &&
- test "$hardcode_minus_L_CXX" != no; then
- # Linking always hardcodes the temporary library directory.
- hardcode_action_CXX=relink
- else
- # We can link without hardcoding, and we can hardcode nonexisting dirs.
- hardcode_action_CXX=immediate
- fi
-else
- # We cannot hardcode anything, or else we can only hardcode existing
- # directories.
- hardcode_action_CXX=unsupported
-fi
-echo "$as_me:$LINENO: result: $hardcode_action_CXX" >&5
-echo "${ECHO_T}$hardcode_action_CXX" >&6
-
-if test "$hardcode_action_CXX" = relink; then
- # Fast installation is not supported
- enable_fast_install=no
-elif test "$shlibpath_overrides_runpath" = yes ||
- test "$enable_shared" = no; then
- # Fast installation is not necessary
- enable_fast_install=needless
-fi
-
-striplib=
-old_striplib=
-echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5
-echo $ECHO_N "checking whether stripping libraries is possible... $ECHO_C" >&6
-if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then
- test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
- test -z "$striplib" && striplib="$STRIP --strip-unneeded"
- echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6
-else
-# FIXME - insert some real tests, host_os isn't really good enough
- case $host_os in
- darwin*)
- if test -n "$STRIP" ; then
- striplib="$STRIP -x"
- echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6
- else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
- ;;
- *)
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
- ;;
- esac
-fi
-
echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5
echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6
library_names_spec=
libname_spec='lib$name'
soname_spec=
-shrext=".so"
+shrext_cmds=".so"
postinstall_cmds=
postuninstall_cmds=
finish_cmds=
@@ -10931,7 +11841,7 @@ aix4* | aix5*)
amigaos*)
library_names_spec='$libname.ixlibrary $libname.a'
# Create ${libname}_ixlibrary.a entries in /sys/libs.
- finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "(cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a)"; (cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a) || exit 1; done'
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
;;
beos*)
@@ -10940,7 +11850,7 @@ beos*)
shlibpath_var=LIBRARY_PATH
;;
-bsdi4*)
+bsdi[45]*)
version_type=linux
need_version=no
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
@@ -10956,7 +11866,7 @@ bsdi4*)
cygwin* | mingw* | pw32*)
version_type=windows
- shrext=".dll"
+ shrext_cmds=".dll"
need_version=no
need_lib_prefix=no
@@ -10968,7 +11878,8 @@ cygwin* | mingw* | pw32*)
dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~
dldir=$destdir/`dirname \$dlpath`~
test -d \$dldir || mkdir -p \$dldir~
- $install_prog $dir/$dlname \$dldir/$dlname'
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname'
postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
dlpath=$dir/\$dldll~
$rm \$dlpath'
@@ -10978,7 +11889,7 @@ cygwin* | mingw* | pw32*)
cygwin*)
# Cygwin DLLs use 'cyg' prefix rather than 'lib'
soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
- sys_lib_search_path_spec="/lib /lib/w32api /usr/lib /usr/local/lib"
+ sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
;;
mingw*)
# MinGW DLLs use traditional 'lib' prefix
@@ -10998,7 +11909,7 @@ cygwin* | mingw* | pw32*)
;;
pw32*)
# pw32 DLLs use 'pw' prefix rather than 'lib'
- library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/./-/g'`${versuffix}${shared_ext}'
+ library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
;;
esac
;;
@@ -11017,17 +11928,16 @@ darwin* | rhapsody*)
version_type=darwin
need_lib_prefix=no
need_version=no
- # FIXME: Relying on posixy $() will cause problems for
- # cross-compilation, but unfortunately the echo tests do not
- # yet detect zsh echo's removal of \ escapes.
library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext'
soname_spec='${libname}${release}${major}$shared_ext'
shlibpath_overrides_runpath=yes
shlibpath_var=DYLD_LIBRARY_PATH
- shrext='$(test .$module = .yes && echo .so || echo .dylib)'
+ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
# Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same.
- if $CC -v 2>&1 | grep 'Apple' >/dev/null ; then
- sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"`
+ if test "$GCC" = yes; then
+ sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"`
+ else
+ sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib'
fi
sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
;;
@@ -11045,8 +11955,29 @@ freebsd1*)
dynamic_linker=no
;;
-freebsd*)
- objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout`
+kfreebsd*-gnu)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='GNU ld.so'
+ ;;
+
+freebsd* | dragonfly*)
+ # DragonFly does not have aout. When/if they implement a new
+ # versioning mechanism, adjust this.
+ if test -x /usr/bin/objformat; then
+ objformat=`/usr/bin/objformat`
+ else
+ case $host_os in
+ freebsd[123]*) objformat=aout ;;
+ *) objformat=elf ;;
+ esac
+ fi
version_type=freebsd-$objformat
case $version_type in
freebsd-elf*)
@@ -11064,14 +11995,19 @@ freebsd*)
freebsd2*)
shlibpath_overrides_runpath=yes
;;
- freebsd3.01* | freebsdelf3.01*)
+ freebsd3.[01]* | freebsdelf3.[01]*)
shlibpath_overrides_runpath=yes
hardcode_into_libs=yes
;;
- *) # from 3.2 on
+ freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
shlibpath_overrides_runpath=no
hardcode_into_libs=yes
;;
+ freebsd*) # from 4.6 on
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
esac
;;
@@ -11091,9 +12027,9 @@ hpux9* | hpux10* | hpux11*)
version_type=sunos
need_lib_prefix=no
need_version=no
- case "$host_cpu" in
+ case $host_cpu in
ia64*)
- shrext='.so'
+ shrext_cmds='.so'
hardcode_into_libs=yes
dynamic_linker="$host_os dld.so"
shlibpath_var=LD_LIBRARY_PATH
@@ -11108,7 +12044,7 @@ hpux9* | hpux10* | hpux11*)
sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
;;
hppa*64*)
- shrext='.sl'
+ shrext_cmds='.sl'
hardcode_into_libs=yes
dynamic_linker="$host_os dld.sl"
shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
@@ -11119,7 +12055,7 @@ hpux9* | hpux10* | hpux11*)
sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
;;
*)
- shrext='.sl'
+ shrext_cmds='.sl'
dynamic_linker="$host_os dld.sl"
shlibpath_var=SHLIB_PATH
shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
@@ -11131,6 +12067,18 @@ hpux9* | hpux10* | hpux11*)
postinstall_cmds='chmod 555 $lib'
;;
+interix3*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
irix5* | irix6* | nonstopux*)
case $host_os in
nonstopux*) version_type=nonstopux ;;
@@ -11188,6 +12136,12 @@ linux*)
# before this can be enabled.
hardcode_into_libs=yes
+ # Append ld.so.conf contents to the search path
+ if test -f /etc/ld.so.conf; then
+ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
+ sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+ fi
+
# We used to test for /lib/ld.so.1 and disable shared libraries on
# powerpc, because MkLinux only supported shared libraries with the
# GNU dynamic linker. Since this was broken with cross compilers,
@@ -11195,30 +12149,30 @@ linux*)
# people can always --disable-shared, the test was removed, and we
# assume the GNU/Linux dynamic linker is in use.
dynamic_linker='GNU/Linux ld.so'
+ ;;
- # Find out which ABI we are using (multilib Linux x86_64 hack).
- libsuff=
- case "$host_cpu" in
- x86_64*|s390x*)
- echo '#line 11203 "configure"' > conftest.$ac_ext
- if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; then
- case `/usr/bin/file conftest.$ac_objext` in
- *64-bit*)
- libsuff=64
- ;;
- esac
- fi
- rm -rf conftest*
- ;;
- *)
- ;;
- esac
- sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff}"
- sys_lib_search_path_spec="/lib${libsuff} /usr/lib${libsuff} /usr/local/lib${libsuff}"
+netbsdelf*-gnu)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='NetBSD ld.elf_so'
+ ;;
+
+knetbsd*-gnu)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='GNU ld.so'
;;
netbsd*)
@@ -11230,7 +12184,7 @@ netbsd*)
finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
dynamic_linker='NetBSD (a.out) ld.so'
else
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} ${libname}${shared_ext}'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
soname_spec='${libname}${release}${shared_ext}$major'
dynamic_linker='NetBSD ld.elf_so'
fi
@@ -11246,7 +12200,7 @@ newsos6)
shlibpath_overrides_runpath=yes
;;
-nto-qnx)
+nto-qnx*)
version_type=linux
need_lib_prefix=no
need_version=no
@@ -11258,8 +12212,13 @@ nto-qnx)
openbsd*)
version_type=sunos
+ sys_lib_dlsearch_path_spec="/usr/lib"
need_lib_prefix=no
- need_version=no
+ # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+ case $host_os in
+ openbsd3.3 | openbsd3.3.*) need_version=yes ;;
+ *) need_version=no ;;
+ esac
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
shlibpath_var=LD_LIBRARY_PATH
@@ -11279,7 +12238,7 @@ openbsd*)
os2*)
libname_spec='$name'
- shrext=".dll"
+ shrext_cmds=".dll"
need_lib_prefix=no
library_names_spec='$libname${shared_ext} $libname.a'
dynamic_linker='OS/2 ld.exe'
@@ -11297,13 +12256,6 @@ osf3* | osf4* | osf5*)
sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
;;
-sco3.2v5*)
- version_type=osf
- soname_spec='${libname}${release}${shared_ext}$major'
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- ;;
-
solaris*)
version_type=linux
need_lib_prefix=no
@@ -11329,7 +12281,7 @@ sunos4*)
need_version=yes
;;
-sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+sysv4 | sysv4.3*)
version_type=linux
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
soname_spec='${libname}${release}${shared_ext}$major'
@@ -11362,6 +12314,29 @@ sysv4*MP*)
fi
;;
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ version_type=freebsd-elf
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ hardcode_into_libs=yes
+ if test "$with_gnu_ld" = yes; then
+ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+ shlibpath_overrides_runpath=no
+ else
+ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+ shlibpath_overrides_runpath=yes
+ case $host_os in
+ sco3.2v5*)
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+ ;;
+ esac
+ fi
+ sys_lib_dlsearch_path_spec='/usr/lib'
+ ;;
+
uts4*)
version_type=linux
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
@@ -11377,724 +12352,46 @@ echo "$as_me:$LINENO: result: $dynamic_linker" >&5
echo "${ECHO_T}$dynamic_linker" >&6
test "$dynamic_linker" = no && can_build_shared=no
-if test "x$enable_dlopen" != xyes; then
- enable_dlopen=unknown
- enable_dlopen_self=unknown
- enable_dlopen_self_static=unknown
-else
- lt_cv_dlopen=no
- lt_cv_dlopen_libs=
-
- case $host_os in
- beos*)
- lt_cv_dlopen="load_add_on"
- lt_cv_dlopen_libs=
- lt_cv_dlopen_self=yes
- ;;
-
- mingw* | pw32*)
- lt_cv_dlopen="LoadLibrary"
- lt_cv_dlopen_libs=
- ;;
-
- cygwin*)
- lt_cv_dlopen="dlopen"
- lt_cv_dlopen_libs=
- ;;
-
- darwin*)
- # if libdl is installed we need to link against it
- echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5
-echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6
-if test "${ac_cv_lib_dl_dlopen+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-ldl $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any gcc2 internal prototype to avoid an error. */
-#ifdef __cplusplus
-extern "C"
-#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char dlopen ();
-int
-main ()
-{
-dlopen ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_lib_dl_dlopen=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_lib_dl_dlopen=no
-fi
-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5
-echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6
-if test $ac_cv_lib_dl_dlopen = yes; then
- lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
-else
-
- lt_cv_dlopen="dyld"
- lt_cv_dlopen_libs=
- lt_cv_dlopen_self=yes
-
-fi
-
- ;;
-
- *)
- echo "$as_me:$LINENO: checking for shl_load" >&5
-echo $ECHO_N "checking for shl_load... $ECHO_C" >&6
-if test "${ac_cv_func_shl_load+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char shl_load (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-/* Override any gcc2 internal prototype to avoid an error. */
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char shl_load ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_shl_load) || defined (__stub___shl_load)
-choke me
-#else
-char (*f) () = shl_load;
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-int
-main ()
-{
-return f != shl_load;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_func_shl_load=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_func_shl_load=no
-fi
-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5
-echo "${ECHO_T}$ac_cv_func_shl_load" >&6
-if test $ac_cv_func_shl_load = yes; then
- lt_cv_dlopen="shl_load"
-else
- echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5
-echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6
-if test "${ac_cv_lib_dld_shl_load+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-ldld $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any gcc2 internal prototype to avoid an error. */
-#ifdef __cplusplus
-extern "C"
-#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char shl_load ();
-int
-main ()
-{
-shl_load ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_lib_dld_shl_load=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_lib_dld_shl_load=no
-fi
-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5
-echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6
-if test $ac_cv_lib_dld_shl_load = yes; then
- lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"
-else
- echo "$as_me:$LINENO: checking for dlopen" >&5
-echo $ECHO_N "checking for dlopen... $ECHO_C" >&6
-if test "${ac_cv_func_dlopen+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char dlopen (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-/* Override any gcc2 internal prototype to avoid an error. */
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char dlopen ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_dlopen) || defined (__stub___dlopen)
-choke me
-#else
-char (*f) () = dlopen;
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-int
-main ()
-{
-return f != dlopen;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_func_dlopen=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_func_dlopen=no
-fi
-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5
-echo "${ECHO_T}$ac_cv_func_dlopen" >&6
-if test $ac_cv_func_dlopen = yes; then
- lt_cv_dlopen="dlopen"
-else
- echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5
-echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6
-if test "${ac_cv_lib_dl_dlopen+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-ldl $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any gcc2 internal prototype to avoid an error. */
-#ifdef __cplusplus
-extern "C"
-#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char dlopen ();
-int
-main ()
-{
-dlopen ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_lib_dl_dlopen=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_lib_dl_dlopen=no
-fi
-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5
-echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6
-if test $ac_cv_lib_dl_dlopen = yes; then
- lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
-else
- echo "$as_me:$LINENO: checking for dlopen in -lsvld" >&5
-echo $ECHO_N "checking for dlopen in -lsvld... $ECHO_C" >&6
-if test "${ac_cv_lib_svld_dlopen+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lsvld $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any gcc2 internal prototype to avoid an error. */
-#ifdef __cplusplus
-extern "C"
-#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char dlopen ();
-int
-main ()
-{
-dlopen ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_lib_svld_dlopen=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_lib_svld_dlopen=no
-fi
-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_svld_dlopen" >&5
-echo "${ECHO_T}$ac_cv_lib_svld_dlopen" >&6
-if test $ac_cv_lib_svld_dlopen = yes; then
- lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"
-else
- echo "$as_me:$LINENO: checking for dld_link in -ldld" >&5
-echo $ECHO_N "checking for dld_link in -ldld... $ECHO_C" >&6
-if test "${ac_cv_lib_dld_dld_link+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-ldld $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any gcc2 internal prototype to avoid an error. */
-#ifdef __cplusplus
-extern "C"
-#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char dld_link ();
-int
-main ()
-{
-dld_link ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_lib_dld_dld_link=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_lib_dld_dld_link=no
-fi
-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_dld_dld_link" >&5
-echo "${ECHO_T}$ac_cv_lib_dld_dld_link" >&6
-if test $ac_cv_lib_dld_dld_link = yes; then
- lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"
-fi
-
-
-fi
-
-
-fi
-
-
-fi
-
-
-fi
-
-
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
fi
- ;;
- esac
+echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5
+echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6
+hardcode_action_CXX=
+if test -n "$hardcode_libdir_flag_spec_CXX" || \
+ test -n "$runpath_var_CXX" || \
+ test "X$hardcode_automatic_CXX" = "Xyes" ; then
- if test "x$lt_cv_dlopen" != xno; then
- enable_dlopen=yes
+ # We can hardcode non-existant directories.
+ if test "$hardcode_direct_CXX" != no &&
+ # If the only mechanism to avoid hardcoding is shlibpath_var, we
+ # have to relink, otherwise we might link with an installed library
+ # when we should be linking with a yet-to-be-installed one
+ ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, CXX)" != no &&
+ test "$hardcode_minus_L_CXX" != no; then
+ # Linking always hardcodes the temporary library directory.
+ hardcode_action_CXX=relink
else
- enable_dlopen=no
- fi
-
- case $lt_cv_dlopen in
- dlopen)
- save_CPPFLAGS="$CPPFLAGS"
- test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
-
- save_LDFLAGS="$LDFLAGS"
- eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
-
- save_LIBS="$LIBS"
- LIBS="$lt_cv_dlopen_libs $LIBS"
-
- echo "$as_me:$LINENO: checking whether a program can dlopen itself" >&5
-echo $ECHO_N "checking whether a program can dlopen itself... $ECHO_C" >&6
-if test "${lt_cv_dlopen_self+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test "$cross_compiling" = yes; then :
- lt_cv_dlopen_self=cross
-else
- lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
- lt_status=$lt_dlunknown
- cat > conftest.$ac_ext <<EOF
-#line 11899 "configure"
-#include "confdefs.h"
-
-#if HAVE_DLFCN_H
-#include <dlfcn.h>
-#endif
-
-#include <stdio.h>
-
-#ifdef RTLD_GLOBAL
-# define LT_DLGLOBAL RTLD_GLOBAL
-#else
-# ifdef DL_GLOBAL
-# define LT_DLGLOBAL DL_GLOBAL
-# else
-# define LT_DLGLOBAL 0
-# endif
-#endif
-
-/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
- find out it does not work in some platform. */
-#ifndef LT_DLLAZY_OR_NOW
-# ifdef RTLD_LAZY
-# define LT_DLLAZY_OR_NOW RTLD_LAZY
-# else
-# ifdef DL_LAZY
-# define LT_DLLAZY_OR_NOW DL_LAZY
-# else
-# ifdef RTLD_NOW
-# define LT_DLLAZY_OR_NOW RTLD_NOW
-# else
-# ifdef DL_NOW
-# define LT_DLLAZY_OR_NOW DL_NOW
-# else
-# define LT_DLLAZY_OR_NOW 0
-# endif
-# endif
-# endif
-# endif
-#endif
-
-#ifdef __cplusplus
-extern "C" void exit (int);
-#endif
-
-void fnord() { int i=42;}
-int main ()
-{
- void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
- int status = $lt_dlunknown;
-
- if (self)
- {
- if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
- else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
- /* dlclose (self); */
- }
-
- exit (status);
-}
-EOF
- if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then
- (./conftest; exit; ) 2>/dev/null
- lt_status=$?
- case x$lt_status in
- x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;
- x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;;
- x$lt_unknown|x*) lt_cv_dlopen_self=no ;;
- esac
- else :
- # compilation failed
- lt_cv_dlopen_self=no
+ # We can link without hardcoding, and we can hardcode nonexisting dirs.
+ hardcode_action_CXX=immediate
fi
-fi
-rm -fr conftest*
-
-
-fi
-echo "$as_me:$LINENO: result: $lt_cv_dlopen_self" >&5
-echo "${ECHO_T}$lt_cv_dlopen_self" >&6
-
- if test "x$lt_cv_dlopen_self" = xyes; then
- LDFLAGS="$LDFLAGS $link_static_flag"
- echo "$as_me:$LINENO: checking whether a statically linked program can dlopen itself" >&5
-echo $ECHO_N "checking whether a statically linked program can dlopen itself... $ECHO_C" >&6
-if test "${lt_cv_dlopen_self_static+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test "$cross_compiling" = yes; then :
- lt_cv_dlopen_self_static=cross
else
- lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
- lt_status=$lt_dlunknown
- cat > conftest.$ac_ext <<EOF
-#line 11997 "configure"
-#include "confdefs.h"
-
-#if HAVE_DLFCN_H
-#include <dlfcn.h>
-#endif
-
-#include <stdio.h>
-
-#ifdef RTLD_GLOBAL
-# define LT_DLGLOBAL RTLD_GLOBAL
-#else
-# ifdef DL_GLOBAL
-# define LT_DLGLOBAL DL_GLOBAL
-# else
-# define LT_DLGLOBAL 0
-# endif
-#endif
-
-/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
- find out it does not work in some platform. */
-#ifndef LT_DLLAZY_OR_NOW
-# ifdef RTLD_LAZY
-# define LT_DLLAZY_OR_NOW RTLD_LAZY
-# else
-# ifdef DL_LAZY
-# define LT_DLLAZY_OR_NOW DL_LAZY
-# else
-# ifdef RTLD_NOW
-# define LT_DLLAZY_OR_NOW RTLD_NOW
-# else
-# ifdef DL_NOW
-# define LT_DLLAZY_OR_NOW DL_NOW
-# else
-# define LT_DLLAZY_OR_NOW 0
-# endif
-# endif
-# endif
-# endif
-#endif
-
-#ifdef __cplusplus
-extern "C" void exit (int);
-#endif
-
-void fnord() { int i=42;}
-int main ()
-{
- void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
- int status = $lt_dlunknown;
-
- if (self)
- {
- if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
- else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
- /* dlclose (self); */
- }
-
- exit (status);
-}
-EOF
- if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then
- (./conftest; exit; ) 2>/dev/null
- lt_status=$?
- case x$lt_status in
- x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;
- x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;;
- x$lt_unknown|x*) lt_cv_dlopen_self_static=no ;;
- esac
- else :
- # compilation failed
- lt_cv_dlopen_self_static=no
- fi
-fi
-rm -fr conftest*
-
-
+ # We cannot hardcode anything, or else we can only hardcode existing
+ # directories.
+ hardcode_action_CXX=unsupported
fi
-echo "$as_me:$LINENO: result: $lt_cv_dlopen_self_static" >&5
-echo "${ECHO_T}$lt_cv_dlopen_self_static" >&6
- fi
-
- CPPFLAGS="$save_CPPFLAGS"
- LDFLAGS="$save_LDFLAGS"
- LIBS="$save_LIBS"
- ;;
- esac
-
- case $lt_cv_dlopen_self in
- yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
- *) enable_dlopen_self=unknown ;;
- esac
+echo "$as_me:$LINENO: result: $hardcode_action_CXX" >&5
+echo "${ECHO_T}$hardcode_action_CXX" >&6
- case $lt_cv_dlopen_self_static in
- yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
- *) enable_dlopen_self_static=unknown ;;
- esac
+if test "$hardcode_action_CXX" = relink; then
+ # Fast installation is not supported
+ enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+ test "$enable_shared" = no; then
+ # Fast installation is not necessary
+ enable_fast_install=needless
fi
@@ -12111,7 +12408,8 @@ if test -f "$ltmain"; then
# Now quote all the things that may contain metacharacters while being
# careful not to overquote the AC_SUBSTed values. We take copies of the
# variables and quote the copies for generation of the libtool script.
- for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC NM SED SHELL \
+ for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \
+ SED SHELL STRIP \
libname_spec library_names_spec soname_spec extract_expsyms_cmds \
old_striplib striplib file_magic_cmd finish_cmds finish_eval \
deplibs_check_method reload_flag reload_cmds need_locks \
@@ -12211,6 +12509,12 @@ fast_install=$enable_fast_install
# The host system.
host_alias=$host_alias
host=$host
+host_os=$host_os
+
+# The build system.
+build_alias=$build_alias
+build=$build
+build_os=$build_os
# An echo program that does not interpret backslashes.
echo=$lt_echo
@@ -12222,6 +12526,9 @@ AR_FLAGS=$lt_AR_FLAGS
# A C compiler.
LTCC=$lt_LTCC
+# LTCC compiler flags.
+LTCFLAGS=$lt_LTCFLAGS
+
# A language-specific compiler.
CC=$lt_compiler_CXX
@@ -12241,7 +12548,7 @@ LN_S=$lt_LN_S
NM=$lt_NM
# A symbol stripping program
-STRIP=$STRIP
+STRIP=$lt_STRIP
# Used to examine libraries when file_magic_cmd begins "file"
MAGIC_CMD=$MAGIC_CMD
@@ -12272,7 +12579,7 @@ objext="$ac_objext"
libext="$libext"
# Shared library suffix (normally ".so").
-shrext='$shrext'
+shrext_cmds='$shrext_cmds'
# Executable file suffix (normally "").
exeext="$exeext"
@@ -12287,7 +12594,7 @@ max_cmd_len=$lt_cv_sys_max_cmd_len
# Does compiler simultaneously support -c and -o options?
compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX
-# Must we lock files when doing compilation ?
+# Must we lock files when doing compilation?
need_locks=$lt_need_locks
# Do we need the lib prefix for modules?
@@ -12489,7 +12796,10 @@ else
# If there is no Makefile yet, we rely on a make rule to execute
# `config.status --recheck' to rerun these tests and create the
# libtool script then.
- test -f Makefile && make "$ltmain"
+ ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'`
+ if test -f "$ltmain_in"; then
+ test -f Makefile && make "$ltmain"
+ fi
fi
@@ -12561,16 +12871,42 @@ lt_simple_link_test_code=" program t\n end\n"
# If no C compiler was specified, use CC.
LTCC=${LTCC-"$CC"}
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
# Allow CC to be a program name with arguments.
compiler=$CC
+# save warnings/boilerplate of simple test code
+ac_outfile=conftest.$ac_objext
+printf "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$rm conftest*
+
+ac_outfile=conftest.$ac_objext
+printf "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$rm conftest*
+
+
# Allow CC to be a program name with arguments.
lt_save_CC="$CC"
CC=${F77-"f77"}
compiler=$CC
compiler_F77=$CC
-cc_basename=`$echo X"$compiler" | $Xsed -e 's%^.*/%%'`
+for cc_temp in $compiler""; do
+ case $cc_temp in
+ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+done
+cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
+
echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5
echo $ECHO_N "checking if libtool supports shared libraries... $ECHO_C" >&6
@@ -12583,7 +12919,7 @@ test "$can_build_shared" = "no" && enable_shared=no
# On AIX, shared libraries and static libraries use the same namespace, and
# are all built from PIC.
-case "$host_os" in
+case $host_os in
aix3*)
test "$enable_shared" = yes && enable_static=no
if test -n "$RANLIB"; then
@@ -12591,8 +12927,10 @@ aix3*)
postinstall_cmds='$RANLIB $lib'
fi
;;
-aix4*)
- test "$enable_shared" = yes && enable_static=no
+aix4* | aix5*)
+ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+ test "$enable_shared" = yes && enable_static=no
+ fi
;;
esac
echo "$as_me:$LINENO: result: $enable_shared" >&5
@@ -12605,8 +12943,6 @@ test "$enable_shared" = yes || enable_static=yes
echo "$as_me:$LINENO: result: $enable_static" >&5
echo "${ECHO_T}$enable_static" >&6
-test "$ld_shlibs_F77" = no && can_build_shared=no
-
GCC_F77="$G77"
LD_F77="$LD"
@@ -12653,6 +12989,11 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6
lt_prog_compiler_pic_F77='-fno-common'
;;
+ interix3*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+
msdosdjgpp*)
# Just because we use GCC doesn't mean we suddenly get shared libraries
# on systems that don't support them.
@@ -12669,7 +13010,7 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6
hpux*)
# PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
# not for PA HP-UX.
- case "$host_cpu" in
+ case $host_cpu in
hppa*64*|ia64*)
# +Z the default
;;
@@ -12695,6 +13036,16 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6
lt_prog_compiler_static_F77='-bnso -bI:/lib/syscalls.exp'
fi
;;
+ darwin*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ case $cc_basename in
+ xlc*)
+ lt_prog_compiler_pic_F77='-qnocommon'
+ lt_prog_compiler_wl_F77='-Wl,'
+ ;;
+ esac
+ ;;
mingw* | pw32* | os2*)
# This hack is so that the source file can tell whether it is being
@@ -12706,7 +13057,7 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6
lt_prog_compiler_wl_F77='-Wl,'
# PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
# not for PA HP-UX.
- case "$host_cpu" in
+ case $host_cpu in
hppa*64*|ia64*)
# +Z the default
;;
@@ -12730,13 +13081,20 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6
;;
linux*)
- case $CC in
- icc|ecc)
+ case $cc_basename in
+ icc* | ecc*)
lt_prog_compiler_wl_F77='-Wl,'
lt_prog_compiler_pic_F77='-KPIC'
lt_prog_compiler_static_F77='-static'
;;
- ccc)
+ pgcc* | pgf77* | pgf90* | pgf95*)
+ # Portland Group compilers (*not* the Pentium gcc compiler,
+ # which looks to be a dead project)
+ lt_prog_compiler_wl_F77='-Wl,'
+ lt_prog_compiler_pic_F77='-fpic'
+ lt_prog_compiler_static_F77='-Bstatic'
+ ;;
+ ccc*)
lt_prog_compiler_wl_F77='-Wl,'
# All Alpha code is PIC.
lt_prog_compiler_static_F77='-non_shared'
@@ -12750,15 +13108,15 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6
lt_prog_compiler_static_F77='-non_shared'
;;
- sco3.2v5*)
- lt_prog_compiler_pic_F77='-Kpic'
- lt_prog_compiler_static_F77='-dn'
- ;;
-
solaris*)
- lt_prog_compiler_wl_F77='-Wl,'
lt_prog_compiler_pic_F77='-KPIC'
lt_prog_compiler_static_F77='-Bstatic'
+ case $cc_basename in
+ f77* | f90* | f95*)
+ lt_prog_compiler_wl_F77='-Qoption ld ';;
+ *)
+ lt_prog_compiler_wl_F77='-Wl,';;
+ esac
;;
sunos4*)
@@ -12767,7 +13125,7 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6
lt_prog_compiler_static_F77='-Bstatic'
;;
- sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ sysv4 | sysv4.2uw2* | sysv4.3*)
lt_prog_compiler_wl_F77='-Wl,'
lt_prog_compiler_pic_F77='-KPIC'
lt_prog_compiler_static_F77='-Bstatic'
@@ -12780,6 +13138,17 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6
fi
;;
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ lt_prog_compiler_wl_F77='-Wl,'
+ lt_prog_compiler_pic_F77='-KPIC'
+ lt_prog_compiler_static_F77='-Bstatic'
+ ;;
+
+ unicos*)
+ lt_prog_compiler_wl_F77='-Wl,'
+ lt_prog_compiler_can_build_shared_F77=no
+ ;;
+
uts4*)
lt_prog_compiler_pic_F77='-pic'
lt_prog_compiler_static_F77='-Bstatic'
@@ -12798,7 +13167,8 @@ echo "${ECHO_T}$lt_prog_compiler_pic_F77" >&6
# Check to make sure the PIC flag actually works.
#
if test -n "$lt_prog_compiler_pic_F77"; then
- echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_F77 works" >&5
+
+echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_F77 works" >&5
echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_F77 works... $ECHO_C" >&6
if test "${lt_prog_compiler_pic_works_F77+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -12813,18 +13183,20 @@ else
# with a dollar sign (not a hyphen), so the echo should work correctly.
# The option is referenced via a variable to avoid confusing sed.
lt_compile=`echo "$ac_compile" | $SED \
- -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:12819: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:13189: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:12823: \$? = $ac_status" >&5
+ echo "$as_me:13193: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
- # So say no if there are warnings
- if test ! -s conftest.err; then
+ # So say no if there are warnings other than the usual output.
+ $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
lt_prog_compiler_pic_works_F77=yes
fi
fi
@@ -12845,7 +13217,7 @@ else
fi
fi
-case "$host_os" in
+case $host_os in
# For platforms which do not support PIC, -DPIC is meaningless:
*djgpp*)
lt_prog_compiler_pic_F77=
@@ -12855,6 +13227,48 @@ case "$host_os" in
;;
esac
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl_F77 eval lt_tmp_static_flag=\"$lt_prog_compiler_static_F77\"
+echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6
+if test "${lt_prog_compiler_static_works_F77+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ lt_prog_compiler_static_works_F77=no
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+ printf "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ lt_prog_compiler_static_works_F77=yes
+ fi
+ else
+ lt_prog_compiler_static_works_F77=yes
+ fi
+ fi
+ $rm conftest*
+ LDFLAGS="$save_LDFLAGS"
+
+fi
+echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works_F77" >&5
+echo "${ECHO_T}$lt_prog_compiler_static_works_F77" >&6
+
+if test x"$lt_prog_compiler_static_works_F77" = xyes; then
+ :
+else
+ lt_prog_compiler_static_F77=
+fi
+
+
echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5
echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6
if test "${lt_cv_prog_compiler_c_o_F77+set}" = set; then
@@ -12867,38 +13281,36 @@ else
mkdir out
printf "$lt_simple_compile_test_code" > conftest.$ac_ext
- # According to Tom Tromey, Ian Lance Taylor reported there are C compilers
- # that will create temporary files in the current directory regardless of
- # the output directory. Thus, making CWD read-only will cause this test
- # to fail, enabling locking or at least warning the user not to do parallel
- # builds.
- chmod -w .
-
lt_compiler_flag="-o out/conftest2.$ac_objext"
# Insert the option either (1) after the last *FLAGS variable, or
# (2) before a word containing "conftest.", or (3) at the end.
# Note that $ac_compile itself does not contain backslashes and begins
# with a dollar sign (not a hyphen), so the echo should work correctly.
lt_compile=`echo "$ac_compile" | $SED \
- -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:12886: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:13293: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:12890: \$? = $ac_status" >&5
+ echo "$as_me:13297: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings
- if test ! -s out/conftest.err; then
+ $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
lt_cv_prog_compiler_c_o_F77=yes
fi
fi
- chmod u+w .
- $rm conftest* out/*
- rmdir out
+ chmod u+w . 2>&5
+ $rm conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files
+ $rm out/* && rmdir out
cd ..
rmdir conftest
$rm conftest*
@@ -12969,6 +13381,16 @@ echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared librar
# rely on this symbol name, it's probably fine to never include it in
# preloaded symbol tables.
extract_expsyms_cmds=
+ # Just being paranoid about ensuring that cc_basename is set.
+ for cc_temp in $compiler""; do
+ case $cc_temp in
+ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+done
+cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
case $host_os in
cygwin* | mingw* | pw32*)
@@ -12979,6 +13401,10 @@ echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared librar
with_gnu_ld=no
fi
;;
+ interix*)
+ # we just hope/assume this is gcc and not c89 (= MSVC++)
+ with_gnu_ld=yes
+ ;;
openbsd*)
with_gnu_ld=no
;;
@@ -12989,6 +13415,27 @@ echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared librar
# If archive_cmds runs LD, not CC, wlarc should be empty
wlarc='${wl}'
+ # Set some defaults for GNU ld with shared library support. These
+ # are reset later if shared libraries are not supported. Putting them
+ # here allows them to be overridden if necessary.
+ runpath_var=LD_RUN_PATH
+ hardcode_libdir_flag_spec_F77='${wl}--rpath ${wl}$libdir'
+ export_dynamic_flag_spec_F77='${wl}--export-dynamic'
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then
+ whole_archive_flag_spec_F77="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ else
+ whole_archive_flag_spec_F77=
+ fi
+ supports_anon_versioning=no
+ case `$LD -v 2>/dev/null` in
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
+ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+ *\ 2.11.*) ;; # other 2.11 versions
+ *) supports_anon_versioning=yes ;;
+ esac
+
# See if GNU ld supports shared libraries.
case $host_os in
aix3* | aix4* | aix5*)
@@ -13039,10 +13486,10 @@ EOF
allow_undefined_flag_F77=unsupported
always_export_symbols_F77=no
enable_shared_with_static_runtimes_F77=yes
- export_symbols_cmds_F77='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols'
+ export_symbols_cmds_F77='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols'
if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
- archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib'
+ archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
# If the export-symbols file already is a .def file (1st line
# is EXPORTS), use it as is; otherwise, prepend...
archive_expsym_cmds_F77='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
@@ -13051,13 +13498,60 @@ EOF
echo EXPORTS > $output_objdir/$soname.def;
cat $export_symbols >> $output_objdir/$soname.def;
fi~
- $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib'
+ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
else
- ld_shlibs=no
+ ld_shlibs_F77=no
+ fi
+ ;;
+
+ interix3*)
+ hardcode_direct_F77=no
+ hardcode_shlibpath_var_F77=no
+ hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir'
+ export_dynamic_flag_spec_F77='${wl}-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ archive_cmds_F77='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ archive_expsym_cmds_F77='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+
+ linux*)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ tmp_addflag=
+ case $cc_basename,$host_cpu in
+ pgcc*) # Portland Group C compiler
+ whole_archive_flag_spec_F77='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
+ tmp_addflag=' $pic_flag'
+ ;;
+ pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers
+ whole_archive_flag_spec_F77='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
+ tmp_addflag=' $pic_flag -Mnomain' ;;
+ ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
+ tmp_addflag=' -i_dynamic' ;;
+ efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64
+ tmp_addflag=' -i_dynamic -nofor_main' ;;
+ ifc* | ifort*) # Intel Fortran compiler
+ tmp_addflag=' -nofor_main' ;;
+ esac
+ archive_cmds_F77='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+
+ if test $supports_anon_versioning = yes; then
+ archive_expsym_cmds_F77='$echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ $echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+ fi
+ link_all_deplibs_F77=no
+ else
+ ld_shlibs_F77=no
fi
;;
- netbsd*)
+ netbsd* | netbsdelf*-gnu | knetbsd*-gnu)
if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
archive_cmds_F77='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
wlarc=
@@ -13067,7 +13561,7 @@ EOF
fi
;;
- solaris* | sysv5*)
+ solaris*)
if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
ld_shlibs_F77=no
cat <<EOF 1>&2
@@ -13088,6 +13582,33 @@ EOF
fi
;;
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+ case `$LD -v 2>&1` in
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
+ ld_shlibs_F77=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ ;;
+ *)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ hardcode_libdir_flag_spec_F77='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`'
+ archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib'
+ archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib'
+ else
+ ld_shlibs_F77=no
+ fi
+ ;;
+ esac
+ ;;
+
sunos4*)
archive_cmds_F77='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
wlarc=
@@ -13095,31 +13616,6 @@ EOF
hardcode_shlibpath_var_F77=no
;;
- linux*)
- if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
- tmp_archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_cmds_F77="$tmp_archive_cmds"
- supports_anon_versioning=no
- case `$LD -v 2>/dev/null` in
- *\ 01.* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
- *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
- *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
- *\ 2.11.*) ;; # other 2.11 versions
- *) supports_anon_versioning=yes ;;
- esac
- if test $supports_anon_versioning = yes; then
- archive_expsym_cmds_F77='$echo "{ global:" > $output_objdir/$libname.ver~
-cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
-$echo "local: *; };" >> $output_objdir/$libname.ver~
- $CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
- else
- archive_expsym_cmds_F77="$tmp_archive_cmds"
- fi
- else
- ld_shlibs_F77=no
- fi
- ;;
-
*)
if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
@@ -13130,16 +13626,11 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~
;;
esac
- if test "$ld_shlibs_F77" = yes; then
- runpath_var=LD_RUN_PATH
- hardcode_libdir_flag_spec_F77='${wl}--rpath ${wl}$libdir'
- export_dynamic_flag_spec_F77='${wl}--export-dynamic'
- # ancient GNU ld didn't support --whole-archive et. al.
- if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then
- whole_archive_flag_spec_F77="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
- else
- whole_archive_flag_spec_F77=
- fi
+ if test "$ld_shlibs_F77" = no; then
+ runpath_var=
+ hardcode_libdir_flag_spec_F77=
+ export_dynamic_flag_spec_F77=
+ whole_archive_flag_spec_F77=
fi
else
# PORTME fill in a description of your system's linker (not GNU ld)
@@ -13151,7 +13642,7 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~
# Note: this linker hardcodes the directories in LIBPATH if there
# are no directories specified by -L.
hardcode_minus_L_F77=yes
- if test "$GCC" = yes && test -z "$link_static_flag"; then
+ if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
# Neither direct hardcoding nor static linking is supported with a
# broken collect2.
hardcode_direct_F77=unsupported
@@ -13185,6 +13676,7 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~
break
fi
done
+ ;;
esac
exp_sym_flag='-bexport'
@@ -13203,7 +13695,7 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~
link_all_deplibs_F77=yes
if test "$GCC" = yes; then
- case $host_os in aix4.012|aix4.012.*)
+ case $host_os in aix4.[012]|aix4.[012].*)
# We only want to do this on AIX 4.2 and lower, the check
# below for broken collect2 doesn't work under 4.3+
collect2name=`${CC} -print-prog-name=collect2`
@@ -13222,8 +13714,12 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~
hardcode_libdir_flag_spec_F77='-L$libdir'
hardcode_libdir_separator_F77=
fi
+ ;;
esac
shared_flag='-shared'
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag="$shared_flag "'${wl}-G'
+ fi
else
# not using gcc
if test "$host_cpu" = ia64; then
@@ -13231,11 +13727,11 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~
# chokes on -Wl,-G. The following line is correct:
shared_flag='-G'
else
- if test "$aix_use_runtimelinking" = yes; then
+ if test "$aix_use_runtimelinking" = yes; then
shared_flag='${wl}-G'
else
shared_flag='${wl}-bM:SRE'
- fi
+ fi
fi
fi
@@ -13254,11 +13750,20 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
+ (eval $ac_link) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest$ac_exeext'
+ { ac_try='test -z "$ac_f77_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -13275,16 +13780,17 @@ else
sed 's/^/| /' conftest.$ac_ext >&5
fi
-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
hardcode_libdir_flag_spec_F77='${wl}-blibpath:$libdir:'"$aix_libpath"
- archive_expsym_cmds_F77="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+ archive_expsym_cmds_F77="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
else
if test "$host_cpu" = ia64; then
hardcode_libdir_flag_spec_F77='${wl}-R $libdir:/usr/lib:/lib'
allow_undefined_flag_F77="-z nodefs"
- archive_expsym_cmds_F77="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"
+ archive_expsym_cmds_F77="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
else
# Determine the default libpath from the value encoded in an empty executable.
cat >conftest.$ac_ext <<_ACEOF
@@ -13294,11 +13800,20 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
+ (eval $ac_link) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest$ac_exeext'
+ { ac_try='test -z "$ac_f77_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -13315,7 +13830,8 @@ else
sed 's/^/| /' conftest.$ac_ext >&5
fi
-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
hardcode_libdir_flag_spec_F77='${wl}-blibpath:$libdir:'"$aix_libpath"
@@ -13323,13 +13839,11 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
# -berok will link without error, but may produce a broken library.
no_undefined_flag_F77=' ${wl}-bernotok'
allow_undefined_flag_F77=' ${wl}-berok'
- # -bexpall does not export symbols beginning with underscore (_)
- always_export_symbols_F77=yes
# Exported symbols can be pulled into shared objects from archives
- whole_archive_flag_spec_F77=' '
+ whole_archive_flag_spec_F77='$convenience'
archive_cmds_need_lc_F77=yes
- # This is similar to how AIX traditionally builds it's shared libraries.
- archive_expsym_cmds_F77="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+ # This is similar to how AIX traditionally builds its shared libraries.
+ archive_expsym_cmds_F77="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
fi
fi
;;
@@ -13342,7 +13856,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
ld_shlibs_F77=no
;;
- bsdi4*)
+ bsdi[45]*)
export_dynamic_flag_spec_F77=-rdynamic
;;
@@ -13356,55 +13870,64 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
# Tell ltmain to make .lib files, not .a files.
libext=lib
# Tell ltmain to make .dll files, not .so files.
- shrext=".dll"
+ shrext_cmds=".dll"
# FIXME: Setting linknames here is a bad hack.
archive_cmds_F77='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames='
# The linker will automatically build a .lib file if we build a DLL.
old_archive_From_new_cmds_F77='true'
# FIXME: Should let the user specify the lib program.
old_archive_cmds_F77='lib /OUT:$oldlib$oldobjs$old_deplibs'
- fix_srcfile_path='`cygpath -w "$srcfile"`'
+ fix_srcfile_path_F77='`cygpath -w "$srcfile"`'
enable_shared_with_static_runtimes_F77=yes
;;
darwin* | rhapsody*)
- if $CC -v 2>&1 | grep 'Apple' >/dev/null ; then
- archive_cmds_need_lc_F77=no
- case "$host_os" in
- rhapsody* | darwin1.[012])
- allow_undefined_flag_F77='-undefined suppress'
- ;;
- *) # Darwin 1.3 on
- test -z ${LD_TWOLEVEL_NAMESPACE} && allow_undefined_flag_F77='-flat_namespace -undefined suppress'
- ;;
+ case $host_os in
+ rhapsody* | darwin1.[012])
+ allow_undefined_flag_F77='${wl}-undefined ${wl}suppress'
+ ;;
+ *) # Darwin 1.3 on
+ if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then
+ allow_undefined_flag_F77='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
+ else
+ case ${MACOSX_DEPLOYMENT_TARGET} in
+ 10.[012])
+ allow_undefined_flag_F77='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
+ ;;
+ 10.*)
+ allow_undefined_flag_F77='${wl}-undefined ${wl}dynamic_lookup'
+ ;;
+ esac
+ fi
+ ;;
esac
- # FIXME: Relying on posixy $() will cause problems for
- # cross-compilation, but unfortunately the echo tests do not
- # yet detect zsh echo's removal of \ escapes. Also zsh mangles
- # `"' quotes if we put them in here... so don't!
- lt_int_apple_cc_single_mod=no
- output_verbose_link_cmd='echo'
- if $CC -dumpspecs 2>&1 | grep 'single_module' >/dev/null ; then
- lt_int_apple_cc_single_mod=yes
- fi
- if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
- archive_cmds_F77='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
- else
- archive_cmds_F77='$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
- fi
- module_cmds_F77='$CC -bundle ${wl}-bind_at_load $allow_undefined_flag -o $lib $libobjs $deplibs$compiler_flags'
- # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's
- if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
- archive_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
- else
- archive_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
- fi
- module_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -bundle $allow_undefined_flag -o $lib $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ archive_cmds_need_lc_F77=no
hardcode_direct_F77=no
hardcode_automatic_F77=yes
hardcode_shlibpath_var_F77=unsupported
- whole_archive_flag_spec_F77='-all_load $convenience'
+ whole_archive_flag_spec_F77=''
link_all_deplibs_F77=yes
+ if test "$GCC" = yes ; then
+ output_verbose_link_cmd='echo'
+ archive_cmds_F77='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+ module_cmds_F77='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+ # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
+ archive_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ module_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ else
+ case $cc_basename in
+ xlc*)
+ output_verbose_link_cmd='echo'
+ archive_cmds_F77='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring'
+ module_cmds_F77='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+ # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
+ archive_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ module_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ ;;
+ *)
+ ld_shlibs_F77=no
+ ;;
+ esac
fi
;;
@@ -13438,13 +13961,22 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
;;
# FreeBSD 3 and greater uses gcc -shared to do shared libraries.
- freebsd*)
+ freebsd* | dragonfly*)
archive_cmds_F77='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
hardcode_libdir_flag_spec_F77='-R$libdir'
hardcode_direct_F77=yes
hardcode_shlibpath_var_F77=no
;;
+ # GNU/kFreeBSD uses gcc -shared to do shared libraries.
+ kfreebsd*-gnu)
+ archive_cmds_F77='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
+ hardcode_libdir_flag_spec_F77='-R$libdir'
+ hardcode_direct_F77=yes
+ hardcode_shlibpath_var_F77=no
+ link_all_deplibs_F77=no
+ ;;
+
hpux9*)
if test "$GCC" = yes; then
archive_cmds_F77='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
@@ -13461,47 +13993,62 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
export_dynamic_flag_spec_F77='${wl}-E'
;;
- hpux10* | hpux11*)
+ hpux10*)
if test "$GCC" = yes -a "$with_gnu_ld" = no; then
- case "$host_cpu" in
- hppa*64*|ia64*)
+ archive_cmds_F77='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds_F77='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ if test "$with_gnu_ld" = no; then
+ hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator_F77=:
+
+ hardcode_direct_F77=yes
+ export_dynamic_flag_spec_F77='${wl}-E'
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L_F77=yes
+ fi
+ ;;
+
+ hpux11*)
+ if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+ case $host_cpu in
+ hppa*64*)
archive_cmds_F77='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
;;
+ ia64*)
+ archive_cmds_F77='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
*)
archive_cmds_F77='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
;;
esac
else
- case "$host_cpu" in
- hppa*64*|ia64*)
- archive_cmds_F77='$LD -b +h $soname -o $lib $libobjs $deplibs $linker_flags'
+ case $host_cpu in
+ hppa*64*)
+ archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
*)
- archive_cmds_F77='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+ archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
;;
esac
fi
if test "$with_gnu_ld" = no; then
- case "$host_cpu" in
- hppa*64*)
- hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir'
+ hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator_F77=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
hardcode_libdir_flag_spec_ld_F77='+b $libdir'
- hardcode_libdir_separator_F77=:
- hardcode_direct_F77=no
- hardcode_shlibpath_var_F77=no
- ;;
- ia64*)
- hardcode_libdir_flag_spec_F77='-L$libdir'
hardcode_direct_F77=no
hardcode_shlibpath_var_F77=no
-
- # hardcode_minus_L: Not really in the search PATH,
- # but as the default location of the library.
- hardcode_minus_L_F77=yes
;;
*)
- hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir'
- hardcode_libdir_separator_F77=:
hardcode_direct_F77=yes
export_dynamic_flag_spec_F77='${wl}-E'
@@ -13525,7 +14072,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
link_all_deplibs_F77=yes
;;
- netbsd*)
+ netbsd* | netbsdelf*-gnu | knetbsd*-gnu)
if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
else
@@ -13549,6 +14096,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
hardcode_shlibpath_var_F77=no
if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
archive_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir'
export_dynamic_flag_spec_F77='${wl}-E'
else
@@ -13594,7 +14142,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
allow_undefined_flag_F77=' -expect_unresolved \*'
archive_cmds_F77='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
archive_expsym_cmds_F77='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~
- $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib~$rm $lib.exp'
+ $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp'
# Both c and cxx compiler support -rpath directly
hardcode_libdir_flag_spec_F77='-rpath $libdir'
@@ -13602,21 +14150,15 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
hardcode_libdir_separator_F77=:
;;
- sco3.2v5*)
- archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_shlibpath_var_F77=no
- export_dynamic_flag_spec_F77='${wl}-Bexport'
- runpath_var=LD_RUN_PATH
- hardcode_runpath_var=yes
- ;;
-
solaris*)
no_undefined_flag_F77=' -z text'
if test "$GCC" = yes; then
+ wlarc='${wl}'
archive_cmds_F77='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
archive_expsym_cmds_F77='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
$CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp'
else
+ wlarc=''
archive_cmds_F77='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
archive_expsym_cmds_F77='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
$LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
@@ -13625,8 +14167,18 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
hardcode_shlibpath_var_F77=no
case $host_os in
solaris2.[0-5] | solaris2.[0-5].*) ;;
- *) # Supported since Solaris 2.6 (maybe 2.5.1?)
- whole_archive_flag_spec_F77='-z allextract$convenience -z defaultextract' ;;
+ *)
+ # The compiler driver will combine linker options so we
+ # cannot just pass the convience library names through
+ # without $wl, iff we do not link with $LD.
+ # Luckily, gcc supports the same syntax we need for Sun Studio.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ case $wlarc in
+ '')
+ whole_archive_flag_spec_F77='-z allextract$convenience -z defaultextract' ;;
+ *)
+ whole_archive_flag_spec_F77='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;;
+ esac ;;
esac
link_all_deplibs_F77=yes
;;
@@ -13683,36 +14235,45 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
fi
;;
- sysv4.2uw2*)
- archive_cmds_F77='$LD -G -o $lib $libobjs $deplibs $linker_flags'
- hardcode_direct_F77=yes
- hardcode_minus_L_F77=no
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7*)
+ no_undefined_flag_F77='${wl}-z,text'
+ archive_cmds_need_lc_F77=no
hardcode_shlibpath_var_F77=no
- hardcode_runpath_var=yes
- runpath_var=LD_RUN_PATH
- ;;
+ runpath_var='LD_RUN_PATH'
- sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[78]* | unixware7*)
- no_undefined_flag_F77='${wl}-z ${wl}text'
if test "$GCC" = yes; then
- archive_cmds_F77='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds_F77='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds_F77='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
else
- archive_cmds_F77='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds_F77='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds_F77='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
fi
- runpath_var='LD_RUN_PATH'
- hardcode_shlibpath_var_F77=no
;;
- sysv5*)
- no_undefined_flag_F77=' -z text'
- # $CC -shared without GNU ld will not create a library from C++
- # object files and a static libstdc++, better avoid it by now
- archive_cmds_F77='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
- archive_expsym_cmds_F77='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
- $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
- hardcode_libdir_flag_spec_F77=
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We can NOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ no_undefined_flag_F77='${wl}-z,text'
+ allow_undefined_flag_F77='${wl}-z,nodefs'
+ archive_cmds_need_lc_F77=no
hardcode_shlibpath_var_F77=no
+ hardcode_libdir_flag_spec_F77='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
+ hardcode_libdir_separator_F77=':'
+ link_all_deplibs_F77=yes
+ export_dynamic_flag_spec_F77='${wl}-Bexport'
runpath_var='LD_RUN_PATH'
+
+ if test "$GCC" = yes; then
+ archive_cmds_F77='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds_F77='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds_F77='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds_F77='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
;;
uts4*)
@@ -13731,11 +14292,6 @@ echo "$as_me:$LINENO: result: $ld_shlibs_F77" >&5
echo "${ECHO_T}$ld_shlibs_F77" >&6
test "$ld_shlibs_F77" = no && can_build_shared=no
-variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
-if test "$GCC" = yes; then
- variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
-fi
-
#
# Do we need to explicitly link libc?
#
@@ -13768,6 +14324,7 @@ echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&
libobjs=conftest.$ac_objext
deplibs=
wl=$lt_prog_compiler_wl_F77
+ pic_flag=$lt_prog_compiler_pic_F77
compiler_flags=-v
linker_flags=-v
verstring=
@@ -13798,78 +14355,12 @@ echo "${ECHO_T}$archive_cmds_need_lc_F77" >&6
;;
esac
-echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5
-echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6
-hardcode_action_F77=
-if test -n "$hardcode_libdir_flag_spec_F77" || \
- test -n "$runpath_var F77" || \
- test "X$hardcode_automatic_F77"="Xyes" ; then
-
- # We can hardcode non-existant directories.
- if test "$hardcode_direct_F77" != no &&
- # If the only mechanism to avoid hardcoding is shlibpath_var, we
- # have to relink, otherwise we might link with an installed library
- # when we should be linking with a yet-to-be-installed one
- ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, F77)" != no &&
- test "$hardcode_minus_L_F77" != no; then
- # Linking always hardcodes the temporary library directory.
- hardcode_action_F77=relink
- else
- # We can link without hardcoding, and we can hardcode nonexisting dirs.
- hardcode_action_F77=immediate
- fi
-else
- # We cannot hardcode anything, or else we can only hardcode existing
- # directories.
- hardcode_action_F77=unsupported
-fi
-echo "$as_me:$LINENO: result: $hardcode_action_F77" >&5
-echo "${ECHO_T}$hardcode_action_F77" >&6
-
-if test "$hardcode_action_F77" = relink; then
- # Fast installation is not supported
- enable_fast_install=no
-elif test "$shlibpath_overrides_runpath" = yes ||
- test "$enable_shared" = no; then
- # Fast installation is not necessary
- enable_fast_install=needless
-fi
-
-striplib=
-old_striplib=
-echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5
-echo $ECHO_N "checking whether stripping libraries is possible... $ECHO_C" >&6
-if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then
- test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
- test -z "$striplib" && striplib="$STRIP --strip-unneeded"
- echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6
-else
-# FIXME - insert some real tests, host_os isn't really good enough
- case $host_os in
- darwin*)
- if test -n "$STRIP" ; then
- striplib="$STRIP -x"
- echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6
- else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
- ;;
- *)
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
- ;;
- esac
-fi
-
echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5
echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6
library_names_spec=
libname_spec='lib$name'
soname_spec=
-shrext=".so"
+shrext_cmds=".so"
postinstall_cmds=
postuninstall_cmds=
finish_cmds=
@@ -13957,7 +14448,7 @@ aix4* | aix5*)
amigaos*)
library_names_spec='$libname.ixlibrary $libname.a'
# Create ${libname}_ixlibrary.a entries in /sys/libs.
- finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "(cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a)"; (cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a) || exit 1; done'
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
;;
beos*)
@@ -13966,7 +14457,7 @@ beos*)
shlibpath_var=LIBRARY_PATH
;;
-bsdi4*)
+bsdi[45]*)
version_type=linux
need_version=no
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
@@ -13982,7 +14473,7 @@ bsdi4*)
cygwin* | mingw* | pw32*)
version_type=windows
- shrext=".dll"
+ shrext_cmds=".dll"
need_version=no
need_lib_prefix=no
@@ -13994,7 +14485,8 @@ cygwin* | mingw* | pw32*)
dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~
dldir=$destdir/`dirname \$dlpath`~
test -d \$dldir || mkdir -p \$dldir~
- $install_prog $dir/$dlname \$dldir/$dlname'
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname'
postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
dlpath=$dir/\$dldll~
$rm \$dlpath'
@@ -14004,7 +14496,7 @@ cygwin* | mingw* | pw32*)
cygwin*)
# Cygwin DLLs use 'cyg' prefix rather than 'lib'
soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
- sys_lib_search_path_spec="/lib /lib/w32api /usr/lib /usr/local/lib"
+ sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
;;
mingw*)
# MinGW DLLs use traditional 'lib' prefix
@@ -14024,7 +14516,7 @@ cygwin* | mingw* | pw32*)
;;
pw32*)
# pw32 DLLs use 'pw' prefix rather than 'lib'
- library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/./-/g'`${versuffix}${shared_ext}'
+ library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
;;
esac
;;
@@ -14043,17 +14535,16 @@ darwin* | rhapsody*)
version_type=darwin
need_lib_prefix=no
need_version=no
- # FIXME: Relying on posixy $() will cause problems for
- # cross-compilation, but unfortunately the echo tests do not
- # yet detect zsh echo's removal of \ escapes.
library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext'
soname_spec='${libname}${release}${major}$shared_ext'
shlibpath_overrides_runpath=yes
shlibpath_var=DYLD_LIBRARY_PATH
- shrext='$(test .$module = .yes && echo .so || echo .dylib)'
+ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
# Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same.
- if $CC -v 2>&1 | grep 'Apple' >/dev/null ; then
- sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"`
+ if test "$GCC" = yes; then
+ sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"`
+ else
+ sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib'
fi
sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
;;
@@ -14071,8 +14562,29 @@ freebsd1*)
dynamic_linker=no
;;
-freebsd*)
- objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout`
+kfreebsd*-gnu)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='GNU ld.so'
+ ;;
+
+freebsd* | dragonfly*)
+ # DragonFly does not have aout. When/if they implement a new
+ # versioning mechanism, adjust this.
+ if test -x /usr/bin/objformat; then
+ objformat=`/usr/bin/objformat`
+ else
+ case $host_os in
+ freebsd[123]*) objformat=aout ;;
+ *) objformat=elf ;;
+ esac
+ fi
version_type=freebsd-$objformat
case $version_type in
freebsd-elf*)
@@ -14090,14 +14602,19 @@ freebsd*)
freebsd2*)
shlibpath_overrides_runpath=yes
;;
- freebsd3.01* | freebsdelf3.01*)
+ freebsd3.[01]* | freebsdelf3.[01]*)
shlibpath_overrides_runpath=yes
hardcode_into_libs=yes
;;
- *) # from 3.2 on
+ freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
shlibpath_overrides_runpath=no
hardcode_into_libs=yes
;;
+ freebsd*) # from 4.6 on
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
esac
;;
@@ -14117,9 +14634,9 @@ hpux9* | hpux10* | hpux11*)
version_type=sunos
need_lib_prefix=no
need_version=no
- case "$host_cpu" in
+ case $host_cpu in
ia64*)
- shrext='.so'
+ shrext_cmds='.so'
hardcode_into_libs=yes
dynamic_linker="$host_os dld.so"
shlibpath_var=LD_LIBRARY_PATH
@@ -14134,7 +14651,7 @@ hpux9* | hpux10* | hpux11*)
sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
;;
hppa*64*)
- shrext='.sl'
+ shrext_cmds='.sl'
hardcode_into_libs=yes
dynamic_linker="$host_os dld.sl"
shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
@@ -14145,7 +14662,7 @@ hpux9* | hpux10* | hpux11*)
sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
;;
*)
- shrext='.sl'
+ shrext_cmds='.sl'
dynamic_linker="$host_os dld.sl"
shlibpath_var=SHLIB_PATH
shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
@@ -14157,6 +14674,18 @@ hpux9* | hpux10* | hpux11*)
postinstall_cmds='chmod 555 $lib'
;;
+interix3*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
irix5* | irix6* | nonstopux*)
case $host_os in
nonstopux*) version_type=nonstopux ;;
@@ -14214,6 +14743,12 @@ linux*)
# before this can be enabled.
hardcode_into_libs=yes
+ # Append ld.so.conf contents to the search path
+ if test -f /etc/ld.so.conf; then
+ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
+ sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+ fi
+
# We used to test for /lib/ld.so.1 and disable shared libraries on
# powerpc, because MkLinux only supported shared libraries with the
# GNU dynamic linker. Since this was broken with cross compilers,
@@ -14221,30 +14756,30 @@ linux*)
# people can always --disable-shared, the test was removed, and we
# assume the GNU/Linux dynamic linker is in use.
dynamic_linker='GNU/Linux ld.so'
+ ;;
- # Find out which ABI we are using (multilib Linux x86_64 hack).
- libsuff=
- case "$host_cpu" in
- x86_64*|s390x*)
- echo '#line 14229 "configure"' > conftest.$ac_ext
- if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; then
- case `/usr/bin/file conftest.$ac_objext` in
- *64-bit*)
- libsuff=64
- ;;
- esac
- fi
- rm -rf conftest*
- ;;
- *)
- ;;
- esac
- sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff}"
- sys_lib_search_path_spec="/lib${libsuff} /usr/lib${libsuff} /usr/local/lib${libsuff}"
+netbsdelf*-gnu)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='NetBSD ld.elf_so'
+ ;;
+
+knetbsd*-gnu)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='GNU ld.so'
;;
netbsd*)
@@ -14256,7 +14791,7 @@ netbsd*)
finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
dynamic_linker='NetBSD (a.out) ld.so'
else
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} ${libname}${shared_ext}'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
soname_spec='${libname}${release}${shared_ext}$major'
dynamic_linker='NetBSD ld.elf_so'
fi
@@ -14272,7 +14807,7 @@ newsos6)
shlibpath_overrides_runpath=yes
;;
-nto-qnx)
+nto-qnx*)
version_type=linux
need_lib_prefix=no
need_version=no
@@ -14284,8 +14819,13 @@ nto-qnx)
openbsd*)
version_type=sunos
+ sys_lib_dlsearch_path_spec="/usr/lib"
need_lib_prefix=no
- need_version=no
+ # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+ case $host_os in
+ openbsd3.3 | openbsd3.3.*) need_version=yes ;;
+ *) need_version=no ;;
+ esac
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
shlibpath_var=LD_LIBRARY_PATH
@@ -14305,7 +14845,7 @@ openbsd*)
os2*)
libname_spec='$name'
- shrext=".dll"
+ shrext_cmds=".dll"
need_lib_prefix=no
library_names_spec='$libname${shared_ext} $libname.a'
dynamic_linker='OS/2 ld.exe'
@@ -14323,13 +14863,6 @@ osf3* | osf4* | osf5*)
sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
;;
-sco3.2v5*)
- version_type=osf
- soname_spec='${libname}${release}${shared_ext}$major'
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- ;;
-
solaris*)
version_type=linux
need_lib_prefix=no
@@ -14355,7 +14888,7 @@ sunos4*)
need_version=yes
;;
-sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+sysv4 | sysv4.3*)
version_type=linux
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
soname_spec='${libname}${release}${shared_ext}$major'
@@ -14388,6 +14921,29 @@ sysv4*MP*)
fi
;;
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ version_type=freebsd-elf
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ hardcode_into_libs=yes
+ if test "$with_gnu_ld" = yes; then
+ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+ shlibpath_overrides_runpath=no
+ else
+ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+ shlibpath_overrides_runpath=yes
+ case $host_os in
+ sco3.2v5*)
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+ ;;
+ esac
+ fi
+ sys_lib_dlsearch_path_spec='/usr/lib'
+ ;;
+
uts4*)
version_type=linux
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
@@ -14403,6 +14959,48 @@ echo "$as_me:$LINENO: result: $dynamic_linker" >&5
echo "${ECHO_T}$dynamic_linker" >&6
test "$dynamic_linker" = no && can_build_shared=no
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5
+echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6
+hardcode_action_F77=
+if test -n "$hardcode_libdir_flag_spec_F77" || \
+ test -n "$runpath_var_F77" || \
+ test "X$hardcode_automatic_F77" = "Xyes" ; then
+
+ # We can hardcode non-existant directories.
+ if test "$hardcode_direct_F77" != no &&
+ # If the only mechanism to avoid hardcoding is shlibpath_var, we
+ # have to relink, otherwise we might link with an installed library
+ # when we should be linking with a yet-to-be-installed one
+ ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, F77)" != no &&
+ test "$hardcode_minus_L_F77" != no; then
+ # Linking always hardcodes the temporary library directory.
+ hardcode_action_F77=relink
+ else
+ # We can link without hardcoding, and we can hardcode nonexisting dirs.
+ hardcode_action_F77=immediate
+ fi
+else
+ # We cannot hardcode anything, or else we can only hardcode existing
+ # directories.
+ hardcode_action_F77=unsupported
+fi
+echo "$as_me:$LINENO: result: $hardcode_action_F77" >&5
+echo "${ECHO_T}$hardcode_action_F77" >&6
+
+if test "$hardcode_action_F77" = relink; then
+ # Fast installation is not supported
+ enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+ test "$enable_shared" = no; then
+ # Fast installation is not necessary
+ enable_fast_install=needless
+fi
+
# The else clause should only fire when bootstrapping the
# libtool distribution, otherwise you forgot to ship ltmain.sh
@@ -14417,7 +15015,8 @@ if test -f "$ltmain"; then
# Now quote all the things that may contain metacharacters while being
# careful not to overquote the AC_SUBSTed values. We take copies of the
# variables and quote the copies for generation of the libtool script.
- for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC NM SED SHELL \
+ for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \
+ SED SHELL STRIP \
libname_spec library_names_spec soname_spec extract_expsyms_cmds \
old_striplib striplib file_magic_cmd finish_cmds finish_eval \
deplibs_check_method reload_flag reload_cmds need_locks \
@@ -14517,6 +15116,12 @@ fast_install=$enable_fast_install
# The host system.
host_alias=$host_alias
host=$host
+host_os=$host_os
+
+# The build system.
+build_alias=$build_alias
+build=$build
+build_os=$build_os
# An echo program that does not interpret backslashes.
echo=$lt_echo
@@ -14528,6 +15133,9 @@ AR_FLAGS=$lt_AR_FLAGS
# A C compiler.
LTCC=$lt_LTCC
+# LTCC compiler flags.
+LTCFLAGS=$lt_LTCFLAGS
+
# A language-specific compiler.
CC=$lt_compiler_F77
@@ -14547,7 +15155,7 @@ LN_S=$lt_LN_S
NM=$lt_NM
# A symbol stripping program
-STRIP=$STRIP
+STRIP=$lt_STRIP
# Used to examine libraries when file_magic_cmd begins "file"
MAGIC_CMD=$MAGIC_CMD
@@ -14578,7 +15186,7 @@ objext="$ac_objext"
libext="$libext"
# Shared library suffix (normally ".so").
-shrext='$shrext'
+shrext_cmds='$shrext_cmds'
# Executable file suffix (normally "").
exeext="$exeext"
@@ -14593,7 +15201,7 @@ max_cmd_len=$lt_cv_sys_max_cmd_len
# Does compiler simultaneously support -c and -o options?
compiler_c_o=$lt_lt_cv_prog_compiler_c_o_F77
-# Must we lock files when doing compilation ?
+# Must we lock files when doing compilation?
need_locks=$lt_need_locks
# Do we need the lib prefix for modules?
@@ -14795,7 +15403,10 @@ else
# If there is no Makefile yet, we rely on a make rule to execute
# `config.status --recheck' to rerun these tests and create the
# libtool script then.
- test -f Makefile && make "$ltmain"
+ ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'`
+ if test -f "$ltmain_in"; then
+ test -f Makefile && make "$ltmain"
+ fi
fi
@@ -14828,33 +15439,63 @@ objext_GCJ=$objext
lt_simple_compile_test_code="class foo {}\n"
# Code to be used in simple link tests
-lt_simple_link_test_code='public class conftest { public static void main(String argv) {}; }\n'
+lt_simple_link_test_code='public class conftest { public static void main(String[] argv) {}; }\n'
# ltmain only uses $CC for tagged configurations so make sure $CC is set.
# If no C compiler was specified, use CC.
LTCC=${LTCC-"$CC"}
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
# Allow CC to be a program name with arguments.
compiler=$CC
+# save warnings/boilerplate of simple test code
+ac_outfile=conftest.$ac_objext
+printf "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$rm conftest*
+
+ac_outfile=conftest.$ac_objext
+printf "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$rm conftest*
+
+
# Allow CC to be a program name with arguments.
lt_save_CC="$CC"
CC=${GCJ-"gcj"}
compiler=$CC
compiler_GCJ=$CC
+for cc_temp in $compiler""; do
+ case $cc_temp in
+ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+done
+cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
+
# GCJ did not exist at the time GCC didn't implicitly link libc in.
archive_cmds_need_lc_GCJ=no
+old_archive_cmds_GCJ=$old_archive_cmds
+
lt_prog_compiler_no_builtin_flag_GCJ=
if test "$GCC" = yes; then
lt_prog_compiler_no_builtin_flag_GCJ=' -fno-builtin'
- echo "$as_me:$LINENO: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+
+echo "$as_me:$LINENO: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
echo $ECHO_N "checking if $compiler supports -fno-rtti -fno-exceptions... $ECHO_C" >&6
if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -14869,18 +15510,20 @@ else
# with a dollar sign (not a hyphen), so the echo should work correctly.
# The option is referenced via a variable to avoid confusing sed.
lt_compile=`echo "$ac_compile" | $SED \
- -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:14875: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:15516: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:14879: \$? = $ac_status" >&5
+ echo "$as_me:15520: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
- # So say no if there are warnings
- if test ! -s conftest.err; then
+ # So say no if there are warnings other than the usual output.
+ $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
lt_cv_prog_compiler_rtti_exceptions=yes
fi
fi
@@ -14941,6 +15584,11 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6
lt_prog_compiler_pic_GCJ='-fno-common'
;;
+ interix3*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+
msdosdjgpp*)
# Just because we use GCC doesn't mean we suddenly get shared libraries
# on systems that don't support them.
@@ -14957,7 +15605,7 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6
hpux*)
# PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
# not for PA HP-UX.
- case "$host_cpu" in
+ case $host_cpu in
hppa*64*|ia64*)
# +Z the default
;;
@@ -14983,6 +15631,16 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6
lt_prog_compiler_static_GCJ='-bnso -bI:/lib/syscalls.exp'
fi
;;
+ darwin*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ case $cc_basename in
+ xlc*)
+ lt_prog_compiler_pic_GCJ='-qnocommon'
+ lt_prog_compiler_wl_GCJ='-Wl,'
+ ;;
+ esac
+ ;;
mingw* | pw32* | os2*)
# This hack is so that the source file can tell whether it is being
@@ -14994,7 +15652,7 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6
lt_prog_compiler_wl_GCJ='-Wl,'
# PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
# not for PA HP-UX.
- case "$host_cpu" in
+ case $host_cpu in
hppa*64*|ia64*)
# +Z the default
;;
@@ -15018,13 +15676,20 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6
;;
linux*)
- case $CC in
- icc|ecc)
+ case $cc_basename in
+ icc* | ecc*)
lt_prog_compiler_wl_GCJ='-Wl,'
lt_prog_compiler_pic_GCJ='-KPIC'
lt_prog_compiler_static_GCJ='-static'
;;
- ccc)
+ pgcc* | pgf77* | pgf90* | pgf95*)
+ # Portland Group compilers (*not* the Pentium gcc compiler,
+ # which looks to be a dead project)
+ lt_prog_compiler_wl_GCJ='-Wl,'
+ lt_prog_compiler_pic_GCJ='-fpic'
+ lt_prog_compiler_static_GCJ='-Bstatic'
+ ;;
+ ccc*)
lt_prog_compiler_wl_GCJ='-Wl,'
# All Alpha code is PIC.
lt_prog_compiler_static_GCJ='-non_shared'
@@ -15038,15 +15703,15 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6
lt_prog_compiler_static_GCJ='-non_shared'
;;
- sco3.2v5*)
- lt_prog_compiler_pic_GCJ='-Kpic'
- lt_prog_compiler_static_GCJ='-dn'
- ;;
-
solaris*)
- lt_prog_compiler_wl_GCJ='-Wl,'
lt_prog_compiler_pic_GCJ='-KPIC'
lt_prog_compiler_static_GCJ='-Bstatic'
+ case $cc_basename in
+ f77* | f90* | f95*)
+ lt_prog_compiler_wl_GCJ='-Qoption ld ';;
+ *)
+ lt_prog_compiler_wl_GCJ='-Wl,';;
+ esac
;;
sunos4*)
@@ -15055,7 +15720,7 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6
lt_prog_compiler_static_GCJ='-Bstatic'
;;
- sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ sysv4 | sysv4.2uw2* | sysv4.3*)
lt_prog_compiler_wl_GCJ='-Wl,'
lt_prog_compiler_pic_GCJ='-KPIC'
lt_prog_compiler_static_GCJ='-Bstatic'
@@ -15068,6 +15733,17 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6
fi
;;
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ lt_prog_compiler_wl_GCJ='-Wl,'
+ lt_prog_compiler_pic_GCJ='-KPIC'
+ lt_prog_compiler_static_GCJ='-Bstatic'
+ ;;
+
+ unicos*)
+ lt_prog_compiler_wl_GCJ='-Wl,'
+ lt_prog_compiler_can_build_shared_GCJ=no
+ ;;
+
uts4*)
lt_prog_compiler_pic_GCJ='-pic'
lt_prog_compiler_static_GCJ='-Bstatic'
@@ -15086,7 +15762,8 @@ echo "${ECHO_T}$lt_prog_compiler_pic_GCJ" >&6
# Check to make sure the PIC flag actually works.
#
if test -n "$lt_prog_compiler_pic_GCJ"; then
- echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_GCJ works" >&5
+
+echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_GCJ works" >&5
echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_GCJ works... $ECHO_C" >&6
if test "${lt_prog_compiler_pic_works_GCJ+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
@@ -15101,18 +15778,20 @@ else
# with a dollar sign (not a hyphen), so the echo should work correctly.
# The option is referenced via a variable to avoid confusing sed.
lt_compile=`echo "$ac_compile" | $SED \
- -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:15107: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:15784: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:15111: \$? = $ac_status" >&5
+ echo "$as_me:15788: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
- # So say no if there are warnings
- if test ! -s conftest.err; then
+ # So say no if there are warnings other than the usual output.
+ $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
lt_prog_compiler_pic_works_GCJ=yes
fi
fi
@@ -15133,7 +15812,7 @@ else
fi
fi
-case "$host_os" in
+case $host_os in
# For platforms which do not support PIC, -DPIC is meaningless:
*djgpp*)
lt_prog_compiler_pic_GCJ=
@@ -15143,6 +15822,48 @@ case "$host_os" in
;;
esac
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl_GCJ eval lt_tmp_static_flag=\"$lt_prog_compiler_static_GCJ\"
+echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6
+if test "${lt_prog_compiler_static_works_GCJ+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ lt_prog_compiler_static_works_GCJ=no
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+ printf "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ lt_prog_compiler_static_works_GCJ=yes
+ fi
+ else
+ lt_prog_compiler_static_works_GCJ=yes
+ fi
+ fi
+ $rm conftest*
+ LDFLAGS="$save_LDFLAGS"
+
+fi
+echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works_GCJ" >&5
+echo "${ECHO_T}$lt_prog_compiler_static_works_GCJ" >&6
+
+if test x"$lt_prog_compiler_static_works_GCJ" = xyes; then
+ :
+else
+ lt_prog_compiler_static_GCJ=
+fi
+
+
echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5
echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6
if test "${lt_cv_prog_compiler_c_o_GCJ+set}" = set; then
@@ -15155,38 +15876,36 @@ else
mkdir out
printf "$lt_simple_compile_test_code" > conftest.$ac_ext
- # According to Tom Tromey, Ian Lance Taylor reported there are C compilers
- # that will create temporary files in the current directory regardless of
- # the output directory. Thus, making CWD read-only will cause this test
- # to fail, enabling locking or at least warning the user not to do parallel
- # builds.
- chmod -w .
-
lt_compiler_flag="-o out/conftest2.$ac_objext"
# Insert the option either (1) after the last *FLAGS variable, or
# (2) before a word containing "conftest.", or (3) at the end.
# Note that $ac_compile itself does not contain backslashes and begins
# with a dollar sign (not a hyphen), so the echo should work correctly.
lt_compile=`echo "$ac_compile" | $SED \
- -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:15174: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:15888: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:15178: \$? = $ac_status" >&5
+ echo "$as_me:15892: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings
- if test ! -s out/conftest.err; then
+ $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
lt_cv_prog_compiler_c_o_GCJ=yes
fi
fi
- chmod u+w .
- $rm conftest* out/*
- rmdir out
+ chmod u+w . 2>&5
+ $rm conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files
+ $rm out/* && rmdir out
cd ..
rmdir conftest
$rm conftest*
@@ -15257,6 +15976,16 @@ echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared librar
# rely on this symbol name, it's probably fine to never include it in
# preloaded symbol tables.
extract_expsyms_cmds=
+ # Just being paranoid about ensuring that cc_basename is set.
+ for cc_temp in $compiler""; do
+ case $cc_temp in
+ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+done
+cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
case $host_os in
cygwin* | mingw* | pw32*)
@@ -15267,6 +15996,10 @@ echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared librar
with_gnu_ld=no
fi
;;
+ interix*)
+ # we just hope/assume this is gcc and not c89 (= MSVC++)
+ with_gnu_ld=yes
+ ;;
openbsd*)
with_gnu_ld=no
;;
@@ -15277,6 +16010,27 @@ echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared librar
# If archive_cmds runs LD, not CC, wlarc should be empty
wlarc='${wl}'
+ # Set some defaults for GNU ld with shared library support. These
+ # are reset later if shared libraries are not supported. Putting them
+ # here allows them to be overridden if necessary.
+ runpath_var=LD_RUN_PATH
+ hardcode_libdir_flag_spec_GCJ='${wl}--rpath ${wl}$libdir'
+ export_dynamic_flag_spec_GCJ='${wl}--export-dynamic'
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then
+ whole_archive_flag_spec_GCJ="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ else
+ whole_archive_flag_spec_GCJ=
+ fi
+ supports_anon_versioning=no
+ case `$LD -v 2>/dev/null` in
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
+ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+ *\ 2.11.*) ;; # other 2.11 versions
+ *) supports_anon_versioning=yes ;;
+ esac
+
# See if GNU ld supports shared libraries.
case $host_os in
aix3* | aix4* | aix5*)
@@ -15327,10 +16081,10 @@ EOF
allow_undefined_flag_GCJ=unsupported
always_export_symbols_GCJ=no
enable_shared_with_static_runtimes_GCJ=yes
- export_symbols_cmds_GCJ='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols'
+ export_symbols_cmds_GCJ='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols'
if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
- archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib'
+ archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
# If the export-symbols file already is a .def file (1st line
# is EXPORTS), use it as is; otherwise, prepend...
archive_expsym_cmds_GCJ='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
@@ -15339,13 +16093,60 @@ EOF
echo EXPORTS > $output_objdir/$soname.def;
cat $export_symbols >> $output_objdir/$soname.def;
fi~
- $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib'
+ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
else
- ld_shlibs=no
+ ld_shlibs_GCJ=no
+ fi
+ ;;
+
+ interix3*)
+ hardcode_direct_GCJ=no
+ hardcode_shlibpath_var_GCJ=no
+ hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir'
+ export_dynamic_flag_spec_GCJ='${wl}-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ archive_cmds_GCJ='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ archive_expsym_cmds_GCJ='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+
+ linux*)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ tmp_addflag=
+ case $cc_basename,$host_cpu in
+ pgcc*) # Portland Group C compiler
+ whole_archive_flag_spec_GCJ='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
+ tmp_addflag=' $pic_flag'
+ ;;
+ pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers
+ whole_archive_flag_spec_GCJ='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
+ tmp_addflag=' $pic_flag -Mnomain' ;;
+ ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
+ tmp_addflag=' -i_dynamic' ;;
+ efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64
+ tmp_addflag=' -i_dynamic -nofor_main' ;;
+ ifc* | ifort*) # Intel Fortran compiler
+ tmp_addflag=' -nofor_main' ;;
+ esac
+ archive_cmds_GCJ='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+
+ if test $supports_anon_versioning = yes; then
+ archive_expsym_cmds_GCJ='$echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ $echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+ fi
+ link_all_deplibs_GCJ=no
+ else
+ ld_shlibs_GCJ=no
fi
;;
- netbsd*)
+ netbsd* | netbsdelf*-gnu | knetbsd*-gnu)
if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
archive_cmds_GCJ='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
wlarc=
@@ -15355,7 +16156,7 @@ EOF
fi
;;
- solaris* | sysv5*)
+ solaris*)
if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
ld_shlibs_GCJ=no
cat <<EOF 1>&2
@@ -15376,6 +16177,33 @@ EOF
fi
;;
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+ case `$LD -v 2>&1` in
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
+ ld_shlibs_GCJ=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ ;;
+ *)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ hardcode_libdir_flag_spec_GCJ='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`'
+ archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib'
+ archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib'
+ else
+ ld_shlibs_GCJ=no
+ fi
+ ;;
+ esac
+ ;;
+
sunos4*)
archive_cmds_GCJ='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
wlarc=
@@ -15383,31 +16211,6 @@ EOF
hardcode_shlibpath_var_GCJ=no
;;
- linux*)
- if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
- tmp_archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
- archive_cmds_GCJ="$tmp_archive_cmds"
- supports_anon_versioning=no
- case `$LD -v 2>/dev/null` in
- *\ 01.* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
- *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
- *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
- *\ 2.11.*) ;; # other 2.11 versions
- *) supports_anon_versioning=yes ;;
- esac
- if test $supports_anon_versioning = yes; then
- archive_expsym_cmds_GCJ='$echo "{ global:" > $output_objdir/$libname.ver~
-cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
-$echo "local: *; };" >> $output_objdir/$libname.ver~
- $CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
- else
- archive_expsym_cmds_GCJ="$tmp_archive_cmds"
- fi
- else
- ld_shlibs_GCJ=no
- fi
- ;;
-
*)
if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
@@ -15418,16 +16221,11 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~
;;
esac
- if test "$ld_shlibs_GCJ" = yes; then
- runpath_var=LD_RUN_PATH
- hardcode_libdir_flag_spec_GCJ='${wl}--rpath ${wl}$libdir'
- export_dynamic_flag_spec_GCJ='${wl}--export-dynamic'
- # ancient GNU ld didn't support --whole-archive et. al.
- if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then
- whole_archive_flag_spec_GCJ="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
- else
- whole_archive_flag_spec_GCJ=
- fi
+ if test "$ld_shlibs_GCJ" = no; then
+ runpath_var=
+ hardcode_libdir_flag_spec_GCJ=
+ export_dynamic_flag_spec_GCJ=
+ whole_archive_flag_spec_GCJ=
fi
else
# PORTME fill in a description of your system's linker (not GNU ld)
@@ -15439,7 +16237,7 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~
# Note: this linker hardcodes the directories in LIBPATH if there
# are no directories specified by -L.
hardcode_minus_L_GCJ=yes
- if test "$GCC" = yes && test -z "$link_static_flag"; then
+ if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
# Neither direct hardcoding nor static linking is supported with a
# broken collect2.
hardcode_direct_GCJ=unsupported
@@ -15473,6 +16271,7 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~
break
fi
done
+ ;;
esac
exp_sym_flag='-bexport'
@@ -15491,7 +16290,7 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~
link_all_deplibs_GCJ=yes
if test "$GCC" = yes; then
- case $host_os in aix4.012|aix4.012.*)
+ case $host_os in aix4.[012]|aix4.[012].*)
# We only want to do this on AIX 4.2 and lower, the check
# below for broken collect2 doesn't work under 4.3+
collect2name=`${CC} -print-prog-name=collect2`
@@ -15510,8 +16309,12 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~
hardcode_libdir_flag_spec_GCJ='-L$libdir'
hardcode_libdir_separator_GCJ=
fi
+ ;;
esac
shared_flag='-shared'
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag="$shared_flag "'${wl}-G'
+ fi
else
# not using gcc
if test "$host_cpu" = ia64; then
@@ -15519,11 +16322,11 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~
# chokes on -Wl,-G. The following line is correct:
shared_flag='-G'
else
- if test "$aix_use_runtimelinking" = yes; then
+ if test "$aix_use_runtimelinking" = yes; then
shared_flag='${wl}-G'
else
shared_flag='${wl}-bM:SRE'
- fi
+ fi
fi
fi
@@ -15536,7 +16339,6 @@ $echo "local: *; };" >> $output_objdir/$libname.ver~
allow_undefined_flag_GCJ='-berok'
# Determine the default libpath from the value encoded in an empty executable.
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -15553,11 +16355,20 @@ main ()
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
+ (eval $ac_link) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest$ac_exeext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -15574,20 +16385,20 @@ else
sed 's/^/| /' conftest.$ac_ext >&5
fi
-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
hardcode_libdir_flag_spec_GCJ='${wl}-blibpath:$libdir:'"$aix_libpath"
- archive_expsym_cmds_GCJ="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+ archive_expsym_cmds_GCJ="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
else
if test "$host_cpu" = ia64; then
hardcode_libdir_flag_spec_GCJ='${wl}-R $libdir:/usr/lib:/lib'
allow_undefined_flag_GCJ="-z nodefs"
- archive_expsym_cmds_GCJ="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"
+ archive_expsym_cmds_GCJ="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
else
# Determine the default libpath from the value encoded in an empty executable.
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -15604,11 +16415,20 @@ main ()
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
+ (eval $ac_link) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest$ac_exeext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -15625,7 +16445,8 @@ else
sed 's/^/| /' conftest.$ac_ext >&5
fi
-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
hardcode_libdir_flag_spec_GCJ='${wl}-blibpath:$libdir:'"$aix_libpath"
@@ -15633,13 +16454,11 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
# -berok will link without error, but may produce a broken library.
no_undefined_flag_GCJ=' ${wl}-bernotok'
allow_undefined_flag_GCJ=' ${wl}-berok'
- # -bexpall does not export symbols beginning with underscore (_)
- always_export_symbols_GCJ=yes
# Exported symbols can be pulled into shared objects from archives
- whole_archive_flag_spec_GCJ=' '
+ whole_archive_flag_spec_GCJ='$convenience'
archive_cmds_need_lc_GCJ=yes
- # This is similar to how AIX traditionally builds it's shared libraries.
- archive_expsym_cmds_GCJ="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+ # This is similar to how AIX traditionally builds its shared libraries.
+ archive_expsym_cmds_GCJ="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
fi
fi
;;
@@ -15652,7 +16471,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
ld_shlibs_GCJ=no
;;
- bsdi4*)
+ bsdi[45]*)
export_dynamic_flag_spec_GCJ=-rdynamic
;;
@@ -15666,55 +16485,64 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
# Tell ltmain to make .lib files, not .a files.
libext=lib
# Tell ltmain to make .dll files, not .so files.
- shrext=".dll"
+ shrext_cmds=".dll"
# FIXME: Setting linknames here is a bad hack.
archive_cmds_GCJ='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames='
# The linker will automatically build a .lib file if we build a DLL.
old_archive_From_new_cmds_GCJ='true'
# FIXME: Should let the user specify the lib program.
old_archive_cmds_GCJ='lib /OUT:$oldlib$oldobjs$old_deplibs'
- fix_srcfile_path='`cygpath -w "$srcfile"`'
+ fix_srcfile_path_GCJ='`cygpath -w "$srcfile"`'
enable_shared_with_static_runtimes_GCJ=yes
;;
darwin* | rhapsody*)
- if $CC -v 2>&1 | grep 'Apple' >/dev/null ; then
- archive_cmds_need_lc_GCJ=no
- case "$host_os" in
- rhapsody* | darwin1.[012])
- allow_undefined_flag_GCJ='-undefined suppress'
- ;;
- *) # Darwin 1.3 on
- test -z ${LD_TWOLEVEL_NAMESPACE} && allow_undefined_flag_GCJ='-flat_namespace -undefined suppress'
- ;;
+ case $host_os in
+ rhapsody* | darwin1.[012])
+ allow_undefined_flag_GCJ='${wl}-undefined ${wl}suppress'
+ ;;
+ *) # Darwin 1.3 on
+ if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then
+ allow_undefined_flag_GCJ='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
+ else
+ case ${MACOSX_DEPLOYMENT_TARGET} in
+ 10.[012])
+ allow_undefined_flag_GCJ='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
+ ;;
+ 10.*)
+ allow_undefined_flag_GCJ='${wl}-undefined ${wl}dynamic_lookup'
+ ;;
+ esac
+ fi
+ ;;
esac
- # FIXME: Relying on posixy $() will cause problems for
- # cross-compilation, but unfortunately the echo tests do not
- # yet detect zsh echo's removal of \ escapes. Also zsh mangles
- # `"' quotes if we put them in here... so don't!
- lt_int_apple_cc_single_mod=no
- output_verbose_link_cmd='echo'
- if $CC -dumpspecs 2>&1 | grep 'single_module' >/dev/null ; then
- lt_int_apple_cc_single_mod=yes
- fi
- if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
- archive_cmds_GCJ='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
- else
- archive_cmds_GCJ='$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
- fi
- module_cmds_GCJ='$CC -bundle ${wl}-bind_at_load $allow_undefined_flag -o $lib $libobjs $deplibs$compiler_flags'
- # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's
- if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
- archive_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
- else
- archive_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r ${wl}-bind_at_load -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
- fi
- module_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -bundle $allow_undefined_flag -o $lib $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ archive_cmds_need_lc_GCJ=no
hardcode_direct_GCJ=no
hardcode_automatic_GCJ=yes
hardcode_shlibpath_var_GCJ=unsupported
- whole_archive_flag_spec_GCJ='-all_load $convenience'
+ whole_archive_flag_spec_GCJ=''
link_all_deplibs_GCJ=yes
+ if test "$GCC" = yes ; then
+ output_verbose_link_cmd='echo'
+ archive_cmds_GCJ='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+ module_cmds_GCJ='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+ # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
+ archive_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ module_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ else
+ case $cc_basename in
+ xlc*)
+ output_verbose_link_cmd='echo'
+ archive_cmds_GCJ='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring'
+ module_cmds_GCJ='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+ # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
+ archive_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ module_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ ;;
+ *)
+ ld_shlibs_GCJ=no
+ ;;
+ esac
fi
;;
@@ -15748,13 +16576,22 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
;;
# FreeBSD 3 and greater uses gcc -shared to do shared libraries.
- freebsd*)
+ freebsd* | dragonfly*)
archive_cmds_GCJ='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
hardcode_libdir_flag_spec_GCJ='-R$libdir'
hardcode_direct_GCJ=yes
hardcode_shlibpath_var_GCJ=no
;;
+ # GNU/kFreeBSD uses gcc -shared to do shared libraries.
+ kfreebsd*-gnu)
+ archive_cmds_GCJ='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
+ hardcode_libdir_flag_spec_GCJ='-R$libdir'
+ hardcode_direct_GCJ=yes
+ hardcode_shlibpath_var_GCJ=no
+ link_all_deplibs_GCJ=no
+ ;;
+
hpux9*)
if test "$GCC" = yes; then
archive_cmds_GCJ='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
@@ -15771,47 +16608,62 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
export_dynamic_flag_spec_GCJ='${wl}-E'
;;
- hpux10* | hpux11*)
+ hpux10*)
if test "$GCC" = yes -a "$with_gnu_ld" = no; then
- case "$host_cpu" in
- hppa*64*|ia64*)
+ archive_cmds_GCJ='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds_GCJ='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ if test "$with_gnu_ld" = no; then
+ hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator_GCJ=:
+
+ hardcode_direct_GCJ=yes
+ export_dynamic_flag_spec_GCJ='${wl}-E'
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L_GCJ=yes
+ fi
+ ;;
+
+ hpux11*)
+ if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+ case $host_cpu in
+ hppa*64*)
archive_cmds_GCJ='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
;;
+ ia64*)
+ archive_cmds_GCJ='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
*)
archive_cmds_GCJ='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
;;
esac
else
- case "$host_cpu" in
- hppa*64*|ia64*)
- archive_cmds_GCJ='$LD -b +h $soname -o $lib $libobjs $deplibs $linker_flags'
+ case $host_cpu in
+ hppa*64*)
+ archive_cmds_GCJ='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ archive_cmds_GCJ='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
;;
*)
- archive_cmds_GCJ='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+ archive_cmds_GCJ='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
;;
esac
fi
if test "$with_gnu_ld" = no; then
- case "$host_cpu" in
- hppa*64*)
- hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir'
+ hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator_GCJ=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
hardcode_libdir_flag_spec_ld_GCJ='+b $libdir'
- hardcode_libdir_separator_GCJ=:
- hardcode_direct_GCJ=no
- hardcode_shlibpath_var_GCJ=no
- ;;
- ia64*)
- hardcode_libdir_flag_spec_GCJ='-L$libdir'
hardcode_direct_GCJ=no
hardcode_shlibpath_var_GCJ=no
-
- # hardcode_minus_L: Not really in the search PATH,
- # but as the default location of the library.
- hardcode_minus_L_GCJ=yes
;;
*)
- hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir'
- hardcode_libdir_separator_GCJ=:
hardcode_direct_GCJ=yes
export_dynamic_flag_spec_GCJ='${wl}-E'
@@ -15835,7 +16687,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
link_all_deplibs_GCJ=yes
;;
- netbsd*)
+ netbsd* | netbsdelf*-gnu | knetbsd*-gnu)
if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
else
@@ -15859,6 +16711,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
hardcode_shlibpath_var_GCJ=no
if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
archive_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir'
export_dynamic_flag_spec_GCJ='${wl}-E'
else
@@ -15904,7 +16757,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
allow_undefined_flag_GCJ=' -expect_unresolved \*'
archive_cmds_GCJ='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
archive_expsym_cmds_GCJ='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~
- $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib~$rm $lib.exp'
+ $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp'
# Both c and cxx compiler support -rpath directly
hardcode_libdir_flag_spec_GCJ='-rpath $libdir'
@@ -15912,21 +16765,15 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
hardcode_libdir_separator_GCJ=:
;;
- sco3.2v5*)
- archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
- hardcode_shlibpath_var_GCJ=no
- export_dynamic_flag_spec_GCJ='${wl}-Bexport'
- runpath_var=LD_RUN_PATH
- hardcode_runpath_var=yes
- ;;
-
solaris*)
no_undefined_flag_GCJ=' -z text'
if test "$GCC" = yes; then
+ wlarc='${wl}'
archive_cmds_GCJ='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
archive_expsym_cmds_GCJ='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
$CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp'
else
+ wlarc=''
archive_cmds_GCJ='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
archive_expsym_cmds_GCJ='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
$LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
@@ -15935,8 +16782,18 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
hardcode_shlibpath_var_GCJ=no
case $host_os in
solaris2.[0-5] | solaris2.[0-5].*) ;;
- *) # Supported since Solaris 2.6 (maybe 2.5.1?)
- whole_archive_flag_spec_GCJ='-z allextract$convenience -z defaultextract' ;;
+ *)
+ # The compiler driver will combine linker options so we
+ # cannot just pass the convience library names through
+ # without $wl, iff we do not link with $LD.
+ # Luckily, gcc supports the same syntax we need for Sun Studio.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ case $wlarc in
+ '')
+ whole_archive_flag_spec_GCJ='-z allextract$convenience -z defaultextract' ;;
+ *)
+ whole_archive_flag_spec_GCJ='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;;
+ esac ;;
esac
link_all_deplibs_GCJ=yes
;;
@@ -15993,36 +16850,45 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
fi
;;
- sysv4.2uw2*)
- archive_cmds_GCJ='$LD -G -o $lib $libobjs $deplibs $linker_flags'
- hardcode_direct_GCJ=yes
- hardcode_minus_L_GCJ=no
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7*)
+ no_undefined_flag_GCJ='${wl}-z,text'
+ archive_cmds_need_lc_GCJ=no
hardcode_shlibpath_var_GCJ=no
- hardcode_runpath_var=yes
- runpath_var=LD_RUN_PATH
- ;;
+ runpath_var='LD_RUN_PATH'
- sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[78]* | unixware7*)
- no_undefined_flag_GCJ='${wl}-z ${wl}text'
if test "$GCC" = yes; then
- archive_cmds_GCJ='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds_GCJ='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds_GCJ='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
else
- archive_cmds_GCJ='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_cmds_GCJ='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds_GCJ='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
fi
- runpath_var='LD_RUN_PATH'
- hardcode_shlibpath_var_GCJ=no
;;
- sysv5*)
- no_undefined_flag_GCJ=' -z text'
- # $CC -shared without GNU ld will not create a library from C++
- # object files and a static libstdc++, better avoid it by now
- archive_cmds_GCJ='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
- archive_expsym_cmds_GCJ='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
- $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
- hardcode_libdir_flag_spec_GCJ=
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We can NOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ no_undefined_flag_GCJ='${wl}-z,text'
+ allow_undefined_flag_GCJ='${wl}-z,nodefs'
+ archive_cmds_need_lc_GCJ=no
hardcode_shlibpath_var_GCJ=no
+ hardcode_libdir_flag_spec_GCJ='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
+ hardcode_libdir_separator_GCJ=':'
+ link_all_deplibs_GCJ=yes
+ export_dynamic_flag_spec_GCJ='${wl}-Bexport'
runpath_var='LD_RUN_PATH'
+
+ if test "$GCC" = yes; then
+ archive_cmds_GCJ='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds_GCJ='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds_GCJ='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds_GCJ='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
;;
uts4*)
@@ -16041,11 +16907,6 @@ echo "$as_me:$LINENO: result: $ld_shlibs_GCJ" >&5
echo "${ECHO_T}$ld_shlibs_GCJ" >&6
test "$ld_shlibs_GCJ" = no && can_build_shared=no
-variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
-if test "$GCC" = yes; then
- variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
-fi
-
#
# Do we need to explicitly link libc?
#
@@ -16078,6 +16939,7 @@ echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&
libobjs=conftest.$ac_objext
deplibs=
wl=$lt_prog_compiler_wl_GCJ
+ pic_flag=$lt_prog_compiler_pic_GCJ
compiler_flags=-v
linker_flags=-v
verstring=
@@ -16108,78 +16970,12 @@ echo "${ECHO_T}$archive_cmds_need_lc_GCJ" >&6
;;
esac
-echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5
-echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6
-hardcode_action_GCJ=
-if test -n "$hardcode_libdir_flag_spec_GCJ" || \
- test -n "$runpath_var GCJ" || \
- test "X$hardcode_automatic_GCJ"="Xyes" ; then
-
- # We can hardcode non-existant directories.
- if test "$hardcode_direct_GCJ" != no &&
- # If the only mechanism to avoid hardcoding is shlibpath_var, we
- # have to relink, otherwise we might link with an installed library
- # when we should be linking with a yet-to-be-installed one
- ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, GCJ)" != no &&
- test "$hardcode_minus_L_GCJ" != no; then
- # Linking always hardcodes the temporary library directory.
- hardcode_action_GCJ=relink
- else
- # We can link without hardcoding, and we can hardcode nonexisting dirs.
- hardcode_action_GCJ=immediate
- fi
-else
- # We cannot hardcode anything, or else we can only hardcode existing
- # directories.
- hardcode_action_GCJ=unsupported
-fi
-echo "$as_me:$LINENO: result: $hardcode_action_GCJ" >&5
-echo "${ECHO_T}$hardcode_action_GCJ" >&6
-
-if test "$hardcode_action_GCJ" = relink; then
- # Fast installation is not supported
- enable_fast_install=no
-elif test "$shlibpath_overrides_runpath" = yes ||
- test "$enable_shared" = no; then
- # Fast installation is not necessary
- enable_fast_install=needless
-fi
-
-striplib=
-old_striplib=
-echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5
-echo $ECHO_N "checking whether stripping libraries is possible... $ECHO_C" >&6
-if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then
- test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
- test -z "$striplib" && striplib="$STRIP --strip-unneeded"
- echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6
-else
-# FIXME - insert some real tests, host_os isn't really good enough
- case $host_os in
- darwin*)
- if test -n "$STRIP" ; then
- striplib="$STRIP -x"
- echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6
- else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
- ;;
- *)
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
- ;;
- esac
-fi
-
echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5
echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6
library_names_spec=
libname_spec='lib$name'
soname_spec=
-shrext=".so"
+shrext_cmds=".so"
postinstall_cmds=
postuninstall_cmds=
finish_cmds=
@@ -16267,7 +17063,7 @@ aix4* | aix5*)
amigaos*)
library_names_spec='$libname.ixlibrary $libname.a'
# Create ${libname}_ixlibrary.a entries in /sys/libs.
- finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "(cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a)"; (cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a) || exit 1; done'
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
;;
beos*)
@@ -16276,7 +17072,7 @@ beos*)
shlibpath_var=LIBRARY_PATH
;;
-bsdi4*)
+bsdi[45]*)
version_type=linux
need_version=no
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
@@ -16292,7 +17088,7 @@ bsdi4*)
cygwin* | mingw* | pw32*)
version_type=windows
- shrext=".dll"
+ shrext_cmds=".dll"
need_version=no
need_lib_prefix=no
@@ -16304,7 +17100,8 @@ cygwin* | mingw* | pw32*)
dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~
dldir=$destdir/`dirname \$dlpath`~
test -d \$dldir || mkdir -p \$dldir~
- $install_prog $dir/$dlname \$dldir/$dlname'
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname'
postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
dlpath=$dir/\$dldll~
$rm \$dlpath'
@@ -16314,7 +17111,7 @@ cygwin* | mingw* | pw32*)
cygwin*)
# Cygwin DLLs use 'cyg' prefix rather than 'lib'
soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
- sys_lib_search_path_spec="/lib /lib/w32api /usr/lib /usr/local/lib"
+ sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
;;
mingw*)
# MinGW DLLs use traditional 'lib' prefix
@@ -16334,7 +17131,7 @@ cygwin* | mingw* | pw32*)
;;
pw32*)
# pw32 DLLs use 'pw' prefix rather than 'lib'
- library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/./-/g'`${versuffix}${shared_ext}'
+ library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
;;
esac
;;
@@ -16353,17 +17150,16 @@ darwin* | rhapsody*)
version_type=darwin
need_lib_prefix=no
need_version=no
- # FIXME: Relying on posixy $() will cause problems for
- # cross-compilation, but unfortunately the echo tests do not
- # yet detect zsh echo's removal of \ escapes.
library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext'
soname_spec='${libname}${release}${major}$shared_ext'
shlibpath_overrides_runpath=yes
shlibpath_var=DYLD_LIBRARY_PATH
- shrext='$(test .$module = .yes && echo .so || echo .dylib)'
+ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
# Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same.
- if $CC -v 2>&1 | grep 'Apple' >/dev/null ; then
- sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"`
+ if test "$GCC" = yes; then
+ sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"`
+ else
+ sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib'
fi
sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
;;
@@ -16381,8 +17177,29 @@ freebsd1*)
dynamic_linker=no
;;
-freebsd*)
- objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout`
+kfreebsd*-gnu)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='GNU ld.so'
+ ;;
+
+freebsd* | dragonfly*)
+ # DragonFly does not have aout. When/if they implement a new
+ # versioning mechanism, adjust this.
+ if test -x /usr/bin/objformat; then
+ objformat=`/usr/bin/objformat`
+ else
+ case $host_os in
+ freebsd[123]*) objformat=aout ;;
+ *) objformat=elf ;;
+ esac
+ fi
version_type=freebsd-$objformat
case $version_type in
freebsd-elf*)
@@ -16400,14 +17217,19 @@ freebsd*)
freebsd2*)
shlibpath_overrides_runpath=yes
;;
- freebsd3.01* | freebsdelf3.01*)
+ freebsd3.[01]* | freebsdelf3.[01]*)
shlibpath_overrides_runpath=yes
hardcode_into_libs=yes
;;
- *) # from 3.2 on
+ freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
shlibpath_overrides_runpath=no
hardcode_into_libs=yes
;;
+ freebsd*) # from 4.6 on
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
esac
;;
@@ -16427,9 +17249,9 @@ hpux9* | hpux10* | hpux11*)
version_type=sunos
need_lib_prefix=no
need_version=no
- case "$host_cpu" in
+ case $host_cpu in
ia64*)
- shrext='.so'
+ shrext_cmds='.so'
hardcode_into_libs=yes
dynamic_linker="$host_os dld.so"
shlibpath_var=LD_LIBRARY_PATH
@@ -16444,7 +17266,7 @@ hpux9* | hpux10* | hpux11*)
sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
;;
hppa*64*)
- shrext='.sl'
+ shrext_cmds='.sl'
hardcode_into_libs=yes
dynamic_linker="$host_os dld.sl"
shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
@@ -16455,7 +17277,7 @@ hpux9* | hpux10* | hpux11*)
sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
;;
*)
- shrext='.sl'
+ shrext_cmds='.sl'
dynamic_linker="$host_os dld.sl"
shlibpath_var=SHLIB_PATH
shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
@@ -16467,6 +17289,18 @@ hpux9* | hpux10* | hpux11*)
postinstall_cmds='chmod 555 $lib'
;;
+interix3*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
irix5* | irix6* | nonstopux*)
case $host_os in
nonstopux*) version_type=nonstopux ;;
@@ -16524,6 +17358,12 @@ linux*)
# before this can be enabled.
hardcode_into_libs=yes
+ # Append ld.so.conf contents to the search path
+ if test -f /etc/ld.so.conf; then
+ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
+ sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+ fi
+
# We used to test for /lib/ld.so.1 and disable shared libraries on
# powerpc, because MkLinux only supported shared libraries with the
# GNU dynamic linker. Since this was broken with cross compilers,
@@ -16531,30 +17371,30 @@ linux*)
# people can always --disable-shared, the test was removed, and we
# assume the GNU/Linux dynamic linker is in use.
dynamic_linker='GNU/Linux ld.so'
+ ;;
- # Find out which ABI we are using (multilib Linux x86_64 hack).
- libsuff=
- case "$host_cpu" in
- x86_64*|s390x*)
- echo '#line 16539 "configure"' > conftest.$ac_ext
- if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; then
- case `/usr/bin/file conftest.$ac_objext` in
- *64-bit*)
- libsuff=64
- ;;
- esac
- fi
- rm -rf conftest*
- ;;
- *)
- ;;
- esac
- sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff}"
- sys_lib_search_path_spec="/lib${libsuff} /usr/lib${libsuff} /usr/local/lib${libsuff}"
+netbsdelf*-gnu)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='NetBSD ld.elf_so'
+ ;;
+
+knetbsd*-gnu)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='GNU ld.so'
;;
netbsd*)
@@ -16566,7 +17406,7 @@ netbsd*)
finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
dynamic_linker='NetBSD (a.out) ld.so'
else
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} ${libname}${shared_ext}'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
soname_spec='${libname}${release}${shared_ext}$major'
dynamic_linker='NetBSD ld.elf_so'
fi
@@ -16582,7 +17422,7 @@ newsos6)
shlibpath_overrides_runpath=yes
;;
-nto-qnx)
+nto-qnx*)
version_type=linux
need_lib_prefix=no
need_version=no
@@ -16594,8 +17434,13 @@ nto-qnx)
openbsd*)
version_type=sunos
+ sys_lib_dlsearch_path_spec="/usr/lib"
need_lib_prefix=no
- need_version=no
+ # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+ case $host_os in
+ openbsd3.3 | openbsd3.3.*) need_version=yes ;;
+ *) need_version=no ;;
+ esac
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
shlibpath_var=LD_LIBRARY_PATH
@@ -16615,7 +17460,7 @@ openbsd*)
os2*)
libname_spec='$name'
- shrext=".dll"
+ shrext_cmds=".dll"
need_lib_prefix=no
library_names_spec='$libname${shared_ext} $libname.a'
dynamic_linker='OS/2 ld.exe'
@@ -16633,13 +17478,6 @@ osf3* | osf4* | osf5*)
sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
;;
-sco3.2v5*)
- version_type=osf
- soname_spec='${libname}${release}${shared_ext}$major'
- library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
- shlibpath_var=LD_LIBRARY_PATH
- ;;
-
solaris*)
version_type=linux
need_lib_prefix=no
@@ -16665,7 +17503,7 @@ sunos4*)
need_version=yes
;;
-sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+sysv4 | sysv4.3*)
version_type=linux
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
soname_spec='${libname}${release}${shared_ext}$major'
@@ -16698,6 +17536,29 @@ sysv4*MP*)
fi
;;
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ version_type=freebsd-elf
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ hardcode_into_libs=yes
+ if test "$with_gnu_ld" = yes; then
+ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+ shlibpath_overrides_runpath=no
+ else
+ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+ shlibpath_overrides_runpath=yes
+ case $host_os in
+ sco3.2v5*)
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+ ;;
+ esac
+ fi
+ sys_lib_dlsearch_path_spec='/usr/lib'
+ ;;
+
uts4*)
version_type=linux
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
@@ -16713,724 +17574,46 @@ echo "$as_me:$LINENO: result: $dynamic_linker" >&5
echo "${ECHO_T}$dynamic_linker" >&6
test "$dynamic_linker" = no && can_build_shared=no
-if test "x$enable_dlopen" != xyes; then
- enable_dlopen=unknown
- enable_dlopen_self=unknown
- enable_dlopen_self_static=unknown
-else
- lt_cv_dlopen=no
- lt_cv_dlopen_libs=
-
- case $host_os in
- beos*)
- lt_cv_dlopen="load_add_on"
- lt_cv_dlopen_libs=
- lt_cv_dlopen_self=yes
- ;;
-
- mingw* | pw32*)
- lt_cv_dlopen="LoadLibrary"
- lt_cv_dlopen_libs=
- ;;
-
- cygwin*)
- lt_cv_dlopen="dlopen"
- lt_cv_dlopen_libs=
- ;;
-
- darwin*)
- # if libdl is installed we need to link against it
- echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5
-echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6
-if test "${ac_cv_lib_dl_dlopen+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-ldl $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any gcc2 internal prototype to avoid an error. */
-#ifdef __cplusplus
-extern "C"
-#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char dlopen ();
-int
-main ()
-{
-dlopen ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_lib_dl_dlopen=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_lib_dl_dlopen=no
-fi
-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5
-echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6
-if test $ac_cv_lib_dl_dlopen = yes; then
- lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
-else
-
- lt_cv_dlopen="dyld"
- lt_cv_dlopen_libs=
- lt_cv_dlopen_self=yes
-
-fi
-
- ;;
-
- *)
- echo "$as_me:$LINENO: checking for shl_load" >&5
-echo $ECHO_N "checking for shl_load... $ECHO_C" >&6
-if test "${ac_cv_func_shl_load+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char shl_load (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-/* Override any gcc2 internal prototype to avoid an error. */
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char shl_load ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_shl_load) || defined (__stub___shl_load)
-choke me
-#else
-char (*f) () = shl_load;
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-int
-main ()
-{
-return f != shl_load;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_func_shl_load=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_func_shl_load=no
-fi
-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5
-echo "${ECHO_T}$ac_cv_func_shl_load" >&6
-if test $ac_cv_func_shl_load = yes; then
- lt_cv_dlopen="shl_load"
-else
- echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5
-echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6
-if test "${ac_cv_lib_dld_shl_load+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-ldld $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any gcc2 internal prototype to avoid an error. */
-#ifdef __cplusplus
-extern "C"
-#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char shl_load ();
-int
-main ()
-{
-shl_load ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_lib_dld_shl_load=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_lib_dld_shl_load=no
-fi
-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5
-echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6
-if test $ac_cv_lib_dld_shl_load = yes; then
- lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"
-else
- echo "$as_me:$LINENO: checking for dlopen" >&5
-echo $ECHO_N "checking for dlopen... $ECHO_C" >&6
-if test "${ac_cv_func_dlopen+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char dlopen (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-/* Override any gcc2 internal prototype to avoid an error. */
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char dlopen ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_dlopen) || defined (__stub___dlopen)
-choke me
-#else
-char (*f) () = dlopen;
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-int
-main ()
-{
-return f != dlopen;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_func_dlopen=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_func_dlopen=no
-fi
-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5
-echo "${ECHO_T}$ac_cv_func_dlopen" >&6
-if test $ac_cv_func_dlopen = yes; then
- lt_cv_dlopen="dlopen"
-else
- echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5
-echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6
-if test "${ac_cv_lib_dl_dlopen+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-ldl $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any gcc2 internal prototype to avoid an error. */
-#ifdef __cplusplus
-extern "C"
-#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char dlopen ();
-int
-main ()
-{
-dlopen ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_lib_dl_dlopen=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_lib_dl_dlopen=no
-fi
-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5
-echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6
-if test $ac_cv_lib_dl_dlopen = yes; then
- lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
-else
- echo "$as_me:$LINENO: checking for dlopen in -lsvld" >&5
-echo $ECHO_N "checking for dlopen in -lsvld... $ECHO_C" >&6
-if test "${ac_cv_lib_svld_dlopen+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lsvld $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any gcc2 internal prototype to avoid an error. */
-#ifdef __cplusplus
-extern "C"
-#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char dlopen ();
-int
-main ()
-{
-dlopen ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_lib_svld_dlopen=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_lib_svld_dlopen=no
-fi
-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_svld_dlopen" >&5
-echo "${ECHO_T}$ac_cv_lib_svld_dlopen" >&6
-if test $ac_cv_lib_svld_dlopen = yes; then
- lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"
-else
- echo "$as_me:$LINENO: checking for dld_link in -ldld" >&5
-echo $ECHO_N "checking for dld_link in -ldld... $ECHO_C" >&6
-if test "${ac_cv_lib_dld_dld_link+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-ldld $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any gcc2 internal prototype to avoid an error. */
-#ifdef __cplusplus
-extern "C"
-#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char dld_link ();
-int
-main ()
-{
-dld_link ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_lib_dld_dld_link=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_lib_dld_dld_link=no
-fi
-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_dld_dld_link" >&5
-echo "${ECHO_T}$ac_cv_lib_dld_dld_link" >&6
-if test $ac_cv_lib_dld_dld_link = yes; then
- lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"
-fi
-
-
-fi
-
-
-fi
-
-
-fi
-
-
-fi
-
-
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
fi
- ;;
- esac
+echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5
+echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6
+hardcode_action_GCJ=
+if test -n "$hardcode_libdir_flag_spec_GCJ" || \
+ test -n "$runpath_var_GCJ" || \
+ test "X$hardcode_automatic_GCJ" = "Xyes" ; then
- if test "x$lt_cv_dlopen" != xno; then
- enable_dlopen=yes
+ # We can hardcode non-existant directories.
+ if test "$hardcode_direct_GCJ" != no &&
+ # If the only mechanism to avoid hardcoding is shlibpath_var, we
+ # have to relink, otherwise we might link with an installed library
+ # when we should be linking with a yet-to-be-installed one
+ ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, GCJ)" != no &&
+ test "$hardcode_minus_L_GCJ" != no; then
+ # Linking always hardcodes the temporary library directory.
+ hardcode_action_GCJ=relink
else
- enable_dlopen=no
- fi
-
- case $lt_cv_dlopen in
- dlopen)
- save_CPPFLAGS="$CPPFLAGS"
- test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
-
- save_LDFLAGS="$LDFLAGS"
- eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
-
- save_LIBS="$LIBS"
- LIBS="$lt_cv_dlopen_libs $LIBS"
-
- echo "$as_me:$LINENO: checking whether a program can dlopen itself" >&5
-echo $ECHO_N "checking whether a program can dlopen itself... $ECHO_C" >&6
-if test "${lt_cv_dlopen_self+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test "$cross_compiling" = yes; then :
- lt_cv_dlopen_self=cross
-else
- lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
- lt_status=$lt_dlunknown
- cat > conftest.$ac_ext <<EOF
-#line 17235 "configure"
-#include "confdefs.h"
-
-#if HAVE_DLFCN_H
-#include <dlfcn.h>
-#endif
-
-#include <stdio.h>
-
-#ifdef RTLD_GLOBAL
-# define LT_DLGLOBAL RTLD_GLOBAL
-#else
-# ifdef DL_GLOBAL
-# define LT_DLGLOBAL DL_GLOBAL
-# else
-# define LT_DLGLOBAL 0
-# endif
-#endif
-
-/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
- find out it does not work in some platform. */
-#ifndef LT_DLLAZY_OR_NOW
-# ifdef RTLD_LAZY
-# define LT_DLLAZY_OR_NOW RTLD_LAZY
-# else
-# ifdef DL_LAZY
-# define LT_DLLAZY_OR_NOW DL_LAZY
-# else
-# ifdef RTLD_NOW
-# define LT_DLLAZY_OR_NOW RTLD_NOW
-# else
-# ifdef DL_NOW
-# define LT_DLLAZY_OR_NOW DL_NOW
-# else
-# define LT_DLLAZY_OR_NOW 0
-# endif
-# endif
-# endif
-# endif
-#endif
-
-#ifdef __cplusplus
-extern "C" void exit (int);
-#endif
-
-void fnord() { int i=42;}
-int main ()
-{
- void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
- int status = $lt_dlunknown;
-
- if (self)
- {
- if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
- else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
- /* dlclose (self); */
- }
-
- exit (status);
-}
-EOF
- if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then
- (./conftest; exit; ) 2>/dev/null
- lt_status=$?
- case x$lt_status in
- x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;
- x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;;
- x$lt_unknown|x*) lt_cv_dlopen_self=no ;;
- esac
- else :
- # compilation failed
- lt_cv_dlopen_self=no
+ # We can link without hardcoding, and we can hardcode nonexisting dirs.
+ hardcode_action_GCJ=immediate
fi
-fi
-rm -fr conftest*
-
-
-fi
-echo "$as_me:$LINENO: result: $lt_cv_dlopen_self" >&5
-echo "${ECHO_T}$lt_cv_dlopen_self" >&6
-
- if test "x$lt_cv_dlopen_self" = xyes; then
- LDFLAGS="$LDFLAGS $link_static_flag"
- echo "$as_me:$LINENO: checking whether a statically linked program can dlopen itself" >&5
-echo $ECHO_N "checking whether a statically linked program can dlopen itself... $ECHO_C" >&6
-if test "${lt_cv_dlopen_self_static+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
else
- if test "$cross_compiling" = yes; then :
- lt_cv_dlopen_self_static=cross
-else
- lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
- lt_status=$lt_dlunknown
- cat > conftest.$ac_ext <<EOF
-#line 17333 "configure"
-#include "confdefs.h"
-
-#if HAVE_DLFCN_H
-#include <dlfcn.h>
-#endif
-
-#include <stdio.h>
-
-#ifdef RTLD_GLOBAL
-# define LT_DLGLOBAL RTLD_GLOBAL
-#else
-# ifdef DL_GLOBAL
-# define LT_DLGLOBAL DL_GLOBAL
-# else
-# define LT_DLGLOBAL 0
-# endif
-#endif
-
-/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
- find out it does not work in some platform. */
-#ifndef LT_DLLAZY_OR_NOW
-# ifdef RTLD_LAZY
-# define LT_DLLAZY_OR_NOW RTLD_LAZY
-# else
-# ifdef DL_LAZY
-# define LT_DLLAZY_OR_NOW DL_LAZY
-# else
-# ifdef RTLD_NOW
-# define LT_DLLAZY_OR_NOW RTLD_NOW
-# else
-# ifdef DL_NOW
-# define LT_DLLAZY_OR_NOW DL_NOW
-# else
-# define LT_DLLAZY_OR_NOW 0
-# endif
-# endif
-# endif
-# endif
-#endif
-
-#ifdef __cplusplus
-extern "C" void exit (int);
-#endif
-
-void fnord() { int i=42;}
-int main ()
-{
- void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
- int status = $lt_dlunknown;
-
- if (self)
- {
- if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
- else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
- /* dlclose (self); */
- }
-
- exit (status);
-}
-EOF
- if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then
- (./conftest; exit; ) 2>/dev/null
- lt_status=$?
- case x$lt_status in
- x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;
- x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;;
- x$lt_unknown|x*) lt_cv_dlopen_self_static=no ;;
- esac
- else :
- # compilation failed
- lt_cv_dlopen_self_static=no
- fi
-fi
-rm -fr conftest*
-
-
+ # We cannot hardcode anything, or else we can only hardcode existing
+ # directories.
+ hardcode_action_GCJ=unsupported
fi
-echo "$as_me:$LINENO: result: $lt_cv_dlopen_self_static" >&5
-echo "${ECHO_T}$lt_cv_dlopen_self_static" >&6
- fi
-
- CPPFLAGS="$save_CPPFLAGS"
- LDFLAGS="$save_LDFLAGS"
- LIBS="$save_LIBS"
- ;;
- esac
-
- case $lt_cv_dlopen_self in
- yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
- *) enable_dlopen_self=unknown ;;
- esac
+echo "$as_me:$LINENO: result: $hardcode_action_GCJ" >&5
+echo "${ECHO_T}$hardcode_action_GCJ" >&6
- case $lt_cv_dlopen_self_static in
- yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
- *) enable_dlopen_self_static=unknown ;;
- esac
+if test "$hardcode_action_GCJ" = relink; then
+ # Fast installation is not supported
+ enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+ test "$enable_shared" = no; then
+ # Fast installation is not necessary
+ enable_fast_install=needless
fi
@@ -17447,7 +17630,8 @@ if test -f "$ltmain"; then
# Now quote all the things that may contain metacharacters while being
# careful not to overquote the AC_SUBSTed values. We take copies of the
# variables and quote the copies for generation of the libtool script.
- for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC NM SED SHELL \
+ for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \
+ SED SHELL STRIP \
libname_spec library_names_spec soname_spec extract_expsyms_cmds \
old_striplib striplib file_magic_cmd finish_cmds finish_eval \
deplibs_check_method reload_flag reload_cmds need_locks \
@@ -17547,6 +17731,12 @@ fast_install=$enable_fast_install
# The host system.
host_alias=$host_alias
host=$host
+host_os=$host_os
+
+# The build system.
+build_alias=$build_alias
+build=$build
+build_os=$build_os
# An echo program that does not interpret backslashes.
echo=$lt_echo
@@ -17558,6 +17748,9 @@ AR_FLAGS=$lt_AR_FLAGS
# A C compiler.
LTCC=$lt_LTCC
+# LTCC compiler flags.
+LTCFLAGS=$lt_LTCFLAGS
+
# A language-specific compiler.
CC=$lt_compiler_GCJ
@@ -17577,7 +17770,7 @@ LN_S=$lt_LN_S
NM=$lt_NM
# A symbol stripping program
-STRIP=$STRIP
+STRIP=$lt_STRIP
# Used to examine libraries when file_magic_cmd begins "file"
MAGIC_CMD=$MAGIC_CMD
@@ -17608,7 +17801,7 @@ objext="$ac_objext"
libext="$libext"
# Shared library suffix (normally ".so").
-shrext='$shrext'
+shrext_cmds='$shrext_cmds'
# Executable file suffix (normally "").
exeext="$exeext"
@@ -17623,7 +17816,7 @@ max_cmd_len=$lt_cv_sys_max_cmd_len
# Does compiler simultaneously support -c and -o options?
compiler_c_o=$lt_lt_cv_prog_compiler_c_o_GCJ
-# Must we lock files when doing compilation ?
+# Must we lock files when doing compilation?
need_locks=$lt_need_locks
# Do we need the lib prefix for modules?
@@ -17825,7 +18018,10 @@ else
# If there is no Makefile yet, we rely on a make rule to execute
# `config.status --recheck' to rerun these tests and create the
# libtool script then.
- test -f Makefile && make "$ltmain"
+ ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'`
+ if test -f "$ltmain_in"; then
+ test -f Makefile && make "$ltmain"
+ fi
fi
@@ -17864,15 +18060,42 @@ lt_simple_link_test_code="$lt_simple_compile_test_code"
# If no C compiler was specified, use CC.
LTCC=${LTCC-"$CC"}
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
# Allow CC to be a program name with arguments.
compiler=$CC
+# save warnings/boilerplate of simple test code
+ac_outfile=conftest.$ac_objext
+printf "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$rm conftest*
+
+ac_outfile=conftest.$ac_objext
+printf "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$rm conftest*
+
+
# Allow CC to be a program name with arguments.
lt_save_CC="$CC"
CC=${RC-"windres"}
compiler=$CC
compiler_RC=$CC
+for cc_temp in $compiler""; do
+ case $cc_temp in
+ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+done
+cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
+
lt_cv_prog_compiler_c_o_RC=yes
# The else clause should only fire when bootstrapping the
@@ -17888,7 +18111,8 @@ if test -f "$ltmain"; then
# Now quote all the things that may contain metacharacters while being
# careful not to overquote the AC_SUBSTed values. We take copies of the
# variables and quote the copies for generation of the libtool script.
- for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC NM SED SHELL \
+ for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \
+ SED SHELL STRIP \
libname_spec library_names_spec soname_spec extract_expsyms_cmds \
old_striplib striplib file_magic_cmd finish_cmds finish_eval \
deplibs_check_method reload_flag reload_cmds need_locks \
@@ -17988,6 +18212,12 @@ fast_install=$enable_fast_install
# The host system.
host_alias=$host_alias
host=$host
+host_os=$host_os
+
+# The build system.
+build_alias=$build_alias
+build=$build
+build_os=$build_os
# An echo program that does not interpret backslashes.
echo=$lt_echo
@@ -17999,6 +18229,9 @@ AR_FLAGS=$lt_AR_FLAGS
# A C compiler.
LTCC=$lt_LTCC
+# LTCC compiler flags.
+LTCFLAGS=$lt_LTCFLAGS
+
# A language-specific compiler.
CC=$lt_compiler_RC
@@ -18018,7 +18251,7 @@ LN_S=$lt_LN_S
NM=$lt_NM
# A symbol stripping program
-STRIP=$STRIP
+STRIP=$lt_STRIP
# Used to examine libraries when file_magic_cmd begins "file"
MAGIC_CMD=$MAGIC_CMD
@@ -18049,7 +18282,7 @@ objext="$ac_objext"
libext="$libext"
# Shared library suffix (normally ".so").
-shrext='$shrext'
+shrext_cmds='$shrext_cmds'
# Executable file suffix (normally "").
exeext="$exeext"
@@ -18064,7 +18297,7 @@ max_cmd_len=$lt_cv_sys_max_cmd_len
# Does compiler simultaneously support -c and -o options?
compiler_c_o=$lt_lt_cv_prog_compiler_c_o_RC
-# Must we lock files when doing compilation ?
+# Must we lock files when doing compilation?
need_locks=$lt_need_locks
# Do we need the lib prefix for modules?
@@ -18266,7 +18499,10 @@ else
# If there is no Makefile yet, we rely on a make rule to execute
# `config.status --recheck' to rerun these tests and create the
# libtool script then.
- test -f Makefile && make "$ltmain"
+ ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'`
+ if test -f "$ltmain_in"; then
+ test -f Makefile && make "$ltmain"
+ fi
fi
@@ -18346,7 +18582,6 @@ else
ac_cv_c_inline=no
for ac_kw in inline __inline__ __inline; do
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -18361,11 +18596,20 @@ $ac_kw foo_t foo () {return 0; }
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -18377,23 +18621,27 @@ else
sed 's/^/| /' conftest.$ac_ext >&5
fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
done
fi
echo "$as_me:$LINENO: result: $ac_cv_c_inline" >&5
echo "${ECHO_T}$ac_cv_c_inline" >&6
+
+
case $ac_cv_c_inline in
inline | yes) ;;
- no)
-cat >>confdefs.h <<\_ACEOF
-#define inline
-_ACEOF
- ;;
- *) cat >>confdefs.h <<_ACEOF
-#define inline $ac_cv_c_inline
+ *)
+ case $ac_cv_c_inline in
+ no) ac_val=;;
+ *) ac_val=$ac_cv_c_inline;;
+ esac
+ cat >>confdefs.h <<_ACEOF
+#ifndef __cplusplus
+#define inline $ac_val
+#endif
_ACEOF
- ;;
+ ;;
esac
@@ -18404,32 +18652,38 @@ echo $ECHO_N "checking for __attribute__... $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <stdlib.h>
+ static void foo(void) __attribute__ ((unused));
+ void foo(void) { exit(1); }
int
main ()
{
-static void foo(void) __attribute__ ((unused));
- static void
- foo(void) {
- exit(1);
- }
+
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -18443,7 +18697,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
ac_cv___attribute__=no
fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
fi
if test "$ac_cv___attribute__" = "yes"; then
@@ -18464,7 +18718,6 @@ if test "${ac_cv_header_stdc+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -18485,11 +18738,20 @@ main ()
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -18502,12 +18764,11 @@ sed 's/^/| /' conftest.$ac_ext >&5
ac_cv_header_stdc=no
fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
if test $ac_cv_header_stdc = yes; then
# SunOS 4.x string.h does not declare mem*, contrary to ANSI.
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -18529,7 +18790,6 @@ fi
if test $ac_cv_header_stdc = yes; then
# ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -18554,7 +18814,6 @@ if test $ac_cv_header_stdc = yes; then
:
else
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -18566,9 +18825,9 @@ cat >>conftest.$ac_ext <<_ACEOF
# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
#else
# define ISLOWER(c) \
- (('a' <= (c) && (c) <= 'i') \
- || ('j' <= (c) && (c) <= 'r') \
- || ('s' <= (c) && (c) <= 'z'))
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
#endif
@@ -18579,7 +18838,7 @@ main ()
int i;
for (i = 0; i < 256; i++)
if (XOR (islower (i), ISLOWER (i))
- || toupper (i) != TOUPPER (i))
+ || toupper (i) != TOUPPER (i))
exit(2);
exit (0);
}
@@ -18604,7 +18863,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
( exit $ac_status )
ac_cv_header_stdc=no
fi
-rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
fi
fi
fi
@@ -18619,14 +18878,12 @@ _ACEOF
fi
-# Here are some examples of how to check for the existence of a fn or file
echo "$as_me:$LINENO: checking for __int64" >&5
echo $ECHO_N "checking for __int64... $ECHO_C" >&6
if test "${ac_cv_type___int64+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -18646,11 +18903,20 @@ if (sizeof (__int64))
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -18663,7 +18929,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
ac_cv_type___int64=no
fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: $ac_cv_type___int64" >&5
echo "${ECHO_T}$ac_cv_type___int64" >&6
@@ -18676,6 +18942,71 @@ _ACEOF
fi
# defined in some windows platforms
+echo "$as_me:$LINENO: checking for struct mallinfo" >&5
+echo $ECHO_N "checking for struct mallinfo... $ECHO_C" >&6
+if test "${ac_cv_type_struct_mallinfo+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <malloc.h>
+
+int
+main ()
+{
+if ((struct mallinfo *) 0)
+ return 0;
+if (sizeof (struct mallinfo))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_type_struct_mallinfo=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_struct_mallinfo=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_struct_mallinfo" >&5
+echo "${ECHO_T}$ac_cv_type_struct_mallinfo" >&6
+if test $ac_cv_type_struct_mallinfo = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_MALLINFO 1
+_ACEOF
+
+
+fi
+
for ac_func in sbrk
do
@@ -18686,21 +19017,28 @@ if eval "test \"\${$as_ac_var+set}\" = set"; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func (); below.
Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
<limits.h> exists even on freestanding compilers. */
+
#ifdef __STDC__
# include <limits.h>
#else
# include <assert.h>
#endif
+
+#undef $ac_func
+
/* Override any gcc2 internal prototype to avoid an error. */
#ifdef __cplusplus
extern "C"
@@ -18731,11 +19069,20 @@ return f != $ac_func;
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
+ (eval $ac_link) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest$ac_exeext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -18748,7 +19095,8 @@ sed 's/^/| /' conftest.$ac_ext >&5
eval "$as_ac_var=no"
fi
-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
@@ -18770,21 +19118,28 @@ if eval "test \"\${$as_ac_var+set}\" = set"; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func (); below.
Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
<limits.h> exists even on freestanding compilers. */
+
#ifdef __STDC__
# include <limits.h>
#else
# include <assert.h>
#endif
+
+#undef $ac_func
+
/* Override any gcc2 internal prototype to avoid an error. */
#ifdef __cplusplus
extern "C"
@@ -18815,11 +19170,20 @@ return f != $ac_func;
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
+ (eval $ac_link) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest$ac_exeext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -18832,7 +19196,8 @@ sed 's/^/| /' conftest.$ac_ext >&5
eval "$as_ac_var=no"
fi
-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
@@ -18862,7 +19227,6 @@ else
echo "$as_me:$LINENO: checking $ac_header usability" >&5
echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -18873,11 +19237,20 @@ $ac_includes_default
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -18890,7 +19263,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
ac_header_compiler=no
fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
echo "${ECHO_T}$ac_header_compiler" >&6
@@ -18898,7 +19271,6 @@ echo "${ECHO_T}$ac_header_compiler" >&6
echo "$as_me:$LINENO: checking $ac_header presence" >&5
echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -18916,6 +19288,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
(exit $ac_status); } >/dev/null; then
if test -s conftest.err; then
ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
else
ac_cpp_err=
fi
@@ -18935,32 +19308,31 @@ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
echo "${ECHO_T}$ac_header_preproc" >&6
# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc in
- yes:no )
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
{ echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
- (
- cat <<\_ASBOX
-## ------------------------------------ ##
-## Report this to bug-autoconf@gnu.org. ##
-## ------------------------------------ ##
-_ASBOX
- ) |
- sed "s/^/$as_me: WARNING: /" >&2
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
;;
- no:yes )
+ no:yes:* )
{ echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
(
cat <<\_ASBOX
## ------------------------------------ ##
-## Report this to bug-autoconf@gnu.org. ##
+## Report this to opensource@google.com ##
## ------------------------------------ ##
_ASBOX
) |
@@ -18972,7 +19344,7 @@ echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
if eval "test \"\${$as_ac_Header+set}\" = set"; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
- eval "$as_ac_Header=$ac_header_preproc"
+ eval "$as_ac_Header=\$ac_header_preproc"
fi
echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
@@ -18997,21 +19369,28 @@ if eval "test \"\${$as_ac_var+set}\" = set"; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $ac_func innocuous_$ac_func
+
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func (); below.
Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
<limits.h> exists even on freestanding compilers. */
+
#ifdef __STDC__
# include <limits.h>
#else
# include <assert.h>
#endif
+
+#undef $ac_func
+
/* Override any gcc2 internal prototype to avoid an error. */
#ifdef __cplusplus
extern "C"
@@ -19042,11 +19421,20 @@ return f != $ac_func;
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
+ (eval $ac_link) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest$ac_exeext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -19059,7 +19447,8 @@ sed 's/^/| /' conftest.$ac_ext >&5
eval "$as_ac_var=no"
fi
-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
@@ -19080,7 +19469,6 @@ else
ac_cv_func_mmap_fixed_mapped=no
else
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -19188,9 +19576,9 @@ main ()
data2 = (char *) malloc (2 * pagesize);
if (!data2)
exit (1);
- data2 += (pagesize - ((int) data2 & (pagesize - 1))) & (pagesize - 1);
+ data2 += (pagesize - ((long) data2 & (pagesize - 1))) & (pagesize - 1);
if (data2 != mmap (data2, pagesize, PROT_READ | PROT_WRITE,
- MAP_PRIVATE | MAP_FIXED, fd, 0L))
+ MAP_PRIVATE | MAP_FIXED, fd, 0L))
exit (1);
for (i = 0; i < pagesize; ++i)
if (*(data + i) != *(data2 + i))
@@ -19233,7 +19621,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
( exit $ac_status )
ac_cv_func_mmap_fixed_mapped=no
fi
-rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
fi
fi
echo "$as_me:$LINENO: result: $ac_cv_func_mmap_fixed_mapped" >&5
@@ -19264,7 +19652,6 @@ else
echo "$as_me:$LINENO: checking $ac_header usability" >&5
echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -19275,11 +19662,20 @@ $ac_includes_default
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -19292,7 +19688,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
ac_header_compiler=no
fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
echo "${ECHO_T}$ac_header_compiler" >&6
@@ -19300,7 +19696,6 @@ echo "${ECHO_T}$ac_header_compiler" >&6
echo "$as_me:$LINENO: checking $ac_header presence" >&5
echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -19318,6 +19713,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
(exit $ac_status); } >/dev/null; then
if test -s conftest.err; then
ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
else
ac_cpp_err=
fi
@@ -19337,32 +19733,31 @@ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
echo "${ECHO_T}$ac_header_preproc" >&6
# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc in
- yes:no )
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
{ echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
- (
- cat <<\_ASBOX
-## ------------------------------------ ##
-## Report this to bug-autoconf@gnu.org. ##
-## ------------------------------------ ##
-_ASBOX
- ) |
- sed "s/^/$as_me: WARNING: /" >&2
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
;;
- no:yes )
+ no:yes:* )
{ echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
(
cat <<\_ASBOX
## ------------------------------------ ##
-## Report this to bug-autoconf@gnu.org. ##
+## Report this to opensource@google.com ##
## ------------------------------------ ##
_ASBOX
) |
@@ -19374,7 +19769,7 @@ echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
if eval "test \"\${$as_ac_Header+set}\" = set"; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
- eval "$as_ac_Header=$ac_header_preproc"
+ eval "$as_ac_Header=\$ac_header_preproc"
fi
echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
@@ -19406,7 +19801,6 @@ else
echo "$as_me:$LINENO: checking $ac_header usability" >&5
echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -19417,11 +19811,20 @@ $ac_includes_default
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -19434,7 +19837,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
ac_header_compiler=no
fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
echo "${ECHO_T}$ac_header_compiler" >&6
@@ -19442,7 +19845,6 @@ echo "${ECHO_T}$ac_header_compiler" >&6
echo "$as_me:$LINENO: checking $ac_header presence" >&5
echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -19460,6 +19862,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
(exit $ac_status); } >/dev/null; then
if test -s conftest.err; then
ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
else
ac_cpp_err=
fi
@@ -19479,32 +19882,31 @@ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
echo "${ECHO_T}$ac_header_preproc" >&6
# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc in
- yes:no )
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
{ echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
- (
- cat <<\_ASBOX
-## ------------------------------------ ##
-## Report this to bug-autoconf@gnu.org. ##
-## ------------------------------------ ##
-_ASBOX
- ) |
- sed "s/^/$as_me: WARNING: /" >&2
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
;;
- no:yes )
+ no:yes:* )
{ echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
(
cat <<\_ASBOX
## ------------------------------------ ##
-## Report this to bug-autoconf@gnu.org. ##
+## Report this to opensource@google.com ##
## ------------------------------------ ##
_ASBOX
) |
@@ -19516,7 +19918,7 @@ echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
if eval "test \"\${$as_ac_Header+set}\" = set"; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
- eval "$as_ac_Header=$ac_header_preproc"
+ eval "$as_ac_Header=\$ac_header_preproc"
fi
echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
@@ -19530,7 +19932,7 @@ _ACEOF
fi
done
- # for stacktrace (will be needed soon)
+ # for stacktrace
for ac_header in unwind.h
do
@@ -19548,7 +19950,6 @@ else
echo "$as_me:$LINENO: checking $ac_header usability" >&5
echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -19559,11 +19960,20 @@ $ac_includes_default
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -19576,7 +19986,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
ac_header_compiler=no
fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
echo "${ECHO_T}$ac_header_compiler" >&6
@@ -19584,7 +19994,6 @@ echo "${ECHO_T}$ac_header_compiler" >&6
echo "$as_me:$LINENO: checking $ac_header presence" >&5
echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -19602,6 +20011,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
(exit $ac_status); } >/dev/null; then
if test -s conftest.err; then
ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
else
ac_cpp_err=
fi
@@ -19621,32 +20031,31 @@ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
echo "${ECHO_T}$ac_header_preproc" >&6
# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc in
- yes:no )
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
{ echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
- (
- cat <<\_ASBOX
-## ------------------------------------ ##
-## Report this to bug-autoconf@gnu.org. ##
-## ------------------------------------ ##
-_ASBOX
- ) |
- sed "s/^/$as_me: WARNING: /" >&2
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
;;
- no:yes )
+ no:yes:* )
{ echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
(
cat <<\_ASBOX
## ------------------------------------ ##
-## Report this to bug-autoconf@gnu.org. ##
+## Report this to opensource@google.com ##
## ------------------------------------ ##
_ASBOX
) |
@@ -19658,7 +20067,7 @@ echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
if eval "test \"\${$as_ac_Header+set}\" = set"; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
- eval "$as_ac_Header=$ac_header_preproc"
+ eval "$as_ac_Header=\$ac_header_preproc"
fi
echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
@@ -19672,7 +20081,7 @@ _ACEOF
fi
done
- # for stacktrace (will be needed soon)
+ # for stacktrace
for ac_header in conflict-signal.h
do
@@ -19690,7 +20099,6 @@ else
echo "$as_me:$LINENO: checking $ac_header usability" >&5
echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -19701,11 +20109,20 @@ $ac_includes_default
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -19718,7 +20135,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
ac_header_compiler=no
fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
echo "${ECHO_T}$ac_header_compiler" >&6
@@ -19726,7 +20143,6 @@ echo "${ECHO_T}$ac_header_compiler" >&6
echo "$as_me:$LINENO: checking $ac_header presence" >&5
echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -19744,6 +20160,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
(exit $ac_status); } >/dev/null; then
if test -s conftest.err; then
ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
else
ac_cpp_err=
fi
@@ -19763,32 +20180,31 @@ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
echo "${ECHO_T}$ac_header_preproc" >&6
# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc in
- yes:no )
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
{ echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
- (
- cat <<\_ASBOX
-## ------------------------------------ ##
-## Report this to bug-autoconf@gnu.org. ##
-## ------------------------------------ ##
-_ASBOX
- ) |
- sed "s/^/$as_me: WARNING: /" >&2
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
;;
- no:yes )
+ no:yes:* )
{ echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
(
cat <<\_ASBOX
## ------------------------------------ ##
-## Report this to bug-autoconf@gnu.org. ##
+## Report this to opensource@google.com ##
## ------------------------------------ ##
_ASBOX
) |
@@ -19800,7 +20216,7 @@ echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
if eval "test \"\${$as_ac_Header+set}\" = set"; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
- eval "$as_ac_Header=$ac_header_preproc"
+ eval "$as_ac_Header=\$ac_header_preproc"
fi
echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
@@ -19832,7 +20248,6 @@ else
echo "$as_me:$LINENO: checking $ac_header usability" >&5
echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -19843,11 +20258,20 @@ $ac_includes_default
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -19860,7 +20284,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
ac_header_compiler=no
fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
echo "${ECHO_T}$ac_header_compiler" >&6
@@ -19868,7 +20292,6 @@ echo "${ECHO_T}$ac_header_compiler" >&6
echo "$as_me:$LINENO: checking $ac_header presence" >&5
echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -19886,6 +20309,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
(exit $ac_status); } >/dev/null; then
if test -s conftest.err; then
ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
else
ac_cpp_err=
fi
@@ -19905,32 +20329,31 @@ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
echo "${ECHO_T}$ac_header_preproc" >&6
# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc in
- yes:no )
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
{ echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
- (
- cat <<\_ASBOX
-## ------------------------------------ ##
-## Report this to bug-autoconf@gnu.org. ##
-## ------------------------------------ ##
-_ASBOX
- ) |
- sed "s/^/$as_me: WARNING: /" >&2
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
;;
- no:yes )
+ no:yes:* )
{ echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
(
cat <<\_ASBOX
## ------------------------------------ ##
-## Report this to bug-autoconf@gnu.org. ##
+## Report this to opensource@google.com ##
## ------------------------------------ ##
_ASBOX
) |
@@ -19942,7 +20365,7 @@ echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
if eval "test \"\${$as_ac_Header+set}\" = set"; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
- eval "$as_ac_Header=$ac_header_preproc"
+ eval "$as_ac_Header=\$ac_header_preproc"
fi
echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
@@ -19974,7 +20397,6 @@ else
echo "$as_me:$LINENO: checking $ac_header usability" >&5
echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -19985,11 +20407,20 @@ $ac_includes_default
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -20002,7 +20433,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
ac_header_compiler=no
fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
echo "${ECHO_T}$ac_header_compiler" >&6
@@ -20010,7 +20441,6 @@ echo "${ECHO_T}$ac_header_compiler" >&6
echo "$as_me:$LINENO: checking $ac_header presence" >&5
echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -20028,6 +20458,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
(exit $ac_status); } >/dev/null; then
if test -s conftest.err; then
ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
else
ac_cpp_err=
fi
@@ -20047,32 +20478,31 @@ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
echo "${ECHO_T}$ac_header_preproc" >&6
# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc in
- yes:no )
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
{ echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
- (
- cat <<\_ASBOX
-## ------------------------------------ ##
-## Report this to bug-autoconf@gnu.org. ##
-## ------------------------------------ ##
-_ASBOX
- ) |
- sed "s/^/$as_me: WARNING: /" >&2
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
;;
- no:yes )
+ no:yes:* )
{ echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
(
cat <<\_ASBOX
## ------------------------------------ ##
-## Report this to bug-autoconf@gnu.org. ##
+## Report this to opensource@google.com ##
## ------------------------------------ ##
_ASBOX
) |
@@ -20084,7 +20514,7 @@ echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
if eval "test \"\${$as_ac_Header+set}\" = set"; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
- eval "$as_ac_Header=$ac_header_preproc"
+ eval "$as_ac_Header=\$ac_header_preproc"
fi
echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
@@ -20116,7 +20546,6 @@ else
echo "$as_me:$LINENO: checking $ac_header usability" >&5
echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -20127,11 +20556,20 @@ $ac_includes_default
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -20144,7 +20582,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
ac_header_compiler=no
fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
echo "${ECHO_T}$ac_header_compiler" >&6
@@ -20152,7 +20590,6 @@ echo "${ECHO_T}$ac_header_compiler" >&6
echo "$as_me:$LINENO: checking $ac_header presence" >&5
echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -20170,6 +20607,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
(exit $ac_status); } >/dev/null; then
if test -s conftest.err; then
ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
else
ac_cpp_err=
fi
@@ -20189,32 +20627,180 @@ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
echo "${ECHO_T}$ac_header_preproc" >&6
# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc in
- yes:no )
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
{ echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
(
cat <<\_ASBOX
## ------------------------------------ ##
-## Report this to bug-autoconf@gnu.org. ##
+## Report this to opensource@google.com ##
## ------------------------------------ ##
_ASBOX
) |
sed "s/^/$as_me: WARNING: /" >&2
;;
- no:yes )
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+ # for heapchecker_unittest
+
+for ac_header in pwd.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+ # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
{ echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
(
cat <<\_ASBOX
## ------------------------------------ ##
-## Report this to bug-autoconf@gnu.org. ##
+## Report this to opensource@google.com ##
## ------------------------------------ ##
_ASBOX
) |
@@ -20226,7 +20812,7 @@ echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
if eval "test \"\${$as_ac_Header+set}\" = set"; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
- eval "$as_ac_Header=$ac_header_preproc"
+ eval "$as_ac_Header=\$ac_header_preproc"
fi
echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
@@ -20247,13 +20833,13 @@ if test "${ac_cv_member_struct_sigcontext_sc_eip+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
-#include <signal.h>
+#define _XOPEN_SOURCE 500
+ #include <signal.h>
int
main ()
@@ -20267,11 +20853,20 @@ return 0;
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -20283,13 +20878,13 @@ else
sed 's/^/| /' conftest.$ac_ext >&5
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
-#include <signal.h>
+#define _XOPEN_SOURCE 500
+ #include <signal.h>
int
main ()
@@ -20303,11 +20898,20 @@ return 0;
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -20320,9 +20924,9 @@ sed 's/^/| /' conftest.$ac_ext >&5
ac_cv_member_struct_sigcontext_sc_eip=no
fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: $ac_cv_member_struct_sigcontext_sc_eip" >&5
echo "${ECHO_T}$ac_cv_member_struct_sigcontext_sc_eip" >&6
@@ -20340,13 +20944,13 @@ if test "${ac_cv_member_struct_ucontext_uc_mcontext+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
-#include <signal.h>
+#define _XOPEN_SOURCE 500
+ #include <signal.h>
int
main ()
@@ -20360,11 +20964,20 @@ return 0;
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -20376,13 +20989,13 @@ else
sed 's/^/| /' conftest.$ac_ext >&5
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
-#include <signal.h>
+#define _XOPEN_SOURCE 500
+ #include <signal.h>
int
main ()
@@ -20396,11 +21009,20 @@ return 0;
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -20413,9 +21035,9 @@ sed 's/^/| /' conftest.$ac_ext >&5
ac_cv_member_struct_ucontext_uc_mcontext=no
fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: $ac_cv_member_struct_ucontext_uc_mcontext" >&5
echo "${ECHO_T}$ac_cv_member_struct_ucontext_uc_mcontext" >&6
@@ -20433,13 +21055,13 @@ if test "${ac_cv_member_struct_sigcontext_eip+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
-#include <signal.h>
+#define _XOPEN_SOURCE 500
+ #include <signal.h>
int
main ()
@@ -20453,11 +21075,20 @@ return 0;
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -20469,13 +21100,13 @@ else
sed 's/^/| /' conftest.$ac_ext >&5
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
-#include <signal.h>
+#define _XOPEN_SOURCE 500
+ #include <signal.h>
int
main ()
@@ -20489,11 +21120,20 @@ return 0;
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -20506,9 +21146,9 @@ sed 's/^/| /' conftest.$ac_ext >&5
ac_cv_member_struct_sigcontext_eip=no
fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: $ac_cv_member_struct_sigcontext_eip" >&5
echo "${ECHO_T}$ac_cv_member_struct_sigcontext_eip" >&6
@@ -20526,13 +21166,13 @@ if test "${ac_cv_member_struct_sigcontext_rip+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
-#include <signal.h>
+#define _XOPEN_SOURCE 500
+ #include <signal.h>
int
main ()
@@ -20546,11 +21186,20 @@ return 0;
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -20562,13 +21211,13 @@ else
sed 's/^/| /' conftest.$ac_ext >&5
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
-#include <signal.h>
+#define _XOPEN_SOURCE 500
+ #include <signal.h>
int
main ()
@@ -20582,11 +21231,20 @@ return 0;
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -20599,9 +21257,9 @@ sed 's/^/| /' conftest.$ac_ext >&5
ac_cv_member_struct_sigcontext_rip=no
fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: $ac_cv_member_struct_sigcontext_rip" >&5
echo "${ECHO_T}$ac_cv_member_struct_sigcontext_rip" >&6
@@ -20619,13 +21277,13 @@ if test "${ac_cv_member_struct_sigcontext_sc_ip+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
-#include <signal.h>
+#define _XOPEN_SOURCE 500
+ #include <signal.h>
int
main ()
@@ -20639,11 +21297,20 @@ return 0;
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -20655,13 +21322,13 @@ else
sed 's/^/| /' conftest.$ac_ext >&5
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
-#include <signal.h>
+#define _XOPEN_SOURCE 500
+ #include <signal.h>
int
main ()
@@ -20675,11 +21342,20 @@ return 0;
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -20692,9 +21368,9 @@ sed 's/^/| /' conftest.$ac_ext >&5
ac_cv_member_struct_sigcontext_sc_ip=no
fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: $ac_cv_member_struct_sigcontext_sc_ip" >&5
echo "${ECHO_T}$ac_cv_member_struct_sigcontext_sc_ip" >&6
@@ -20712,13 +21388,13 @@ if test "${ac_cv_member_struct_siginfo_si_faddr+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
-#include <signal.h>
+#define _XOPEN_SOURCE 500
+ #include <signal.h>
int
main ()
@@ -20732,11 +21408,20 @@ return 0;
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -20748,13 +21433,13 @@ else
sed 's/^/| /' conftest.$ac_ext >&5
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
-#include <signal.h>
+#define _XOPEN_SOURCE 500
+ #include <signal.h>
int
main ()
@@ -20768,11 +21453,20 @@ return 0;
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -20785,9 +21479,9 @@ sed 's/^/| /' conftest.$ac_ext >&5
ac_cv_member_struct_siginfo_si_faddr=no
fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: $ac_cv_member_struct_siginfo_si_faddr" >&5
echo "${ECHO_T}$ac_cv_member_struct_siginfo_si_faddr" >&6
@@ -20805,13 +21499,13 @@ if test "${ac_cv_member_struct_sigcontext_regs__nip+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
-#include <signal.h>
+#define _XOPEN_SOURCE 500
+ #include <signal.h>
int
main ()
@@ -20825,11 +21519,20 @@ return 0;
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -20841,13 +21544,13 @@ else
sed 's/^/| /' conftest.$ac_ext >&5
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
-#include <signal.h>
+#define _XOPEN_SOURCE 500
+ #include <signal.h>
int
main ()
@@ -20861,11 +21564,20 @@ return 0;
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -20878,9 +21590,9 @@ sed 's/^/| /' conftest.$ac_ext >&5
ac_cv_member_struct_sigcontext_regs__nip=no
fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: $ac_cv_member_struct_sigcontext_regs__nip" >&5
echo "${ECHO_T}$ac_cv_member_struct_sigcontext_regs__nip" >&6
@@ -20894,14 +21606,148 @@ _ACEOF
fi
+# We want to link in libunwind if it exists
+echo "$as_me:$LINENO: checking for backtrace in -lunwind" >&5
+echo $ECHO_N "checking for backtrace in -lunwind... $ECHO_C" >&6
+if test "${ac_cv_lib_unwind_backtrace+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lunwind $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char backtrace ();
+int
+main ()
+{
+backtrace ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_lib_unwind_backtrace=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_unwind_backtrace=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_unwind_backtrace" >&5
+echo "${ECHO_T}$ac_cv_lib_unwind_backtrace" >&6
+if test $ac_cv_lib_unwind_backtrace = yes; then
+ UNWIND_LIBS=-lunwind
+else
+ UNWIND_LIBS=
+fi
+
+
+
+# On x86_64, instead of libunwind, we can choose to compile with frame-pointers
+# (This isn't needed on i386, where -fno-omit-frame-pointer is the default).
+# Check whether --enable-frame_pointer or --disable-frame_pointer was given.
+if test "${enable_frame_pointer+set}" = set; then
+ enableval="$enable_frame_pointer"
+
+else
+ enable_frame_pointer=no
+fi;
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+return __x86_64__ == 1 ? 0 : 1
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ is_x86_64=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+is_x86_64=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+EXTRA_CXXFLAGS=
+if test "$is_x86_64" = yes -a "$enable_frame_pointer" = "yes"; then
+ EXTRA_CXXFLAGS=-fno-omit-frame-pointer
+elif test "$is_x86_64" = yes -a "$enable_frame_pointer" != "yes"; then
+ # TODO(csilvers): set -DNO_FRAME_POINTER in the Makefile instead, based
+ # on the presence of -f[no-]omit-frame-pointer in cxxflags.
+ EXTRA_CXXFLAGS=-DNO_FRAME_POINTER
+fi
+
+
# Defines PRIuS
-echo "$as_me:$LINENO: checking printf format code for printing a size_t" >&5
-echo $ECHO_N "checking printf format code for printing a size_t... $ECHO_C" >&6
-if test "${ac_cv_formatting_prius+set}" = set; then
+echo "$as_me:$LINENO: checking printf format code for printing a size_t and ssize_t" >&5
+echo $ECHO_N "checking printf format code for printing a size_t and ssize_t... $ECHO_C" >&6
+if test "${ac_cv_formatting_prius_prefix+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -20918,25 +21764,33 @@ unsigned int v1 = 0; size_t v2 = 0; return (&v1 - &v2)
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
- ac_cv_formatting_prius=u
+ ac_cv_formatting_prius_prefix=; ac_cv_prius_defined=1
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -20953,25 +21807,33 @@ unsigned long v1 = 0; size_t v2 = 0; return (&v1 - &v2)
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
- ac_cv_formatting_prius=lu
+ ac_cv_formatting_prius_prefix=l; ac_cv_prius_defined=1
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -20988,32 +21850,52 @@ unsigned long long v1 = 0; size_t v2 = 0; return (&v1 - &v2)
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
- ac_cv_formatting_prius=llu
+ ac_cv_formatting_prius_prefix=ll; ac_cv_prius_defined=1
+
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-echo "$as_me:$LINENO: result: $ac_cv_formatting_prius" >&5
-echo "${ECHO_T}$ac_cv_formatting_prius" >&6
- if test -z "$ac_cv_formatting_prius"; then
- ac_cv_formatting_prius=zu;
+echo "$as_me:$LINENO: result: $ac_cv_formatting_prius_prefix" >&5
+echo "${ECHO_T}$ac_cv_formatting_prius_prefix" >&6
+ if test -z "$ac_cv_formatting_prius_defined"; then
+ ac_cv_formatting_prius_prefix=z;
fi
cat >>confdefs.h <<_ACEOF
-#define PRIuS "$ac_cv_formatting_prius"
+#define PRIuS "${ac_cv_formatting_prius_prefix}u"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PRIxS "${ac_cv_formatting_prius_prefix}x"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PRIdS "${ac_cv_formatting_prius_prefix}d"
_ACEOF
@@ -21022,7 +21904,6 @@ _ACEOF
echo "$as_me:$LINENO: checking for __builtin_stack_pointer()" >&5
echo $ECHO_N "checking for __builtin_stack_pointer()... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -21032,18 +21913,27 @@ cat >>conftest.$ac_ext <<_ACEOF
int
main ()
{
-void *sp = __builtin_stack_pointer();
+void *sp = __builtin_stack_pointer()
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
+ (eval $ac_link) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest$ac_exeext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -21063,9 +21953,140 @@ sed 's/^/| /' conftest.$ac_ext >&5
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
+# If we support __thread, that can speed up tcmalloc a bit.
+echo "$as_me:$LINENO: checking for __thread" >&5
+echo $ECHO_N "checking for __thread... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+static __thread int p = 0
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_TLS 1
+_ACEOF
+
+ echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
+# We also need to check if the kernel supports __thread, which requires uname()
+echo "$as_me:$LINENO: checking whether uname is declared" >&5
+echo $ECHO_N "checking whether uname is declared... $ECHO_C" >&6
+if test "${ac_cv_have_decl_uname+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/utsname.h>
+
+int
+main ()
+{
+#ifndef uname
+ char *p = (char *) uname;
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_have_decl_uname=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_have_decl_uname=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_have_decl_uname" >&5
+echo "${ECHO_T}$ac_cv_have_decl_uname" >&6
+if test $ac_cv_have_decl_uname = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_UNAME 1
+_ACEOF
+
+
+else
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_UNAME 0
+_ACEOF
+
+
+fi
+
+
-# A lot of the code in this directory depends on pthreads
+# In fact, a lot of the code in this directory depends on pthreads
@@ -21093,7 +22114,6 @@ if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
echo "$as_me:$LINENO: checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS" >&5
echo $ECHO_N "checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -21117,11 +22137,20 @@ pthread_join ();
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
+ (eval $ac_link) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest$ac_exeext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -21133,7 +22162,8 @@ else
sed 's/^/| /' conftest.$ac_ext >&5
fi
-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
echo "$as_me:$LINENO: result: $acx_pthread_ok" >&5
echo "${ECHO_T}$acx_pthread_ok" >&6
if test x"$acx_pthread_ok" = xno; then
@@ -21270,7 +22300,6 @@ echo $ECHO_N "checking for the pthreads library -l$flag... $ECHO_C" >&6
# functions on Solaris that doesn't have a non-functional libc stub.
# We try pthread_create on general principles.
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -21289,11 +22318,20 @@ pthread_t th; pthread_join(th, 0);
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
+ (eval $ac_link) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest$ac_exeext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -21305,7 +22343,8 @@ else
sed 's/^/| /' conftest.$ac_ext >&5
fi
-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
@@ -21334,7 +22373,6 @@ echo $ECHO_N "checking for joinable pthread attribute... $ECHO_C" >&6
attr_name=unknown
for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -21351,11 +22389,20 @@ int attr=$attr; return attr;
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
+ (eval $ac_link) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest$ac_exeext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -21367,7 +22414,8 @@ else
sed 's/^/| /' conftest.$ac_ext >&5
fi
-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
done
echo "$as_me:$LINENO: result: $attr_name" >&5
echo "${ECHO_T}$attr_name" >&6
@@ -21475,7 +22523,6 @@ echo "${ECHO_T}yes" >&6
echo "$as_me:$LINENO: checking whether -pthread is sufficient with -shared" >&5
echo $ECHO_N "checking whether -pthread is sufficient with -shared... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -21494,11 +22541,20 @@ pthread_t th; pthread_join(th, 0);
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
+ (eval $ac_link) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest$ac_exeext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -21510,7 +22566,8 @@ else
sed 's/^/| /' conftest.$ac_ext >&5
fi
-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
if test "x$ok" = xyes; then
echo "$as_me:$LINENO: result: yes" >&5
@@ -21529,7 +22586,6 @@ echo "${ECHO_T}no" >&6
echo $ECHO_N "checking whether -lpthread fixes that... $ECHO_C" >&6
LIBS="-lpthread $PTHREAD_LIBS $save_LIBS"
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -21548,11 +22604,20 @@ pthread_t th; pthread_join(th, 0);
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
+ (eval $ac_link) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest$ac_exeext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -21564,7 +22629,8 @@ else
sed 's/^/| /' conftest.$ac_ext >&5
fi
-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
if test "x$ok" = xyes; then
echo "$as_me:$LINENO: result: yes" >&5
@@ -21583,7 +22649,6 @@ echo "${ECHO_T}no" >&6
echo $ECHO_N "checking whether -lc_r fixes that... $ECHO_C" >&6
LIBS="-lc_r $PTHREAD_LIBS $save_LIBS"
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -21602,11 +22667,20 @@ pthread_t th; pthread_join(th, 0);
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
+ (eval $ac_link) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest$ac_exeext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -21618,7 +22692,8 @@ else
sed 's/^/| /' conftest.$ac_ext >&5
fi
-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
if test "x$ok" = xyes; then
echo "$as_me:$LINENO: result: yes" >&5
@@ -21678,20 +22753,20 @@ if test "${ac_cv_cxx_namespaces+set}" = set; then
else
- ac_ext=cc
+ ac_ext=cc
ac_cpp='$CXXCPP $CPPFLAGS'
ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
- cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
+ cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
-namespace Outer { namespace Inner { int i = 0; }}
+namespace Outer {
+ namespace Inner { int i = 0; }}
int
main ()
{
@@ -21702,11 +22777,20 @@ using namespace Outer::Inner; return i;
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
+ { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -21719,25 +22803,23 @@ sed 's/^/| /' conftest.$ac_ext >&5
ac_cv_cxx_namespaces=no
fi
-rm -f conftest.$ac_objext conftest.$ac_ext
- ac_ext=c
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
fi
echo "$as_me:$LINENO: result: $ac_cv_cxx_namespaces" >&5
echo "${ECHO_T}$ac_cv_cxx_namespaces" >&6
-if test "$ac_cv_cxx_namespaces" = yes; then
+ if test "$ac_cv_cxx_namespaces" = yes; then
cat >>confdefs.h <<\_ACEOF
-#define HAVE_NAMESPACES
+#define HAVE_NAMESPACES 1
_ACEOF
-fi
-
+ fi
echo "$as_me:$LINENO: checking what namespace STL code is in" >&5
echo $ECHO_N "checking what namespace STL code is in... $ECHO_C" >&6
if test "${ac_cv_cxx_stl_namespace+set}" = set; then
@@ -21753,7 +22835,6 @@ ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ex
ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -21770,11 +22851,20 @@ vector<int> t; return 0;
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
+ { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -21786,9 +22876,8 @@ else
sed 's/^/| /' conftest.$ac_ext >&5
fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -21805,11 +22894,20 @@ std::vector<int> t; return 0;
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
+ { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -21821,7 +22919,7 @@ else
sed 's/^/| /' conftest.$ac_ext >&5
fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -21862,7 +22960,6 @@ ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ex
ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -21879,11 +22976,20 @@ hash_map<int, int> t; return 0;
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
+ { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -21895,9 +23001,8 @@ else
sed 's/^/| /' conftest.$ac_ext >&5
fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -21914,11 +23019,20 @@ __gnu_cxx::hash_map<int, int> t; return 0;
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
+ { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -21930,9 +23044,8 @@ else
sed 's/^/| /' conftest.$ac_ext >&5
fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -21949,11 +23062,20 @@ std::hash_map<int, int> t; return 0;
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
+ { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -21965,9 +23087,8 @@ else
sed 's/^/| /' conftest.$ac_ext >&5
fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -21984,11 +23105,20 @@ stdext::hash_map<int, int> t; return 0;
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
+ (eval $ac_compile) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest.$ac_objext'
+ { ac_try='test -z "$ac_cxx_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -22000,7 +23130,7 @@ else
sed 's/^/| /' conftest.$ac_ext >&5
fi
-rm -f conftest.$ac_objext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
@@ -22090,10 +23220,10 @@ echo $ECHO_N "checking writing an include-helper for hash_set... $ECHO_C" >&6
{ if $as_mkdir_p; then
mkdir -p `(dirname src/google/perftools/hash_set.h) 2>/dev/null ||
$as_expr Xsrc/google/perftools/hash_set.h : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- Xsrc/google/perftools/hash_set.h : 'X\(//\)[^/]' \| \
- Xsrc/google/perftools/hash_set.h : 'X\(//\)$' \| \
- Xsrc/google/perftools/hash_set.h : 'X\(/\)' \| \
- . : '\(.\)' 2>/dev/null ||
+ Xsrc/google/perftools/hash_set.h : 'X\(//\)[^/]' \| \
+ Xsrc/google/perftools/hash_set.h : 'X\(//\)$' \| \
+ Xsrc/google/perftools/hash_set.h : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
echo Xsrc/google/perftools/hash_set.h |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
/^X\(\/\/\)[^/].*/{ s//\1/; q; }
@@ -22103,10 +23233,10 @@ echo Xsrc/google/perftools/hash_set.h |
else
as_dir=`(dirname src/google/perftools/hash_set.h) 2>/dev/null ||
$as_expr Xsrc/google/perftools/hash_set.h : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- Xsrc/google/perftools/hash_set.h : 'X\(//\)[^/]' \| \
- Xsrc/google/perftools/hash_set.h : 'X\(//\)$' \| \
- Xsrc/google/perftools/hash_set.h : 'X\(/\)' \| \
- . : '\(.\)' 2>/dev/null ||
+ Xsrc/google/perftools/hash_set.h : 'X\(//\)[^/]' \| \
+ Xsrc/google/perftools/hash_set.h : 'X\(//\)$' \| \
+ Xsrc/google/perftools/hash_set.h : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
echo Xsrc/google/perftools/hash_set.h |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
/^X\(\/\/\)[^/].*/{ s//\1/; q; }
@@ -22118,10 +23248,10 @@ echo Xsrc/google/perftools/hash_set.h |
as_dirs="$as_dir $as_dirs"
as_dir=`(dirname "$as_dir") 2>/dev/null ||
$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$as_dir" : 'X\(//\)[^/]' \| \
- X"$as_dir" : 'X\(//\)$' \| \
- X"$as_dir" : 'X\(/\)' \| \
- . : '\(.\)' 2>/dev/null ||
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
echo X"$as_dir" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
/^X\(\/\/\)[^/].*/{ s//\1/; q; }
@@ -22132,10 +23262,10 @@ echo X"$as_dir" |
test ! -n "$as_dirs" || mkdir $as_dirs
fi || { { echo "$as_me:$LINENO: error: cannot create directory \`(dirname src/google/perftools/hash_set.h) 2>/dev/null ||
$as_expr Xsrc/google/perftools/hash_set.h : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- Xsrc/google/perftools/hash_set.h : 'X\(//\)[^/]' \| \
- Xsrc/google/perftools/hash_set.h : 'X\(//\)$' \| \
- Xsrc/google/perftools/hash_set.h : 'X\(/\)' \| \
- . : '\(.\)' 2>/dev/null ||
+ Xsrc/google/perftools/hash_set.h : 'X\(//\)[^/]' \| \
+ Xsrc/google/perftools/hash_set.h : 'X\(//\)$' \| \
+ Xsrc/google/perftools/hash_set.h : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
echo Xsrc/google/perftools/hash_set.h |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
/^X\(\/\/\)[^/].*/{ s//\1/; q; }
@@ -22144,10 +23274,10 @@ echo Xsrc/google/perftools/hash_set.h |
s/.*/./; q'\`" >&5
echo "$as_me: error: cannot create directory \`(dirname src/google/perftools/hash_set.h) 2>/dev/null ||
$as_expr Xsrc/google/perftools/hash_set.h : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- Xsrc/google/perftools/hash_set.h : 'X\(//\)[^/]' \| \
- Xsrc/google/perftools/hash_set.h : 'X\(//\)$' \| \
- Xsrc/google/perftools/hash_set.h : 'X\(/\)' \| \
- . : '\(.\)' 2>/dev/null ||
+ Xsrc/google/perftools/hash_set.h : 'X\(//\)[^/]' \| \
+ Xsrc/google/perftools/hash_set.h : 'X\(//\)$' \| \
+ Xsrc/google/perftools/hash_set.h : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
echo Xsrc/google/perftools/hash_set.h |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
/^X\(\/\/\)[^/].*/{ s//\1/; q; }
@@ -22174,7 +23304,6 @@ if test "${ac_cv_have_program_invocation_name+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
-#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
@@ -22191,11 +23320,20 @@ char c = *program_invocation_name; return 0;
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
+ (eval $ac_link) 2>conftest.er1
ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -s conftest$ac_exeext'
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
@@ -22208,7 +23346,8 @@ sed 's/^/| /' conftest.$ac_ext >&5
ac_cv_have_program_invocation_name=no
fi
-rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: $ac_cv_have_program_invocation_name" >&5
@@ -22265,13 +23404,13 @@ _ACEOF
# `set' does not quote correctly, so add quotes (double-quote
# substitution turns \\\\ into \\, and sed turns \\ into \).
sed -n \
- "s/'/'\\\\''/g;
- s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+ "s/'/'\\\\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
;;
*)
# `set' quotes correctly as required by POSIX, so do not add quotes.
sed -n \
- "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+ "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
;;
esac;
} |
@@ -22301,13 +23440,13 @@ test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
# trailing colons and then remove the whole line if VPATH becomes empty
# (actually we leave an empty line to preserve line numbers).
if test "x$srcdir" = x.; then
- ac_vpsub='/^[ ]*VPATH[ ]*=/{
+ ac_vpsub='/^[ ]*VPATH[ ]*=/{
s/:*\$(srcdir):*/:/;
s/:*\${srcdir}:*/:/;
s/:*@srcdir@:*/:/;
-s/^\([^=]*=[ ]*\):*/\1/;
+s/^\([^=]*=[ ]*\):*/\1/;
s/:*$//;
-s/^[^=]*=[ ]*$//;
+s/^[^=]*=[ ]*$//;
}'
fi
@@ -22318,7 +23457,7 @@ ac_ltlibobjs=
for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
# 1. Remove the extension, and $U if already installed.
ac_i=`echo "$ac_i" |
- sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
+ sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
# 2. Add them.
ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
@@ -22335,6 +23474,20 @@ echo "$as_me: error: conditional \"AMDEP\" was never defined.
Usually this means the macro was only invoked conditionally." >&2;}
{ (exit 1); exit 1; }; }
fi
+if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
+ { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then
+ { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCXX\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"am__fastdepCXX\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+fi
: ${CONFIG_STATUS=./config.status}
ac_clean_files_save=$ac_clean_files
@@ -22369,9 +23522,10 @@ if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
set -o posix
fi
+DUALCASE=1; export DUALCASE # for MKS sh
# Support unset when possible.
-if (FOO=FOO; unset FOO) >/dev/null 2>&1; then
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
as_unset=unset
else
as_unset=false
@@ -22390,7 +23544,7 @@ for as_var in \
LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
LC_TELEPHONE LC_TIME
do
- if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then
+ if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
eval $as_var=C; export $as_var
else
$as_unset $as_var
@@ -22569,16 +23723,17 @@ rm -f conf$$ conf$$.exe conf$$.file
if mkdir -p . 2>/dev/null; then
as_mkdir_p=:
else
+ test -d ./-p && rmdir ./-p
as_mkdir_p=false
fi
as_executable_p="test -f"
# Sed expression to map a string onto a valid CPP name.
-as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g"
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
# Sed expression to map a string onto a valid variable name.
-as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g"
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
# IFS
@@ -22604,8 +23759,8 @@ _ASBOX
} >&5
cat >&5 <<_CSEOF
-This file was extended by google-perftools $as_me 0.8, which was
-generated by GNU Autoconf 2.57. Invocation command line was
+This file was extended by google-perftools $as_me 0.90, which was
+generated by GNU Autoconf 2.59. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
CONFIG_HEADERS = $CONFIG_HEADERS
@@ -22649,9 +23804,9 @@ Usage: $0 [OPTIONS] [FILE]...
-d, --debug don't remove temporary files
--recheck update $as_me by reconfiguring in the same conditions
--file=FILE[:TEMPLATE]
- instantiate the configuration file FILE
+ instantiate the configuration file FILE
--header=FILE[:TEMPLATE]
- instantiate the configuration header FILE
+ instantiate the configuration header FILE
Configuration files:
$config_files
@@ -22667,12 +23822,11 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF
ac_cs_version="\\
-google-perftools config.status 0.8
-configured by $0, generated by GNU Autoconf 2.57,
+google-perftools config.status 0.90
+configured by $0, generated by GNU Autoconf 2.59,
with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
-Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
-Free Software Foundation, Inc.
+Copyright (C) 2003 Free Software Foundation, Inc.
This config.status script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it."
srcdir=$srcdir
@@ -22869,6 +24023,7 @@ s,@LIBS@,$LIBS,;t t
s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t
s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t
s,@INSTALL_DATA@,$INSTALL_DATA,;t t
+s,@CYGPATH_W@,$CYGPATH_W,;t t
s,@PACKAGE@,$PACKAGE,;t t
s,@VERSION@,$VERSION,;t t
s,@ACLOCAL@,$ACLOCAL,;t t
@@ -22876,13 +24031,17 @@ s,@AUTOCONF@,$AUTOCONF,;t t
s,@AUTOMAKE@,$AUTOMAKE,;t t
s,@AUTOHEADER@,$AUTOHEADER,;t t
s,@MAKEINFO@,$MAKEINFO,;t t
-s,@AMTAR@,$AMTAR,;t t
s,@install_sh@,$install_sh,;t t
s,@STRIP@,$STRIP,;t t
s,@ac_ct_STRIP@,$ac_ct_STRIP,;t t
s,@INSTALL_STRIP_PROGRAM@,$INSTALL_STRIP_PROGRAM,;t t
+s,@mkdir_p@,$mkdir_p,;t t
s,@AWK@,$AWK,;t t
s,@SET_MAKE@,$SET_MAKE,;t t
+s,@am__leading_dot@,$am__leading_dot,;t t
+s,@AMTAR@,$AMTAR,;t t
+s,@am__tar@,$am__tar,;t t
+s,@am__untar@,$am__untar,;t t
s,@CC@,$CC,;t t
s,@CFLAGS@,$CFLAGS,;t t
s,@LDFLAGS@,$LDFLAGS,;t t
@@ -22897,11 +24056,15 @@ s,@AMDEP_TRUE@,$AMDEP_TRUE,;t t
s,@AMDEP_FALSE@,$AMDEP_FALSE,;t t
s,@AMDEPBACKSLASH@,$AMDEPBACKSLASH,;t t
s,@CCDEPMODE@,$CCDEPMODE,;t t
+s,@am__fastdepCC_TRUE@,$am__fastdepCC_TRUE,;t t
+s,@am__fastdepCC_FALSE@,$am__fastdepCC_FALSE,;t t
s,@CPP@,$CPP,;t t
s,@CXX@,$CXX,;t t
s,@CXXFLAGS@,$CXXFLAGS,;t t
s,@ac_ct_CXX@,$ac_ct_CXX,;t t
s,@CXXDEPMODE@,$CXXDEPMODE,;t t
+s,@am__fastdepCXX_TRUE@,$am__fastdepCXX_TRUE,;t t
+s,@am__fastdepCXX_FALSE@,$am__fastdepCXX_FALSE,;t t
s,@build@,$build,;t t
s,@build_cpu@,$build_cpu,;t t
s,@build_vendor@,$build_vendor,;t t
@@ -22923,6 +24086,8 @@ s,@FFLAGS@,$FFLAGS,;t t
s,@ac_ct_F77@,$ac_ct_F77,;t t
s,@LIBTOOL@,$LIBTOOL,;t t
s,@LIBTOOL_DEPS@,$LIBTOOL_DEPS,;t t
+s,@UNWIND_LIBS@,$UNWIND_LIBS,;t t
+s,@EXTRA_CXXFLAGS@,$EXTRA_CXXFLAGS,;t t
s,@acx_pthread_config@,$acx_pthread_config,;t t
s,@PTHREAD_CC@,$PTHREAD_CC,;t t
s,@PTHREAD_LIBS@,$PTHREAD_LIBS,;t t
@@ -22958,9 +24123,9 @@ _ACEOF
(echo ':t
/@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
if test -z "$ac_sed_cmds"; then
- ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
+ ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
else
- ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
+ ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
fi
ac_sed_frag=`expr $ac_sed_frag + 1`
ac_beg=$ac_end
@@ -22978,21 +24143,21 @@ for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
# Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
case $ac_file in
- | *:- | *:-:* ) # input from stdin
- cat >$tmp/stdin
- ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
- ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+ cat >$tmp/stdin
+ ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
*:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
- ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
* ) ac_file_in=$ac_file.in ;;
esac
# Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
ac_dir=`(dirname "$ac_file") 2>/dev/null ||
$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$ac_file" : 'X\(//\)[^/]' \| \
- X"$ac_file" : 'X\(//\)$' \| \
- X"$ac_file" : 'X\(/\)' \| \
- . : '\(.\)' 2>/dev/null ||
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
echo X"$ac_file" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
/^X\(\/\/\)[^/].*/{ s//\1/; q; }
@@ -23008,10 +24173,10 @@ echo X"$ac_file" |
as_dirs="$as_dir $as_dirs"
as_dir=`(dirname "$as_dir") 2>/dev/null ||
$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$as_dir" : 'X\(//\)[^/]' \| \
- X"$as_dir" : 'X\(//\)$' \| \
- X"$as_dir" : 'X\(/\)' \| \
- . : '\(.\)' 2>/dev/null ||
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
echo X"$as_dir" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
/^X\(\/\/\)[^/].*/{ s//\1/; q; }
@@ -23049,12 +24214,45 @@ case $srcdir in
ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
ac_top_srcdir=$ac_top_builddir$srcdir ;;
esac
-# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
-# absolute.
-ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
-ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd`
-ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
-ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+ case "$ac_dir" in
+ .) ac_abs_builddir=`pwd`;;
+ [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+ *) ac_abs_builddir=`pwd`/"$ac_dir";;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+ case ${ac_top_builddir}. in
+ .) ac_abs_top_builddir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+ *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+ case $ac_srcdir in
+ .) ac_abs_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+ *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+ case $ac_top_srcdir in
+ .) ac_abs_top_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+ *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+ esac;;
+esac
case $INSTALL in
@@ -23062,11 +24260,6 @@ ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
*) ac_INSTALL=$ac_top_builddir$INSTALL ;;
esac
- if test x"$ac_file" != x-; then
- { echo "$as_me:$LINENO: creating $ac_file" >&5
-echo "$as_me: creating $ac_file" >&6;}
- rm -f "$ac_file"
- fi
# Let's still pretend it is `configure' which instantiates (i.e., don't
# use $as_me), people would be surprised to read:
# /* config.h. Generated by config.status. */
@@ -23076,7 +24269,7 @@ echo "$as_me: creating $ac_file" >&6;}
configure_input="$ac_file. "
fi
configure_input=$configure_input"Generated from `echo $ac_file_in |
- sed 's,.*/,,'` by configure."
+ sed 's,.*/,,'` by configure."
# First look for the input files in the build tree, otherwise in the
# src tree.
@@ -23085,26 +24278,32 @@ echo "$as_me: creating $ac_file" >&6;}
case $f in
-) echo $tmp/stdin ;;
[\\/$]*)
- # Absolute (can't be DOS-style, as IFS=:)
- test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+ # Absolute (can't be DOS-style, as IFS=:)
+ test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
echo "$as_me: error: cannot find input file: $f" >&2;}
{ (exit 1); exit 1; }; }
- echo $f;;
+ echo "$f";;
*) # Relative
- if test -f "$f"; then
- # Build tree
- echo $f
- elif test -f "$srcdir/$f"; then
- # Source tree
- echo $srcdir/$f
- else
- # /dev/null tree
- { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+ if test -f "$f"; then
+ # Build tree
+ echo "$f"
+ elif test -f "$srcdir/$f"; then
+ # Source tree
+ echo "$srcdir/$f"
+ else
+ # /dev/null tree
+ { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
echo "$as_me: error: cannot find input file: $f" >&2;}
{ (exit 1); exit 1; }; }
- fi;;
+ fi;;
esac
done` || { (exit 1); exit 1; }
+
+ if test x"$ac_file" != x-; then
+ { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+ rm -f "$ac_file"
+ fi
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF
sed "$ac_vpsub
@@ -23144,12 +24343,12 @@ cat >>$CONFIG_STATUS <<\_ACEOF
# NAME is the cpp macro being defined and VALUE is the value it is being given.
#
# ac_d sets the value in "#define NAME VALUE" lines.
-ac_dA='s,^\([ ]*\)#\([ ]*define[ ][ ]*\)'
-ac_dB='[ ].*$,\1#\2'
+ac_dA='s,^\([ ]*\)#\([ ]*define[ ][ ]*\)'
+ac_dB='[ ].*$,\1#\2'
ac_dC=' '
ac_dD=',;t'
# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
-ac_uA='s,^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_uA='s,^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
ac_uB='$,\1#\2define\3'
ac_uC=' '
ac_uD=',;t'
@@ -23158,11 +24357,11 @@ for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue
# Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
case $ac_file in
- | *:- | *:-:* ) # input from stdin
- cat >$tmp/stdin
- ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
- ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+ cat >$tmp/stdin
+ ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
*:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
- ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+ ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
* ) ac_file_in=$ac_file.in ;;
esac
@@ -23176,28 +24375,29 @@ echo "$as_me: creating $ac_file" >&6;}
case $f in
-) echo $tmp/stdin ;;
[\\/$]*)
- # Absolute (can't be DOS-style, as IFS=:)
- test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+ # Absolute (can't be DOS-style, as IFS=:)
+ test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
echo "$as_me: error: cannot find input file: $f" >&2;}
{ (exit 1); exit 1; }; }
- echo $f;;
+ # Do quote $f, to prevent DOS paths from being IFS'd.
+ echo "$f";;
*) # Relative
- if test -f "$f"; then
- # Build tree
- echo $f
- elif test -f "$srcdir/$f"; then
- # Source tree
- echo $srcdir/$f
- else
- # /dev/null tree
- { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+ if test -f "$f"; then
+ # Build tree
+ echo "$f"
+ elif test -f "$srcdir/$f"; then
+ # Source tree
+ echo "$srcdir/$f"
+ else
+ # /dev/null tree
+ { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
echo "$as_me: error: cannot find input file: $f" >&2;}
{ (exit 1); exit 1; }; }
- fi;;
+ fi;;
esac
done` || { (exit 1); exit 1; }
# Remove the trailing spaces.
- sed 's/[ ]*$//' $ac_file_inputs >$tmp/in
+ sed 's/[ ]*$//' $ac_file_inputs >$tmp/in
_ACEOF
@@ -23220,9 +24420,9 @@ s/[\\&,]/\\&/g
s,[\\$`],\\&,g
t clear
: clear
-s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*\)\(([^)]*)\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp
+s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*\)\(([^)]*)\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp
t end
-s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp
+s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp
: end
_ACEOF
# If some macros were called several times there might be several times
@@ -23236,13 +24436,13 @@ rm -f confdef2sed.sed
# example, in the case of _POSIX_SOURCE, which is predefined and required
# on some systems where configure will not decide to define it.
cat >>conftest.undefs <<\_ACEOF
-s,^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */,
+s,^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */,
_ACEOF
# Break up conftest.defines because some shells have a limit on the size
# of here documents, and old seds have small limits too (100 cmds).
echo ' # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS
-echo ' if grep "^[ ]*#[ ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS
+echo ' if grep "^[ ]*#[ ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS
echo ' # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS
echo ' :' >>$CONFIG_STATUS
rm -f conftest.tail
@@ -23251,7 +24451,7 @@ do
# Write a limited-size here document to $tmp/defines.sed.
echo ' cat >$tmp/defines.sed <<CEOF' >>$CONFIG_STATUS
# Speed up: don't consider the non `#define' lines.
- echo '/^[ ]*#[ ]*define/!b' >>$CONFIG_STATUS
+ echo '/^[ ]*#[ ]*define/!b' >>$CONFIG_STATUS
# Work around the forget-to-reset-the-flag bug.
echo 't clr' >>$CONFIG_STATUS
echo ': clr' >>$CONFIG_STATUS
@@ -23278,7 +24478,7 @@ do
# Write a limited-size here document to $tmp/undefs.sed.
echo ' cat >$tmp/undefs.sed <<CEOF' >>$CONFIG_STATUS
# Speed up: don't consider the non `#undef'
- echo '/^[ ]*#[ ]*undef/!b' >>$CONFIG_STATUS
+ echo '/^[ ]*#[ ]*undef/!b' >>$CONFIG_STATUS
# Work around the forget-to-reset-the-flag bug.
echo 't clr' >>$CONFIG_STATUS
echo ': clr' >>$CONFIG_STATUS
@@ -23312,10 +24512,10 @@ echo "$as_me: $ac_file is unchanged" >&6;}
else
ac_dir=`(dirname "$ac_file") 2>/dev/null ||
$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$ac_file" : 'X\(//\)[^/]' \| \
- X"$ac_file" : 'X\(//\)$' \| \
- X"$ac_file" : 'X\(/\)' \| \
- . : '\(.\)' 2>/dev/null ||
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
echo X"$ac_file" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
/^X\(\/\/\)[^/].*/{ s//\1/; q; }
@@ -23331,10 +24531,10 @@ echo X"$ac_file" |
as_dirs="$as_dir $as_dirs"
as_dir=`(dirname "$as_dir") 2>/dev/null ||
$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$as_dir" : 'X\(//\)[^/]' \| \
- X"$as_dir" : 'X\(//\)$' \| \
- X"$as_dir" : 'X\(/\)' \| \
- . : '\(.\)' 2>/dev/null ||
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
echo X"$as_dir" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
/^X\(\/\/\)[^/].*/{ s//\1/; q; }
@@ -23354,13 +24554,29 @@ echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
cat $tmp/config.h
rm -f $tmp/config.h
fi
- # Run the commands associated with the file.
- case $ac_file in
- src/config.h ) # update the timestamp
-echo 'timestamp for src/config.h' >"src/stamp-h1"
- ;;
+# Compute $ac_file's index in $config_headers.
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+ case $_am_header in
+ $ac_file | $ac_file:* )
+ break ;;
+ * )
+ _am_stamp_count=`expr $_am_stamp_count + 1` ;;
esac
done
+echo "timestamp for $ac_file" >`(dirname $ac_file) 2>/dev/null ||
+$as_expr X$ac_file : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X$ac_file : 'X\(//\)[^/]' \| \
+ X$ac_file : 'X\(//\)$' \| \
+ X$ac_file : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X$ac_file |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`/stamp-h$_am_stamp_count
+done
_ACEOF
cat >>$CONFIG_STATUS <<\_ACEOF
@@ -23372,16 +24588,41 @@ for ac_file in : $CONFIG_COMMANDS; do test "x$ac_file" = x: && continue
ac_source=`echo "$ac_file" | sed 's,[^:]*:,,'`
ac_dir=`(dirname "$ac_dest") 2>/dev/null ||
$as_expr X"$ac_dest" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$ac_dest" : 'X\(//\)[^/]' \| \
- X"$ac_dest" : 'X\(//\)$' \| \
- X"$ac_dest" : 'X\(/\)' \| \
- . : '\(.\)' 2>/dev/null ||
+ X"$ac_dest" : 'X\(//\)[^/]' \| \
+ X"$ac_dest" : 'X\(//\)$' \| \
+ X"$ac_dest" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
echo X"$ac_dest" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
/^X\(\/\/\)[^/].*/{ s//\1/; q; }
/^X\(\/\/\)$/{ s//\1/; q; }
/^X\(\/\).*/{ s//\1/; q; }
s/.*/./; q'`
+ { if $as_mkdir_p; then
+ mkdir -p "$ac_dir"
+ else
+ as_dir="$ac_dir"
+ as_dirs=
+ while test ! -d "$as_dir"; do
+ as_dirs="$as_dir $as_dirs"
+ as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+ /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+ /^X\(\/\/\)$/{ s//\1/; q; }
+ /^X\(\/\).*/{ s//\1/; q; }
+ s/.*/./; q'`
+ done
+ test ! -n "$as_dirs" || mkdir $as_dirs
+ fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+ { (exit 1); exit 1; }; }; }
+
ac_builddir=.
if test "$ac_dir" != .; then
@@ -23407,12 +24648,45 @@ case $srcdir in
ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
ac_top_srcdir=$ac_top_builddir$srcdir ;;
esac
-# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
-# absolute.
-ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
-ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd`
-ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
-ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+ case "$ac_dir" in
+ .) ac_abs_builddir=`pwd`;;
+ [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+ *) ac_abs_builddir=`pwd`/"$ac_dir";;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+ case ${ac_top_builddir}. in
+ .) ac_abs_top_builddir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+ *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+ case $ac_srcdir in
+ .) ac_abs_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+ *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+ esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+ case $ac_top_srcdir in
+ .) ac_abs_top_srcdir=$ac_abs_builddir;;
+ [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+ *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+ esac;;
+esac
{ echo "$as_me:$LINENO: executing $ac_dest commands" >&5
@@ -23430,10 +24704,10 @@ echo "$as_me: executing $ac_dest commands" >&6;}
if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then
dirpart=`(dirname "$mf") 2>/dev/null ||
$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$mf" : 'X\(//\)[^/]' \| \
- X"$mf" : 'X\(//\)$' \| \
- X"$mf" : 'X\(/\)' \| \
- . : '\(.\)' 2>/dev/null ||
+ X"$mf" : 'X\(//\)[^/]' \| \
+ X"$mf" : 'X\(//\)$' \| \
+ X"$mf" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
echo X"$mf" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
/^X\(\/\/\)[^/].*/{ s//\1/; q; }
@@ -23443,36 +24717,30 @@ echo X"$mf" |
else
continue
fi
- grep '^DEP_FILES *= *[^ #]' < "$mf" > /dev/null || continue
- # Extract the definition of DEP_FILES from the Makefile without
- # running `make'.
- DEPDIR=`sed -n -e '/^DEPDIR = / s///p' < "$mf"`
+ # Extract the definition of DEPDIR, am__include, and am__quote
+ # from the Makefile without running `make'.
+ DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
test -z "$DEPDIR" && continue
+ am__include=`sed -n 's/^am__include = //p' < "$mf"`
+ test -z "am__include" && continue
+ am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
# When using ansi2knr, U may be empty or an underscore; expand it
- U=`sed -n -e '/^U = / s///p' < "$mf"`
- test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR"
- # We invoke sed twice because it is the simplest approach to
- # changing $(DEPDIR) to its actual value in the expansion.
- for file in `sed -n -e '
- /^DEP_FILES = .*\\\\$/ {
- s/^DEP_FILES = //
- :loop
- s/\\\\$//
- p
- n
- /\\\\$/ b loop
- p
- }
- /^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \
+ U=`sed -n 's/^U = //p' < "$mf"`
+ # Find all dependency output files, they are included files with
+ # $(DEPDIR) in their names. We invoke sed twice because it is the
+ # simplest approach to changing $(DEPDIR) to its actual value in the
+ # expansion.
+ for file in `sed -n "
+ s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
# Make sure the directory exists.
test -f "$dirpart/$file" && continue
fdir=`(dirname "$file") 2>/dev/null ||
$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$file" : 'X\(//\)[^/]' \| \
- X"$file" : 'X\(//\)$' \| \
- X"$file" : 'X\(/\)' \| \
- . : '\(.\)' 2>/dev/null ||
+ X"$file" : 'X\(//\)[^/]' \| \
+ X"$file" : 'X\(//\)$' \| \
+ X"$file" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
echo X"$file" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
/^X\(\/\/\)[^/].*/{ s//\1/; q; }
@@ -23488,10 +24756,10 @@ echo X"$file" |
as_dirs="$as_dir $as_dirs"
as_dir=`(dirname "$as_dir") 2>/dev/null ||
$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$as_dir" : 'X\(//\)[^/]' \| \
- X"$as_dir" : 'X\(//\)$' \| \
- X"$as_dir" : 'X\(/\)' \| \
- . : '\(.\)' 2>/dev/null ||
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| \
+ . : '\(.\)' 2>/dev/null ||
echo X"$as_dir" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
/^X\(\/\/\)[^/].*/{ s//\1/; q; }
diff --git a/configure.ac b/configure.ac
index f72e687..20aa4ad 100644
--- a/configure.ac
+++ b/configure.ac
@@ -5,7 +5,7 @@
# make sure we're interpreted by some minimal autoconf
AC_PREREQ(2.57)
-AC_INIT(google-perftools, 0.8, opensource@google.com)
+AC_INIT(google-perftools, 0.90, opensource@google.com)
# The argument here is just something that should be in the current directory
# (for sanity checking)
AC_CONFIG_SRCDIR(README)
@@ -26,18 +26,19 @@ AX_C___ATTRIBUTE__
# Check whether some low-level functions/files are available
AC_HEADER_STDC
-# Here are some examples of how to check for the existence of a fn or file
AC_CHECK_TYPES([__int64]) # defined in some windows platforms
+AC_CHECK_TYPES([struct mallinfo],,, [#include <malloc.h>])
AC_CHECK_FUNCS(sbrk) # for tcmalloc to get memory
AC_CHECK_FUNCS(munmap)
AC_FUNC_MMAP
AC_CHECK_HEADERS(execinfo.h) # for stacktrace? and heapchecker_unittest
-AC_CHECK_HEADERS(libunwind.h) # for stacktrace (will be needed soon)
-AC_CHECK_HEADERS(unwind.h) # for stacktrace (will be needed soon)
+AC_CHECK_HEADERS(libunwind.h) # for stacktrace
+AC_CHECK_HEADERS(unwind.h) # for stacktrace
AC_CHECK_HEADERS(conflict-signal.h) # defined on some windows platforms
AC_CHECK_HEADERS(linux/ptrace.h)
AC_CHECK_HEADERS(syscall.h)
AC_CHECK_HEADERS(grp.h) # for heapchecker_unittest
+AC_CHECK_HEADERS(pwd.h) # for heapchecker_unittest
AC_CHECK_MEMBERS([struct sigcontext.sc_eip,
struct ucontext.uc_mcontext,
struct sigcontext.eip,
@@ -45,20 +46,54 @@ AC_CHECK_MEMBERS([struct sigcontext.sc_eip,
struct sigcontext.sc_ip,
struct siginfo.si_faddr,
struct sigcontext.regs->nip],,,
- [#include <signal.h>])
+ [#define _XOPEN_SOURCE 500
+ #include <signal.h>])
+
+# We want to link in libunwind if it exists
+AC_CHECK_LIB(unwind, backtrace, UNWIND_LIBS=-lunwind, UNWIND_LIBS=)
+AC_SUBST(UNWIND_LIBS)
+
+# On x86_64, instead of libunwind, we can choose to compile with frame-pointers
+# (This isn't needed on i386, where -fno-omit-frame-pointer is the default).
+AC_ARG_ENABLE(frame_pointer,
+ AS_HELP_STRING([--enable-frame-pointer],
+ [On x86_64 systems, compile with -fno-omit-frame-pointer (see INSTALL)]),
+ , enable_frame_pointer=no)
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM(, [return __x86_64__ == 1 ? 0 : 1])],
+ [is_x86_64=yes], [is_x86_64=no])
+EXTRA_CXXFLAGS=
+if test "$is_x86_64" = yes -a "$enable_frame_pointer" = "yes"; then
+ EXTRA_CXXFLAGS=-fno-omit-frame-pointer
+elif test "$is_x86_64" = yes -a "$enable_frame_pointer" != "yes"; then
+ # TODO(csilvers): set -DNO_FRAME_POINTER in the Makefile instead, based
+ # on the presence of -f[no-]omit-frame-pointer in cxxflags.
+ EXTRA_CXXFLAGS=-DNO_FRAME_POINTER
+fi
+AC_SUBST(EXTRA_CXXFLAGS)
# Defines PRIuS
AC_COMPILER_CHARACTERISTICS
# Check if __builtin_stack_pointer() is available (for elfcore.h)
AC_MSG_CHECKING([for __builtin_stack_pointer()])
-AC_LINK_IFELSE([AC_LANG_PROGRAM(, [void *sp = __builtin_stack_pointer();])],
+AC_LINK_IFELSE([AC_LANG_PROGRAM(, [void *sp = __builtin_stack_pointer()])],
[AC_DEFINE(HAVE_BUILTIN_STACK_POINTER, 1,
Define to 1 if compiler supports __builtin_stack_pointer)
AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no])])
-# A lot of the code in this directory depends on pthreads
+# If we support __thread, that can speed up tcmalloc a bit.
+AC_MSG_CHECKING([for __thread])
+AC_LINK_IFELSE([AC_LANG_PROGRAM(, [static __thread int p = 0])],
+ [AC_DEFINE(HAVE_TLS, 1,
+ Define to 1 if compiler supports __thread)
+ AC_MSG_RESULT([yes])],
+ [AC_MSG_RESULT([no])])
+
+# We also need to check if the kernel supports __thread, which requires uname()
+AC_CHECK_DECLS(uname,,, [#include <sys/utsname.h>])
+
+# In fact, a lot of the code in this directory depends on pthreads
ACX_PTHREAD
# Find out what namespace 'normal' STL code lives in
diff --git a/doc/cpu_profiler.html b/doc/cpuprofile.html
index ff98321..4b5136e 100644
--- a/doc/cpu_profiler.html
+++ b/doc/cpuprofile.html
@@ -1,48 +1,57 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<HTML>
<HEAD>
-<title>Google CPU Profiler</title>
+ <link rel="stylesheet" href="designstyle.css">
+ <title>Google CPU Profiler</title>
</HEAD>
<BODY>
-This is the CPU profiler we use at Google. There are three parts to
-using it: linking the library into an application, running the code,
-and analyzing the output.
+<p align=right>
+ <i>Last modified
+ <script type=text/javascript>
+ var lm = new Date(document.lastModified);
+ document.write(lm.toDateString());
+ </script></i>
+</p>
+
+<p>This is the CPU profiler we use at Google. There are three parts
+to using it: linking the library into an application, running the
+code, and analyzing the output.</p>
<H1>Linking in the Library</H1>
-<p>To install the CPU profiler into your executable, add -lprofiler to
-the link-time step for your executable. (It's also probably possible
-to add in the profiler at run-time using LD_PRELOAD, but this isn't
-necessarily recommended.)</p>
+<p>To install the CPU profiler into your executable, add
+<code>-lprofiler</code> to the link-time step for your executable.
+(It's also probably possible to add in the profiler at run-time using
+<code>LD_PRELOAD</code>, but this isn't necessarily recommended.)</p>
-<p>This does <i>not</i> turn on CPU profiling; it just inserts the code.
-For that reason, it's practical to just always link -lprofiler into a
-binary while developing; that's what we do at Google. (However, since
-any user can turn on the profiler by setting an environment variable,
-it's not necessarily recommended to install profiler-linked binaries
-into a production, running system.)</p>
+<p>This does <i>not</i> turn on CPU profiling; it just inserts the
+code. For that reason, it's practical to just always link
+<code>-lprofiler</code> into a binary while developing; that's what we
+do at Google. (However, since any user can turn on the profiler by
+setting an environment variable, it's not necessarily recommended to
+install profiler-linked binaries into a production, running
+system.)</p>
<H1>Running the Code</H1>
-<p>There are two alternatives to actually turn on CPU profiling for a
-given run of an executable:</p>
+<p>There are several alternatives to actually turn on CPU profiling
+for a given run of an executable:</p>
<ol>
-<li> Define the environment variable CPUPROFILE to the filename to dump the
- profile to. For instance, to profile /usr/local/netscape:
- <pre>
- $ CPUPROFILE=/tmp/profile /usr/local/netscape # sh
- % setenv CPUPROFILE /tmp/profile; /usr/local/netscape # csh
- </pre>
- OR
-
-<li> In your code, bracket the code you want profiled in calls to
- ProfilerStart() and ProfilerStop(). ProfilerStart() will take the
- profile-filename as an argument.
+ <li> <p>Define the environment variable CPUPROFILE to the filename
+ to dump the profile to. For instance, to profile
+ <code>/usr/local/bin/my_binary_compiled_with_tcmalloc</code>:</p>
+ <pre>% env CPUPROFILE=/tmp/mybin.prof /usr/local/bin/my_binary_compiled_with_tcmalloc</pre>
+
+ <li> <p>In your code, bracket the code you want profiled in calls to
+ <code>ProfilerStart()</code> and <code>ProfilerStop()</code>.
+ <code>ProfilerStart()</code> will take
+ the profile-filename as an argument.</p>
</ol>
<p>In Linux 2.6 and above, profiling works correctly with threads,
@@ -55,60 +64,59 @@ CPUPROFILE with the child's process id).</p>
<p>For security reasons, CPU profiling will not write to a file -- and
is thus not usable -- for setuid programs.</p>
-<H2>Controlling Behavior via the Environment</H2>
+<H2>Modifying Runtime Behavior</H2>
-<p>In addition to the environment variable <code>CPUPROFILE</code>,
-which determines where profiles are written, there are several
-environment variables which control the performance of the CPU
-profile.</p>
+<p>You can more finely control the behavior of the CPU profiler via
+environment variables.</p>
<table frame=box rules=sides cellpadding=5 width=100%>
-<tr>
-<td><code>PROFILEFREQUENCY=<i>x</i></code></td>
- <td>How many interrupts/second the cpu-profiler samples.
- </td>
+
+<tr valign=top>
+ <td><code>CPUPROFILE_FREQUENCY=<i>x</i></code></td>
+ <td>
+ How many interrupts/second the cpu-profiler samples.
+ </td>
</tr>
+
</table>
-<H1>Analyzing the Output</H1>
-<p>pprof is the script used to analyze a profile. It has many output
-modes, both textual and graphical. Some give just raw numbers, much
-like the -pg output of gcc, and others show the data in the form of a
-dependency graph.</p>
+<h1><a name="pprof">Analyzing the Output</a></h1>
-<p>pprof <b>requires</b> perl5 to be installed to run. It also
-requires dot to be installed for any of the graphical output routines,
-and gv to be installed for --gv mode (described below).</p>
+<p><code>pprof</code> is the script used to analyze a profile. It has
+many output modes, both textual and graphical. Some give just raw
+numbers, much like the <code>-pg</code> output of <code>gcc</code>,
+and others show the data in the form of a dependency graph.</p>
+
+<p>pprof <b>requires</b> <code>perl5</code> to be installed to run.
+It also requires <code>dot</code> to be installed for any of the
+graphical output routines, and <code>gv</code> to be installed for
+<code>--gv</code> mode (described below).
+</p>
<p>Here are some ways to call pprof. These are described in more
detail below.</p>
<pre>
-% pprof "program" "profile"
- Generates one line per procedure
-
-% pprof --gv "program" "profile"
- Generates annotated call-graph and displays via "gv"
-
-% pprof --gv --focus=Mutex "program" "profile"
- Restrict to code paths that involve an entry that matches "Mutex"
-
-% pprof --gv --focus=Mutex --ignore=string "program" "profile"
- Restrict to code paths that involve an entry that matches "Mutex"
- and does not match "string"
-
-% pprof --list=IBF_CheckDocid "program" "profile"
- Generates disassembly listing of all routines with at least one
- sample that match the --list=<regexp> pattern. The listing is
- annotated with the flat and cumulative sample counts at each line.
-
-% pprof --disasm=IBF_CheckDocid "program" "profile"
- Generates disassembly listing of all routines with at least one
- sample that match the --disasm=<regexp> pattern. The listing is
- annotated with the flat and cumulative sample counts at each PC value.
+% pprof /bin/ls ls.prof
+ Enters "interactive" mode
+% pprof --text /bin/ls ls.prof
+ Outputs one line per procedure
+% pprof --gv /bin/ls ls.prof
+ Displays annotated call-graph via 'gv'
+% pprof --gv --focus=Mutex /bin/ls ls.prof
+ Restricts to code paths including a .*Mutex.* entry
+% pprof --gv --focus=Mutex --ignore=string /bin/ls ls.prof
+ Code paths including Mutex but not string
+% pprof --list=getdir /bin/ls ls.prof
+ (Per-line) annotated source listing for getdir()
+% pprof --disasm=getdir /bin/ls ls.prof
+ (Per-PC) annotated disassembly for getdir()
+% pprof --text localhost:1234
+ Outputs one line per procedure for localhost:1234
</pre>
+
<h3>Analyzing Text Output</h3>
<p>Text mode has lines of output that look like this:</p>
@@ -138,9 +146,8 @@ annotated with timing information, like so:</p>
</td></tr></table></center>
</A>
-<p>Each node represents a procedure.
-The directed edges indicate caller to callee relations. Each node is
-formatted as follows:</p>
+<p>Each node represents a procedure. The directed edges indicate
+caller to callee relations. Each node is formatted as follows:</p>
<center><pre>
Class Name
@@ -157,34 +164,38 @@ time spent executing the instructions directly contained in the
procedure (and in any other procedures that were inlined into the
procedure). The "cumulative" time is the sum of the "local" time and
the time spent in any callees. If the cumulative time is the same as
-the local time, it is not printed.
+the local time, it is not printed.</p>
<p>For instance, the timing information for test_main_thread()
indicates that 155 units (about 1.55 seconds) were spent executing the
-code in test_main_thread() and 200 units were spent while executing
-test_main_thread() and its callees such as snprintf().</p>
+code in <code>test_main_thread()</code> and 200 units were spent while
+executing <code>test_main_thread()</code> and its callees such as
+<code>snprintf()</code>.</p>
<p>The size of the node is proportional to the local count. The
percentage displayed in the node corresponds to the count divided by
the total run time of the program (that is, the cumulative count for
-main()).</p>
+<code>main()</code>).</p>
<h3>Edge Information</h3>
<p>An edge from one node to another indicates a caller to callee
relationship. Each edge is labelled with the time spent by the callee
-on behalf of the caller. E.g, the edge from test_main_thread() to
-snprintf() indicates that of the 200 samples in
-test_main_thread(), 37 are because of calls to snprintf().</p>
+on behalf of the caller. E.g, the edge from
+<code>test_main_thread()</code> to <code>snprintf()</code> indicates
+that of the 200 samples in <code>test_main_thread()</code>, 37 are
+because of calls to <code>snprintf()</code>.</p>
-<p>Note that test_main_thread() has an edge to vsnprintf(), even
-though test_main_thread() doesn't call that function directly. This
-is because the code was compiled with -O2; the profile reflects the
-optimized control flow.</p>
+<p>Note that <code>test_main_thread()</code> has an edge to
+<code>vsnprintf()</code>, even though <code>test_main_thread()</code>
+doesn't call that function directly. This is because the code was
+compiled with <code>-O2</code>; the profile reflects the optimized
+control flow.</p>
<h3>Meta Information</h3>
-The top of the display should contain some meta information like:
+<p>The top of the display should contain some meta information
+like:</p>
<pre>
/tmp/profiler2_unittest
Total samples: 202
@@ -193,13 +204,13 @@ The top of the display should contain some meta information like:
Dropped edges with &lt;= 0 samples
</pre>
-This section contains the name of the program, and the total samples
-collected during the profiling run. If the --focus option is on (see
-the <a href="#focus">Focus</a> section below), the legend also
-contains the number of samples being shown in the focused display.
-Furthermore, some unimportant nodes and edges are dropped to reduce
-clutter. The characteristics of the dropped nodes and edges are also
-displayed in the legend.
+<p>This section contains the name of the program, and the total
+samples collected during the profiling run. If the
+<code>--focus</code> option is on (see the <a href="#focus">Focus</a>
+section below), the legend also contains the number of samples being
+shown in the focused display. Furthermore, some unimportant nodes and
+edges are dropped to reduce clutter. The characteristics of the
+dropped nodes and edges are also displayed in the legend.</p>
<h3><a name=focus>Focus and Ignore</a></h3>
@@ -208,7 +219,8 @@ piece of the program. You specify a regular expression. Any portion
of the call-graph that is on a path which contains at least one node
matching the regular expression is preserved. The rest of the
call-graph is dropped on the floor. For example, you can focus on the
-vsnprintf() libc call in profiler2_unittest as follows:</p>
+<code>vsnprintf()</code> libc call in <code>profiler2_unittest</code>
+as follows:</p>
<pre>
% pprof --gv --focus=vsnprintf /tmp/profiler2_unittest test.prof
@@ -219,17 +231,28 @@ vsnprintf() libc call in profiler2_unittest as follows:</p>
</td></tr></table></center>
</A>
-<p>
-Similarly, you can supply the --ignore option to ignore
-samples that match a specified regular expression. E.g.,
-if you are interested in everything except calls to snprintf(),
-you can say:
+<p>Similarly, you can supply the <code>--ignore</code> option to
+ignore samples that match a specified regular expression. E.g., if
+you are interested in everything except calls to
+<code>snprintf()</code>, you can say:</p>
<pre>
% pprof --gv --ignore=snprintf /tmp/profiler2_unittest test.prof
</pre>
+
+<h3>Interactive mode</a></h3>
+
+<p>By default -- if you don't specify any flags to the contrary --
+pprof runs in interactive mode. At the <code>(pprof)</code> prompt,
+you can run many of the commands described above. You can type
+<code>help</code> for a list of what commands are available in
+interactive mode.</p>
+
<h3><a name=options>pprof Options</a></h3>
+For a complete list of pprof options, you can run <code>pprof
+--help</code>.
+
<h4>Output Type</h4>
<p>
@@ -238,39 +261,46 @@ you can say:
<tr valign=top>
<td><code>--text</code></td>
<td>
- Produces a textual listing. This is currently the default
- since it does not need to access to an X display, or
- dot or gv. However if you
- have these programs installed, you will probably be
- happier with the --gv output.
+ Produces a textual listing. (Note: If you have an X display, and
+ <code>dot</code> and <code>gv</code> installed, you will probably
+ be happier with the <code>--gv</code> output.)
</td>
</tr>
<tr valign=top>
<td><code>--gv</code></td>
<td>
Generates annotated call-graph, converts to postscript, and
- displays via gv.
+ displays via gv (requres <code>dot</code> and <code>gv</code> be
+ installed).
</td>
</tr>
<tr valign=top>
<td><code>--dot</code></td>
<td>
Generates the annotated call-graph in dot format and
- emits to stdout.
+ emits to stdout (requres <code>dot</code> be installed).
</td>
</tr>
<tr valign=top>
<td><code>--ps</code></td>
<td>
Generates the annotated call-graph in Postscript format and
- emits to stdout.
+ emits to stdout (requres <code>dot</code> be installed).
+ </td>
+</tr>
+<tr valign=top>
+ <td><code>--pdf</code></td>
+ <td>
+ Generates the annotated call-graph in PDF format and emits to
+ stdout (requires <code>dot</code> and <code>ps2pdf</code> be
+ installed).
</td>
</tr>
<tr valign=top>
<td><code>--gif</code></td>
<td>
Generates the annotated call-graph in GIF format and
- emits to stdout.
+ emits to stdout (requres <code>dot</code> be installed).
</td>
</tr>
<tr valign=top>
@@ -304,8 +334,8 @@ you can say:
<p>By default, pprof produces one entry per procedure. However you can
use one of the following options to change the granularity of the
-output. The --files option seems to be particularly useless, and may
-be removed eventually.</p>
+output. The <code>--files</code> option seems to be particularly
+useless, and may be removed eventually.</p>
<center>
<table frame=box rules=sides cellpadding=5 width=100%>
@@ -398,42 +428,49 @@ display. The following options control this effect:</p>
<p>The dropped edges and nodes account for some count mismatches in
the display. For example, the cumulative count for
-snprintf() in the first diagram above was 41. However the local
-count (1) and the count along the outgoing edges (12+1+20+6) add up to
-only 40.</p>
+<code>snprintf()</code> in the first diagram above was 41. However
+the local count (1) and the count along the outgoing edges (12+1+20+6)
+add up to only 40.</p>
<h1>Caveats</h1>
<ul>
-<li> If the program exits because of a signal, the generated profile
- will be <font color=red>incomplete, and may perhaps be
- completely empty.</font>
-<li> The displayed graph may have disconnected regions because
- of the edge-dropping heuristics described above.
-<li> If the program linked in a library that was not compiled
- with enough symbolic information, all samples associated
- with the library may be charged to the last symbol found
- in the program before the libary. This will artificially
- inflate the count for that symbol.
-<li> If you run the program on one machine, and profile it on another,
- and the shared libraries are different on the two machines, the
- profiling output may be confusing: samples that fall within
- the shared libaries may be assigned to arbitrary procedures.
-<li> If your program forks, the children will also be profiled (since
- they inherit the same CPUPROFILE setting). Each process is
- profiled separately; to distinguish the child profiles from the
- parent profile and from each other, all children will have their
- process-id appended to the CPUPROFILE name.
-<li> Due to a hack we make to work around a possible gcc bug, your
- profiles may end up named strangely if the first character of
- your CPUPROFILE variable has ascii value greater than 127. This
- should be exceedingly rare, but if you need to use such a name,
- just set prepend <code>./</code> to your filename:
- <code>CPUPROFILE=./&Auml;gypten</code>.
+ <li> If the program exits because of a signal, the generated profile
+ will be <font color=red>incomplete, and may perhaps be
+ completely empty</font>.
+ <li> The displayed graph may have disconnected regions because
+ of the edge-dropping heuristics described above.
+ <li> If the program linked in a library that was not compiled
+ with enough symbolic information, all samples associated
+ with the library may be charged to the last symbol found
+ in the program before the library. This will artificially
+ inflate the count for that symbol.
+ <li> If you run the program on one machine, and profile it on
+ another, and the shared libraries are different on the two
+ machines, the profiling output may be confusing: samples that
+ fall within shared libaries may be assigned to arbitrary
+ procedures.
+ <li> If your program forks, the children will also be profiled
+ (since they inherit the same CPUPROFILE setting). Each process
+ is profiled separately; to distinguish the child profiles from
+ the parent profile and from each other, all children will have
+ their process-id appended to the CPUPROFILE name.
+ <li> Due to a hack we make to work around a possible gcc bug, your
+ profiles may end up named strangely if the first character of
+ your CPUPROFILE variable has ascii value greater than 127.
+ This should be exceedingly rare, but if you need to use such a
+ name, just set prepend <code>./</code> to your filename:
+ <code>CPUPROFILE=./&Auml;gypten</code>.
</ul>
+
<hr>
-Last modified: Wed Apr 20 04:54:23 PDT 2005
-</body>
-</html>
+<address>Sanjay Ghemawat<br>
+<!-- Created: Tue Dec 19 10:43:14 PST 2000 -->
+<!-- hhmts start -->
+Last modified: Sat Feb 24 13:11:38 PST 2007 (csilvers)
+<!-- hhmts end -->
+</address>
+</BODY>
+</HTML>
diff --git a/doc/designstyle.css b/doc/designstyle.css
new file mode 100644
index 0000000..f5d1ec2
--- /dev/null
+++ b/doc/designstyle.css
@@ -0,0 +1,115 @@
+body {
+ background-color: #ffffff;
+ color: black;
+ margin-right: 1in;
+ margin-left: 1in;
+}
+
+
+h1, h2, h3, h4, h5, h6 {
+ color: #3366ff;
+ font-family: sans-serif;
+}
+@media print {
+ /* Darker version for printing */
+ h1, h2, h3, h4, h5, h6 {
+ color: #000080;
+ font-family: helvetica, sans-serif;
+ }
+}
+
+h1 {
+ text-align: center;
+ font-size: 18pt;
+}
+h2 {
+ margin-left: -0.5in;
+}
+h3 {
+ margin-left: -0.25in;
+}
+h4 {
+ margin-left: -0.125in;
+}
+hr {
+ margin-left: -1in;
+}
+
+/* Definition lists: definition term bold */
+dt {
+ font-weight: bold;
+}
+
+address {
+ text-align: right;
+}
+/* Use the <code> tag for bits of code and <var> for variables and objects. */
+code,pre,samp,var {
+ color: #006000;
+}
+/* Use the <file> tag for file and directory paths and names. */
+file {
+ color: #905050;
+ font-family: monospace;
+}
+/* Use the <kbd> tag for stuff the user should type. */
+kbd {
+ color: #600000;
+}
+div.note p {
+ float: right;
+ width: 3in;
+ margin-right: 0%;
+ padding: 1px;
+ border: 2px solid #6060a0;
+ background-color: #fffff0;
+}
+
+UL.nobullets {
+ list-style-type: none;
+ list-style-image: none;
+ margin-left: -1em;
+}
+
+/*
+body:after {
+ content: "Google Confidential";
+}
+*/
+
+/* pretty printing styles. See prettify.js */
+.str { color: #080; }
+.kwd { color: #008; }
+.com { color: #800; }
+.typ { color: #606; }
+.lit { color: #066; }
+.pun { color: #660; }
+.pln { color: #000; }
+.tag { color: #008; }
+.atn { color: #606; }
+.atv { color: #080; }
+pre.prettyprint { padding: 2px; border: 1px solid #888; }
+
+.embsrc { background: #eee; }
+
+@media print {
+ .str { color: #060; }
+ .kwd { color: #006; font-weight: bold; }
+ .com { color: #600; font-style: italic; }
+ .typ { color: #404; font-weight: bold; }
+ .lit { color: #044; }
+ .pun { color: #440; }
+ .pln { color: #000; }
+ .tag { color: #006; font-weight: bold; }
+ .atn { color: #404; }
+ .atv { color: #060; }
+}
+
+/* Table Column Headers */
+.hdr {
+ color: #006;
+ font-weight: bold;
+ background-color: #dddddd; }
+.hdr2 {
+ color: #006;
+ background-color: #eeeeee; } \ No newline at end of file
diff --git a/doc/heap_checker.html b/doc/heap_checker.html
index a8fa26c..ae50d70 100644
--- a/doc/heap_checker.html
+++ b/doc/heap_checker.html
@@ -1,142 +1,576 @@
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
-<html>
-<head>
-<title>Google Heap Checker</title>
-</head>
+<HTML>
-<body>
-<h1>Automatic Leaks Checking Support</h1>
+<HEAD>
+ <link rel="stylesheet" href="designstyle.css">
+ <title>Google Heap Leak Checker</title>
+</HEAD>
-This document describes how to check the heap usage of a C++
-program. This facility can be useful for automatically detecting
-memory leaks.
+<BODY>
-<h2>Linking in the Heap Checker</h2>
-
-<p>
-You can heap-check any program that has the tcmalloc library linked
-in. No recompilation is necessary to use the heap checker.
+<p align=right>
+ <i>Last modified
+ <script type=text/javascript>
+ var lm = new Date(document.lastModified);
+ document.write(lm.toDateString());
+ </script></i>
</p>
-<p>
-In order to catch all heap leaks, tcmalloc must be linked <i>last</i> into
-your executable. The heap checker may mischaracterize some memory
-accesses in libraries listed after it on the link line. For instance,
-it may report these libraries as leaking memory when they're not.
-(See the source code for more details.)
-</p>
+<p>This is the heap checker we use at Google to detect memory leaks in
+C++ programs. There are three parts to using it: linking the library
+into an application, running the code, and analyzing the output.</p>
-<p>
-It's safe to link in tcmalloc even if you don't expect to
-heap-check your program. Your programs will not run any slower
-as long as you don't use any of the heap-checker features.
-</p>
-<p>
-You can run the heap checker on applications you didn't compile
-yourself, by using LD_PRELOAD:
-</p>
-<pre>
- $ LD_PRELOAD="/usr/lib/libtcmalloc.so" HEAPCHECK=normal <binary>
-</pre>
-<p>
-We don't necessarily recommend this mode of usage.
-</p>
+<H1>Linking in the Library</H1>
-<h2>Turning On Heap Checking</h2>
+<p>The heap-checker is part of tcmalloc, so to install the heap
+checker into your executable, add <code>-ltcmalloc</code> to the
+link-time step for your executable. Also, while we don't necessarily
+recommend this form of usage, it's possible to add in the profiler at
+run-time using <code>LD_PRELOAD</code>:
+<pre>% env LD_PRELOAD="/usr/lib/libtcmalloc.so" <binary></pre>
-<p>There are two alternatives to actually turn on heap checking for a
-given run of an executable.</p>
+<p>This does <i>not</i> turn on heap checking; it just inserts the
+code. For that reason, it's practical to just always link
+<code>-ltcmalloc</code> into a binary while developing; that's what we
+do at Google. (However, since any user can turn on the profiler by
+setting an environment variable, it's not necessarily recommended to
+install heapchecker-linked binaries into a production, running
+system.) Note that if you wish to use the heap checker, you must
+also use the tcmalloc memory-allocation library. There is no way
+currently to use the heap checker separate from tcmalloc.</p>
-<ul>
-<li> For whole-program heap-checking, define the environment variable
- HEAPCHECK to the type of heap
- checking you want: normal, strict, or draconian. For instance,
- to heap-check <code>/bin/ls</code>:
- <pre>
- $ HEAPCHECK=normal /bin/ls
- % setenv HEAPCHECK normal; /bin/ls # csh
- </pre>
- OR
-
-<li> For partial-code heap-checking, you need to modify your code.
- For each piece of code you want heap-checked, bracket the code
- by creating a <code>HeapLeakChecker</code> object
- (which takes a descriptive label as an argument), and calling
- <code>check.NoLeaks()</code> at the end of the code you want
- checked. This will verify no more memory is allocated at the
- end of the code segment than was allocated in the beginning. To
- actually turn on the heap-checking, set the environment variable
- HEAPCHECK to <code>local</code>.
+
+<h1>Running the Code</h1>
+
+<p>Note: For security reasons, heap profiling will not write to a file
+-- and is thus not usable -- for setuid programs.</p>
+
+<h2><a name="whole_program">Whole-program Heap Leak Checking</a></h2>
+
+<p>The recommended way to use the heap checker is in "whole program"
+mode. In this case, the heap-checker starts tracking memory
+allocations before the start of <code>main()</code>, and checks again
+at program-exit. If it finds any memory leaks -- that is, any memory
+not pointed to by objects that are still "live" at program-exit -- it
+aborts the program (via <code>exit(1)</code>) and prints a message
+describing how to track down the memory leak (using <A
+HREF="heapprofile.html#pprof">pprof</A>).
+
+<p>Here's how to run a program with whole-program heap checking:</p>
+
+<ol>
+ <li> <p>Define the environment variable HEAPCHECK to the <A
+ HREF="#types">type of heap-checking</A> to do. For instance,
+ to heap-check
+ <code>/usr/local/bin/my_binary_compiled_with_tcmalloc</code>:</p>
+ <pre>% env HEAPCHECK=normal /usr/local/bin/my_binary_compiled_with_tcmalloc</pre>
</ol>
-<p>
-Here is an example of the second usage. The following code will
-die if <code>Foo()</code> leaks any memory
-(i.e. it allocates memory that is not freed by the time it returns):
-</p>
+<p>No other action is required.</p>
+
+<p>Note that since the heap-checker uses the heap-profiling framework
+internally, it is not possible to run both the heap-checker and <A
+HREF="heapprofile.html">heap profiler</A> at the same time.</p>
+
+
+<h3><a name="types">Flavors of Heap Checking</a></h3>
+
+<p>These are the legal values when running a whole-program heap
+check:</p>
+<ol>
+ <li> <code>minimal</code>
+ <li> <code>normal</code>
+ <li> <code>strict</code>
+ <li> <code>draconian</code>
+</ol>
+
+<p>"Minimal" heap-checking starts as late as possible ina
+initialization, meaning you can leak some memory in your
+initialization routines (that run before <code>main()</code>, say),
+and not trigger a leak message. If you frequently (and purposefully)
+leak data in one-time global initializers, "minimal" mode is useful
+for you. Otherwise, you should avoid it for stricter modes.</p>
+
+<p>"Normal" heap-checking tracks <A HREF="#live">live objects</A> and
+reports a leak for any data that is not reachable via a live object
+when the program exits.</p>
+
+<p>"Strict" heap-checking is much like "normal" but has a few extra
+checks that memory isn't lost in global destructors. In particular,
+if you have a global variable that allocates memory during program
+execution, and then "forgets" about the memory in the global
+destructor (say, by setting the pointer to it to NULL) without freeing
+it, that will prompt a leak message in "strict" mode, though not in
+"normal" mode.</p>
+
+<p>"Draconian" heap-checking is appropriate for those who like to be
+very precise about their memory management, and want the heap-checker
+to help them enforce it. In "draconian" mode, the heap-checker does
+not do "live object" checking at all, so it reports a leak unless
+<i>all</i> allocated memory is freed before program exit. (However,
+you can use <A HREF="#disable">IgnoreObject()</A> to re-enable
+liveness-checking on an object-by-object basis.)</p>
+
+<p>"Normal" mode, as the name implies, is the one used most often at
+Google. It's appropriate for everyday heap-checking use.</p>
+
+<p>In addition, there are two other possible modes:</p>
+<ul>
+ <li> <code>as-is</code>
+ <li> <code>local</code>
+</ul>
+<p><code>as-is</code> is the most flexible mode; it allows you to
+specify the various <A HREF="#options">knobs</A> of the heap checker
+explicitly. <code>local</code> activates the <A
+HREF="#explicit">explicit heap-check instrumentation</A>, but does not
+turn on any whole-program leak checking.</p>
+
+
+<h3><A NAME="tweaking">Tweaking whole-program checking</A></h3>
+
+<p>In some cases you want to check the whole program for memory leaks,
+but waiting for after <code>main()</code> exits to do the first
+whole-program leak check is waiting too long: e.g. in a long-running
+server one might wish to simply periodically check for leaks while the
+server is running. In this case, you can call the static method
+<code>NoGlobalLeaks()</code>, to verify no global leaks have happened
+as of that point in the program.</p>
+
+<p>Alternately, doing the check after <code>main()</code> exits might
+be too late. Perhaps you have some objects that are known not to
+clean up properly at exit. You'd like to do the "at exit" check
+before those objects are destroyed (since while they're live, any
+memory they point to will not be considered a leak). In that case,
+you can call <code>NoGlobalLeaks()</code> manually, near the end of
+<code>main()</code>, and then call <code>CancelGlobalCheck()</code> to
+turn off the automatic post-<code>main()</code> check.</p>
+
+<p>Finally, there's a helper macro for "strict" and "draconian" modes,
+which require all global memory to be freed before program exit. This
+freeing can be time-consuming and is often unnecessary, since libc
+cleans up all memory at program-exit for you. If you want the
+benefits of "strict"/"draconian" modes without the cost of all that
+freeing, look at <code>REGISTER_HEAPCHECK_CLEANUP</code> (in
+<code>heap-checker.h</code>). This macro allows you to mark specific
+cleanup code as active only when the heap-checker is turned on.</p>
+
+
+<h2><a name="explicit">Explicit (Partial-program) Heap Leak Checking</h2>
+
+<p>Instead of whole-program checking, you can check certain parts of
+your code to verify they do not have memory leaks. There are two
+types of checks you can do. The "no leak" check verifies that between
+two parts of a program, no memory is allocated without being freed; it
+checks that memory does not grow. The stricter "same heap" check
+verifies that two parts of a program share the same heap profile; that
+is, that the memory does not grow <i>or shrink</i>, or change in any
+way.</p>
+
+<p>To use this kind of checking code, bracket the code you want
+checked by creating a <code>HeapLeakChecker</code> object at the
+beginning of the code segment, and calling <code>*SameHeap()</code> or
+<code>*NoLeaks()</code> at the end.</p>
+
+<p>Here's an example:</p>
<pre>
- HeapProfileLeakChecker checker("foo");
- Foo();
- assert(checker.NoLeaks());
+ HeapLeakChecker heap_checker("test_foo");
+ {
+ code that exercises some foo functionality;
+ this code should preserve memory allocation state;
+ }
+ if (!heap_checker.SameHeap()) assert("" == "heap memory leak");
</pre>
-<p>
-When the <code>checker</code> object is allocated, it creates
-one heap profile. When <code>checker.NoLeaks()</code> is invoked,
-it creates another heap profile and compares it to the previously
-created profile. If the new profile indicates memory growth
-(or any memory allocation change if one
-uses <code>checker.SameHeap()</code> instead), <code>NoLeaks()</code>
-will return false and the program will abort. An error message will
-also be printed out saying how <code>pprof</code> command can be run
-to get a detailed analysis of the actual leaks.
-</p>
+<p>The various flavors of these functions -- <code>SameHeap()</code>,
+<code>QuickSameHeap()</code>, <code>BriefSameHeap()</code> -- trade
+off running time for accuracy: the faster routines might miss some
+legitimate leaks. For instance, the briefest tests might be confused
+by code like this:</p>
+<pre>
+ void LeakTwentyBytes() {
+ char* a = malloc(20);
+ HeapLeakChecker heap_checker("test_malloc");
+ char* b = malloc(20);
+ free(a);
+ // This will pass: it totes up 20 bytes allocated and 20 bytes freed
+ assert(heap_checker.BriefNoLeaks()); // doesn't detect that b is leaked
+ }
+</pre>
-<p>
-See the comments for <code>HeapProfileLeakChecker</code> class in
-<code>heap-checker.h</code> and the code in
-<code>heap-checker_unittest.cc</code> for more information and
-examples. (TODO: document it all here instead!)
-</p>
+<p>(This is because <code>BriefSameHeap()</code> does not use <A
+HREF="#pprof">pprof</A>, which is slower but is better able to track
+allocations in tricky situations like the above.)</p>
-<p>
-<b>IMPORTANT NOTE</b>: pthreads handling is currently incomplete.
-Heap leak checks will fail with bogus leaks if there are pthreads live
-at construction or leak checking time. One solution, for global
-heap-checking, is to make sure all threads but the main thread have
-exited at program-end time. We hope (as of March 2005) to have a fix
-soon.
-</p>
+<p>Note that adding in the <code>HeapLeakChecker</code> object merely
+instruments the code for leak-checking. To actually turn on this
+leak-checking on a particular run of the executable, you must still
+run with the heap-checker turned on:</p>
+<pre>% env HEAPCHECK=local /usr/local/bin/my_binary_compiled_with_tcmalloc</pre>
+<p>If you want to do whole-program leak checking in addition to this
+manual leak checking, you can run in <code>normal</code> or some other
+mode instead: they'll run the "local" checks in addition to the
+whole-program check.</p>
-<h2>Disabling Heap-checking of Known Leaks</h2>
-<p>
-Sometimes your code has leaks that you know about and are willing to
-accept. You would like the heap checker to ignore them when checking
-your program. You can do this by bracketing the code in question with
-an appropriate heap-checking object:
-</p>
+<h2><a name="disable">Disabling Heap-checking of Known Leaks</a></h2>
+
+<p>Sometimes your code has leaks that you know about and are willing
+to accept. You would like the heap checker to ignore them when
+checking your program. You can do this by bracketing the code in
+question with an appropriate heap-checking construct:</p>
<pre>
- #include <google/heap-checker.h>
...
void *mark = HeapLeakChecker::GetDisableChecksStart();
&lt;leaky code&gt;
HeapLeakChecker::DisableChecksToHereFrom(mark);
+ ...
</pre>
+<p>Alternately, you can use <code>IgnoreObject()</code>, which takes a
+pointer to an object to ignore. That memory, and everything reachable
+from it (by following pointers), is ignored for the purposes of leak
+checking. You can call <code>UnignoreObject()</code> to undo the
+effects of <code>IgnoreObject()</code>.</p>
+
+
+<h2><a name="options">Tuning the Heap Checker</h2>
+
+<p>The heap leak checker has many options, some that trade off running
+time and accuracy, and others that increase the sensitivity at the
+risk of returning false positives. For most uses, the range covered
+by the <A HREF="#types">heap-check flavors</A> is enough, but in
+specialized cases more control can be helpful.</p>
+
<p>
-Some libc routines allocate memory, and may need to be 'disabled' in
-this way. As time goes on, we hope to encode proper handling of
-these routines into the heap-checker library code, so applications
-needn't worry about them, but that process is not yet complete.
+These options are specified via environment varaiables.
</p>
+<p>This first set of options controls sensitivity and accuracy. These
+options are ignored unless you run the heap checker in <A
+HREF="#types">as-is</A> mode.
+
+<table frame=box rules=sides cellpadding=5 width=100%>
+
+<tr valign=top>
+ <td><code>HEAP_CHECK_AFTER_DESTRUCTORS</code></td>
+ <td>Default: false</td>
+ <td>
+ When true, do the final leak check after all other global
+ destructors have run. When false, do it after all
+ <code>REGISTER_HEAPCHECK_CLEANUP</code>, typically much earlier in
+ the global-destructor process.
+ </td>
+</tr>
+
+<tr valign=top>
+ <td><code>HEAP_CHECK_IGNORE_THREAD_LIVE</code></td>
+ <td>Default: true</td>
+ <td>
+ If true, ignore objects reachable from thread stacks and registers
+ (that is, do not report them as leaks).
+ </td>
+</tr>
+
+<tr valign=top>
+ <td><code>HEAP_CHECK_IGNORE_GLOBAL_LIVE</code></td>
+ <td>Default: true</td>
+ <td>
+ If true, ignore objects reachable from global variables and data
+ (that is, do not report them as leaks).
+ </td>
+</tr>
+
+</table>
+
+<p>These options modify the behavior of whole-program leak
+checking.</p>
+
+<table frame=box rules=sides cellpadding=5 width=100%>
+
+<tr valign=top>
+ <td><code>HEAP_CHECK_REPORT</code></td>
+ <td>Default: true</td>
+ <td>
+ If true, use <code>pprof</code> to report more info about found leaks.
+ </td>
+</tr>
+
+<tr valign=top>
+ <td><code>HEAP_CHECK_STRICT_CHECK</code></td>
+ <td>Default: true</td>
+ <td>
+ If true, do the program-end check via <code>SameHeap()</code>;
+ if false, use <code>NoLeaks()</code>.
+ </td>
+</tr>
+
+</table>
+
+<p>These options apply to all types of leak checking.</p>
+
+<table frame=box rules=sides cellpadding=5 width=100%>
+
+<tr valign=top>
+ <td><code>HEAP_CHECK_IDENTIFY_LEAKS</code></td>
+ <td>Default: false</td>
+ <td>
+ If true, generate the addresses of the leaked objects in the
+ generated memory leak profile files.
+ </td>
+</tr>
+
+<tr valign=top>
+ <td><code>HEAP_CHECK_TEST_POINTER_ALIGNMENT</code></td>
+ <td>Default: false</td>
+ <td>
+ If true, check all leaks to see if they might be due to the use
+ of unaligned pointers.
+ </td>
+</tr>
+
+<tr valign=top>
+ <td><code>PPROF_PATH</code></td>
+ <td>Default: pprof</td>
+<td>
+ The location of the <code>pprof</code> executable.
+ </td>
+</tr>
+
+<tr valign=top>
+ <td><code>HEAP_CHECK_DUMP_DIRECTORY</code></td>
+ <td>Default: /tmp</td>
+ <td>
+ Where the heap-profile files are kept while the program is running.
+ </td>
+</tr>
+
+</table>
+
+
+<h2>Tips for Handling Detected Leaks</h2>
+
+<p>What do you do when the heap leak checker detects a memory leak?
+First, you should run the reported <code>pprof</code> command;
+hopefully, that is enough to track down the location where the leak
+occurs.</p>
+
+<p>If the leak is a real leak, you should fix it!</p>
+
+<p>If you are sure that the reported leaks are not dangerous and there
+is no good way to fix them, then you can use
+<code>HeapLeakChecker::GetDisableChecksStart()</code> and/or
+<code>HeapLeakChecker::IgnoreObject()</code> to disable heap-checking
+for certain parts of the codebase.</p>
+
+<p>In "strict" or "draconian" mode, leaks may be due to incomplete
+cleanup in the destructors of global variables. If you don't wish to
+augment the cleanup routines, but still want to run in "strict" or
+"draconian" mode, consider using <A
+HREF="#tweaking"><code>REGISTER_HEAPCHECK_CLEANUP</code></A>.</p>
+
+
+<h1>How It Works</h1>
+
+<p>When a <code>HeapLeakChecker</code> object is constructed, it dumps
+a memory-usage profile named
+<code>&lt;prefix&gt;.&lt;name&gt;-beg.heap</code> to a temporary
+directory. When <code>*NoLeaks()</code> or <code>*SameHeap()</code>
+is called (for whole-program checking, this happens automatically at
+program-exit), it dumps another profile, named
+<code>&lt;prefix&gt;.&lt;name&gt;-end.heap</code>.
+(<code>&lt;prefix&gt;</code> is typically determined automatically,
+and <code>&lt;name&gt;</code> is typically <code>argv[0]</code>.) It
+then compares the two profiles. If the second profile shows more
+memory use than the first (or, for <code>*SameHeap()</code> calls,
+any different pattern of memory use than the first), the
+<code>*NoLeaks()</code> or <code>*SameHeap()</code> function will
+return false. For "whole program" profiling, this will cause the
+executable to abort (via <code>exit(1)</code>). In all cases, it will
+print a message on how to process the dumped profiles to locate
+leaks.</p>
+
+<h3><A name=live>Detecting Live Objects</A></h3>
+
+<p>At any point during a program's execution, all memory that is
+accessible at that time is considered "live." This includes global
+variables, and also any memory that is reachable by following pointers
+from a global variable. It also includes all memory reachable from
+the current stack frame and from current CPU registers (this captures
+local variables). Finally, it includes the thread equivalents of
+these: thread-local storage and thread heaps, memory reachable from
+thread-local storage and thread heaps, and memory reachable from
+thread CPU registers.</p>
+
+<p>In all modes except "draconian," live memory is not
+considered to be a leak. We detect this by doing a liveness flood,
+traversing pointers to heap objects starting from some initial memory
+regions we know to potentially contain live pointer data. Note that
+this flood might potentially not find some (global) live data region
+to start the flood from. If you find such, please file a bug.</p>
+
+<p>The liveness flood attempts to treat any properly aligned byte
+sequences as pointers to heap objects and thinks that it found a good
+pointer whenever the current heap memory map contains an object with
+the address whose byte representation we found. Some pointers into
+not-at-start of object will also work here.</p>
+
+<p>As a result of this simple approach, it's possible (though
+unlikely) for the flood to be inexact and occasionally result in
+leaked objects being erroneously determined to be live. For instance,
+random bit patterns can happen to look like pointers to leaked heap
+objects. More likely, stale pointer data not corresponding to any
+live program variables can be still present in memory regions,
+especially in thread stacks. For instance, depending on how the local
+<code>malloc</code> is implemented, it may reuse a heap object
+address:</p>
+<pre>
+ char* p = new char[1]; // new might return 0x80000000, say.
+ delete p;
+ new char[1]; // new might return 0x80000000 again
+ // This last new is a leak, but doesn't seem it: p looks like it points to it
+</pre>
+
+<p>In other words, imprecisions in the liveness flood mean that for
+any heap leak check we might miss some memory leaks. This means that
+for local leak checks, we might report a memory leak in the local
+area, even though the leak actually happened before the
+<code>HeapLeakChecker</code> object was constructed. Note that for
+whole-program checks, a leak report <i>does</i> always correspond to a
+real leak (since there's no "before" to have created a false-live
+object).</p>
+
+<p>While this liveness flood approach is not very portable and not
+100% accurate, it works in most cases and saves us from writing a lot
+of explicit clean up code and other hassles when dealing with thread
+data.</p>
+
+
+<h3><A NAME="pprof">More Exact Checking via pprof</A></h3>
+
+<p>The perftools profiling tool, <code>pprof</code>, is primarily
+intended for users to use interactively in order to explore heap and
+CPU usage. However, the heap-checker can -- and, by default, does -
+call <code>pprof</code> internally, in order to improve its leak
+checking.</p>
+
+<p>In particular, the heap-checker calls <code>pprof</code> to utilize
+the full call-path for all allocations. <code>pprof</code> uses this
+data to disambiguate allocations. When the time comes to do a
+<code>SameHeap</code> or <code>NoLeaks</code> check, the heap-checker
+asks <code>pprof</code> to do this check on an
+allocation-by-allocation basis, rather than just by comparing global
+counts.</p>
+
+<p>Here's an example. Consider the following function:</p>
+<pre>
+ void LeakTwentyBytes() {
+ char* a = malloc(20);
+ HeapLeakChecker heap_checker("test_malloc");
+ char* b = malloc(20);
+ free(a);
+ heap_checker.NoLeaks();
+ }
+</pre>
+
+<p>Without using pprof, the only thing we will do is count up the
+number of allocations and frees inside the leak-checked interval.
+Twenty bytes allocated, twenty bytes freed, and the code looks ok.</p>
+
+<p>With pprof, however, we can track the call-path for each
+allocation, and account for them separately. In the example function
+above, there are two call-paths that end in an allocation, one that
+ends in "LeakTwentyBytes:line1" and one that ends in
+"LeakTwentyBytes:line3".</p>
+
+<p>Here's how the heap-checker works when it can use pprof in this
+way:</p>
+<ol>
+ <li> <b>Line 1:</b> Allocate 20 bytes, mark <code>a</code> as having
+ call-path "LeakTwentyBytes:line1", and update the count-map
+ <pre>count["LeakTwentyByte:line1"] += 20;</pre>
+ <li> <b>Line 2:</b> Dump the current <code>count</code> map to a file.
+ <li> <b>Line 3:</b> Allocate 20 bytes, mark <code>b</code> as having
+ call-path "LeakTwentyBytes:line3", and update the count-map:
+ <pre>count["LeakTwentyByte:line3"] += 20;</pre>
+ <li> <b>Line 4:</b> Look up <code>a</code> to find its call-path
+ (stored in line 1), and use that to update the count-map:
+ <pre>count["LeakTwentyByte:line1"] -= 20;</pre>
+ <li> <b>Line 5:</b> Look at each bucket in the current count-map,
+ minus what was dumped in line 2. Here's the diffs we'll have
+ in each bucket:
+ <pre>
+count["LeakTwentyByte:line1"] == -20;
+count["LeakTwentyByte:line3"] == 20;
+ </pre>
+ Since <i>at least one</i> bucket has a positive number, we
+ complain of a leak. (Note if line 5 had been
+ <code>SameHeap</code> instead of <code>NoLeaks</code>, we would
+ have complained if any bucket had had a <i>non-zero</i>
+ number.)
+</ol>
+
+<p>Note that one way to visualize the non-<code>pprof</code> mode is
+that we do the same thing as above, but always use "unknown" as the
+call-path. That is, our count-map always only has one entry in it:
+<code>count["unknown"]</code>. Looking at the example above shows how
+having only one entry in the map can lead to incorrect results.</p>
+
+<p>Here is when <code>pprof</code> is used by the heap-checker:</p>
+<ul>
+ <li> <code>NoLeaks()</code> and <code>SameHeap()</code> both use
+ <code>pprof</code>.
+ <li> <code>BriefNoLeaks()</code> and <code>BriefSameHeap()</code> do
+ not use <code>pprof</code>.
+ <li> <code>QuickNoLeaks</code> and <code>QuickSameHeap()</code> are
+ a kind of compromise: they do <i>not</i> use pprof for their
+ leak check, but if that check happens to find a leak anyway,
+ then they re-do the leak calculation using <code>pprof</code>.
+ This means they do not always find leaks, but when they do,
+ they will be as accurate as possible in their leak report.
+</ul>
+
+<h3>Leak-checking and Threads</h3>
+
+<p>At the time of HeapLeakChecker's construction and during
+<code>*NoLeaks()</code>/<code>*SameHeap()</code> calls, we grab a lock
+and then pause all other threads so other threads do not interfere
+with recording or analyzing the state of the heap.</p>
+
+<p>In general, leak checking works correctly in the presence of
+threads. However, thread stack data liveness determination (via
+<code>base/thread_lister.h</code>) does not work when the program is
+running under GDB, because the ptrace functionality needed for finding
+threads is already hooked to by GDB. Conversely, leak checker's
+ptrace attempts might also interfere with GDB. As a result, GDB can
+result in potentially false leak reports. For this reason, the
+heap-checker turns itself off when running under GDB.</p>
+
+<p>Also, <code>thread_lister</code> only works for Linux pthreads;
+leak checking is unlikely to handle other thread implementations
+correctly.</p>
+
+<p>As mentioned in the discussion of liveness flooding, thread-stack
+liveness determination might mis-classify as reachable objects that
+very recently became unreachable (leaked). This can happen when the
+pointers to now-logically-unreachable objects are present in the
+active thread stack frame. In other words, trivial code like the
+following might not produce the expected leak checking outcome
+depending on how the compiled code works with the stack:</p>
+<pre>
+ int* foo = new int [20];
+ HeapLeakChecker check("a_check");
+ foo = NULL;
+ CHECK(check.NoLeaks()); // this might succeed
+</pre>
+
+
<hr>
-<address><a href="mailto:opensource@google.com">Maxim Lifantsev</a></address>
+<address>Maxim Lifantsev<br>
<!-- Created: Tue Dec 19 10:43:14 PST 2000 -->
<!-- hhmts start -->
-Last modified: Thu Mar 3 05:51:40 PST 2005
+Last modified: Wed Mar 21 15:00:42 PDT 2007 (csilvers)
<!-- hhmts end -->
+</address>
</body>
</html>
diff --git a/doc/heap_profiler.html b/doc/heap_profiler.html
deleted file mode 100644
index ce7168c..0000000
--- a/doc/heap_profiler.html
+++ /dev/null
@@ -1,325 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
-<html>
-<head>
-<title>Google Heap Profiler</title>
-</head>
-
-<body>
-<h1>Profiling heap usage</h1>
-
-This document describes how to profile the heap usage of a C++
-program. This facility can be useful for
-<ul>
-<li> Figuring out what is in the program heap at any given time
-<li> Locating memory leaks
-<li> Finding places that do a lot of allocation
-</ul>
-
-<h2>Linking in the Heap Profiler</h2>
-
-<p>
-You can profile any program that has the tcmalloc library linked
-in. No recompilation is necessary to use the heap profiler.
-</p>
-
-<p>
-It's safe to link in tcmalloc even if you don't expect to
-heap-profiler your program. Your programs will not run any slower
-as long as you don't use any of the heap-profiler features.
-</p>
-
-<p>
-You can run the heap profiler on applications you didn't compile
-yourself, by using LD_PRELOAD:
-</p>
-<pre>
- $ LD_PRELOAD="/usr/lib/libtcmalloc.so" HEAPPROFILE=... <binary>
-</pre>
-<p>
-We don't necessarily recommend this mode of usage.
-</p>
-
-
-<h2>Turning On Heap Profiling</h2>
-
-<p>
-Define the environment variable HEAPPROFILE to the filename to dump the
-profile to. For instance, to profile /usr/local/netscape:
-</p>
-<pre>
- $ HEAPPROFILE=/tmp/profile /usr/local/netscape # sh
- % setenv HEAPPROFILE /tmp/profile; /usr/local/netscape # csh
-</pre>
-
-<p>Profiling also works correctly with sub-processes: each child
-process gets its own profile with its own name (generated by combining
-HEAPPROFILE with the child's process id).</p>
-
-<p>For security reasons, heap profiling will not write to a file --
-and it thus not usable -- for setuid programs.</p>
-
-
-
-<h2>Extracting a profile</h2>
-
-<p>
-If heap-profiling is turned on in a program, the program will periodically
-write profiles to the filesystem. The sequence of profiles will be named:
-</p>
-<pre>
- &lt;prefix&gt;.0000.heap
- &lt;prefix&gt;.0001.heap
- &lt;prefix&gt;.0002.heap
- ...
-</pre>
-<p>
-where <code>&lt;prefix&gt;</code> is the value supplied in
-<code>HEAPPROFILE</code>. Note that if the supplied prefix
-does not start with a <code>/</code>, the profile files will be
-written to the program's working directory.
-</p>
-
-<p>
-By default, a new profile file is written after every 1GB of
-allocation. The profile-writing interval can be adjusted by calling
-HeapProfilerSetAllocationInterval() from your program. This takes one
-argument: a numeric value that indicates the number of bytes of allocation
-between each profile dump.
-</p>
-
-<p>
-You can also generate profiles from specific points in the program
-by inserting a call to <code>HeapProfile()</code>. Example:
-</p>
-<pre>
- extern const char* HeapProfile();
- const char* profile = HeapProfile();
- fputs(profile, stdout);
- free(const_cast&lt;char*&gt;(profile));
-</pre>
-
-<h2>What is profiled</h2>
-
-The profiling system instruments all allocations and frees. It keeps
-track of various pieces of information per allocation site. An
-allocation site is defined as the active stack trace at the call to
-<code>malloc</code>, <code>calloc</code>, <code>realloc</code>, or,
-<code>new</code>.
-
-<h2>Interpreting the profile</h2>
-
-The profile output can be viewed by passing it to the
-<code>pprof</code> tool. The <code>pprof</code> tool can print both
-CPU usage and heap usage information. It is documented in detail
-on the <a href="cpu_profiler.html">CPU Profiling</a> page.
-Heap-profile-specific flags and usage are explained below.
-
-<p>
-Here are some examples. These examples assume the binary is named
-<code>gfs_master</code>, and a sequence of heap profile files can be
-found in files named:
-</p>
-<pre>
- profile.0001.heap
- profile.0002.heap
- ...
- profile.0100.heap
-</pre>
-
-<h3>Why is a process so big</h3>
-
-<pre>
- % pprof --gv gfs_master profile.0100.heap
-</pre>
-
-This command will pop-up a <code>gv</code> window that displays
-the profile information as a directed graph. Here is a portion
-of the resulting output:
-
-<p>
-<center>
-<img src="heap-example1.png">
-</center>
-</p>
-
-A few explanations:
-<ul>
-<li> <code>GFS_MasterChunk::AddServer</code> accounts for 255.6 MB
- of the live memory, which is 25% of the total live memory.
-<li> <code>GFS_MasterChunkTable::UpdateState</code> is directly
- accountable for 176.2 MB of the live memory (i.e., it directly
- allocated 176.2 MB that has not been freed yet). Furthermore,
- it and its callees are responsible for 729.9 MB. The
- labels on the outgoing edges give a good indication of the
- amount allocated by each callee.
-</ul>
-
-<h3>Comparing Profiles</h3>
-
-<p>
-You often want to skip allocations during the initialization phase of
-a program so you can find gradual memory leaks. One simple way to do
-this is to compare two profiles -- both collected after the program
-has been running for a while. Specify the name of the first profile
-using the <code>--base</code> option. Example:
-</p>
-<pre>
- % pprof --base=profile.0004.heap gfs_master profile.0100.heap
-</pre>
-
-<p>
-The memory-usage in <code>profile.0004.heap</code> will be subtracted from
-the memory-usage in <code>profile.0100.heap</code> and the result will
-be displayed.
-</p>
-
-<h3>Text display</h3>
-
-<pre>
-% pprof gfs_master profile.0100.heap
- 255.6 24.7% 24.7% 255.6 24.7% GFS_MasterChunk::AddServer
- 184.6 17.8% 42.5% 298.8 28.8% GFS_MasterChunkTable::Create
- 176.2 17.0% 59.5% 729.9 70.5% GFS_MasterChunkTable::UpdateState
- 169.8 16.4% 75.9% 169.8 16.4% PendingClone::PendingClone
- 76.3 7.4% 83.3% 76.3 7.4% __default_alloc_template::_S_chunk_alloc
- 49.5 4.8% 88.0% 49.5 4.8% hashtable::resize
- ...
-</pre>
-
-<p>
-<ul>
-<li> The first column contains the direct memory use in MB.
-<li> The fourth column contains memory use by the procedure
- and all of its callees.
-<li> The second and fifth columns are just percentage representations
- of the numbers in the first and fifth columns.
-<li> The third column is a cumulative sum of the second column
- (i.e., the <code>k</code>th entry in the third column is the
- sum of the first <code>k</code> entries in the second column.)
-</ul>
-
-<h3>Ignoring or focusing on specific regions</h3>
-
-The following command will give a graphical display of a subset of
-the call-graph. Only paths in the call-graph that match the
-regular expression <code>DataBuffer</code> are included:
-<pre>
-% pprof --gv --focus=DataBuffer gfs_master profile.0100.heap
-</pre>
-
-Similarly, the following command will omit all paths subset of the
-call-graph. All paths in the call-graph that match the regular
-expression <code>DataBuffer</code> are discarded:
-<pre>
-% pprof --gv --ignore=DataBuffer gfs_master profile.0100.heap
-</pre>
-
-<h3>Total allocations + object-level information</h3>
-
-<P>
-All of the previous examples have displayed the amount of in-use
-space. I.e., the number of bytes that have been allocated but not
-freed. You can also get other types of information by supplying
-a flag to <code>pprof</code>:
-</p>
-
-<center>
-<table frame=box rules=sides cellpadding=5 width=100%>
-
-<tr valign=top>
- <td><code>--inuse_space</code></td>
- <td>
- Display the number of in-use megabytes (i.e. space that has
- been allocated but not freed). This is the default.
- </td>
-</tr>
-
-<tr valign=top>
- <td><code>--inuse_objects</code></td>
- <td>
- Display the number of in-use objects (i.e. number of
- objects that have been allocated but not freed).
- </td>
-</tr>
-
-<tr valign=top>
- <td><code>--alloc_space</code></td>
- <td>
- Display the number of allocated megabytes. This includes
- the space that has since been de-allocated. Use this
- if you want to find the main allocation sites in the
- program.
- </td>
-</tr>
-
-<tr valign=top>
- <td><code>--alloc_objects</code></td>
- <td>
- Display the number of allocated objects. This includes
- the objects that have since been de-allocated. Use this
- if you want to find the main allocation sites in the
- program.
- </td>
-
-</table>
-</center>
-
-<h2>Caveats</h2>
-
-<ul>
-<li> <p>
- Heap profiling requires the use of libtcmalloc. This requirement
- may be removed in a future version of the heap profiler, and the
- heap profiler separated out into its own library.
- </p>
-
-<li> <p>
- If the program linked in a library that was not compiled
- with enough symbolic information, all samples associated
- with the library may be charged to the last symbol found
- in the program before the libary. This will artificially
- inflate the count for that symbol.
- </p>
-
-<li> <p>
- If you run the program on one machine, and profile it on another,
- and the shared libraries are different on the two machines, the
- profiling output may be confusing: samples that fall within
- the shared libaries may be assigned to arbitrary procedures.
- </p>
-
-<li> <p>
- Several libraries, such as some STL implementations, do their own
- memory management. This may cause strange profiling results. We
- have code in libtcmalloc to cause STL to use tcmalloc for memory
- management (which in our tests is better than STL's internal
- management), though it only works for some STL implementations.
- </p>
-
-<li> <p>
- If your program forks, the children will also be profiled (since
- they inherit the same HEAPPROFILE setting). Each process is
- profiled separately; to distinguish the child profiles from the
- parent profile and from each other, all children will have their
- process-id attached to the HEAPPROFILE name.
- </p>
-
-<li> <p>
- Due to a hack we make to work around a possible gcc bug, your
- profiles may end up named strangely if the first character of
- your HEAPPROFILE variable has ascii value greater than 127. This
- should be exceedingly rare, but if you need to use such a name,
- just set prepend <code>./</code> to your filename:
- <code>HEAPPROFILE=./&Auml;gypten</code>.
- </p>
-
-</ul>
-
-<hr>
-<address><a href="mailto:opensource@google.com">Sanjay Ghemawat</a></address>
-<!-- Created: Tue Dec 19 10:43:14 PST 2000 -->
-<!-- hhmts start -->
-Last modified: Wed Apr 20 05:46:16 PDT 2005
-<!-- hhmts end -->
-</body>
-</html>
diff --git a/doc/heapprofile.html b/doc/heapprofile.html
new file mode 100644
index 0000000..b155eef
--- /dev/null
+++ b/doc/heapprofile.html
@@ -0,0 +1,355 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<HTML>
+
+<HEAD>
+ <link rel="stylesheet" href="designstyle.css">
+ <title>Google Heap Profiler</title>
+</HEAD>
+
+<BODY>
+
+<p align=right>
+ <i>Last modified
+ <script type=text/javascript>
+ var lm = new Date(document.lastModified);
+ document.write(lm.toDateString());
+ </script></i>
+</p>
+
+<p>This is the heap profiler we use at Google, to explore how C++
+programs manage memory. This facility can be useful for</p>
+<ul>
+ <li> Figuring out what is in the program heap at any given time
+ <li> Locating memory leaks
+ <li> Finding places that do a lot of allocation
+</ul>
+
+<p>The profiling system instruments all allocations and frees. It
+keeps track of various pieces of information per allocation site. An
+allocation site is defined as the active stack trace at the call to
+<code>malloc</code>, <code>calloc</code>, <code>realloc</code>, or,
+<code>new</code>.</p>
+
+<p>There are three parts to using it: linking the library into an
+application, running the code, and analyzing the output.</p>
+
+
+<h1>Linking in the Library</h1>
+
+<p>To install the heap profiler into your executable, add
+<code>-ltcmalloc</code> to the link-time step for your executable.
+Also, while we don't necessarily recommend this form of usage, it's
+possible to add in the profiler at run-time using
+<code>LD_PRELOAD</code>:
+<pre>% env LD_PRELOAD="/usr/lib/libtcmalloc.so" <binary></pre>
+
+<p>This does <i>not</i> turn on heap profiling; it just inserts the
+code. For that reason, it's practical to just always link
+<code>-ltcmalloc</code> into a binary while developing; that's what we
+do at Google. (However, since any user can turn on the profiler by
+setting an environment variable, it's not necessarily recommended to
+install profiler-linked binaries into a production, running
+system.) Note that if you wish to use the heap profiler, you must
+also use the tcmalloc memory-allocation library. There is no way
+currently to use the heap profiler separate from tcmalloc.</p>
+
+
+<h1>Running the Code</h1>
+
+<p>There are several alternatives to actually turn on heap profiling
+for a given run of an executable:</p>
+
+<ol>
+ <li> <p>Define the environment variable HEAPPROFILE to the filename
+ to dump the profile to. For instance, to profile
+ <code>/usr/local/bin/my_binary_compiled_with_tcmalloc</code>:</p>
+ <pre>% env HEAPPROFILE=/tmp/mybin.hprof /usr/local/bin/my_binary_compiled_with_tcmalloc</pre>
+ <li> <p>In your code, bracket the code you want profiled in calls to
+ <code>HeapProfilerStart()</code> and <code>HeapProfilerStop()</code>.
+ <code>HeapProfilerStart()</code> will take
+ the profile-filename-prefix as an argument. You can then use
+ <code>HeapProfileDump()</code> or <code>HeapProfile()</code> to
+ examine the profile.</p>
+</ol>
+
+
+<p>For security reasons, heap profiling will not write to a file --
+and is thus not usable -- for setuid programs.</p>
+
+<H2>Modifying Runtime Behavior</H2>
+
+<p>You can more finely control the behavior of the heap profiler via
+commandline flags.</p>
+
+<table frame=box rules=sides cellpadding=5 width=100%>
+
+<tr valign=top>
+ <td><code>HEAP_PROFILE_ALLOCATION_INTERVAL</code></td>
+ <td>default: 1073741824 (1 Gb)</td>
+ <td>
+ Dump heap profiling information once every specified number of
+ bytes has been allocated by the program.
+ </td>
+</tr>
+
+<tr valign=top>
+ <td><code>HEAP_PROFILE_INUSE_INTERVAL</code></td>
+ <td>default: 104857600 (100 Mb)</td>
+ <td>
+ Dump heap profiling information whenever the high-water memory
+ usage mark increases by the specified number of bytes.
+ </td>
+</tr>
+
+<tr valign=top>
+ <td><code>HEAP_PROFILE_MMAP</code></td>
+ <td>default: false</td>
+ <td>
+ Profile <code>mmap</code> calls in addition to
+ <code>malloc</code>, <code>calloc</code>, <code>realloc</code>,
+ and <code>new</code>.
+ </td>
+</tr>
+
+<tr valign=top>
+ <td><code>HEAP_PROFILE_MMAP_LOG</code></td>
+ <td>default: false</td>
+ <td>
+ Log <code>mmap</code>/<code>munmap</code>calls.
+ </td>
+</tr>
+
+</table>
+
+<H2>Checking for Leaks</H2>
+
+<p>You can use the heap profiler to manually check for leaks, for
+instance by reading the profiler output and looking for large
+allocations. However, for that task, it's easier to use the <A
+HREF="heap_checker.html">automatic heap-checking facility</A> built
+into tcmalloc.</p>
+
+
+<h1><a name="pprof">Analyzing the Output</a></h1>
+
+<p>If heap-profiling is turned on in a program, the program will
+periodically write profiles to the filesystem. The sequence of
+profiles will be named:</p>
+<pre>
+ &lt;prefix&gt;.0000.heap
+ &lt;prefix&gt;.0001.heap
+ &lt;prefix&gt;.0002.heap
+ ...
+</pre>
+<p>where <code>&lt;prefix&gt;</code> is the filename-prefix supplied
+when running the code (e.g. via the <code>HEAPPROFILE</code>
+environment variable). Note that if the supplied prefix
+does not start with a <code>/</code>, the profile files will be
+written to the program's working directory.</p>
+
+<p>The profile output can be viewed by passing it to the
+<code>pprof</code> tool -- the same tool that's used to analyze <A
+HREF="cpuprofile.html">CPU profiles</A>.
+
+<p>Here are some examples. These examples assume the binary is named
+<code>gfs_master</code>, and a sequence of heap profile files can be
+found in files named:</p>
+<pre>
+ /tmp/profile.0001.heap
+ /tmp/profile.0002.heap
+ ...
+ /tmp/profile.0100.heap
+</pre>
+
+<h3>Why is a process so big</h3>
+
+<pre>
+ % pprof --gv gfs_master /tmp/profile.0100.heap
+</pre>
+
+<p>This command will pop-up a <code>gv</code> window that displays
+the profile information as a directed graph. Here is a portion
+of the resulting output:</p>
+
+<p><center>
+<img src="heap-example1.png">
+</center></p>
+
+A few explanations:
+<ul>
+<li> <code>GFS_MasterChunk::AddServer</code> accounts for 255.6 MB
+ of the live memory, which is 25% of the total live memory.
+<li> <code>GFS_MasterChunkTable::UpdateState</code> is directly
+ accountable for 176.2 MB of the live memory (i.e., it directly
+ allocated 176.2 MB that has not been freed yet). Furthermore,
+ it and its callees are responsible for 729.9 MB. The
+ labels on the outgoing edges give a good indication of the
+ amount allocated by each callee.
+</ul>
+
+<h3>Comparing Profiles</h3>
+
+<p>You often want to skip allocations during the initialization phase
+of a program so you can find gradual memory leaks. One simple way to
+do this is to compare two profiles -- both collected after the program
+has been running for a while. Specify the name of the first profile
+using the <code>--base</code> option. For example:</p>
+<pre>
+ % pprof --base=/tmp/profile.0004.heap gfs_master /tmp/profile.0100.heap
+</pre>
+
+<p>The memory-usage in <code>/tmp/profile.0004.heap</code> will be
+subtracted from the memory-usage in
+<code>/tmp/profile.0100.heap</code> and the result will be
+displayed.</p>
+
+<h3>Text display</h3>
+
+<pre>
+% pprof --text gfs_master /tmp/profile.0100.heap
+ 255.6 24.7% 24.7% 255.6 24.7% GFS_MasterChunk::AddServer
+ 184.6 17.8% 42.5% 298.8 28.8% GFS_MasterChunkTable::Create
+ 176.2 17.0% 59.5% 729.9 70.5% GFS_MasterChunkTable::UpdateState
+ 169.8 16.4% 75.9% 169.8 16.4% PendingClone::PendingClone
+ 76.3 7.4% 83.3% 76.3 7.4% __default_alloc_template::_S_chunk_alloc
+ 49.5 4.8% 88.0% 49.5 4.8% hashtable::resize
+ ...
+</pre>
+
+<p>
+<ul>
+ <li> The first column contains the direct memory use in MB.
+ <li> The fourth column contains memory use by the procedure
+ and all of its callees.
+ <li> The second and fifth columns are just percentage
+ representations of the numbers in the first and fifth columns.
+ <li> The third column is a cumulative sum of the second column
+ (i.e., the <code>k</code>th entry in the third column is the
+ sum of the first <code>k</code> entries in the second column.)
+</ul>
+
+<h3>Ignoring or focusing on specific regions</h3>
+
+<p>The following command will give a graphical display of a subset of
+the call-graph. Only paths in the call-graph that match the regular
+expression <code>DataBuffer</code> are included:</p>
+<pre>
+% pprof --gv --focus=DataBuffer gfs_master /tmp/profile.0100.heap
+</pre>
+
+<p>Similarly, the following command will omit all paths subset of the
+call-graph. All paths in the call-graph that match the regular
+expression <code>DataBuffer</code> are discarded:</p>
+<pre>
+% pprof --gv --ignore=DataBuffer gfs_master /tmp/profile.0100.heap
+</pre>
+
+<h3>Total allocations + object-level information</h3>
+
+<p>All of the previous examples have displayed the amount of in-use
+space. I.e., the number of bytes that have been allocated but not
+freed. You can also get other types of information by supplying a
+flag to <code>pprof</code>:</p>
+
+<center>
+<table frame=box rules=sides cellpadding=5 width=100%>
+
+<tr valign=top>
+ <td><code>--inuse_space</code></td>
+ <td>
+ Display the number of in-use megabytes (i.e. space that has
+ been allocated but not freed). This is the default.
+ </td>
+</tr>
+
+<tr valign=top>
+ <td><code>--inuse_objects</code></td>
+ <td>
+ Display the number of in-use objects (i.e. number of
+ objects that have been allocated but not freed).
+ </td>
+</tr>
+
+<tr valign=top>
+ <td><code>--alloc_space</code></td>
+ <td>
+ Display the number of allocated megabytes. This includes
+ the space that has since been de-allocated. Use this
+ if you want to find the main allocation sites in the
+ program.
+ </td>
+</tr>
+
+<tr valign=top>
+ <td><code>--alloc_objects</code></td>
+ <td>
+ Display the number of allocated objects. This includes
+ the objects that have since been de-allocated. Use this
+ if you want to find the main allocation sites in the
+ program.
+ </td>
+
+</table>
+</center>
+
+
+<h3>Interactive mode</a></h3>
+
+<p>By default -- if you don't specify any flags to the contrary --
+pprof runs in interactive mode. At the <code>(pprof)</code> prompt,
+you can run many of the commands described above. You can type
+<code>help</code> for a list of what commands are available in
+interactive mode.</p>
+
+
+<h1>Caveats</h1>
+
+<ul>
+ <li> Heap profiling requires the use of libtcmalloc. This
+ requirement may be removed in a future version of the heap
+ profiler, and the heap profiler separated out into its own
+ library.
+
+ <li> If the program linked in a library that was not compiled
+ with enough symbolic information, all samples associated
+ with the library may be charged to the last symbol found
+ in the program before the libary. This will artificially
+ inflate the count for that symbol.
+
+ <li> If you run the program on one machine, and profile it on
+ another, and the shared libraries are different on the two
+ machines, the profiling output may be confusing: samples that
+ fall within the shared libaries may be assigned to arbitrary
+ procedures.
+
+ <li> Several libraries, such as some STL implementations, do their
+ own memory management. This may cause strange profiling
+ results. We have code in libtcmalloc to cause STL to use
+ tcmalloc for memory management (which in our tests is better
+ than STL's internal management), though it only works for some
+ STL implementations.
+
+ <li> If your program forks, the children will also be profiled
+ (since they inherit the same HEAPPROFILE setting). Each
+ process is profiled separately; to distinguish the child
+ profiles from the parent profile and from each other, all
+ children will have their process-id attached to the HEAPPROFILE
+ name.
+
+ <li> Due to a hack we make to work around a possible gcc bug, your
+ profiles may end up named strangely if the first character of
+ your HEAPPROFILE variable has ascii value greater than 127.
+ This should be exceedingly rare, but if you need to use such a
+ name, just set prepend <code>./</code> to your filename:
+ <code>HEAPPROFILE=./&Auml;gypten</code>.
+</ul>
+
+<hr>
+<address>Sanjay Ghemawat<br>
+<!-- Created: Tue Dec 19 10:43:14 PST 2000 -->
+<!-- hhmts start -->
+Last modified: Sat Feb 24 14:33:15 PST 2007 (csilvers)
+<!-- hhmts end -->
+</address>
+</body>
+</html>
diff --git a/doc/index.html b/doc/index.html
index 94226d5..f4068cb 100644
--- a/doc/index.html
+++ b/doc/index.html
@@ -8,12 +8,13 @@
<ul>
<li> <A HREF="tcmalloc.html">thread-caching malloc</A>
<li> <A HREF="heap_checker.html">heap-checking using tcmalloc</A>
- <li> <A HREF="heap_profiler.html">heap-profiling using tcmalloc</A>
- <li> <A HREF="cpu_profiler.html">CPU profiler</A>
+ <li> <A HREF="heapprofile.html">heap-profiling using tcmalloc</A>
+ <li> <A HREF="cpuprofile.html">CPU profiler</A>
</ul>
<hr>
-Last modified: Fri Mar 11 05:58:27 PST 2005
+Last modified: Wed Mar 21 22:46:51 PDT 2007
+
</BODY>
diff --git a/doc/tcmalloc.html b/doc/tcmalloc.html
index 9ea3a1a..c399188 100644
--- a/doc/tcmalloc.html
+++ b/doc/tcmalloc.html
@@ -3,6 +3,7 @@
<html>
<head>
<title>TCMalloc : Thread-Caching Malloc</title>
+<link rel="stylesheet" href="designstyle.css">
<style type="text/css">
em {
color: red;
@@ -14,45 +15,44 @@
<h1>TCMalloc : Thread-Caching Malloc</h1>
-<address>Sanjay Ghemawat, Paul Menage &lt;opensource@google.com&gt;</address>
+<address>Sanjay Ghemawat</address>
<h2>Motivation</h2>
-TCMalloc is faster than the glibc 2.3 malloc (available as a separate
-library called ptmalloc2) and other mallocs
-that I have tested. ptmalloc2 takes approximately 300 nanoseconds to
-execute a malloc/free pair on a 2.8 GHz P4 (for small objects). The
-TCMalloc implementation takes approximately 50 nanoseconds for the
-same operation pair. Speed is important for a malloc implementation
+<p>TCMalloc is faster than the glibc 2.3 malloc (available as a
+separate library called ptmalloc2) and other mallocs that I have
+tested. ptmalloc2 takes approximately 300 nanoseconds to execute a
+malloc/free pair on a 2.8 GHz P4 (for small objects). The TCMalloc
+implementation takes approximately 50 nanoseconds for the same
+operation pair. Speed is important for a malloc implementation
because if malloc is not fast enough, application writers are inclined
to write their own custom free lists on top of malloc. This can lead
to extra complexity, and more memory usage unless the application
writer is very careful to appropriately size the free lists and
-scavenge idle objects out of the free list
+scavenge idle objects out of the free list.</p>
-<p>
-TCMalloc also reduces lock contention for multi-threaded programs.
+<p>TCMalloc also reduces lock contention for multi-threaded programs.
For small objects, there is virtually zero contention. For large
objects, TCMalloc tries to use fine grained and efficient spinlocks.
ptmalloc2 also reduces lock contention by using per-thread arenas but
there is a big problem with ptmalloc2's use of per-thread arenas. In
ptmalloc2 memory can never move from one arena to another. This can
-lead to huge amounts of wasted space. For example, in one Google application, the first phase would
-allocate approximately 300MB of memory for its data
-structures. When the first phase finished, a second phase would be
-started in the same address space. If this second phase was assigned a
-different arena than the one used by the first phase, this phase would
-not reuse any of the memory left after the first phase and would add
-another 300MB to the address space. Similar memory blowup problems
-were also noticed in other applications.
-
-<p>
-Another benefit of TCMalloc is space-efficient representation of small
-objects. For example, N 8-byte objects can be allocated while using
-space approximately <code>8N * 1.01</code> bytes. I.e., a one-percent
-space overhead. ptmalloc2 uses a four-byte header for each object and
-(I think) rounds up the size to a multiple of 8 bytes and ends up
-using <code>16N</code> bytes.
+lead to huge amounts of wasted space. For example, in one Google
+application, the first phase would allocate approximately 300MB of
+memory for its URL canonicalization data structures. When the first
+phase finished, a second phase would be started in the same address
+space. If this second phase was assigned a different arena than the
+one used by the first phase, this phase would not reuse any of the
+memory left after the first phase and would add another 300MB to the
+address space. Similar memory blowup problems were also noticed in
+other applications.</p>
+
+<p>Another benefit of TCMalloc is space-efficient representation of
+small objects. For example, N 8-byte objects can be allocated while
+using space approximately <code>8N * 1.01</code> bytes. I.e., a
+one-percent space overhead. ptmalloc2 uses a four-byte header for
+each object and (I think) rounds up the size to a multiple of 8 bytes
+and ends up using <code>16N</code> bytes.</p>
<h2>Usage</h2>
@@ -60,20 +60,16 @@ using <code>16N</code> bytes.
<p>To use TCmalloc, just link tcmalloc into your application via the
"-ltcmalloc" linker flag.</p>
-<p>
-You can use tcmalloc in applications you didn't compile yourself, by
-using LD_PRELOAD:
-</p>
+<p>You can use tcmalloc in applications you didn't compile yourself,
+by using LD_PRELOAD:</p>
<pre>
$ LD_PRELOAD="/usr/lib/libtcmalloc.so" <binary>
</pre>
-<p>
-LD_PRELOAD is tricky, and we don't necessarily recommend this mode of
-usage.
-</p>
+<p>LD_PRELOAD is tricky, and we don't necessarily recommend this mode
+of usage.</p>
<p>TCMalloc includes a <A HREF="heap_checker.html">heap checker</A>
-and <A HREF="heap_profiler.html">heap profiler</A> as well.</p>
+and <A HREF="heapprofile.html">heap profiler</A> as well.</p>
<p>If you'd rather link in a version of TCMalloc that does not include
the heap profiler and checker (perhaps to reduce binary size for a
@@ -83,260 +79,265 @@ instead.</p>
<h2>Overview</h2>
-TCMalloc assigns each thread a thread-local cache. Small allocations
-are satisfied from the thread-local cache. Objects are moved from
-central data structures into a thread-local cache as needed, and
-periodic garbage collections are used to migrate memory back from a
-thread-local cache into the central data structures.
+<p>TCMalloc assigns each thread a thread-local cache. Small
+allocations are satisfied from the thread-local cache. Objects are
+moved from central data structures into a thread-local cache as
+needed, and periodic garbage collections are used to migrate memory
+back from a thread-local cache into the central data structures.</p>
<center><img src="overview.gif"></center>
-<p>
-TCMalloc treates objects with size &lt;= 32K ("small" objects)
-differently from larger objects. Large objects are allocated
-directly from the central heap using a page-level allocator
-(a page is a 4K aligned region of memory). I.e., a large object
-is always page-aligned and occupies an integral number of pages.
+<p>TCMalloc treates objects with size &lt;= 32K ("small" objects)
+differently from larger objects. Large objects are allocated directly
+from the central heap using a page-level allocator (a page is a 4K
+aligned region of memory). I.e., a large object is always
+page-aligned and occupies an integral number of pages.</p>
+
+<p>A run of pages can be carved up into a sequence of small objects,
+each equally sized. For example a run of one page (4K) can be carved
+up into 32 objects of size 128 bytes each.</p>
-<p>
-A run of pages can be carved up into a sequence of small objects, each
-equally sized. For example a run of one page (4K) can be carved up
-into 32 objects of size 128 bytes each.
<h2>Small Object Allocation</h2>
-Each small object size maps to one of approximately 170 allocatable
+<p>Each small object size maps to one of approximately 170 allocatable
size-classes. For example, all allocations in the range 961 to 1024
bytes are rounded up to 1024. The size-classes are spaced so that
small sizes are separated by 8 bytes, larger sizes by 16 bytes, even
-larger sizes by 32 bytes, and so forth. The maximal spacing (for sizes
->= ~2K) is 256 bytes.
+larger sizes by 32 bytes, and so forth. The maximal spacing (for
+sizes >= ~2K) is 256 bytes.</p>
-<p>
-A thread cache contains a singly linked list of free objects per size-class.
+<p>A thread cache contains a singly linked list of free objects per
+size-class.</p>
<center><img src="threadheap.gif"></center>
-When allocating a small object: (1) We map its size to the
+<p>When allocating a small object: (1) We map its size to the
corresponding size-class. (2) Look in the corresponding free list in
the thread cache for the current thread. (3) If the free list is not
empty, we remove the first object from the list and return it. When
following this fast path, TCMalloc acquires no locks at all. This
helps speed-up allocation significantly because a lock/unlock pair
-takes approximately 100 nanoseconds on a 2.8 GHz Xeon.
+takes approximately 100 nanoseconds on a 2.8 GHz Xeon.</p>
-<p>
-If the free list is empty: (1) We fetch a bunch of objects from a
+<p>If the free list is empty: (1) We fetch a bunch of objects from a
central free list for this size-class (the central free list is shared
by all threads). (2) Place them in the thread-local free list. (3)
-Return one of the newly fetched objects to the applications.
+Return one of the newly fetched objects to the applications.</p>
+
+<p>If the central free list is also empty: (1) We allocate a run of
+pages from the central page allocator. (2) Split the run into a set
+of objects of this size-class. (3) Place the new objects on the
+central free list. (4) As before, move some of these objects to the
+thread-local free list.</p>
-<p>
-If the central free list is also empty: (1) We allocate a run of pages
-from the central page allocator. (2) Split the run into a set of
-objects of this size-class. (3) Place the new objects on the central
-free list. (4) As before, move some of these objects to the
-thread-local free list.
<h2>Large Object Allocation</h2>
-A large object size (&gt; 32K) is rounded up to a page size (4K) and
-is handled by a central page heap. The central page heap is again an
-array of free lists. For <code>i &lt; 256</code>, the
+<p>A large object size (&gt; 32K) is rounded up to a page size (4K)
+and is handled by a central page heap. The central page heap is again
+an array of free lists. For <code>i &lt; 256</code>, the
<code>k</code>th entry is a free list of runs that consist of
<code>k</code> pages. The <code>256</code>th entry is a free list of
-runs that have length <code>&gt;= 256</code> pages:
+runs that have length <code>&gt;= 256</code> pages: </p>
<center><img src="pageheap.gif"></center>
-<p>
-An allocation for <code>k</code> pages is satisfied by looking in the
-<code>k</code>th free list. If that free list is empty, we look in
-the next free list, and so forth. Eventually, we look in the last
+<p>An allocation for <code>k</code> pages is satisfied by looking in
+the <code>k</code>th free list. If that free list is empty, we look
+in the next free list, and so forth. Eventually, we look in the last
free list if necessary. If that fails, we fetch memory from the
-system (using sbrk, mmap, or by mapping in portions of /dev/mem).
+system (using <code>sbrk</code>, <code>mmap</code>, or by mapping in
+portions of <code>/dev/mem</code>).</p>
-<p>
-If an allocation for <code>k</code> pages is satisfied by a run
+<p>If an allocation for <code>k</code> pages is satisfied by a run
of pages of length &gt; <code>k</code>, the remainder of the
run is re-inserted back into the appropriate free list in the
-page heap.
+page heap.</p>
+
<h2>Spans</h2>
-The heap managed by TCMalloc consists of a set of pages. A run of
+<p>The heap managed by TCMalloc consists of a set of pages. A run of
contiguous pages is represented by a <code>Span</code> object. A span
can either be <em>allocated</em>, or <em>free</em>. If free, the span
is one of the entries in a page heap linked-list. If allocated, it is
either a large object that has been handed off to the application, or
a run of pages that have been split up into a sequence of small
objects. If split into small objects, the size-class of the objects
-is recorded in the span.
+is recorded in the span.</p>
-<p>
-A central array indexed by page number can be used to find the span to
+<p>A central array indexed by page number can be used to find the span to
which a page belongs. For example, span <em>a</em> below occupies 2
pages, span <em>b</em> occupies 1 page, span <em>c</em> occupies 5
-pages and span <em>d</em> occupies 3 pages.
+pages and span <em>d</em> occupies 3 pages.</p>
<center><img src="spanmap.gif"></center>
-A 32-bit address space can fit 2^20 4K pages, so this central array
-takes 4MB of space, which seems acceptable. On 64-bit machines, we
-use a 3-level radix tree instead of an array to map from a page number
-to the corresponding span pointer.
+
+<p>In a 32-bit address space, the central array is represented by a a
+2-level radix tree where the root contains 32 entries and each leaf
+contains 2^15 entries (a 32-bit address spave has 2^20 4K pages, and
+the first level of tree divides the 2^20 pages by 2^5). This leads to
+a starting memory usage of 128KB of space (2^15*4 bytes) for the
+central array, which seems acceptable.</p>
+
+<p>On 64-bit machines, we use a 3-level radix tree.</p>
+
<h2>Deallocation</h2>
-When an object is deallocated, we compute its page number and look it up
-in the central array to find the corresponding span object. The span tells
-us whether or not the object is small, and its size-class if it is
-small. If the object is small, we insert it into the appropriate free
-list in the current thread's thread cache. If the thread cache now
-exceeds a predetermined size (2MB by default), we run a garbage
-collector that moves unused objects from the thread cache into central
-free lists.
-
-<p>
-If the object is large, the span tells us the range of pages covered
+<p>When an object is deallocated, we compute its page number and look
+it up in the central array to find the corresponding span object. The
+span tells us whether or not the object is small, and its size-class
+if it is small. If the object is small, we insert it into the
+appropriate free list in the current thread's thread cache. If the
+thread cache now exceeds a predetermined size (2MB by default), we run
+a garbage collector that moves unused objects from the thread cache
+into central free lists.</p>
+
+<p>If the object is large, the span tells us the range of pages covered
by the object. Suppose this range is <code>[p,q]</code>. We also
lookup the spans for pages <code>p-1</code> and <code>q+1</code>. If
either of these neighboring spans are free, we coalesce them with the
<code>[p,q]</code> span. The resulting span is inserted into the
-appropriate free list in the page heap.
+appropriate free list in the page heap.</p>
+
<h2>Central Free Lists for Small Objects</h2>
-As mentioned before, we keep a central free list for each size-class.
-Each central free list is organized as a two-level data structure:
-a set of spans, and a linked list of free objects per span.
+<p>As mentioned before, we keep a central free list for each
+size-class. Each central free list is organized as a two-level data
+structure: a set of spans, and a linked list of free objects per
+span.</p>
-<p>
-An object is allocated from a central free list by removing the
-first entry from the linked list of some span. (If all spans
-have empty linked lists, a suitably sized span is first allocated
-from the central page heap.)
+<p>An object is allocated from a central free list by removing the
+first entry from the linked list of some span. (If all spans have
+empty linked lists, a suitably sized span is first allocated from the
+central page heap.)</p>
-<p>
-An object is returned to a central free list by adding it to the
+<p>An object is returned to a central free list by adding it to the
linked list of its containing span. If the linked list length now
equals the total number of small objects in the span, this span is now
-completely free and is returned to the page heap.
+completely free and is returned to the page heap.</p>
+
<h2>Garbage Collection of Thread Caches</h2>
-A thread cache is garbage collected when the combined size of all
-objects in the cache exceeds 2MB. The garbage collection threshold
-is automatically decreased as the number of threads increases so that
-we don't waste an inordinate amount of memory in a program with lots
-of threads.
-
-<p>
-We walk over all free lists in the cache and move some number of
-objects from the free list to the corresponding central list.
-
-<p>
-The number of objects to be moved from a free list is determined using
-a per-list low-water-mark <code>L</code>. <code>L</code> records the
-minimum length of the list since the last garbage collection. Note
-that we could have shortened the list by <code>L</code> objects at the
-last garbage collection without requiring any extra accesses to the
-central list. We use this past history as a predictor of future
-accesses and move <code>L/2</code> objects from the thread cache free
-list to the corresponding central free list. This algorithm has the
-nice property that if a thread stops using a particular size, all
-objects of that size will quickly move from the thread cache to the
-central free list where they can be used by other threads.
+<p>A thread cache is garbage collected when the combined size of all
+objects in the cache exceeds 2MB. The garbage collection threshold is
+automatically decreased as the number of threads increases so that we
+don't waste an inordinate amount of memory in a program with lots of
+threads.</p>
+
+<p>We walk over all free lists in the cache and move some number of
+objects from the free list to the corresponding central list.</p>
+
+<p>The number of objects to be moved from a free list is determined
+using a per-list low-water-mark <code>L</code>. <code>L</code>
+records the minimum length of the list since the last garbage
+collection. Note that we could have shortened the list by
+<code>L</code> objects at the last garbage collection without
+requiring any extra accesses to the central list. We use this past
+history as a predictor of future accesses and move <code>L/2</code>
+objects from the thread cache free list to the corresponding central
+free list. This algorithm has the nice property that if a thread
+stops using a particular size, all objects of that size will quickly
+move from the thread cache to the central free list where they can be
+used by other threads.</p>
+
<h2>Performance Notes</h2>
<h3>PTMalloc2 unittest</h3>
-The PTMalloc2 package (now part of glibc) contains a unittest program
-t-test1.c. This forks a number of threads and performs a series of
-allocations and deallocations in each thread; the threads do not
-communicate other than by synchronization in the memory allocator.
-
-<p> t-test1 (included in google-perftools/tests/tcmalloc, and compiled
-as ptmalloc_unittest1) was run with a varying numbers of threads
-(1-20) and maximum allocation sizes (64 bytes - 32Kbytes). These tests
-were run on a 2.4GHz dual Xeon system with hyper-threading enabled,
-using Linux glibc-2.3.2 from RedHat 9, with one million operations per
-thread in each test. In each case, the test was run once normally, and
-once with LD_PRELOAD=libtcmalloc.so.
+
+<p>The PTMalloc2 package (now part of glibc) contains a unittest
+program <code>t-test1.c</code>. This forks a number of threads and
+performs a series of allocations and deallocations in each thread; the
+threads do not communicate other than by synchronization in the memory
+allocator.</p>
+
+<p><code>t-test1</code> (included in
+<code>tests/tcmalloc/</code>, and compiled as
+<code>ptmalloc_unittest1</code>) was run with a varying numbers of
+threads (1-20) and maximum allocation sizes (64 bytes -
+32Kbytes). These tests were run on a 2.4GHz dual Xeon system with
+hyper-threading enabled, using Linux glibc-2.3.2 from RedHat 9, with
+one million operations per thread in each test. In each case, the test
+was run once normally, and once with
+<code>LD_PRELOAD=libtcmalloc.so</code>.
<p>The graphs below show the performance of TCMalloc vs PTMalloc2 for
-several different metrics. Firstly, total operations (millions) per elapsed
-second vs max allocation size, for varying numbers of threads. The raw
-data used to generate these graphs (the output of the "time" utility)
-is available in t-test1.times.txt.
+several different metrics. Firstly, total operations (millions) per
+elapsed second vs max allocation size, for varying numbers of
+threads. The raw data used to generate these graphs (the output of the
+<code>time</code> utility) is available in
+<code>t-test1.times.txt</code>.</p>
-<p>
<table>
<tr>
-<td><img src="tcmalloc-opspersec.vs.size.1.threads.png"></td>
-<td><img src="tcmalloc-opspersec.vs.size.2.threads.png"></td>
-<td><img src="tcmalloc-opspersec.vs.size.3.threads.png"></td>
+ <td><img src="tcmalloc-opspersec.vs.size.1.threads.png"></td>
+ <td><img src="tcmalloc-opspersec.vs.size.2.threads.png"></td>
+ <td><img src="tcmalloc-opspersec.vs.size.3.threads.png"></td>
</tr>
<tr>
-<td><img src="tcmalloc-opspersec.vs.size.4.threads.png"></td>
-<td><img src="tcmalloc-opspersec.vs.size.5.threads.png"></td>
-<td><img src="tcmalloc-opspersec.vs.size.8.threads.png"></td>
+ <td><img src="tcmalloc-opspersec.vs.size.4.threads.png"></td>
+ <td><img src="tcmalloc-opspersec.vs.size.5.threads.png"></td>
+ <td><img src="tcmalloc-opspersec.vs.size.8.threads.png"></td>
</tr>
<tr>
-<td><img src="tcmalloc-opspersec.vs.size.12.threads.png"></td>
-<td><img src="tcmalloc-opspersec.vs.size.16.threads.png"></td>
-<td><img src="tcmalloc-opspersec.vs.size.20.threads.png"></td>
+ <td><img src="tcmalloc-opspersec.vs.size.12.threads.png"></td>
+ <td><img src="tcmalloc-opspersec.vs.size.16.threads.png"></td>
+ <td><img src="tcmalloc-opspersec.vs.size.20.threads.png"></td>
</tr>
</table>
<ul>
-
-<li> TCMalloc is much more consistently scalable than PTMalloc2 - for
-all thread counts >1 it achieves ~7-9 million ops/sec for small
-allocations, falling to ~2 million ops/sec for larger allocations. The
-single-thread case is an obvious outlier, since it is only able to
-keep a single processor busy and hence can achieve fewer
-ops/sec. PTMalloc2 has a much higher variance on operations/sec -
-peaking somewhere around 4 million ops/sec for small allocations and
-falling to <1 million ops/sec for larger allocations.
-
-<li> TCMalloc is faster than PTMalloc2 in the vast majority of cases,
-and particularly for small allocations. Contention between threads is
-less of a problem in TCMalloc.
-
-<li> TCMalloc's performance drops off as the allocation size
-increases. This is because the per-thread cache is garbage-collected
-when it hits a threshold (defaulting to 2MB). With larger allocation
-sizes, fewer objects can be stored in the cache before it is
-garbage-collected.
-
-<li> There is a noticeably drop in the TCMalloc performance at ~32K
-maximum allocation size; at larger sizes performance drops less
-quickly. This is due to the 32K maximum size of objects in the
-per-thread caches; for objects larger than this tcmalloc allocates
-from the central page heap.
-
+ <li> TCMalloc is much more consistently scalable than PTMalloc2 - for
+ all thread counts >1 it achieves ~7-9 million ops/sec for small
+ allocations, falling to ~2 million ops/sec for larger
+ allocations. The single-thread case is an obvious outlier,
+ since it is only able to keep a single processor busy and hence
+ can achieve fewer ops/sec. PTMalloc2 has a much higher variance
+ on operations/sec - peaking somewhere around 4 million ops/sec
+ for small allocations and falling to <1 million ops/sec for
+ larger allocations.
+
+ <li> TCMalloc is faster than PTMalloc2 in the vast majority of
+ cases, and particularly for small allocations. Contention
+ between threads is less of a problem in TCMalloc.
+
+ <li> TCMalloc's performance drops off as the allocation size
+ increases. This is because the per-thread cache is
+ garbage-collected when it hits a threshold (defaulting to
+ 2MB). With larger allocation sizes, fewer objects can be stored
+ in the cache before it is garbage-collected.
+
+ <li> There is a noticeably drop in the TCMalloc performance at ~32K
+ maximum allocation size; at larger sizes performance drops less
+ quickly. This is due to the 32K maximum size of objects in the
+ per-thread caches; for objects larger than this tcmalloc
+ allocates from the central page heap.
</ul>
-<p> Next, operations (millions) per second of CPU time vs number of threads, for
-max allocation size 64 bytes - 128 Kbytes.
+<p>Next, operations (millions) per second of CPU time vs number of
+threads, for max allocation size 64 bytes - 128 Kbytes.</p>
-<p>
<table>
<tr>
-<td><img src="tcmalloc-opspercpusec.vs.threads.64.bytes.png"></td>
-<td><img src="tcmalloc-opspercpusec.vs.threads.256.bytes.png"></td>
-<td><img src="tcmalloc-opspercpusec.vs.threads.1024.bytes.png"></td>
+ <td><img src="tcmalloc-opspercpusec.vs.threads.64.bytes.png"></td>
+ <td><img src="tcmalloc-opspercpusec.vs.threads.256.bytes.png"></td>
+ <td><img src="tcmalloc-opspercpusec.vs.threads.1024.bytes.png"></td>
</tr>
<tr>
-<td><img src="tcmalloc-opspercpusec.vs.threads.4096.bytes.png"></td>
-<td><img src="tcmalloc-opspercpusec.vs.threads.8192.bytes.png"></td>
-<td><img src="tcmalloc-opspercpusec.vs.threads.16384.bytes.png"></td>
+ <td><img src="tcmalloc-opspercpusec.vs.threads.4096.bytes.png"></td>
+ <td><img src="tcmalloc-opspercpusec.vs.threads.8192.bytes.png"></td>
+ <td><img src="tcmalloc-opspercpusec.vs.threads.16384.bytes.png"></td>
</tr>
<tr>
-<td><img src="tcmalloc-opspercpusec.vs.threads.32768.bytes.png"></td>
-<td><img src="tcmalloc-opspercpusec.vs.threads.65536.bytes.png"></td>
-<td><img src="tcmalloc-opspercpusec.vs.threads.131072.bytes.png"></td>
+ <td><img src="tcmalloc-opspercpusec.vs.threads.32768.bytes.png"></td>
+ <td><img src="tcmalloc-opspercpusec.vs.threads.65536.bytes.png"></td>
+ <td><img src="tcmalloc-opspercpusec.vs.threads.131072.bytes.png"></td>
</tr>
</table>
-<p> Here we see again that TCMalloc is both more consistent and more
+<p>Here we see again that TCMalloc is both more consistent and more
efficient than PTMalloc2. For max allocation sizes &lt;32K, TCMalloc
typically achieves ~2-2.5 million ops per second of CPU time with a
large number of threads, whereas PTMalloc achieves generally 0.5-1
@@ -345,31 +346,34 @@ less than this figure. Above 32K max allocation size, TCMalloc drops
to 1-1.5 million ops per second of CPU time, and PTMalloc drops almost
to zero for large numbers of threads (i.e. with PTMalloc, lots of CPU
time is being burned spinning waiting for locks in the heavily
-multi-threaded case).
+multi-threaded case).</p>
+
<h2>Caveats</h2>
<p>For some systems, TCMalloc may not work correctly on with
-applications that aren't linked against libpthread.so (or the
-equivalent on your OS). It should work on Linux using glibc 2.3, but
-other OS/libc combinations have not been tested.
+applications that aren't linked against <code>libpthread.so</code> (or
+the equivalent on your OS). It should work on Linux using glibc 2.3,
+but other OS/libc combinations have not been tested.</p>
<p>TCMalloc may be somewhat more memory hungry than other mallocs,
-though it tends not to have the huge blowups that can happen with
-other mallocs. In particular, at startup TCMalloc allocates
-approximately 6 MB of memory. It would be easy to roll a specialized
-version that trades a little bit of speed for more space efficiency.
-
-<p>
-TCMalloc currently does not return any memory to the system.
-
-<p>
-Don't try to load TCMalloc into a running binary (e.g., using
-JNI in Java programs). The binary will have allocated some
-objects using the system malloc, and may try to pass them
-to TCMalloc for deallocation. TCMalloc will not be able
-to handle such objects.
-
+(but tends not to have the huge blowups that can happen with other
+mallocs). In particular, at startup TCMalloc allocates approximately
+240KB of internal memory.</p>
+
+<p>Don't try to load TCMalloc into a running binary (e.g., using JNI
+in Java programs). The binary will have allocated some objects using
+the system malloc, and may try to pass them to TCMalloc for
+deallocation. TCMalloc will not be able to handle such objects.</p>
+
+<hr>
+
+<address>Sanjay Ghemawat, Paul Menage<br>
+<!-- Created: Tue Dec 19 10:43:14 PST 2000 -->
+<!-- hhmts start -->
+Last modified: Sat Feb 24 13:11:38 PST 2007 (csilvers)
+<!-- hhmts end -->
+</address>
</body>
</html>
diff --git a/ltmain.sh b/ltmain.sh
index 5b79699..8fc56db 100644
--- a/ltmain.sh
+++ b/ltmain.sh
@@ -1,7 +1,7 @@
# ltmain.sh - Provide generalized library-building support services.
# NOTE: Changing this file will not affect anything until you rerun configure.
#
-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005
# Free Software Foundation, Inc.
# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
#
@@ -17,13 +17,41 @@
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
+basename="s,^.*/,,g"
+
+# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh
+# is ksh but when the shell is invoked as "sh" and the current value of
+# the _XPG environment variable is not equal to 1 (one), the special
+# positional parameter $0, within a function call, is the name of the
+# function.
+progpath="$0"
+
+# The name of this program:
+progname=`echo "$progpath" | $SED $basename`
+modename="$progname"
+
+# Global variables:
+EXIT_SUCCESS=0
+EXIT_FAILURE=1
+
+PROGRAM=ltmain.sh
+PACKAGE=libtool
+VERSION="1.5.22 Debian 1.5.22-2"
+TIMESTAMP=" (1.1220.2.365 2005/12/18 22:14:06)"
+
+# See if we are running on zsh, and set the options which allow our
+# commands through without removal of \ escapes.
+if test -n "${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+fi
+
# Check that we have a working $echo.
if test "X$1" = X--no-reexec; then
# Discard the --no-reexec flag, and continue.
@@ -36,7 +64,7 @@ elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
:
else
# Restart under the correct shell, and then maybe $echo will work.
- exec $SHELL "$0" --no-reexec ${1+"$@"}
+ exec $SHELL "$progpath" --no-reexec ${1+"$@"}
fi
if test "X$1" = X--fallback-echo; then
@@ -45,22 +73,9 @@ if test "X$1" = X--fallback-echo; then
cat <<EOF
$*
EOF
- exit 0
+ exit $EXIT_SUCCESS
fi
-# define SED for historic ltconfig's generated by Libtool 1.3
-test -z "$SED" && SED=sed
-
-# The name of this program.
-progname=`$echo "$0" | ${SED} 's%^.*/%%'`
-modename="$progname"
-
-# Constants.
-PROGRAM=ltmain.sh
-PACKAGE=libtool
-VERSION=1.5
-TIMESTAMP=" (1.1220.2.1 2003/04/14 22:48:00)"
-
default_mode=
help="Try \`$progname --help' for more information."
magic="%%%MAGIC variable%%%"
@@ -73,14 +88,15 @@ rm="rm -f"
Xsed="${SED}"' -e 1s/^X//'
sed_quote_subst='s/\([\\`\\"$\\\\]\)/\\\1/g'
# test EBCDIC or ASCII
-case `echo A|od -x` in
- *[Cc]1*) # EBCDIC based system
- SP2NL="tr '\100' '\n'"
- NL2SP="tr '\r\n' '\100\100'"
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+ # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+ SP2NL='tr \040 \012'
+ NL2SP='tr \015\012 \040\040'
;;
- *) # Assume ASCII based system
- SP2NL="tr '\040' '\012'"
- NL2SP="tr '\015\012' '\040\040'"
+ *) # EBCDIC based system
+ SP2NL='tr \100 \n'
+ NL2SP='tr \r\n \100\100'
;;
esac
@@ -97,12 +113,14 @@ if test "${LANG+set}" = set; then
fi
# Make sure IFS has a sensible default
-: ${IFS=" "}
+lt_nl='
+'
+IFS=" $lt_nl"
if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
$echo "$modename: not configured to build any kind of library" 1>&2
$echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2
- exit 1
+ exit $EXIT_FAILURE
fi
# Global variables.
@@ -114,6 +132,8 @@ run=
show="$echo"
show_help=
execute_dlfiles=
+duplicate_deps=no
+preserve_args=
lo2o="s/\\.lo\$/.${objext}/"
o2lo="s/\\.${objext}\$/.lo/"
@@ -121,10 +141,51 @@ o2lo="s/\\.${objext}\$/.lo/"
# Shell function definitions:
# This seems to be the best place for them
+# func_mktempdir [string]
+# Make a temporary directory that won't clash with other running
+# libtool processes, and avoids race conditions if possible. If
+# given, STRING is the basename for that directory.
+func_mktempdir ()
+{
+ my_template="${TMPDIR-/tmp}/${1-$progname}"
+
+ if test "$run" = ":"; then
+ # Return a directory name, but don't create it in dry-run mode
+ my_tmpdir="${my_template}-$$"
+ else
+
+ # If mktemp works, use that first and foremost
+ my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null`
+
+ if test ! -d "$my_tmpdir"; then
+ # Failing that, at least try and use $RANDOM to avoid a race
+ my_tmpdir="${my_template}-${RANDOM-0}$$"
+
+ save_mktempdir_umask=`umask`
+ umask 0077
+ $mkdir "$my_tmpdir"
+ umask $save_mktempdir_umask
+ fi
+
+ # If we're not in dry-run mode, bomb out on failure
+ test -d "$my_tmpdir" || {
+ $echo "cannot create temporary directory \`$my_tmpdir'" 1>&2
+ exit $EXIT_FAILURE
+ }
+ fi
+
+ $echo "X$my_tmpdir" | $Xsed
+}
+
+
+# func_win32_libid arg
+# return the library type of file 'arg'
+#
# Need a lot of goo to handle *both* DLLs and import libs
# Has to be a shell function in order to 'eat' the argument
# that is supplied when $file_magic_command is called.
-win32_libid () {
+func_win32_libid ()
+{
win32_libid_type="unknown"
win32_fileres=`file -L $1 2>/dev/null`
case $win32_fileres in
@@ -133,17 +194,16 @@ win32_libid () {
;;
*ar\ archive*) # could be an import, or static
if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | \
- grep -E 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then
+ $EGREP -e 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then
win32_nmres=`eval $NM -f posix -A $1 | \
- sed -n -e '1,100{/ I /{x;/import/!{s/^/import/;h;p;};x;};}'`
- if test "X$win32_nmres" = "Ximport" ; then
- win32_libid_type="x86 archive import"
- else
- win32_libid_type="x86 archive static"
- fi
+ $SED -n -e '1,100{/ I /{s,.*,import,;p;q;};}'`
+ case $win32_nmres in
+ import*) win32_libid_type="x86 archive import";;
+ *) win32_libid_type="x86 archive static";;
+ esac
fi
;;
- *DLL*)
+ *DLL*)
win32_libid_type="x86 DLL"
;;
*executable*) # but shell scripts are "executable" too...
@@ -157,9 +217,181 @@ win32_libid () {
$echo $win32_libid_type
}
+
+# func_infer_tag arg
+# Infer tagged configuration to use if any are available and
+# if one wasn't chosen via the "--tag" command line option.
+# Only attempt this if the compiler in the base compile
+# command doesn't match the default compiler.
+# arg is usually of the form 'gcc ...'
+func_infer_tag ()
+{
+ if test -n "$available_tags" && test -z "$tagname"; then
+ CC_quoted=
+ for arg in $CC; do
+ case $arg in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ arg="\"$arg\""
+ ;;
+ esac
+ CC_quoted="$CC_quoted $arg"
+ done
+ case $@ in
+ # Blanks in the command may have been stripped by the calling shell,
+ # but not from the CC environment variable when configure was run.
+ " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*) ;;
+ # Blanks at the start of $base_compile will cause this to fail
+ # if we don't check for them as well.
+ *)
+ for z in $available_tags; do
+ if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then
+ # Evaluate the configuration.
+ eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`"
+ CC_quoted=
+ for arg in $CC; do
+ # Double-quote args containing other shell metacharacters.
+ case $arg in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ arg="\"$arg\""
+ ;;
+ esac
+ CC_quoted="$CC_quoted $arg"
+ done
+ case "$@ " in
+ " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*)
+ # The compiler in the base compile command matches
+ # the one in the tagged configuration.
+ # Assume this is the tagged configuration we want.
+ tagname=$z
+ break
+ ;;
+ esac
+ fi
+ done
+ # If $tagname still isn't set, then no tagged configuration
+ # was found and let the user know that the "--tag" command
+ # line option must be used.
+ if test -z "$tagname"; then
+ $echo "$modename: unable to infer tagged configuration"
+ $echo "$modename: specify a tag with \`--tag'" 1>&2
+ exit $EXIT_FAILURE
+# else
+# $echo "$modename: using $tagname tagged configuration"
+ fi
+ ;;
+ esac
+ fi
+}
+
+
+# func_extract_an_archive dir oldlib
+func_extract_an_archive ()
+{
+ f_ex_an_ar_dir="$1"; shift
+ f_ex_an_ar_oldlib="$1"
+
+ $show "(cd $f_ex_an_ar_dir && $AR x $f_ex_an_ar_oldlib)"
+ $run eval "(cd \$f_ex_an_ar_dir && $AR x \$f_ex_an_ar_oldlib)" || exit $?
+ if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then
+ :
+ else
+ $echo "$modename: ERROR: object name conflicts: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" 1>&2
+ exit $EXIT_FAILURE
+ fi
+}
+
+# func_extract_archives gentop oldlib ...
+func_extract_archives ()
+{
+ my_gentop="$1"; shift
+ my_oldlibs=${1+"$@"}
+ my_oldobjs=""
+ my_xlib=""
+ my_xabs=""
+ my_xdir=""
+ my_status=""
+
+ $show "${rm}r $my_gentop"
+ $run ${rm}r "$my_gentop"
+ $show "$mkdir $my_gentop"
+ $run $mkdir "$my_gentop"
+ my_status=$?
+ if test "$my_status" -ne 0 && test ! -d "$my_gentop"; then
+ exit $my_status
+ fi
+
+ for my_xlib in $my_oldlibs; do
+ # Extract the objects.
+ case $my_xlib in
+ [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;;
+ *) my_xabs=`pwd`"/$my_xlib" ;;
+ esac
+ my_xlib=`$echo "X$my_xlib" | $Xsed -e 's%^.*/%%'`
+ my_xdir="$my_gentop/$my_xlib"
+
+ $show "${rm}r $my_xdir"
+ $run ${rm}r "$my_xdir"
+ $show "$mkdir $my_xdir"
+ $run $mkdir "$my_xdir"
+ exit_status=$?
+ if test "$exit_status" -ne 0 && test ! -d "$my_xdir"; then
+ exit $exit_status
+ fi
+ case $host in
+ *-darwin*)
+ $show "Extracting $my_xabs"
+ # Do not bother doing anything if just a dry run
+ if test -z "$run"; then
+ darwin_orig_dir=`pwd`
+ cd $my_xdir || exit $?
+ darwin_archive=$my_xabs
+ darwin_curdir=`pwd`
+ darwin_base_archive=`$echo "X$darwin_archive" | $Xsed -e 's%^.*/%%'`
+ darwin_arches=`lipo -info "$darwin_archive" 2>/dev/null | $EGREP Architectures 2>/dev/null`
+ if test -n "$darwin_arches"; then
+ darwin_arches=`echo "$darwin_arches" | $SED -e 's/.*are://'`
+ darwin_arch=
+ $show "$darwin_base_archive has multiple architectures $darwin_arches"
+ for darwin_arch in $darwin_arches ; do
+ mkdir -p "unfat-$$/${darwin_base_archive}-${darwin_arch}"
+ lipo -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}"
+ cd "unfat-$$/${darwin_base_archive}-${darwin_arch}"
+ func_extract_an_archive "`pwd`" "${darwin_base_archive}"
+ cd "$darwin_curdir"
+ $rm "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}"
+ done # $darwin_arches
+ ## Okay now we have a bunch of thin objects, gotta fatten them up :)
+ darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print| xargs basename | sort -u | $NL2SP`
+ darwin_file=
+ darwin_files=
+ for darwin_file in $darwin_filelist; do
+ darwin_files=`find unfat-$$ -name $darwin_file -print | $NL2SP`
+ lipo -create -output "$darwin_file" $darwin_files
+ done # $darwin_filelist
+ ${rm}r unfat-$$
+ cd "$darwin_orig_dir"
+ else
+ cd "$darwin_orig_dir"
+ func_extract_an_archive "$my_xdir" "$my_xabs"
+ fi # $darwin_arches
+ fi # $run
+ ;;
+ *)
+ func_extract_an_archive "$my_xdir" "$my_xabs"
+ ;;
+ esac
+ my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP`
+ done
+ func_extract_archives_result="$my_oldobjs"
+}
# End of Shell function definitions
#####################################
+# Darwin sucks
+eval std_shrext=\"$shrext_cmds\"
+
+disable_libs=no
+
# Parse our command line options once, thoroughly.
while test "$#" -gt 0
do
@@ -179,12 +411,13 @@ do
;;
tag)
tagname="$arg"
+ preserve_args="${preserve_args}=$arg"
# Check whether tagname contains only valid characters
case $tagname in
*[!-_A-Za-z0-9,/]*)
$echo "$progname: invalid tag name: $tagname" 1>&2
- exit 1
+ exit $EXIT_FAILURE
;;
esac
@@ -194,10 +427,10 @@ do
# not specially marked.
;;
*)
- if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "$0" > /dev/null; then
+ if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "$progpath" > /dev/null; then
taglist="$taglist $tagname"
# Evaluate the configuration.
- eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$tagname'$/,/^# ### END LIBTOOL TAG CONFIG: '$tagname'$/p' < $0`"
+ eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$tagname'$/,/^# ### END LIBTOOL TAG CONFIG: '$tagname'$/p' < $progpath`"
else
$echo "$progname: ignoring unknown tag $tagname" 1>&2
fi
@@ -223,24 +456,25 @@ do
--version)
$echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP"
$echo
- $echo "Copyright (C) 2003 Free Software Foundation, Inc."
+ $echo "Copyright (C) 2005 Free Software Foundation, Inc."
$echo "This is free software; see the source for copying conditions. There is NO"
$echo "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
- exit 0
+ exit $?
;;
--config)
- ${SED} -e '1,/^# ### BEGIN LIBTOOL CONFIG/d' -e '/^# ### END LIBTOOL CONFIG/,$d' $0
+ ${SED} -e '1,/^# ### BEGIN LIBTOOL CONFIG/d' -e '/^# ### END LIBTOOL CONFIG/,$d' $progpath
# Now print the configurations for the tags.
for tagname in $taglist; do
- ${SED} -n -e "/^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$/,/^# ### END LIBTOOL TAG CONFIG: $tagname$/p" < "$0"
+ ${SED} -n -e "/^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$/,/^# ### END LIBTOOL TAG CONFIG: $tagname$/p" < "$progpath"
done
- exit 0
+ exit $?
;;
--debug)
$echo "$progname: enabling shell trace mode"
set -x
+ preserve_args="$preserve_args $arg"
;;
--dry-run | -n)
@@ -259,7 +493,7 @@ do
else
$echo "disable static libraries"
fi
- exit 0
+ exit $?
;;
--finish) mode="finish" ;;
@@ -271,13 +505,19 @@ do
--quiet | --silent)
show=:
+ preserve_args="$preserve_args $arg"
;;
- --tag) prevopt="--tag" prev=tag ;;
+ --tag)
+ prevopt="--tag"
+ prev=tag
+ preserve_args="$preserve_args --tag"
+ ;;
--tag=*)
set tag "$optarg" ${1+"$@"}
shift
prev=tag
+ preserve_args="$preserve_args --tag"
;;
-dlopen)
@@ -288,7 +528,7 @@ do
-*)
$echo "$modename: unrecognized option \`$arg'" 1>&2
$echo "$help" 1>&2
- exit 1
+ exit $EXIT_FAILURE
;;
*)
@@ -301,9 +541,21 @@ done
if test -n "$prevopt"; then
$echo "$modename: option \`$prevopt' requires an argument" 1>&2
$echo "$help" 1>&2
- exit 1
+ exit $EXIT_FAILURE
fi
+case $disable_libs in
+no)
+ ;;
+shared)
+ build_libtool_libs=no
+ build_old_libs=yes
+ ;;
+static)
+ build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac`
+ ;;
+esac
+
# If this variable is set in any of the actions, the command in it
# will be execed at the end. This prevents here-documents from being
# left over by shells.
@@ -314,7 +566,7 @@ if test -z "$show_help"; then
# Infer the operation mode.
if test -z "$mode"; then
$echo "*** Warning: inferring the mode of operation is deprecated." 1>&2
- $echo "*** Future versions of Libtool will require -mode=MODE be specified." 1>&2
+ $echo "*** Future versions of Libtool will require --mode=MODE be specified." 1>&2
case $nonopt in
*cc | cc* | *++ | gcc* | *-gcc* | g++* | xlc*)
mode=link
@@ -357,7 +609,7 @@ if test -z "$show_help"; then
if test -n "$execute_dlfiles" && test "$mode" != execute; then
$echo "$modename: unrecognized option \`-dlopen'" 1>&2
$echo "$help" 1>&2
- exit 1
+ exit $EXIT_FAILURE
fi
# Change the help message to a mode-specific one.
@@ -372,13 +624,15 @@ if test -z "$show_help"; then
# Get the compilation command and the source file.
base_compile=
srcfile="$nonopt" # always keep a non-empty value in "srcfile"
+ suppress_opt=yes
suppress_output=
arg_mode=normal
libobj=
+ later=
for arg
do
- case "$arg_mode" in
+ case $arg_mode in
arg )
# do not "continue". Instead, add this to base_compile
lastarg="$arg"
@@ -397,24 +651,19 @@ if test -z "$show_help"; then
-o)
if test -n "$libobj" ; then
$echo "$modename: you cannot specify \`-o' more than once" 1>&2
- exit 1
+ exit $EXIT_FAILURE
fi
arg_mode=target
continue
;;
- -static)
- build_old_libs=yes
- continue
- ;;
-
- -prefer-pic)
- pic_mode=yes
+ -static | -prefer-pic | -prefer-non-pic)
+ later="$later $arg"
continue
;;
- -prefer-non-pic)
- pic_mode=no
+ -no-suppress)
+ suppress_opt=no
continue
;;
@@ -427,7 +676,7 @@ if test -z "$show_help"; then
args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"`
lastarg=
save_ifs="$IFS"; IFS=','
- for arg in $args; do
+ for arg in $args; do
IFS="$save_ifs"
# Double-quote args containing other shell metacharacters.
@@ -465,7 +714,10 @@ if test -z "$show_help"; then
case $lastarg in
# Double-quote args containing other shell metacharacters.
# Many Bourne shells cannot handle close brackets correctly
- # in scan sets, so we specify it separately.
+ # in scan sets, and some SunOS ksh mistreat backslash-escaping
+ # in scan sets (worked around with variable expansion),
+ # and furthermore cannot handle '|' '&' '(' ')' in scan sets
+ # at all, so we specify them separately.
*[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
lastarg="\"$lastarg\""
;;
@@ -477,11 +729,11 @@ if test -z "$show_help"; then
case $arg_mode in
arg)
$echo "$modename: you must specify an argument for -Xcompile"
- exit 1
+ exit $EXIT_FAILURE
;;
target)
$echo "$modename: you must specify a target with \`-o'" 1>&2
- exit 1
+ exit $EXIT_FAILURE
;;
*)
# Get the name of the library object.
@@ -514,51 +766,39 @@ if test -z "$show_help"; then
*.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;;
*)
$echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2
- exit 1
+ exit $EXIT_FAILURE
;;
esac
- # Infer tagged configuration to use if any are available and
- # if one wasn't chosen via the "--tag" command line option.
- # Only attempt this if the compiler in the base compile
- # command doesn't match the default compiler.
- if test -n "$available_tags" && test -z "$tagname"; then
- case $base_compile in
- # Blanks in the command may have been stripped by the calling shell,
- # but not from the CC environment variable when configure was run.
- " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "*) ;;
- # Blanks at the start of $base_compile will cause this to fail
- # if we don't check for them as well.
- *)
- for z in $available_tags; do
- if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$0" > /dev/null; then
- # Evaluate the configuration.
- eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $0`"
- case "$base_compile " in
- "$CC "* | " $CC "* | "`$echo $CC` "* | " `$echo $CC` "*)
- # The compiler in the base compile command matches
- # the one in the tagged configuration.
- # Assume this is the tagged configuration we want.
- tagname=$z
- break
- ;;
- esac
- fi
- done
- # If $tagname still isn't set, then no tagged configuration
- # was found and let the user know that the "--tag" command
- # line option must be used.
- if test -z "$tagname"; then
- $echo "$modename: unable to infer tagged configuration"
- $echo "$modename: specify a tag with \`--tag'" 1>&2
- exit 1
-# else
-# $echo "$modename: using $tagname tagged configuration"
- fi
+ func_infer_tag $base_compile
+
+ for arg in $later; do
+ case $arg in
+ -static)
+ build_old_libs=yes
+ continue
+ ;;
+
+ -prefer-pic)
+ pic_mode=yes
+ continue
+ ;;
+
+ -prefer-non-pic)
+ pic_mode=no
+ continue
;;
esac
- fi
+ done
+ qlibobj=`$echo "X$libobj" | $Xsed -e "$sed_quote_subst"`
+ case $qlibobj in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ qlibobj="\"$qlibobj\"" ;;
+ esac
+ test "X$libobj" != "X$qlibobj" \
+ && $echo "X$libobj" | grep '[]~#^*{};<>?"'"'"' &()|`$[]' \
+ && $echo "$modename: libobj name \`$libobj' may not contain shell special characters."
objname=`$echo "X$obj" | $Xsed -e 's%^.*/%%'`
xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'`
if test "X$xdir" = "X$obj"; then
@@ -571,7 +811,7 @@ if test -z "$show_help"; then
if test -z "$base_compile"; then
$echo "$modename: you must specify a compilation command" 1>&2
$echo "$help" 1>&2
- exit 1
+ exit $EXIT_FAILURE
fi
# Delete any leftover library objects.
@@ -582,7 +822,7 @@ if test -z "$show_help"; then
fi
$run $rm $removelist
- trap "$run $rm $removelist; exit 1" 1 2 15
+ trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15
# On Cygwin there's no "real" PIC flag so we must build both object types
case $host_os in
@@ -601,7 +841,7 @@ if test -z "$show_help"; then
output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext}
lockfile="$output_obj.lock"
removelist="$removelist $output_obj $lockfile"
- trap "$run $rm $removelist; exit 1" 1 2 15
+ trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15
else
output_obj=
need_locks=no
@@ -611,7 +851,7 @@ if test -z "$show_help"; then
# Lock this critical section if it is needed
# We use this script file to make the link, it avoids creating a new file
if test "$need_locks" = yes; then
- until $run ln "$0" "$lockfile" 2>/dev/null; do
+ until $run ln "$progpath" "$lockfile" 2>/dev/null; do
$show "Waiting for $lockfile to be removed"
sleep 2
done
@@ -629,14 +869,19 @@ avoid parallel builds (make -j) in this platform, or get a better
compiler."
$run $rm $removelist
- exit 1
+ exit $EXIT_FAILURE
fi
- $echo $srcfile > "$lockfile"
+ $echo "$srcfile" > "$lockfile"
fi
if test -n "$fix_srcfile_path"; then
eval srcfile=\"$fix_srcfile_path\"
fi
+ qsrcfile=`$echo "X$srcfile" | $Xsed -e "$sed_quote_subst"`
+ case $qsrcfile in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ qsrcfile="\"$qsrcfile\"" ;;
+ esac
$run $rm "$libobj" "${libobj}T"
@@ -658,18 +903,18 @@ EOF
fbsd_hideous_sh_bug=$base_compile
if test "$pic_mode" != no; then
- command="$base_compile $srcfile $pic_flag"
+ command="$base_compile $qsrcfile $pic_flag"
else
# Don't build PIC code
- command="$base_compile $srcfile"
+ command="$base_compile $qsrcfile"
fi
if test ! -d "${xdir}$objdir"; then
$show "$mkdir ${xdir}$objdir"
$run $mkdir ${xdir}$objdir
- status=$?
- if test "$status" -ne 0 && test ! -d "${xdir}$objdir"; then
- exit $status
+ exit_status=$?
+ if test "$exit_status" -ne 0 && test ! -d "${xdir}$objdir"; then
+ exit $exit_status
fi
fi
@@ -684,7 +929,7 @@ EOF
if $run eval "$command"; then :
else
test -n "$output_obj" && $run $rm $removelist
- exit 1
+ exit $EXIT_FAILURE
fi
if test "$need_locks" = warn &&
@@ -704,7 +949,7 @@ avoid parallel builds (make -j) in this platform, or get a better
compiler."
$run $rm $removelist
- exit 1
+ exit $EXIT_FAILURE
fi
# Just move the object if needed, then go on to compile the next one
@@ -725,7 +970,9 @@ pic_object='$objdir/$objname'
EOF
# Allow error messages only from the first compilation.
- suppress_output=' >/dev/null 2>&1'
+ if test "$suppress_opt" = yes; then
+ suppress_output=' >/dev/null 2>&1'
+ fi
else
# No PIC object so indicate it doesn't exist in the libtool
# object file.
@@ -739,9 +986,9 @@ EOF
if test "$build_old_libs" = yes; then
if test "$pic_mode" != yes; then
# Don't build PIC code
- command="$base_compile $srcfile"
+ command="$base_compile $qsrcfile"
else
- command="$base_compile $srcfile $pic_flag"
+ command="$base_compile $qsrcfile $pic_flag"
fi
if test "$compiler_c_o" = yes; then
command="$command -o $obj"
@@ -754,7 +1001,7 @@ EOF
if $run eval "$command"; then :
else
$run $rm $removelist
- exit 1
+ exit $EXIT_FAILURE
fi
if test "$need_locks" = warn &&
@@ -774,7 +1021,7 @@ avoid parallel builds (make -j) in this platform, or get a better
compiler."
$run $rm $removelist
- exit 1
+ exit $EXIT_FAILURE
fi
# Just move the object if needed
@@ -812,7 +1059,7 @@ EOF
$run $rm "$lockfile"
fi
- exit 0
+ exit $EXIT_SUCCESS
;;
# libtool link mode
@@ -838,7 +1085,7 @@ EOF
;;
esac
libtool_args="$nonopt"
- base_compile="$nonopt"
+ base_compile="$nonopt $@"
compile_command="$nonopt"
finalize_command="$nonopt"
@@ -870,6 +1117,8 @@ EOF
no_install=no
objs=
non_pic_objects=
+ notinst_path= # paths that contain not-installed libtool libraries
+ precious_files_regex=
prefer_static_libs=no
preload=no
prev=
@@ -883,6 +1132,8 @@ EOF
vinfo=
vinfo_number=no
+ func_infer_tag $base_compile
+
# We need to know -static, to get the right output filenames.
for arg
do
@@ -895,14 +1146,15 @@ EOF
if test -n "$link_static_flag"; then
dlopen_self=$dlopen_self_static
fi
+ prefer_static_libs=yes
else
if test -z "$pic_flag" && test -n "$link_static_flag"; then
dlopen_self=$dlopen_self_static
fi
+ prefer_static_libs=built
fi
build_libtool_libs=no
build_old_libs=yes
- prefer_static_libs=yes
break
;;
esac
@@ -914,7 +1166,6 @@ EOF
# Go through the arguments, transforming them on the way.
while test "$#" -gt 0; do
arg="$1"
- base_compile="$base_compile $arg"
shift
case $arg in
*[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
@@ -978,7 +1229,7 @@ EOF
export_symbols="$arg"
if test ! -f "$arg"; then
$echo "$modename: symbol file \`$arg' does not exist"
- exit 1
+ exit $EXIT_FAILURE
fi
prev=
continue
@@ -993,6 +1244,11 @@ EOF
prev=
continue
;;
+ precious_regex)
+ precious_files_regex="$arg"
+ prev=
+ continue
+ ;;
release)
release="-$arg"
prev=
@@ -1025,7 +1281,7 @@ EOF
test "$pic_object" = none && \
test "$non_pic_object" = none; then
$echo "$modename: cannot find name of object for \`$arg'" 1>&2
- exit 1
+ exit $EXIT_FAILURE
fi
# Extract subdirectory from the argument.
@@ -1073,12 +1329,17 @@ EOF
if test -z "$pic_object" || test "$pic_object" = none ; then
arg="$non_pic_object"
fi
+ else
+ # If the PIC object exists, use it instead.
+ # $xdir was prepended to $pic_object above.
+ non_pic_object="$pic_object"
+ non_pic_objects="$non_pic_objects $non_pic_object"
fi
else
# Only an error if not doing a dry-run.
if test -z "$run"; then
$echo "$modename: \`$arg' is not a valid libtool object" 1>&2
- exit 1
+ exit $EXIT_FAILURE
else
# Dry-run case.
@@ -1099,7 +1360,7 @@ EOF
done
else
$echo "$modename: link input file \`$save_arg' does not exist"
- exit 1
+ exit $EXIT_FAILURE
fi
arg=$save_arg
prev=
@@ -1111,7 +1372,7 @@ EOF
[\\/]* | [A-Za-z]:[\\/]*) ;;
*)
$echo "$modename: only absolute run-paths are allowed" 1>&2
- exit 1
+ exit $EXIT_FAILURE
;;
esac
if test "$prev" = rpath; then
@@ -1151,6 +1412,18 @@ EOF
finalize_command="$finalize_command $qarg"
continue
;;
+ shrext)
+ shrext_cmds="$arg"
+ prev=
+ continue
+ ;;
+ darwin_framework|darwin_framework_skip)
+ test "$prev" = "darwin_framework" && compiler_flags="$compiler_flags $arg"
+ compile_command="$compile_command $arg"
+ finalize_command="$finalize_command $arg"
+ prev=
+ continue
+ ;;
*)
eval "$prev=\"\$arg\""
prev=
@@ -1199,7 +1472,7 @@ EOF
-export-symbols | -export-symbols-regex)
if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
$echo "$modename: more than one -exported-symbols argument is not allowed"
- exit 1
+ exit $EXIT_FAILURE
fi
if test "X$arg" = "X-export-symbols"; then
prev=expsyms
@@ -1209,6 +1482,18 @@ EOF
continue
;;
+ -framework|-arch|-isysroot)
+ case " $CC " in
+ *" ${arg} ${1} "* | *" ${arg} ${1} "*)
+ prev=darwin_framework_skip ;;
+ *) compiler_flags="$compiler_flags $arg"
+ prev=darwin_framework ;;
+ esac
+ compile_command="$compile_command $arg"
+ finalize_command="$finalize_command $arg"
+ continue
+ ;;
+
-inst-prefix-dir)
prev=inst_prefix
continue
@@ -1235,7 +1520,8 @@ EOF
absdir=`cd "$dir" && pwd`
if test -z "$absdir"; then
$echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2
- exit 1
+ absdir="$dir"
+ notinst_path="$notinst_path $dir"
fi
dir="$absdir"
;;
@@ -1249,10 +1535,15 @@ EOF
esac
case $host in
*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
+ testbindir=`$echo "X$dir" | $Xsed -e 's*/lib$*/bin*'`
case :$dllsearchpath: in
*":$dir:"*) ;;
*) dllsearchpath="$dllsearchpath:$dir";;
esac
+ case :$dllsearchpath: in
+ *":$testbindir:"*) ;;
+ *) dllsearchpath="$dllsearchpath:$testbindir";;
+ esac
;;
esac
continue
@@ -1261,15 +1552,15 @@ EOF
-l*)
if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then
case $host in
- *-*-cygwin* | *-*-pw32* | *-*-beos*)
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos*)
# These systems don't actually have a C or math library (as such)
continue
;;
- *-*-mingw* | *-*-os2*)
+ *-*-os2*)
# These systems don't actually have a C library (as such)
test "X$arg" = "X-lc" && continue
;;
- *-*-openbsd* | *-*-freebsd*)
+ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
# Do not include libc due to us having libc/libc_r.
test "X$arg" = "X-lc" && continue
;;
@@ -1277,10 +1568,19 @@ EOF
# Rhapsody C and math libraries are in the System framework
deplibs="$deplibs -framework System"
continue
+ ;;
+ *-*-sco3.2v5* | *-*-sco5v6*)
+ # Causes problems with __ctype
+ test "X$arg" = "X-lc" && continue
+ ;;
+ *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+ # Compiler inserts libc in the correct place for threads to work
+ test "X$arg" = "X-lc" && continue
+ ;;
esac
elif test "X$arg" = "X-lc_r"; then
case $host in
- *-*-openbsd* | *-*-freebsd*)
+ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
# Do not include libc_r directly, use -pthread flag.
continue
;;
@@ -1290,18 +1590,41 @@ EOF
continue
;;
+ # Tru64 UNIX uses -model [arg] to determine the layout of C++
+ # classes, name mangling, and exception handling.
+ -model)
+ compile_command="$compile_command $arg"
+ compiler_flags="$compiler_flags $arg"
+ finalize_command="$finalize_command $arg"
+ prev=xcompiler
+ continue
+ ;;
+
+ -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe)
+ compiler_flags="$compiler_flags $arg"
+ compile_command="$compile_command $arg"
+ finalize_command="$finalize_command $arg"
+ continue
+ ;;
+
-module)
module=yes
continue
;;
- # gcc -m* arguments should be passed to the linker via $compiler_flags
- # in order to pass architecture information to the linker
- # (e.g. 32 vs 64-bit). This may also be accomplished via -Wl,-mfoo
- # but this is not reliable with gcc because gcc may use -mfoo to
- # select a different linker, different libraries, etc, while
- # -Wl,-mfoo simply passes -mfoo to the linker.
- -m*)
+ # -64, -mips[0-9] enable 64-bit mode on the SGI compiler
+ # -r[0-9][0-9]* specifies the processor on the SGI compiler
+ # -xarch=*, -xtarget=* enable 64-bit mode on the Sun compiler
+ # +DA*, +DD* enable 64-bit mode on the HP compiler
+ # -q* pass through compiler args for the IBM compiler
+ # -m* pass through architecture-specific compiler args for GCC
+ # -m*, -t[45]*, -txscale* pass through architecture-specific
+ # compiler args for GCC
+ # -pg pass through profiling flag for GCC
+ # @file GCC response files
+ -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*|-pg| \
+ -t[45]*|-txscale*|@*)
+
# Unknown arguments in both finalize_command and compile_command need
# to be aesthetically quoted because they are evaled later.
arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
@@ -1312,9 +1635,7 @@ EOF
esac
compile_command="$compile_command $arg"
finalize_command="$finalize_command $arg"
- if test "$with_gcc" = "yes" ; then
- compiler_flags="$compiler_flags $arg"
- fi
+ compiler_flags="$compiler_flags $arg"
continue
;;
@@ -1354,6 +1675,11 @@ EOF
-o) prev=output ;;
+ -precious-files-regex)
+ prev=precious_regex
+ continue
+ ;;
+
-release)
prev=release
continue
@@ -1376,7 +1702,7 @@ EOF
[\\/]* | [A-Za-z]:[\\/]*) ;;
*)
$echo "$modename: only absolute run-paths are allowed" 1>&2
- exit 1
+ exit $EXIT_FAILURE
;;
esac
case "$xrpath " in
@@ -1499,7 +1825,7 @@ EOF
test "$pic_object" = none && \
test "$non_pic_object" = none; then
$echo "$modename: cannot find name of object for \`$arg'" 1>&2
- exit 1
+ exit $EXIT_FAILURE
fi
# Extract subdirectory from the argument.
@@ -1547,12 +1873,17 @@ EOF
if test -z "$pic_object" || test "$pic_object" = none ; then
arg="$non_pic_object"
fi
+ else
+ # If the PIC object exists, use it instead.
+ # $xdir was prepended to $pic_object above.
+ non_pic_object="$pic_object"
+ non_pic_objects="$non_pic_objects $non_pic_object"
fi
else
# Only an error if not doing a dry-run.
if test -z "$run"; then
$echo "$modename: \`$arg' is not a valid libtool object" 1>&2
- exit 1
+ exit $EXIT_FAILURE
else
# Dry-run case.
@@ -1619,48 +1950,7 @@ EOF
if test -n "$prev"; then
$echo "$modename: the \`$prevarg' option requires an argument" 1>&2
$echo "$help" 1>&2
- exit 1
- fi
-
- # Infer tagged configuration to use if any are available and
- # if one wasn't chosen via the "--tag" command line option.
- # Only attempt this if the compiler in the base link
- # command doesn't match the default compiler.
- if test -n "$available_tags" && test -z "$tagname"; then
- case $base_compile in
- # Blanks in the command may have been stripped by the calling shell,
- # but not from the CC environment variable when configure was run.
- "$CC "* | " $CC "* | "`$echo $CC` "* | " `$echo $CC` "*) ;;
- # Blanks at the start of $base_compile will cause this to fail
- # if we don't check for them as well.
- *)
- for z in $available_tags; do
- if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$0" > /dev/null; then
- # Evaluate the configuration.
- eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $0`"
- case $base_compile in
- "$CC "* | " $CC "* | "`$echo $CC` "* | " `$echo $CC` "*)
- # The compiler in $compile_command matches
- # the one in the tagged configuration.
- # Assume this is the tagged configuration we want.
- tagname=$z
- break
- ;;
- esac
- fi
- done
- # If $tagname still isn't set, then no tagged configuration
- # was found and let the user know that the "--tag" command
- # line option must be used.
- if test -z "$tagname"; then
- $echo "$modename: unable to infer tagged configuration"
- $echo "$modename: specify a tag with \`--tag'" 1>&2
- exit 1
-# else
-# $echo "$modename: using $tagname tagged configuration"
- fi
- ;;
- esac
+ exit $EXIT_FAILURE
fi
if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then
@@ -1693,9 +1983,9 @@ EOF
if test ! -d "$output_objdir"; then
$show "$mkdir $output_objdir"
$run $mkdir $output_objdir
- status=$?
- if test "$status" -ne 0 && test ! -d "$output_objdir"; then
- exit $status
+ exit_status=$?
+ if test "$exit_status" -ne 0 && test ! -d "$output_objdir"; then
+ exit $exit_status
fi
fi
@@ -1704,7 +1994,7 @@ EOF
"")
$echo "$modename: you must specify an output file" 1>&2
$echo "$help" 1>&2
- exit 1
+ exit $EXIT_FAILURE
;;
*.$libext) linkmode=oldlib ;;
*.lo | *.$objext) linkmode=obj ;;
@@ -1714,7 +2004,7 @@ EOF
case $host in
*cygwin* | *mingw* | *pw32*)
- # don't eliminate duplcations in $postdeps and $predeps
+ # don't eliminate duplications in $postdeps and $predeps
duplicate_compiler_generated_deps=yes
;;
*)
@@ -1758,7 +2048,6 @@ EOF
newlib_search_path=
need_relink=no # whether we're linking any uninstalled libtool libraries
notinst_deplibs= # not-installed libtool libraries
- notinst_path= # paths that contain not-installed libtool libraries
case $linkmode in
lib)
passes="conv link"
@@ -1767,7 +2056,7 @@ EOF
*.la) ;;
*)
$echo "$modename: libraries can \`-dlopen' only libtool libraries: $file" 1>&2
- exit 1
+ exit $EXIT_FAILURE
;;
esac
done
@@ -1793,7 +2082,10 @@ EOF
case $pass in
dlopen) libs="$dlfiles" ;;
dlpreopen) libs="$dlprefiles" ;;
- link) libs="$deplibs %DEPLIBS% $dependency_libs" ;;
+ link)
+ libs="$deplibs %DEPLIBS%"
+ test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs"
+ ;;
esac
fi
if test "$pass" = dlopen; then
@@ -1805,23 +2097,34 @@ EOF
lib=
found=no
case $deplib in
+ -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe)
+ if test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ compiler_flags="$compiler_flags $deplib"
+ fi
+ continue
+ ;;
-l*)
if test "$linkmode" != lib && test "$linkmode" != prog; then
$echo "$modename: warning: \`-l' is ignored for archives/objects" 1>&2
continue
fi
- if test "$pass" = conv; then
- deplibs="$deplib $deplibs"
- continue
- fi
name=`$echo "X$deplib" | $Xsed -e 's/^-l//'`
for searchdir in $newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path; do
- # Search the libtool library
- lib="$searchdir/lib${name}.la"
- if test -f "$lib"; then
- found=yes
- break
- fi
+ for search_ext in .la $std_shrext .so .a; do
+ # Search the libtool library
+ lib="$searchdir/lib${name}${search_ext}"
+ if test -f "$lib"; then
+ if test "$search_ext" = ".la"; then
+ found=yes
+ else
+ found=no
+ fi
+ break 2
+ fi
+ done
done
if test "$found" != yes; then
# deplib doesn't seem to be a libtool library
@@ -1886,11 +2189,11 @@ EOF
fi
if test "$pass" = scan; then
deplibs="$deplib $deplibs"
- newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`
else
compile_deplibs="$deplib $compile_deplibs"
finalize_deplibs="$deplib $finalize_deplibs"
fi
+ newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`
;;
*)
$echo "$modename: warning: \`-L' is ignored for archives/objects" 1>&2
@@ -1918,7 +2221,22 @@ EOF
fi
case $linkmode in
lib)
- if test "$deplibs_check_method" != pass_all; then
+ valid_a_lib=no
+ case $deplibs_check_method in
+ match_pattern*)
+ set dummy $deplibs_check_method
+ match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"`
+ if eval $echo \"$deplib\" 2>/dev/null \
+ | $SED 10q \
+ | $EGREP "$match_pattern_regex" > /dev/null; then
+ valid_a_lib=yes
+ fi
+ ;;
+ pass_all)
+ valid_a_lib=yes
+ ;;
+ esac
+ if test "$valid_a_lib" != yes; then
$echo
$echo "*** Warning: Trying to link with static lib archive $deplib."
$echo "*** I have the capability to make that library automatically link in when"
@@ -1968,15 +2286,15 @@ EOF
esac # case $deplib
if test "$found" = yes || test -f "$lib"; then :
else
- $echo "$modename: cannot find the library \`$lib'" 1>&2
- exit 1
+ $echo "$modename: cannot find the library \`$lib' or unhandled argument \`$deplib'" 1>&2
+ exit $EXIT_FAILURE
fi
# Check to see that this really is a libtool archive.
if (${SED} -e '2q' $lib | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
else
$echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
- exit 1
+ exit $EXIT_FAILURE
fi
ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'`
@@ -1992,6 +2310,8 @@ EOF
# it will not redefine variables installed, or shouldnotlink
installed=yes
shouldnotlink=no
+ avoidtemprpath=
+
# Read the .la file
case $lib in
@@ -2012,7 +2332,7 @@ EOF
if test -z "$libdir"; then
if test -z "$old_library"; then
$echo "$modename: cannot find name of link library for \`$lib'" 1>&2
- exit 1
+ exit $EXIT_FAILURE
fi
# It is a libtool convenience library, so add in its objects.
convenience="$convenience $ladir/$objdir/$old_library"
@@ -2029,12 +2349,12 @@ EOF
done
elif test "$linkmode" != prog && test "$linkmode" != lib; then
$echo "$modename: \`$lib' is not a convenience library" 1>&2
- exit 1
+ exit $EXIT_FAILURE
fi
continue
fi # $pass = conv
-
+
# Get the name of the library we link against.
linklib=
for l in $old_library $library_names; do
@@ -2042,16 +2362,18 @@ EOF
done
if test -z "$linklib"; then
$echo "$modename: cannot find name of link library for \`$lib'" 1>&2
- exit 1
+ exit $EXIT_FAILURE
fi
# This library was specified with -dlopen.
if test "$pass" = dlopen; then
if test -z "$libdir"; then
$echo "$modename: cannot -dlopen a convenience library: \`$lib'" 1>&2
- exit 1
+ exit $EXIT_FAILURE
fi
- if test -z "$dlname" || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then
+ if test -z "$dlname" ||
+ test "$dlopen_support" != yes ||
+ test "$build_libtool_libs" = no; then
# If there is no dlname, no dlopen support or we're linking
# statically, we need to preload. We also need to preload any
# dependent libraries so libltdl's deplib preloader doesn't
@@ -2088,11 +2410,19 @@ EOF
dir="$libdir"
absdir="$libdir"
fi
+ test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes
else
- dir="$ladir/$objdir"
- absdir="$abs_ladir/$objdir"
- # Remove this search path later
- notinst_path="$notinst_path $abs_ladir"
+ if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+ dir="$ladir"
+ absdir="$abs_ladir"
+ # Remove this search path later
+ notinst_path="$notinst_path $abs_ladir"
+ else
+ dir="$ladir/$objdir"
+ absdir="$abs_ladir/$objdir"
+ # Remove this search path later
+ notinst_path="$notinst_path $abs_ladir"
+ fi
fi # $installed = yes
name=`$echo "X$laname" | $Xsed -e 's/\.la$//' -e 's/^lib//'`
@@ -2100,7 +2430,7 @@ EOF
if test "$pass" = dlpreopen; then
if test -z "$libdir"; then
$echo "$modename: cannot -dlpreopen a convenience library: \`$lib'" 1>&2
- exit 1
+ exit $EXIT_FAILURE
fi
# Prefer using a static library (so that no silly _DYNAMIC symbols
# are required to link).
@@ -2127,7 +2457,7 @@ EOF
continue
fi
-
+
if test "$linkmode" = prog && test "$pass" != link; then
newlib_search_path="$newlib_search_path $ladir"
deplibs="$lib $deplibs"
@@ -2165,12 +2495,12 @@ EOF
if test -n "$library_names" &&
{ test "$prefer_static_libs" = no || test -z "$old_library"; }; then
# We need to hardcode the library path
- if test -n "$shlibpath_var"; then
+ if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then
# Make sure the rpath contains only unique directories.
case "$temp_rpath " in
*" $dir "*) ;;
*" $absdir "*) ;;
- *) temp_rpath="$temp_rpath $dir" ;;
+ *) temp_rpath="$temp_rpath $absdir" ;;
esac
fi
@@ -2207,24 +2537,29 @@ EOF
fi
link_static=no # Whether the deplib will be linked statically
+ use_static_libs=$prefer_static_libs
+ if test "$use_static_libs" = built && test "$installed" = yes ; then
+ use_static_libs=no
+ fi
if test -n "$library_names" &&
- { test "$prefer_static_libs" = no || test -z "$old_library"; }; then
+ { test "$use_static_libs" = no || test -z "$old_library"; }; then
if test "$installed" = no; then
notinst_deplibs="$notinst_deplibs $lib"
need_relink=yes
fi
# This is a shared library
-
- # Warn about portability, can't link against -module's on some systems (darwin)
- if test "$shouldnotlink" = yes && test "$pass" = link ; then
+
+ # Warn about portability, can't link against -module's on
+ # some systems (darwin)
+ if test "$shouldnotlink" = yes && test "$pass" = link ; then
$echo
if test "$linkmode" = prog; then
$echo "*** Warning: Linking the executable $output against the loadable module"
else
$echo "*** Warning: Linking the shared library $output against the loadable module"
fi
- $echo "*** $linklib is not portable!"
- fi
+ $echo "*** $linklib is not portable!"
+ fi
if test "$linkmode" = lib &&
test "$hardcode_into_libs" = yes; then
# Hardcode the library path.
@@ -2282,9 +2617,10 @@ EOF
else
$show "extracting exported symbol list from \`$soname'"
save_ifs="$IFS"; IFS='~'
- eval cmds=\"$extract_expsyms_cmds\"
+ cmds=$extract_expsyms_cmds
for cmd in $cmds; do
IFS="$save_ifs"
+ eval cmd=\"$cmd\"
$show "$cmd"
$run eval "$cmd" || exit $?
done
@@ -2295,9 +2631,10 @@ EOF
if test -f "$output_objdir/$newlib"; then :; else
$show "generating import library for \`$soname'"
save_ifs="$IFS"; IFS='~'
- eval cmds=\"$old_archive_from_expsyms_cmds\"
+ cmds=$old_archive_from_expsyms_cmds
for cmd in $cmds; do
IFS="$save_ifs"
+ eval cmd=\"$cmd\"
$show "$cmd"
$run eval "$cmd" || exit $?
done
@@ -2318,11 +2655,15 @@ EOF
if test "$hardcode_direct" = no; then
add="$dir/$linklib"
case $host in
- *-*-sco3.2v5* ) add_dir="-L$dir" ;;
+ *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;;
+ *-*-sysv4*uw2*) add_dir="-L$dir" ;;
+ *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \
+ *-*-unixware7*) add_dir="-L$dir" ;;
*-*-darwin* )
- # if the lib is a module then we can not link against it, someone
- # is ignoring the new warnings I added
- if /usr/bin/file -L $add 2> /dev/null | grep "bundle" >/dev/null ; then
+ # if the lib is a module then we can not link against
+ # it, someone is ignoring the new warnings I added
+ if /usr/bin/file -L $add 2> /dev/null |
+ $EGREP ": [^:]* bundle" >/dev/null ; then
$echo "** Warning, lib $linklib is a module, not a shared library"
if test -z "$old_library" ; then
$echo
@@ -2330,7 +2671,7 @@ EOF
$echo "** The link will probably fail, sorry"
else
add="$dir/$old_library"
- fi
+ fi
fi
esac
elif test "$hardcode_minus_L" = no; then
@@ -2353,7 +2694,7 @@ EOF
add_dir="-L$dir"
# Try looking first in the location we're being installed to.
if test -n "$inst_prefix_dir"; then
- case "$libdir" in
+ case $libdir in
[\\/]*)
add_dir="$add_dir -L$inst_prefix_dir$libdir"
;;
@@ -2372,7 +2713,7 @@ EOF
if test "$lib_linked" != yes; then
$echo "$modename: configuration error: unsupported hardcode properties"
- exit 1
+ exit $EXIT_FAILURE
fi
if test -n "$add_shlibpath"; then
@@ -2415,7 +2756,8 @@ EOF
esac
add="-l$name"
elif test "$hardcode_automatic" = yes; then
- if test -n "$inst_prefix_dir" && test -f "$inst_prefix_dir$libdir/$linklib" ; then
+ if test -n "$inst_prefix_dir" &&
+ test -f "$inst_prefix_dir$libdir/$linklib" ; then
add="$inst_prefix_dir$libdir/$linklib"
else
add="$libdir/$linklib"
@@ -2425,7 +2767,7 @@ EOF
add_dir="-L$libdir"
# Try looking first in the location we're being installed to.
if test -n "$inst_prefix_dir"; then
- case "$libdir" in
+ case $libdir in
[\\/]*)
add_dir="$add_dir -L$inst_prefix_dir$libdir"
;;
@@ -2486,8 +2828,6 @@ EOF
fi
fi
else
- convenience="$convenience $dir/$old_library"
- old_convenience="$old_convenience $dir/$old_library"
deplibs="$dir/$old_library $deplibs"
link_static=yes
fi
@@ -2495,7 +2835,8 @@ EOF
if test "$linkmode" = lib; then
if test -n "$dependency_libs" &&
- { test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes ||
+ { test "$hardcode_into_libs" != yes ||
+ test "$build_old_libs" = yes ||
test "$link_static" = yes; }; then
# Extract -R from dependency_libs
temp_deplibs=
@@ -2552,7 +2893,7 @@ EOF
eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
if test -z "$libdir"; then
$echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2
- exit 1
+ exit $EXIT_FAILURE
fi
if test "$absdir" != "$libdir"; then
$echo "$modename: warning: \`$deplib' seems to be moved" 1>&2
@@ -2562,7 +2903,8 @@ EOF
depdepl=
case $host in
*-*-darwin*)
- # we do not want to link against static libs, but need to link against shared
+ # we do not want to link against static libs,
+ # but need to link against shared
eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
if test -n "$deplibrary_names" ; then
for tmp in $deplibrary_names ; do
@@ -2570,42 +2912,45 @@ EOF
done
if test -f "$path/$depdepl" ; then
depdepl="$path/$depdepl"
- fi
- newlib_search_path="$newlib_search_path $path"
- path=""
+ fi
+ # do not add paths which are already there
+ case " $newlib_search_path " in
+ *" $path "*) ;;
+ *) newlib_search_path="$newlib_search_path $path";;
+ esac
fi
+ path=""
;;
*)
- path="-L$path"
- ;;
- esac
-
+ path="-L$path"
+ ;;
+ esac
;;
- -l*)
+ -l*)
case $host in
*-*-darwin*)
- # Again, we only want to link against shared libraries
- eval tmp_libs=`$echo "X$deplib" | $Xsed -e "s,^\-l,,"`
- for tmp in $newlib_search_path ; do
- if test -f "$tmp/lib$tmp_libs.dylib" ; then
- eval depdepl="$tmp/lib$tmp_libs.dylib"
- break
- fi
- done
- path=""
+ # Again, we only want to link against shared libraries
+ eval tmp_libs=`$echo "X$deplib" | $Xsed -e "s,^\-l,,"`
+ for tmp in $newlib_search_path ; do
+ if test -f "$tmp/lib$tmp_libs.dylib" ; then
+ eval depdepl="$tmp/lib$tmp_libs.dylib"
+ break
+ fi
+ done
+ path=""
;;
*) continue ;;
- esac
+ esac
;;
*) continue ;;
esac
case " $deplibs " in
- *" $depdepl "*) ;;
- *) deplibs="$deplibs $depdepl" ;;
- esac
- case " $deplibs " in
*" $path "*) ;;
- *) deplibs="$deplibs $path" ;;
+ *) deplibs="$path $deplibs" ;;
+ esac
+ case " $deplibs " in
+ *" $depdepl "*) ;;
+ *) deplibs="$depdepl $deplibs" ;;
esac
done
fi # link_all_deplibs != no
@@ -2692,7 +3037,8 @@ EOF
eval $var=\"$tmp_libs\"
done # for var
fi
- # Last step: remove runtime libs from dependency_libs (they stay in deplibs)
+ # Last step: remove runtime libs from dependency_libs
+ # (they stay in deplibs)
tmp_libs=
for i in $dependency_libs ; do
case " $predeps $postdeps $compiler_lib_search_path " in
@@ -2752,19 +3098,19 @@ EOF
case $outputname in
lib*)
name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'`
- eval shared_ext=\"$shrext\"
+ eval shared_ext=\"$shrext_cmds\"
eval libname=\"$libname_spec\"
;;
*)
if test "$module" = no; then
$echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2
$echo "$help" 1>&2
- exit 1
+ exit $EXIT_FAILURE
fi
if test "$need_lib_prefix" != no; then
# Add the "lib" prefix for modules if required
name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'`
- eval shared_ext=\"$shrext\"
+ eval shared_ext=\"$shrext_cmds\"
eval libname=\"$libname_spec\"
else
libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'`
@@ -2775,7 +3121,7 @@ EOF
if test -n "$objs"; then
if test "$deplibs_check_method" != pass_all; then
$echo "$modename: cannot build libtool library \`$output' from non-libtool objects on this host:$objs" 2>&1
- exit 1
+ exit $EXIT_FAILURE
else
$echo
$echo "*** Warning: Linking the shared library $output against the non-libtool"
@@ -2823,13 +3169,13 @@ EOF
if test -n "$8"; then
$echo "$modename: too many parameters to \`-version-info'" 1>&2
$echo "$help" 1>&2
- exit 1
+ exit $EXIT_FAILURE
fi
# convert absolute version numbers to libtool ages
# this retains compatibility with .la files and attempts
# to make the code below a bit more comprehensible
-
+
case $vinfo_number in
yes)
number_major="$2"
@@ -2858,6 +3204,11 @@ EOF
age="$number_minor"
revision="$number_minor"
;;
+ *)
+ $echo "$modename: unknown library version type \`$version_type'" 1>&2
+ $echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2
+ exit $EXIT_FAILURE
+ ;;
esac
;;
no)
@@ -2869,36 +3220,36 @@ EOF
# Check that each of the things are valid numbers.
case $current in
- [0-9]*) ;;
+ 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
*)
- $echo "$modename: CURRENT \`$current' is not a nonnegative integer" 1>&2
+ $echo "$modename: CURRENT \`$current' must be a nonnegative integer" 1>&2
$echo "$modename: \`$vinfo' is not valid version information" 1>&2
- exit 1
+ exit $EXIT_FAILURE
;;
esac
case $revision in
- [0-9]*) ;;
+ 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
*)
- $echo "$modename: REVISION \`$revision' is not a nonnegative integer" 1>&2
+ $echo "$modename: REVISION \`$revision' must be a nonnegative integer" 1>&2
$echo "$modename: \`$vinfo' is not valid version information" 1>&2
- exit 1
+ exit $EXIT_FAILURE
;;
esac
case $age in
- [0-9]*) ;;
+ 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
*)
- $echo "$modename: AGE \`$age' is not a nonnegative integer" 1>&2
+ $echo "$modename: AGE \`$age' must be a nonnegative integer" 1>&2
$echo "$modename: \`$vinfo' is not valid version information" 1>&2
- exit 1
+ exit $EXIT_FAILURE
;;
esac
if test "$age" -gt "$current"; then
$echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2
$echo "$modename: \`$vinfo' is not valid version information" 1>&2
- exit 1
+ exit $EXIT_FAILURE
fi
# Calculate the version variables.
@@ -2915,7 +3266,7 @@ EOF
versuffix="$major.$age.$revision"
# Darwin ld doesn't like 0 for these options...
minor_current=`expr $current + 1`
- verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
+ verstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision"
;;
freebsd-aout)
@@ -2987,7 +3338,7 @@ EOF
*)
$echo "$modename: unknown library version type \`$version_type'" 1>&2
$echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2
- exit 1
+ exit $EXIT_FAILURE
;;
esac
@@ -3041,6 +3392,12 @@ EOF
*.$objext)
;;
$output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*)
+ if test "X$precious_files_regex" != "X"; then
+ if echo $p | $EGREP -e "$precious_files_regex" >/dev/null 2>&1
+ then
+ continue
+ fi
+ fi
removelist="$removelist $p"
;;
*) ;;
@@ -3062,9 +3419,9 @@ EOF
# Eliminate all temporary directories.
for path in $notinst_path; do
- lib_search_path=`$echo "$lib_search_path " | ${SED} -e 's% $path % %g'`
- deplibs=`$echo "$deplibs " | ${SED} -e 's% -L$path % %g'`
- dependency_libs=`$echo "$dependency_libs " | ${SED} -e 's% -L$path % %g'`
+ lib_search_path=`$echo "$lib_search_path " | ${SED} -e "s% $path % %g"`
+ deplibs=`$echo "$deplibs " | ${SED} -e "s% -L$path % %g"`
+ dependency_libs=`$echo "$dependency_libs " | ${SED} -e "s% -L$path % %g"`
done
if test -n "$xrpath"; then
@@ -3115,9 +3472,14 @@ EOF
*-*-netbsd*)
# Don't link with libc until the a.out ld.so is fixed.
;;
- *-*-openbsd* | *-*-freebsd*)
+ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
# Do not include libc due to us having libc/libc_r.
- test "X$arg" = "X-lc" && continue
+ ;;
+ *-*-sco3.2v5* | *-*-sco5v6*)
+ # Causes problems with __ctype
+ ;;
+ *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+ # Compiler inserts libc in the correct place for threads to work
;;
*)
# Add libc to deplibs on all other systems if necessary.
@@ -3161,11 +3523,11 @@ EOF
int main() { return 0; }
EOF
$rm conftest
- $LTCC -o conftest conftest.c $deplibs
+ $LTCC $LTCFLAGS -o conftest conftest.c $deplibs
if test "$?" -eq 0 ; then
ldd_output=`ldd conftest`
for i in $deplibs; do
- name="`expr $i : '-l\(.*\)'`"
+ name=`expr $i : '-l\(.*\)'`
# If $name is empty we are operating on a -L argument.
if test "$name" != "" && test "$name" -ne "0"; then
if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
@@ -3202,11 +3564,11 @@ EOF
# Error occurred in the first compile. Let's try to salvage
# the situation: Compile a separate program for each library.
for i in $deplibs; do
- name="`expr $i : '-l\(.*\)'`"
+ name=`expr $i : '-l\(.*\)'`
# If $name is empty we are operating on a -L argument.
if test "$name" != "" && test "$name" != "0"; then
$rm conftest
- $LTCC -o conftest conftest.c $i
+ $LTCC $LTCFLAGS -o conftest conftest.c $i
# Did it work?
if test "$?" -eq 0 ; then
ldd_output=`ldd conftest`
@@ -3254,7 +3616,7 @@ EOF
set dummy $deplibs_check_method
file_magic_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"`
for a_deplib in $deplibs; do
- name="`expr $a_deplib : '-l\(.*\)'`"
+ name=`expr $a_deplib : '-l\(.*\)'`
# If $name is empty we are operating on a -L argument.
if test "$name" != "" && test "$name" != "0"; then
if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
@@ -3323,7 +3685,7 @@ EOF
set dummy $deplibs_check_method
match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"`
for a_deplib in $deplibs; do
- name="`expr $a_deplib : '-l\(.*\)'`"
+ name=`expr $a_deplib : '-l\(.*\)'`
# If $name is empty we are operating on a -L argument.
if test -n "$name" && test "$name" != "0"; then
if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
@@ -3453,6 +3815,35 @@ EOF
deplibs=$newdeplibs
fi
+
+ # move library search paths that coincide with paths to not yet
+ # installed libraries to the beginning of the library search list
+ new_libs=
+ for path in $notinst_path; do
+ case " $new_libs " in
+ *" -L$path/$objdir "*) ;;
+ *)
+ case " $deplibs " in
+ *" -L$path/$objdir "*)
+ new_libs="$new_libs -L$path/$objdir" ;;
+ esac
+ ;;
+ esac
+ done
+ for deplib in $deplibs; do
+ case $deplib in
+ -L*)
+ case " $new_libs " in
+ *" $deplib "*) ;;
+ *) new_libs="$new_libs $deplib" ;;
+ esac
+ ;;
+ *) new_libs="$new_libs $deplib" ;;
+ esac
+ done
+ deplibs="$new_libs"
+
+
# All the library-specific variables (install_libdir is set above).
library_names=
old_library=
@@ -3520,7 +3911,7 @@ EOF
fi
# Get the real and link names of the library.
- eval shared_ext=\"$shrext\"
+ eval shared_ext=\"$shrext_cmds\"
eval library_names=\"$library_names_spec\"
set dummy $library_names
realname="$2"
@@ -3536,6 +3927,7 @@ EOF
fi
lib="$output_objdir/$realname"
+ linknames=
for link
do
linknames="$linknames $link"
@@ -3550,10 +3942,11 @@ EOF
$show "generating symbol list for \`$libname.la'"
export_symbols="$output_objdir/$libname.exp"
$run $rm $export_symbols
- eval cmds=\"$export_symbols_cmds\"
+ cmds=$export_symbols_cmds
save_ifs="$IFS"; IFS='~'
for cmd in $cmds; do
IFS="$save_ifs"
+ eval cmd=\"$cmd\"
if len=`expr "X$cmd" : ".*"` &&
test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then
$show "$cmd"
@@ -3563,6 +3956,9 @@ EOF
# The command line is too long to execute in one step.
$show "using reloadable object file for export list..."
skipped_export=:
+ # Break out early, otherwise skipped_export may be
+ # set to false by a later but shorter cmd.
+ break
fi
done
IFS="$save_ifs"
@@ -3583,12 +3979,12 @@ EOF
for test_deplib in $deplibs; do
case " $convenience " in
*" $test_deplib "*) ;;
- *)
+ *)
tmp_deplibs="$tmp_deplibs $test_deplib"
;;
esac
done
- deplibs="$tmp_deplibs"
+ deplibs="$tmp_deplibs"
if test -n "$convenience"; then
if test -n "$whole_archive_flag_spec"; then
@@ -3596,67 +3992,13 @@ EOF
eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
else
gentop="$output_objdir/${outputname}x"
- $show "${rm}r $gentop"
- $run ${rm}r "$gentop"
- $show "$mkdir $gentop"
- $run $mkdir "$gentop"
- status=$?
- if test "$status" -ne 0 && test ! -d "$gentop"; then
- exit $status
- fi
generated="$generated $gentop"
- for xlib in $convenience; do
- # Extract the objects.
- case $xlib in
- [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;;
- *) xabs=`pwd`"/$xlib" ;;
- esac
- xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'`
- xdir="$gentop/$xlib"
-
- $show "${rm}r $xdir"
- $run ${rm}r "$xdir"
- $show "$mkdir $xdir"
- $run $mkdir "$xdir"
- status=$?
- if test "$status" -ne 0 && test ! -d "$xdir"; then
- exit $status
- fi
- # We will extract separately just the conflicting names and we will no
- # longer touch any unique names. It is faster to leave these extract
- # automatically by $AR in one run.
- $show "(cd $xdir && $AR x $xabs)"
- $run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
- if ($AR t "$xabs" | sort | sort -uc >/dev/null 2>&1); then
- :
- else
- $echo "$modename: warning: object name conflicts; renaming object files" 1>&2
- $echo "$modename: warning: to ensure that they will not overwrite" 1>&2
- $AR t "$xabs" | sort | uniq -cd | while read -r count name
- do
- i=1
- while test "$i" -le "$count"
- do
- # Put our $i before any first dot (extension)
- # Never overwrite any file
- name_to="$name"
- while test "X$name_to" = "X$name" || test -f "$xdir/$name_to"
- do
- name_to=`$echo "X$name_to" | $Xsed -e "s/\([^.]*\)/\1-$i/"`
- done
- $show "(cd $xdir && $AR xN $i $xabs '$name' && $mv '$name' '$name_to')"
- $run eval "(cd \$xdir && $AR xN $i \$xabs '$name' && $mv '$name' '$name_to')" || exit $?
- i=`expr $i + 1`
- done
- done
- fi
-
- libobjs="$libobjs "`find $xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP`
- done
+ func_extract_archives $gentop $convenience
+ libobjs="$libobjs $func_extract_archives_result"
fi
fi
-
+
if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then
eval flag=\"$thread_safe_flag_spec\"
linker_flags="$linker_flags $flag"
@@ -3670,19 +4012,24 @@ EOF
# Do each of the archive commands.
if test "$module" = yes && test -n "$module_cmds" ; then
if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
- eval cmds=\"$module_expsym_cmds\"
+ eval test_cmds=\"$module_expsym_cmds\"
+ cmds=$module_expsym_cmds
else
- eval cmds=\"$module_cmds\"
+ eval test_cmds=\"$module_cmds\"
+ cmds=$module_cmds
fi
else
if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
- eval cmds=\"$archive_expsym_cmds\"
+ eval test_cmds=\"$archive_expsym_cmds\"
+ cmds=$archive_expsym_cmds
else
- eval cmds=\"$archive_cmds\"
+ eval test_cmds=\"$archive_cmds\"
+ cmds=$archive_cmds
fi
fi
- if test "X$skipped_export" != "X:" && len=`expr "X$cmds" : ".*"` &&
+ if test "X$skipped_export" != "X:" &&
+ len=`expr "X$test_cmds" : ".*" 2>/dev/null` &&
test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then
:
else
@@ -3701,6 +4048,7 @@ EOF
save_libobjs=$libobjs
fi
save_output=$output
+ output_la=`$echo "X$output" | $Xsed -e "$basename"`
# Clear the reloadable object creation command queue and
# initialize k to one.
@@ -3710,13 +4058,13 @@ EOF
delfiles=
last_robj=
k=1
- output=$output_objdir/$save_output-${k}.$objext
+ output=$output_objdir/$output_la-${k}.$objext
# Loop over the list of objects to be linked.
for obj in $save_libobjs
do
eval test_cmds=\"$reload_cmds $objlist $last_robj\"
if test "X$objlist" = X ||
- { len=`expr "X$test_cmds" : ".*"` &&
+ { len=`expr "X$test_cmds" : ".*" 2>/dev/null` &&
test "$len" -le "$max_cmd_len"; }; then
objlist="$objlist $obj"
else
@@ -3730,9 +4078,9 @@ EOF
# the last one created.
eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj\"
fi
- last_robj=$output_objdir/$save_output-${k}.$objext
+ last_robj=$output_objdir/$output_la-${k}.$objext
k=`expr $k + 1`
- output=$output_objdir/$save_output-${k}.$objext
+ output=$output_objdir/$output_la-${k}.$objext
objlist=$obj
len=1
fi
@@ -3752,13 +4100,13 @@ EOF
eval concat_cmds=\"\$concat_cmds~$export_symbols_cmds\"
fi
- # Set up a command to remove the reloadale object files
+ # Set up a command to remove the reloadable object files
# after they are used.
i=0
while test "$i" -lt "$k"
do
i=`expr $i + 1`
- delfiles="$delfiles $output_objdir/$save_output-${i}.$objext"
+ delfiles="$delfiles $output_objdir/$output_la-${i}.$objext"
done
$echo "creating a temporary reloadable object file: $output"
@@ -3783,28 +4131,54 @@ EOF
# value of $libobjs for piecewise linking.
# Do each of the archive commands.
+ if test "$module" = yes && test -n "$module_cmds" ; then
+ if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+ cmds=$module_expsym_cmds
+ else
+ cmds=$module_cmds
+ fi
+ else
if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
- eval cmds=\"$archive_expsym_cmds\"
+ cmds=$archive_expsym_cmds
else
- eval cmds=\"$archive_cmds\"
+ cmds=$archive_cmds
+ fi
fi
# Append the command to remove the reloadable object files
# to the just-reset $cmds.
- eval cmds=\"\$cmds~$rm $delfiles\"
+ eval cmds=\"\$cmds~\$rm $delfiles\"
fi
save_ifs="$IFS"; IFS='~'
for cmd in $cmds; do
IFS="$save_ifs"
+ eval cmd=\"$cmd\"
$show "$cmd"
- $run eval "$cmd" || exit $?
+ $run eval "$cmd" || {
+ lt_exit=$?
+
+ # Restore the uninstalled library and exit
+ if test "$mode" = relink; then
+ $run eval '(cd $output_objdir && $rm ${realname}T && $mv ${realname}U $realname)'
+ fi
+
+ exit $lt_exit
+ }
done
IFS="$save_ifs"
# Restore the uninstalled library and exit
if test "$mode" = relink; then
$run eval '(cd $output_objdir && $rm ${realname}T && $mv $realname ${realname}T && $mv "$realname"U $realname)' || exit $?
- exit 0
+
+ if test -n "$convenience"; then
+ if test -z "$whole_archive_flag_spec"; then
+ $show "${rm}r $gentop"
+ $run ${rm}r "$gentop"
+ fi
+ fi
+
+ exit $EXIT_SUCCESS
fi
# Create links to the real library.
@@ -3852,7 +4226,7 @@ EOF
*.lo)
if test -n "$objs$old_deplibs"; then
$echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2
- exit 1
+ exit $EXIT_FAILURE
fi
libobj="$output"
obj=`$echo "X$output" | $Xsed -e "$lo2o"`
@@ -3881,64 +4255,10 @@ EOF
eval reload_conv_objs=\"\$reload_objs $whole_archive_flag_spec\"
else
gentop="$output_objdir/${obj}x"
- $show "${rm}r $gentop"
- $run ${rm}r "$gentop"
- $show "$mkdir $gentop"
- $run $mkdir "$gentop"
- status=$?
- if test "$status" -ne 0 && test ! -d "$gentop"; then
- exit $status
- fi
generated="$generated $gentop"
- for xlib in $convenience; do
- # Extract the objects.
- case $xlib in
- [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;;
- *) xabs=`pwd`"/$xlib" ;;
- esac
- xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'`
- xdir="$gentop/$xlib"
-
- $show "${rm}r $xdir"
- $run ${rm}r "$xdir"
- $show "$mkdir $xdir"
- $run $mkdir "$xdir"
- status=$?
- if test "$status" -ne 0 && test ! -d "$xdir"; then
- exit $status
- fi
- # We will extract separately just the conflicting names and we will no
- # longer touch any unique names. It is faster to leave these extract
- # automatically by $AR in one run.
- $show "(cd $xdir && $AR x $xabs)"
- $run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
- if ($AR t "$xabs" | sort | sort -uc >/dev/null 2>&1); then
- :
- else
- $echo "$modename: warning: object name conflicts; renaming object files" 1>&2
- $echo "$modename: warning: to ensure that they will not overwrite" 1>&2
- $AR t "$xabs" | sort | uniq -cd | while read -r count name
- do
- i=1
- while test "$i" -le "$count"
- do
- # Put our $i before any first dot (extension)
- # Never overwrite any file
- name_to="$name"
- while test "X$name_to" = "X$name" || test -f "$xdir/$name_to"
- do
- name_to=`$echo "X$name_to" | $Xsed -e "s/\([^.]*\)/\1-$i/"`
- done
- $show "(cd $xdir && $AR xN $i $xabs '$name' && $mv '$name' '$name_to')"
- $run eval "(cd \$xdir && $AR xN $i \$xabs '$name' && $mv '$name' '$name_to')" || exit $?
- i=`expr $i + 1`
- done
- done
- fi
-
- reload_conv_objs="$reload_objs "`find $xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP`
- done
+ func_extract_archives $gentop $convenience
+ reload_conv_objs="$reload_objs $func_extract_archives_result"
fi
fi
@@ -3946,10 +4266,11 @@ EOF
reload_objs="$objs$old_deplibs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test
output="$obj"
- eval cmds=\"$reload_cmds\"
+ cmds=$reload_cmds
save_ifs="$IFS"; IFS='~'
for cmd in $cmds; do
IFS="$save_ifs"
+ eval cmd=\"$cmd\"
$show "$cmd"
$run eval "$cmd" || exit $?
done
@@ -3962,7 +4283,7 @@ EOF
$run ${rm}r $gentop
fi
- exit 0
+ exit $EXIT_SUCCESS
fi
if test "$build_libtool_libs" != yes; then
@@ -3975,17 +4296,18 @@ EOF
# accidentally link it into a program.
# $show "echo timestamp > $libobj"
# $run eval "echo timestamp > $libobj" || exit $?
- exit 0
+ exit $EXIT_SUCCESS
fi
if test -n "$pic_flag" || test "$pic_mode" != default; then
# Only do commands if we really have different PIC objects.
reload_objs="$libobjs $reload_conv_objs"
output="$libobj"
- eval cmds=\"$reload_cmds\"
+ cmds=$reload_cmds
save_ifs="$IFS"; IFS='~'
for cmd in $cmds; do
IFS="$save_ifs"
+ eval cmd=\"$cmd\"
$show "$cmd"
$run eval "$cmd" || exit $?
done
@@ -3997,7 +4319,7 @@ EOF
$run ${rm}r $gentop
fi
- exit 0
+ exit $EXIT_SUCCESS
;;
prog)
@@ -4037,6 +4359,35 @@ EOF
;;
esac
+
+ # move library search paths that coincide with paths to not yet
+ # installed libraries to the beginning of the library search list
+ new_libs=
+ for path in $notinst_path; do
+ case " $new_libs " in
+ *" -L$path/$objdir "*) ;;
+ *)
+ case " $compile_deplibs " in
+ *" -L$path/$objdir "*)
+ new_libs="$new_libs -L$path/$objdir" ;;
+ esac
+ ;;
+ esac
+ done
+ for deplib in $compile_deplibs; do
+ case $deplib in
+ -L*)
+ case " $new_libs " in
+ *" $deplib "*) ;;
+ *) new_libs="$new_libs $deplib" ;;
+ esac
+ ;;
+ *) new_libs="$new_libs $deplib" ;;
+ esac
+ done
+ compile_deplibs="$new_libs"
+
+
compile_command="$compile_command $compile_deplibs"
finalize_command="$finalize_command $finalize_deplibs"
@@ -4081,10 +4432,15 @@ EOF
fi
case $host in
*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
+ testbindir=`$echo "X$libdir" | $Xsed -e 's*/lib$*/bin*'`
case :$dllsearchpath: in
*":$libdir:"*) ;;
*) dllsearchpath="$dllsearchpath:$libdir";;
esac
+ case :$dllsearchpath: in
+ *":$testbindir:"*) ;;
+ *) dllsearchpath="$dllsearchpath:$testbindir";;
+ esac
;;
esac
done
@@ -4198,13 +4554,25 @@ extern \"C\" {
# Prepare the list of exported symbols
if test -z "$export_symbols"; then
- export_symbols="$output_objdir/$output.exp"
+ export_symbols="$output_objdir/$outputname.exp"
$run $rm $export_symbols
- $run eval "${SED} -n -e '/^: @PROGRAM@$/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+ $run eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+ case $host in
+ *cygwin* | *mingw* )
+ $run eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+ $run eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"'
+ ;;
+ esac
else
- $run eval "${SED} -e 's/\([][.*^$]\)/\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$output.exp"'
- $run eval 'grep -f "$output_objdir/$output.exp" < "$nlist" > "$nlist"T'
+ $run eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"'
+ $run eval 'grep -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T'
$run eval 'mv "$nlist"T "$nlist"'
+ case $host in
+ *cygwin* | *mingw* )
+ $run eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+ $run eval 'cat "$nlist" >> "$output_objdir/$outputname.def"'
+ ;;
+ esac
fi
fi
@@ -4255,7 +4623,26 @@ extern \"C\" {
#endif
/* The mapping between symbol names and symbols. */
+"
+
+ case $host in
+ *cygwin* | *mingw* )
+ $echo >> "$output_objdir/$dlsyms" "\
+/* DATA imports from DLLs on WIN32 can't be const, because
+ runtime relocations are performed -- see ld's documentation
+ on pseudo-relocs */
+struct {
+"
+ ;;
+ * )
+ $echo >> "$output_objdir/$dlsyms" "\
const struct {
+"
+ ;;
+ esac
+
+
+ $echo >> "$output_objdir/$dlsyms" "\
const char *name;
lt_ptr address;
}
@@ -4302,20 +4689,33 @@ static const void *lt_preloaded_setup() {
esac
# Now compile the dynamic symbol file.
- $show "(cd $output_objdir && $LTCC -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")"
- $run eval '(cd $output_objdir && $LTCC -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $?
+ $show "(cd $output_objdir && $LTCC $LTCFLAGS -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")"
+ $run eval '(cd $output_objdir && $LTCC $LTCFLAGS -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $?
# Clean up the generated files.
$show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T"
$run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T"
# Transform the symbol file into the correct name.
- compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
- finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
+ case $host in
+ *cygwin* | *mingw* )
+ if test -f "$output_objdir/${outputname}.def" ; then
+ compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}.def $output_objdir/${outputname}S.${objext}%"`
+ finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}.def $output_objdir/${outputname}S.${objext}%"`
+ else
+ compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
+ finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
+ fi
+ ;;
+ * )
+ compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
+ finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
+ ;;
+ esac
;;
*)
$echo "$modename: unknown suffix for \`$dlsyms'" 1>&2
- exit 1
+ exit $EXIT_FAILURE
;;
esac
else
@@ -4336,7 +4736,7 @@ static const void *lt_preloaded_setup() {
# We have no uninstalled library dependencies, so finalize right now.
$show "$link_command"
$run eval "$link_command"
- status=$?
+ exit_status=$?
# Delete the generated files.
if test -n "$dlsyms"; then
@@ -4344,7 +4744,7 @@ static const void *lt_preloaded_setup() {
$run $rm "$output_objdir/${outputname}S.${objext}"
fi
- exit $status
+ exit $exit_status
fi
if test -n "$shlibpath_var"; then
@@ -4403,7 +4803,7 @@ static const void *lt_preloaded_setup() {
# Link the executable and exit
$show "$link_command"
$run eval "$link_command" || exit $?
- exit 0
+ exit $EXIT_SUCCESS
fi
if test "$hardcode_action" = relink; then
@@ -4458,10 +4858,10 @@ static const void *lt_preloaded_setup() {
fi
# Quote $echo for shipping.
- if test "X$echo" = "X$SHELL $0 --fallback-echo"; then
- case $0 in
- [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $0 --fallback-echo";;
- *) qecho="$SHELL `pwd`/$0 --fallback-echo";;
+ if test "X$echo" = "X$SHELL $progpath --fallback-echo"; then
+ case $progpath in
+ [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $progpath --fallback-echo";;
+ *) qecho="$SHELL `pwd`/$progpath --fallback-echo";;
esac
qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"`
else
@@ -4484,10 +4884,12 @@ static const void *lt_preloaded_setup() {
esac
case $host in
*cygwin* | *mingw* )
- cwrappersource=`$echo ${objdir}/lt-${output}.c`
- cwrapper=`$echo ${output}.exe`
- $rm $cwrappersource $cwrapper
- trap "$rm $cwrappersource $cwrapper; exit 1" 1 2 15
+ output_name=`basename $output`
+ output_path=`dirname $output`
+ cwrappersource="$output_path/$objdir/lt-$output_name.c"
+ cwrapper="$output_path/$output_name.exe"
+ $rm $cwrappersource $cwrapper
+ trap "$rm $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15
cat > $cwrappersource <<EOF
@@ -4496,7 +4898,7 @@ static const void *lt_preloaded_setup() {
The $output program cannot be directly executed until all the libtool
libraries that it depends on are installed.
-
+
This wrapper executable should never be moved out of the build directory.
If it is, it will not operate correctly.
@@ -4512,6 +4914,9 @@ EOF
#include <malloc.h>
#include <stdarg.h>
#include <assert.h>
+#include <string.h>
+#include <ctype.h>
+#include <sys/stat.h>
#if defined(PATH_MAX)
# define LT_PATHMAX PATH_MAX
@@ -4522,15 +4927,19 @@ EOF
#endif
#ifndef DIR_SEPARATOR
-#define DIR_SEPARATOR '/'
+# define DIR_SEPARATOR '/'
+# define PATH_SEPARATOR ':'
#endif
#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \
defined (__OS2__)
-#define HAVE_DOS_BASED_FILE_SYSTEM
-#ifndef DIR_SEPARATOR_2
-#define DIR_SEPARATOR_2 '\\'
-#endif
+# define HAVE_DOS_BASED_FILE_SYSTEM
+# ifndef DIR_SEPARATOR_2
+# define DIR_SEPARATOR_2 '\\'
+# endif
+# ifndef PATH_SEPARATOR_2
+# define PATH_SEPARATOR_2 ';'
+# endif
#endif
#ifndef DIR_SEPARATOR_2
@@ -4540,17 +4949,32 @@ EOF
(((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
#endif /* DIR_SEPARATOR_2 */
+#ifndef PATH_SEPARATOR_2
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR)
+#else /* PATH_SEPARATOR_2 */
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2)
+#endif /* PATH_SEPARATOR_2 */
+
#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type)))
#define XFREE(stale) do { \
if (stale) { free ((void *) stale); stale = 0; } \
} while (0)
+/* -DDEBUG is fairly common in CFLAGS. */
+#undef DEBUG
+#if defined DEBUGWRAPPER
+# define DEBUG(format, ...) fprintf(stderr, format, __VA_ARGS__)
+#else
+# define DEBUG(format, ...)
+#endif
+
const char *program_name = NULL;
void * xmalloc (size_t num);
char * xstrdup (const char *string);
-char * basename (const char *name);
-char * fnqualify(const char *path);
+const char * base_name (const char *name);
+char * find_executable(const char *wrapper);
+int check_executable(const char *path);
char * strendzap(char *str, const char *pat);
void lt_fatal (const char *message, ...);
@@ -4559,30 +4983,52 @@ main (int argc, char *argv[])
{
char **newargz;
int i;
-
- program_name = (char *) xstrdup ((char *) basename (argv[0]));
+
+ program_name = (char *) xstrdup (base_name (argv[0]));
+ DEBUG("(main) argv[0] : %s\n",argv[0]);
+ DEBUG("(main) program_name : %s\n",program_name);
newargz = XMALLOC(char *, argc+2);
EOF
- cat >> $cwrappersource <<EOF
- newargz[0] = "$SHELL";
+ cat >> $cwrappersource <<EOF
+ newargz[0] = (char *) xstrdup("$SHELL");
EOF
- cat >> $cwrappersource <<"EOF"
- newargz[1] = fnqualify(argv[0]);
+ cat >> $cwrappersource <<"EOF"
+ newargz[1] = find_executable(argv[0]);
+ if (newargz[1] == NULL)
+ lt_fatal("Couldn't find %s", argv[0]);
+ DEBUG("(main) found exe at : %s\n",newargz[1]);
/* we know the script has the same name, without the .exe */
/* so make sure newargz[1] doesn't end in .exe */
- strendzap(newargz[1],".exe");
+ strendzap(newargz[1],".exe");
for (i = 1; i < argc; i++)
newargz[i+1] = xstrdup(argv[i]);
newargz[argc+1] = NULL;
+
+ for (i=0; i<argc+1; i++)
+ {
+ DEBUG("(main) newargz[%d] : %s\n",i,newargz[i]);
+ ;
+ }
+
EOF
- cat >> $cwrappersource <<EOF
+ case $host_os in
+ mingw*)
+ cat >> $cwrappersource <<EOF
+ execv("$SHELL",(char const **)newargz);
+EOF
+ ;;
+ *)
+ cat >> $cwrappersource <<EOF
execv("$SHELL",newargz);
EOF
+ ;;
+ esac
- cat >> $cwrappersource <<"EOF"
+ cat >> $cwrappersource <<"EOF"
+ return 127;
}
void *
@@ -4595,59 +5041,159 @@ xmalloc (size_t num)
return p;
}
-char *
+char *
xstrdup (const char *string)
{
return string ? strcpy ((char *) xmalloc (strlen (string) + 1), string) : NULL
;
}
-char *
-basename (const char *name)
+const char *
+base_name (const char *name)
{
const char *base;
#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
/* Skip over the disk name in MSDOS pathnames. */
- if (isalpha (name[0]) && name[1] == ':')
+ if (isalpha ((unsigned char)name[0]) && name[1] == ':')
name += 2;
#endif
for (base = name; *name; name++)
if (IS_DIR_SEPARATOR (*name))
base = name + 1;
- return (char *) base;
+ return base;
}
-char *
-fnqualify(const char *path)
+int
+check_executable(const char * path)
{
- size_t size;
- char *p;
+ struct stat st;
+
+ DEBUG("(check_executable) : %s\n", path ? (*path ? path : "EMPTY!") : "NULL!");
+ if ((!path) || (!*path))
+ return 0;
+
+ if ((stat (path, &st) >= 0) &&
+ (
+ /* MinGW & native WIN32 do not support S_IXOTH or S_IXGRP */
+#if defined (S_IXOTH)
+ ((st.st_mode & S_IXOTH) == S_IXOTH) ||
+#endif
+#if defined (S_IXGRP)
+ ((st.st_mode & S_IXGRP) == S_IXGRP) ||
+#endif
+ ((st.st_mode & S_IXUSR) == S_IXUSR))
+ )
+ return 1;
+ else
+ return 0;
+}
+
+/* Searches for the full path of the wrapper. Returns
+ newly allocated full path name if found, NULL otherwise */
+char *
+find_executable (const char* wrapper)
+{
+ int has_slash = 0;
+ const char* p;
+ const char* p_next;
+ /* static buffer for getcwd */
char tmp[LT_PATHMAX + 1];
+ int tmp_len;
+ char* concat_name;
- assert(path != NULL);
+ DEBUG("(find_executable) : %s\n", wrapper ? (*wrapper ? wrapper : "EMPTY!") : "NULL!");
- /* Is it qualified already? */
+ if ((wrapper == NULL) || (*wrapper == '\0'))
+ return NULL;
+
+ /* Absolute path? */
#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
- if (isalpha (path[0]) && path[1] == ':')
- return xstrdup (path);
+ if (isalpha ((unsigned char)wrapper[0]) && wrapper[1] == ':')
+ {
+ concat_name = xstrdup (wrapper);
+ if (check_executable(concat_name))
+ return concat_name;
+ XFREE(concat_name);
+ }
+ else
+ {
+#endif
+ if (IS_DIR_SEPARATOR (wrapper[0]))
+ {
+ concat_name = xstrdup (wrapper);
+ if (check_executable(concat_name))
+ return concat_name;
+ XFREE(concat_name);
+ }
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+ }
#endif
- if (IS_DIR_SEPARATOR (path[0]))
- return xstrdup (path);
- /* prepend the current directory */
- /* doesn't handle '~' */
+ for (p = wrapper; *p; p++)
+ if (*p == '/')
+ {
+ has_slash = 1;
+ break;
+ }
+ if (!has_slash)
+ {
+ /* no slashes; search PATH */
+ const char* path = getenv ("PATH");
+ if (path != NULL)
+ {
+ for (p = path; *p; p = p_next)
+ {
+ const char* q;
+ size_t p_len;
+ for (q = p; *q; q++)
+ if (IS_PATH_SEPARATOR(*q))
+ break;
+ p_len = q - p;
+ p_next = (*q == '\0' ? q : q + 1);
+ if (p_len == 0)
+ {
+ /* empty path: current directory */
+ if (getcwd (tmp, LT_PATHMAX) == NULL)
+ lt_fatal ("getcwd failed");
+ tmp_len = strlen(tmp);
+ concat_name = XMALLOC(char, tmp_len + 1 + strlen(wrapper) + 1);
+ memcpy (concat_name, tmp, tmp_len);
+ concat_name[tmp_len] = '/';
+ strcpy (concat_name + tmp_len + 1, wrapper);
+ }
+ else
+ {
+ concat_name = XMALLOC(char, p_len + 1 + strlen(wrapper) + 1);
+ memcpy (concat_name, p, p_len);
+ concat_name[p_len] = '/';
+ strcpy (concat_name + p_len + 1, wrapper);
+ }
+ if (check_executable(concat_name))
+ return concat_name;
+ XFREE(concat_name);
+ }
+ }
+ /* not found in PATH; assume curdir */
+ }
+ /* Relative path | not found in path: prepend cwd */
if (getcwd (tmp, LT_PATHMAX) == NULL)
lt_fatal ("getcwd failed");
- size = strlen(tmp) + 1 + strlen(path) + 1; /* +2 for '/' and '\0' */
- p = XMALLOC(char, size);
- sprintf(p, "%s%c%s", tmp, DIR_SEPARATOR, path);
- return p;
+ tmp_len = strlen(tmp);
+ concat_name = XMALLOC(char, tmp_len + 1 + strlen(wrapper) + 1);
+ memcpy (concat_name, tmp, tmp_len);
+ concat_name[tmp_len] = '/';
+ strcpy (concat_name + tmp_len + 1, wrapper);
+
+ if (check_executable(concat_name))
+ return concat_name;
+ XFREE(concat_name);
+ return NULL;
}
char *
-strendzap(char *str, const char *pat)
+strendzap(char *str, const char *pat)
{
size_t len, patlen;
@@ -4667,7 +5213,7 @@ strendzap(char *str, const char *pat)
}
static void
-lt_error_core (int exit_status, const char * mode,
+lt_error_core (int exit_status, const char * mode,
const char * message, va_list ap)
{
fprintf (stderr, "%s: %s: ", program_name, mode);
@@ -4687,16 +5233,16 @@ lt_fatal (const char *message, ...)
va_end (ap);
}
EOF
- # we should really use a build-platform specific compiler
- # here, but OTOH, the wrappers (shell script and this C one)
- # are only useful if you want to execute the "real" binary.
- # Since the "real" binary is built for $host, then this
- # wrapper might as well be built for $host, too.
- $run $LTCC -s -o $cwrapper $cwrappersource
- ;;
- esac
- $rm $output
- trap "$rm $output; exit 1" 1 2 15
+ # we should really use a build-platform specific compiler
+ # here, but OTOH, the wrappers (shell script and this C one)
+ # are only useful if you want to execute the "real" binary.
+ # Since the "real" binary is built for $host, then this
+ # wrapper might as well be built for $host, too.
+ $run $LTCC $LTCFLAGS -s -o $cwrapper $cwrappersource
+ ;;
+ esac
+ $rm $output
+ trap "$rm $output; exit $EXIT_FAILURE" 1 2 15
$echo > $output "\
#! $SHELL
@@ -4717,7 +5263,7 @@ sed_quote_subst='$sed_quote_subst'
# The HP-UX ksh and POSIX shell print the target directory to stdout
# if CDPATH is set.
-if test \"\${CDPATH+set}\" = set; then CDPATH=:; export CDPATH; fi
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
relink_command=\"$relink_command\"
@@ -4796,7 +5342,7 @@ else
else
$echo \"\$relink_command_output\" >&2
$rm \"\$progdir/\$file\"
- exit 1
+ exit $EXIT_FAILURE
fi
fi
@@ -4846,32 +5392,32 @@ else
# Backslashes separate directories on plain windows
*-*-mingw | *-*-os2*)
$echo >> $output "\
- exec \$progdir\\\\\$program \${1+\"\$@\"}
+ exec \"\$progdir\\\\\$program\" \${1+\"\$@\"}
"
;;
*)
$echo >> $output "\
- exec \$progdir/\$program \${1+\"\$@\"}
+ exec \"\$progdir/\$program\" \${1+\"\$@\"}
"
;;
esac
$echo >> $output "\
\$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\"
- exit 1
+ exit $EXIT_FAILURE
fi
else
# The program doesn't exist.
- \$echo \"\$0: error: \$progdir/\$program does not exist\" 1>&2
+ \$echo \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2
\$echo \"This script is just a wrapper for \$program.\" 1>&2
$echo \"See the $PACKAGE documentation for more information.\" 1>&2
- exit 1
+ exit $EXIT_FAILURE
fi
fi\
"
chmod +x $output
fi
- exit 0
+ exit $EXIT_SUCCESS
;;
esac
@@ -4894,76 +5440,78 @@ fi\
if test -n "$addlibs"; then
gentop="$output_objdir/${outputname}x"
- $show "${rm}r $gentop"
- $run ${rm}r "$gentop"
- $show "$mkdir $gentop"
- $run $mkdir "$gentop"
- status=$?
- if test "$status" -ne 0 && test ! -d "$gentop"; then
- exit $status
- fi
generated="$generated $gentop"
- # Add in members from convenience archives.
- for xlib in $addlibs; do
- # Extract the objects.
- case $xlib in
- [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;;
- *) xabs=`pwd`"/$xlib" ;;
- esac
- xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'`
- xdir="$gentop/$xlib"
-
- $show "${rm}r $xdir"
- $run ${rm}r "$xdir"
- $show "$mkdir $xdir"
- $run $mkdir "$xdir"
- status=$?
- if test "$status" -ne 0 && test ! -d "$xdir"; then
- exit $status
- fi
- # We will extract separately just the conflicting names and we will no
- # longer touch any unique names. It is faster to leave these extract
- # automatically by $AR in one run.
- $show "(cd $xdir && $AR x $xabs)"
- $run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
- if ($AR t "$xabs" | sort | sort -uc >/dev/null 2>&1); then
- :
- else
- $echo "$modename: warning: object name conflicts; renaming object files" 1>&2
- $echo "$modename: warning: to ensure that they will not overwrite" 1>&2
- $AR t "$xabs" | sort | uniq -cd | while read -r count name
- do
- i=1
- while test "$i" -le "$count"
- do
- # Put our $i before any first dot (extension)
- # Never overwrite any file
- name_to="$name"
- while test "X$name_to" = "X$name" || test -f "$xdir/$name_to"
- do
- name_to=`$echo "X$name_to" | $Xsed -e "s/\([^.]*\)/\1-$i/"`
- done
- $show "(cd $xdir && $AR xN $i $xabs '$name' && $mv '$name' '$name_to')"
- $run eval "(cd \$xdir && $AR xN $i \$xabs '$name' && $mv '$name' '$name_to')" || exit $?
- i=`expr $i + 1`
- done
- done
- fi
-
- oldobjs="$oldobjs "`find $xdir -name \*.${objext} -print -o -name \*.lo -print | $NL2SP`
- done
+ func_extract_archives $gentop $addlibs
+ oldobjs="$oldobjs $func_extract_archives_result"
fi
# Do each command in the archive commands.
if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
- eval cmds=\"$old_archive_from_new_cmds\"
+ cmds=$old_archive_from_new_cmds
else
+ # POSIX demands no paths to be encoded in archives. We have
+ # to avoid creating archives with duplicate basenames if we
+ # might have to extract them afterwards, e.g., when creating a
+ # static archive out of a convenience library, or when linking
+ # the entirety of a libtool archive into another (currently
+ # not supported by libtool).
+ if (for obj in $oldobjs
+ do
+ $echo "X$obj" | $Xsed -e 's%^.*/%%'
+ done | sort | sort -uc >/dev/null 2>&1); then
+ :
+ else
+ $echo "copying selected object files to avoid basename conflicts..."
+
+ if test -z "$gentop"; then
+ gentop="$output_objdir/${outputname}x"
+ generated="$generated $gentop"
+
+ $show "${rm}r $gentop"
+ $run ${rm}r "$gentop"
+ $show "$mkdir $gentop"
+ $run $mkdir "$gentop"
+ exit_status=$?
+ if test "$exit_status" -ne 0 && test ! -d "$gentop"; then
+ exit $exit_status
+ fi
+ fi
+
+ save_oldobjs=$oldobjs
+ oldobjs=
+ counter=1
+ for obj in $save_oldobjs
+ do
+ objbase=`$echo "X$obj" | $Xsed -e 's%^.*/%%'`
+ case " $oldobjs " in
+ " ") oldobjs=$obj ;;
+ *[\ /]"$objbase "*)
+ while :; do
+ # Make sure we don't pick an alternate name that also
+ # overlaps.
+ newobj=lt$counter-$objbase
+ counter=`expr $counter + 1`
+ case " $oldobjs " in
+ *[\ /]"$newobj "*) ;;
+ *) if test ! -f "$gentop/$newobj"; then break; fi ;;
+ esac
+ done
+ $show "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj"
+ $run ln "$obj" "$gentop/$newobj" ||
+ $run cp "$obj" "$gentop/$newobj"
+ oldobjs="$oldobjs $gentop/$newobj"
+ ;;
+ *) oldobjs="$oldobjs $obj" ;;
+ esac
+ done
+ fi
+
eval cmds=\"$old_archive_cmds\"
if len=`expr "X$cmds" : ".*"` &&
test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then
- :
+ cmds=$old_archive_cmds
else
# the command line is too long to link in one step, link in parts
$echo "using piecewise archive linking..."
@@ -4972,31 +5520,18 @@ fi\
objlist=
concat_cmds=
save_oldobjs=$oldobjs
- # GNU ar 2.10+ was changed to match POSIX; thus no paths are
- # encoded into archives. This makes 'ar r' malfunction in
- # this piecewise linking case whenever conflicting object
- # names appear in distinct ar calls; check, warn and compensate.
- if (for obj in $save_oldobjs
- do
- $echo "X$obj" | $Xsed -e 's%^.*/%%'
- done | sort | sort -uc >/dev/null 2>&1); then
- :
- else
- $echo "$modename: warning: object name conflicts; overriding AR_FLAGS to 'cq'" 1>&2
- $echo "$modename: warning: to ensure that POSIX-compatible ar will work" 1>&2
- AR_FLAGS=cq
- fi
+
# Is there a better way of finding the last object in the list?
for obj in $save_oldobjs
do
last_oldobj=$obj
- done
+ done
for obj in $save_oldobjs
do
oldobjs="$objlist $obj"
objlist="$objlist $obj"
eval test_cmds=\"$old_archive_cmds\"
- if len=`expr "X$test_cmds" : ".*"` &&
+ if len=`expr "X$test_cmds" : ".*" 2>/dev/null` &&
test "$len" -le "$max_cmd_len"; then
:
else
@@ -5004,7 +5539,7 @@ fi\
oldobjs=$objlist
if test "$obj" = "$last_oldobj" ; then
RANLIB=$save_RANLIB
- fi
+ fi
test -z "$concat_cmds" || concat_cmds=$concat_cmds~
eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\"
objlist=
@@ -5015,12 +5550,13 @@ fi\
if test "X$oldobjs" = "X" ; then
eval cmds=\"\$concat_cmds\"
else
- eval cmds=\"\$concat_cmds~$old_archive_cmds\"
+ eval cmds=\"\$concat_cmds~\$old_archive_cmds\"
fi
fi
fi
save_ifs="$IFS"; IFS='~'
for cmd in $cmds; do
+ eval cmd=\"$cmd\"
IFS="$save_ifs"
$show "$cmd"
$run eval "$cmd" || exit $?
@@ -5052,8 +5588,12 @@ fi\
fi
done
# Quote the link command for shipping.
- relink_command="(cd `pwd`; $SHELL $0 --mode=relink $libtool_args @inst_prefix_dir@)"
+ relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"`
+ if test "$hardcode_automatic" = yes ; then
+ relink_command=
+ fi
+
# Only create the output if not a dry run.
if test -z "$run"; then
@@ -5072,7 +5612,7 @@ fi\
eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
if test -z "$libdir"; then
$echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2
- exit 1
+ exit $EXIT_FAILURE
fi
newdependency_libs="$newdependency_libs $libdir/$name"
;;
@@ -5086,7 +5626,7 @@ fi\
eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
if test -z "$libdir"; then
$echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
- exit 1
+ exit $EXIT_FAILURE
fi
newdlfiles="$newdlfiles $libdir/$name"
done
@@ -5097,11 +5637,30 @@ fi\
eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
if test -z "$libdir"; then
$echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
- exit 1
+ exit $EXIT_FAILURE
fi
newdlprefiles="$newdlprefiles $libdir/$name"
done
dlprefiles="$newdlprefiles"
+ else
+ newdlfiles=
+ for lib in $dlfiles; do
+ case $lib in
+ [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
+ *) abs=`pwd`"/$lib" ;;
+ esac
+ newdlfiles="$newdlfiles $abs"
+ done
+ dlfiles="$newdlfiles"
+ newdlprefiles=
+ for lib in $dlprefiles; do
+ case $lib in
+ [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
+ *) abs=`pwd`"/$lib" ;;
+ esac
+ newdlprefiles="$newdlprefiles $abs"
+ done
+ dlprefiles="$newdlprefiles"
fi
$rm $output
# place dlname in correct position for cygwin
@@ -5158,7 +5717,7 @@ relink_command=\"$relink_command\""
$run eval '(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)' || exit $?
;;
esac
- exit 0
+ exit $EXIT_SUCCESS
;;
# libtool install mode
@@ -5169,11 +5728,11 @@ relink_command=\"$relink_command\""
# install_prog (especially on Windows NT).
if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh ||
# Allow the use of GNU shtool's install command.
- $echo "X$nonopt" | $Xsed | grep shtool > /dev/null; then
+ $echo "X$nonopt" | grep shtool > /dev/null; then
# Aesthetically quote it.
arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"`
case $arg in
- *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*)
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
arg="\"$arg\""
;;
esac
@@ -5182,14 +5741,14 @@ relink_command=\"$relink_command\""
shift
else
install_prog=
- arg="$nonopt"
+ arg=$nonopt
fi
# The real first argument should be the name of the installation program.
# Aesthetically quote it.
arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
case $arg in
- *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*)
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
arg="\"$arg\""
;;
esac
@@ -5207,28 +5766,31 @@ relink_command=\"$relink_command\""
do
if test -n "$dest"; then
files="$files $dest"
- dest="$arg"
+ dest=$arg
continue
fi
case $arg in
-d) isdir=yes ;;
- -f) prev="-f" ;;
- -g) prev="-g" ;;
- -m) prev="-m" ;;
- -o) prev="-o" ;;
+ -f)
+ case " $install_prog " in
+ *[\\\ /]cp\ *) ;;
+ *) prev=$arg ;;
+ esac
+ ;;
+ -g | -m | -o) prev=$arg ;;
-s)
stripme=" -s"
continue
;;
- -*) ;;
-
+ -*)
+ ;;
*)
# If the previous option needed an argument, then skip it.
if test -n "$prev"; then
prev=
else
- dest="$arg"
+ dest=$arg
continue
fi
;;
@@ -5237,7 +5799,7 @@ relink_command=\"$relink_command\""
# Aesthetically quote the argument.
arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
case $arg in
- *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*)
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
arg="\"$arg\""
;;
esac
@@ -5247,13 +5809,13 @@ relink_command=\"$relink_command\""
if test -z "$install_prog"; then
$echo "$modename: you must specify an install program" 1>&2
$echo "$help" 1>&2
- exit 1
+ exit $EXIT_FAILURE
fi
if test -n "$prev"; then
$echo "$modename: the \`$prev' option requires an argument" 1>&2
$echo "$help" 1>&2
- exit 1
+ exit $EXIT_FAILURE
fi
if test -z "$files"; then
@@ -5263,7 +5825,7 @@ relink_command=\"$relink_command\""
$echo "$modename: you must specify a destination" 1>&2
fi
$echo "$help" 1>&2
- exit 1
+ exit $EXIT_FAILURE
fi
# Strip any trailing slash from the destination.
@@ -5284,7 +5846,7 @@ relink_command=\"$relink_command\""
if test "$#" -gt 2; then
$echo "$modename: \`$dest' is not a directory" 1>&2
$echo "$help" 1>&2
- exit 1
+ exit $EXIT_FAILURE
fi
fi
case $destdir in
@@ -5296,7 +5858,7 @@ relink_command=\"$relink_command\""
*)
$echo "$modename: \`$destdir' must be an absolute directory name" 1>&2
$echo "$help" 1>&2
- exit 1
+ exit $EXIT_FAILURE
;;
esac
done
@@ -5325,7 +5887,7 @@ relink_command=\"$relink_command\""
else
$echo "$modename: \`$file' is not a valid libtool archive" 1>&2
$echo "$help" 1>&2
- exit 1
+ exit $EXIT_FAILURE
fi
library_names=
@@ -5367,7 +5929,7 @@ relink_command=\"$relink_command\""
# but it's something to keep an eye on.
if test "$inst_prefix_dir" = "$destdir"; then
$echo "$modename: error: cannot install \`$file' to a directory not ending in $libdir" 1>&2
- exit 1
+ exit $EXIT_FAILURE
fi
if test -n "$inst_prefix_dir"; then
@@ -5382,7 +5944,7 @@ relink_command=\"$relink_command\""
if $run eval "$relink_command"; then :
else
$echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2
- exit 1
+ exit $EXIT_FAILURE
fi
fi
@@ -5406,23 +5968,36 @@ relink_command=\"$relink_command\""
if test "$#" -gt 0; then
# Delete the old symlinks, and create new ones.
+ # Try `ln -sf' first, because the `ln' binary might depend on
+ # the symlink we replace! Solaris /bin/ln does not understand -f,
+ # so we also need to try rm && ln -s.
for linkname
do
if test "$linkname" != "$realname"; then
- $show "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)"
- $run eval "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)"
+ $show "(cd $destdir && { $LN_S -f $realname $linkname || { $rm $linkname && $LN_S $realname $linkname; }; })"
+ $run eval "(cd $destdir && { $LN_S -f $realname $linkname || { $rm $linkname && $LN_S $realname $linkname; }; })"
fi
done
fi
# Do each command in the postinstall commands.
lib="$destdir/$realname"
- eval cmds=\"$postinstall_cmds\"
+ cmds=$postinstall_cmds
save_ifs="$IFS"; IFS='~'
for cmd in $cmds; do
IFS="$save_ifs"
+ eval cmd=\"$cmd\"
$show "$cmd"
- $run eval "$cmd" || exit $?
+ $run eval "$cmd" || {
+ lt_exit=$?
+
+ # Restore the uninstalled library and exit
+ if test "$mode" = relink; then
+ $run eval '(cd $output_objdir && $rm ${realname}T && $mv ${realname}U $realname)'
+ fi
+
+ exit $lt_exit
+ }
done
IFS="$save_ifs"
fi
@@ -5460,7 +6035,7 @@ relink_command=\"$relink_command\""
*)
$echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2
$echo "$help" 1>&2
- exit 1
+ exit $EXIT_FAILURE
;;
esac
@@ -5478,7 +6053,7 @@ relink_command=\"$relink_command\""
$show "$install_prog $staticobj $staticdest"
$run eval "$install_prog \$staticobj \$staticdest" || exit $?
fi
- exit 0
+ exit $EXIT_SUCCESS
;;
*)
@@ -5516,23 +6091,21 @@ relink_command=\"$relink_command\""
notinst_deplibs=
relink_command=
- # To insure that "foo" is sourced, and not "foo.exe",
- # finese the cygwin/MSYS system by explicitly sourcing "foo."
- # which disallows the automatic-append-.exe behavior.
- case $build in
- *cygwin* | *mingw*) wrapperdot=${wrapper}. ;;
- *) wrapperdot=${wrapper} ;;
- esac
+ # Note that it is not necessary on cygwin/mingw to append a dot to
+ # foo even if both foo and FILE.exe exist: automatic-append-.exe
+ # behavior happens only for exec(3), not for open(2)! Also, sourcing
+ # `FILE.' does not work on cygwin managed mounts.
+ #
# If there is no directory component, then add one.
- case $file in
- */* | *\\*) . ${wrapperdot} ;;
- *) . ./${wrapperdot} ;;
+ case $wrapper in
+ */* | *\\*) . ${wrapper} ;;
+ *) . ./${wrapper} ;;
esac
# Check the variables that should have been set.
if test -z "$notinst_deplibs"; then
$echo "$modename: invalid libtool wrapper script \`$wrapper'" 1>&2
- exit 1
+ exit $EXIT_FAILURE
fi
finalize=yes
@@ -5554,36 +6127,21 @@ relink_command=\"$relink_command\""
done
relink_command=
- # To insure that "foo" is sourced, and not "foo.exe",
- # finese the cygwin/MSYS system by explicitly sourcing "foo."
- # which disallows the automatic-append-.exe behavior.
- case $build in
- *cygwin* | *mingw*) wrapperdot=${wrapper}. ;;
- *) wrapperdot=${wrapper} ;;
- esac
+ # Note that it is not necessary on cygwin/mingw to append a dot to
+ # foo even if both foo and FILE.exe exist: automatic-append-.exe
+ # behavior happens only for exec(3), not for open(2)! Also, sourcing
+ # `FILE.' does not work on cygwin managed mounts.
+ #
# If there is no directory component, then add one.
- case $file in
- */* | *\\*) . ${wrapperdot} ;;
- *) . ./${wrapperdot} ;;
+ case $wrapper in
+ */* | *\\*) . ${wrapper} ;;
+ *) . ./${wrapper} ;;
esac
outputname=
if test "$fast_install" = no && test -n "$relink_command"; then
if test "$finalize" = yes && test -z "$run"; then
- tmpdir="/tmp"
- test -n "$TMPDIR" && tmpdir="$TMPDIR"
- tmpdir_mktemp=`mktemp -d $tmpdir/libtool-XXXXXX 2> /dev/null`
- if test "$?" = 0 ; then
- tmpdir="$tmpdir_mktemp"
- unset tmpdir_mktemp
- else
- tmpdir="$tmpdir/libtool-$$"
- fi
- if $mkdir -p "$tmpdir" && chmod 700 "$tmpdir"; then :
- else
- $echo "$modename: error: cannot create temporary directory \`$tmpdir'" 1>&2
- continue
- fi
+ tmpdir=`func_mktempdir`
file=`$echo "X$file$stripped_ext" | $Xsed -e 's%^.*/%%'`
outputname="$tmpdir/$file"
# Replace the output file specification.
@@ -5607,7 +6165,7 @@ relink_command=\"$relink_command\""
fi
# remove .exe since cygwin /usr/bin/install will append another
- # one anyways
+ # one anyway
case $install_prog,$host in
*/usr/bin/install*,*cygwin*)
case $file:$destfile in
@@ -5639,16 +6197,17 @@ relink_command=\"$relink_command\""
$show "$install_prog $file $oldlib"
$run eval "$install_prog \$file \$oldlib" || exit $?
- if test -n "$stripme" && test -n "$striplib"; then
+ if test -n "$stripme" && test -n "$old_striplib"; then
$show "$old_striplib $oldlib"
$run eval "$old_striplib $oldlib" || exit $?
fi
# Do each command in the postinstall commands.
- eval cmds=\"$old_postinstall_cmds\"
+ cmds=$old_postinstall_cmds
save_ifs="$IFS"; IFS='~'
for cmd in $cmds; do
IFS="$save_ifs"
+ eval cmd=\"$cmd\"
$show "$cmd"
$run eval "$cmd" || exit $?
done
@@ -5662,9 +6221,9 @@ relink_command=\"$relink_command\""
if test -n "$current_libdirs"; then
# Maybe just do a dry run.
test -n "$run" && current_libdirs=" -n$current_libdirs"
- exec_cmd='$SHELL $0 --finish$current_libdirs'
+ exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs'
else
- exit 0
+ exit $EXIT_SUCCESS
fi
;;
@@ -5683,10 +6242,11 @@ relink_command=\"$relink_command\""
for libdir in $libdirs; do
if test -n "$finish_cmds"; then
# Do each command in the finish commands.
- eval cmds=\"$finish_cmds\"
+ cmds=$finish_cmds
save_ifs="$IFS"; IFS='~'
for cmd in $cmds; do
IFS="$save_ifs"
+ eval cmd=\"$cmd\"
$show "$cmd"
$run eval "$cmd" || admincmds="$admincmds
$cmd"
@@ -5703,9 +6263,9 @@ relink_command=\"$relink_command\""
fi
# Exit here if they wanted silent mode.
- test "$show" = : && exit 0
+ test "$show" = : && exit $EXIT_SUCCESS
- $echo "----------------------------------------------------------------------"
+ $echo "X----------------------------------------------------------------------" | $Xsed
$echo "Libraries have been installed in:"
for libdir in $libdirs; do
$echo " $libdir"
@@ -5738,8 +6298,8 @@ relink_command=\"$relink_command\""
$echo
$echo "See any operating system documentation about shared libraries for"
$echo "more information, such as the ld(1) and ld.so(8) manual pages."
- $echo "----------------------------------------------------------------------"
- exit 0
+ $echo "X----------------------------------------------------------------------" | $Xsed
+ exit $EXIT_SUCCESS
;;
# libtool execute mode
@@ -5751,7 +6311,7 @@ relink_command=\"$relink_command\""
if test -z "$cmd"; then
$echo "$modename: you must specify a COMMAND" 1>&2
$echo "$help"
- exit 1
+ exit $EXIT_FAILURE
fi
# Handle -dlopen flags immediately.
@@ -5759,7 +6319,7 @@ relink_command=\"$relink_command\""
if test ! -f "$file"; then
$echo "$modename: \`$file' is not a file" 1>&2
$echo "$help" 1>&2
- exit 1
+ exit $EXIT_FAILURE
fi
dir=
@@ -5770,7 +6330,7 @@ relink_command=\"$relink_command\""
else
$echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
$echo "$help" 1>&2
- exit 1
+ exit $EXIT_FAILURE
fi
# Read the libtool library.
@@ -5797,7 +6357,7 @@ relink_command=\"$relink_command\""
dir="$dir/$objdir"
else
$echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2
- exit 1
+ exit $EXIT_FAILURE
fi
;;
@@ -5877,7 +6437,7 @@ relink_command=\"$relink_command\""
$echo "export $shlibpath_var"
fi
$echo "$cmd$args"
- exit 0
+ exit $EXIT_SUCCESS
fi
;;
@@ -5905,7 +6465,7 @@ relink_command=\"$relink_command\""
if test -z "$rm"; then
$echo "$modename: you must specify an RM program" 1>&2
$echo "$help" 1>&2
- exit 1
+ exit $EXIT_FAILURE
fi
rmdirs=
@@ -5955,15 +6515,24 @@ relink_command=\"$relink_command\""
rmfiles="$rmfiles $objdir/$n"
done
test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library"
- test "$mode" = clean && rmfiles="$rmfiles $objdir/$name $objdir/${name}i"
- if test "$mode" = uninstall; then
+ case "$mode" in
+ clean)
+ case " $library_names " in
+ # " " in the beginning catches empty $dlname
+ *" $dlname "*) ;;
+ *) rmfiles="$rmfiles $objdir/$dlname" ;;
+ esac
+ test -n "$libdir" && rmfiles="$rmfiles $objdir/$name $objdir/${name}i"
+ ;;
+ uninstall)
if test -n "$library_names"; then
# Do each command in the postuninstall commands.
- eval cmds=\"$postuninstall_cmds\"
+ cmds=$postuninstall_cmds
save_ifs="$IFS"; IFS='~'
for cmd in $cmds; do
IFS="$save_ifs"
+ eval cmd=\"$cmd\"
$show "$cmd"
$run eval "$cmd"
if test "$?" -ne 0 && test "$rmforce" != yes; then
@@ -5975,10 +6544,11 @@ relink_command=\"$relink_command\""
if test -n "$old_library"; then
# Do each command in the old_postuninstall commands.
- eval cmds=\"$old_postuninstall_cmds\"
+ cmds=$old_postuninstall_cmds
save_ifs="$IFS"; IFS='~'
for cmd in $cmds; do
IFS="$save_ifs"
+ eval cmd=\"$cmd\"
$show "$cmd"
$run eval "$cmd"
if test "$?" -ne 0 && test "$rmforce" != yes; then
@@ -5988,7 +6558,8 @@ relink_command=\"$relink_command\""
IFS="$save_ifs"
fi
# FIXME: should reinstall the best remaining shared library.
- fi
+ ;;
+ esac
fi
;;
@@ -6017,7 +6588,7 @@ relink_command=\"$relink_command\""
if test "$mode" = clean ; then
noexename=$name
case $file in
- *.exe)
+ *.exe)
file=`$echo $file|${SED} 's,.exe$,,'`
noexename=`$echo $name|${SED} 's,.exe$,,'`
# $file with .exe has already been added to rmfiles,
@@ -6062,20 +6633,20 @@ relink_command=\"$relink_command\""
"")
$echo "$modename: you must specify a MODE" 1>&2
$echo "$generic_help" 1>&2
- exit 1
+ exit $EXIT_FAILURE
;;
esac
if test -z "$exec_cmd"; then
$echo "$modename: invalid operation mode \`$mode'" 1>&2
$echo "$generic_help" 1>&2
- exit 1
+ exit $EXIT_FAILURE
fi
fi # test -z "$show_help"
if test -n "$exec_cmd"; then
eval exec $exec_cmd
- exit 1
+ exit $EXIT_FAILURE
fi
# We need to display help for each of the modes.
@@ -6111,7 +6682,7 @@ MODE-ARGS vary depending on the MODE. Try \`$modename --help --mode=MODE' for
a more detailed description of MODE.
Report bugs to <bug-libtool@gnu.org>."
- exit 0
+ exit $EXIT_SUCCESS
;;
clean)
@@ -6223,6 +6794,8 @@ The following components of LINK-COMMAND are treated specially:
-no-undefined declare that a library does not refer to external symbols
-o OUTPUT-FILE create OUTPUT-FILE from the specified objects
-objectlist FILE Use a list of object files found in FILE to specify objects
+ -precious-files-regex REGEX
+ don't remove output files matching REGEX
-release RELEASE specify package release information
-rpath LIBDIR the created library will eventually be installed in LIBDIR
-R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries
@@ -6264,14 +6837,14 @@ Otherwise, only FILE itself is deleted using RM."
*)
$echo "$modename: invalid operation mode \`$mode'" 1>&2
$echo "$help" 1>&2
- exit 1
+ exit $EXIT_FAILURE
;;
esac
$echo
$echo "Try \`$modename --help' for more information about other modes."
-exit 0
+exit $?
# The TAGs below are defined such that we never get into a situation
# in which we disable both kinds of libraries. Given conflicting
@@ -6285,12 +6858,11 @@ exit 0
# configuration. But we'll never go from static-only to shared-only.
# ### BEGIN LIBTOOL TAG CONFIG: disable-shared
-build_libtool_libs=no
-build_old_libs=yes
+disable_libs=shared
# ### END LIBTOOL TAG CONFIG: disable-shared
# ### BEGIN LIBTOOL TAG CONFIG: disable-static
-build_old_libs=`case $build_libtool_libs in yes) $echo no;; *) $echo yes;; esac`
+disable_libs=static
# ### END LIBTOOL TAG CONFIG: disable-static
# Local Variables:
diff --git a/packages/deb/changelog b/packages/deb/changelog
index 97a5436..a38bdc5 100644
--- a/packages/deb/changelog
+++ b/packages/deb/changelog
@@ -1,5 +1,146 @@
+google-perftools (0.90-1) unstable; urgency=low
+
+ * google-perftools: version 0.90 release
+ * (As the version-number jump hints, this is a major new release:
+ almost every piece of functionality was rewritten. I can't do
+ justice to all the changes, but will concentrate on highlights.)
+ *** USER-VISIBLE CHANGES:
+ * Ability to "release" unused memory added to tcmalloc
+ * Exposed more tweaking knobs via environment variables (see docs)
+ * pprof tries harder to map addresses to functions
+ * tcmalloc_minimal compiles and runs on FreeBSD 6.0 and Solaris 10
+ *** INTERNAL CHANGES:
+ * Much better 64-bit support
+ * Better multiple-processor support (e.g. multicore contention tweaks)
+ * Support for recent kernel ABI changes (e.g. new arg to mremap)
+ * Addition of spinlocks to tcmalloc to reduce contention cost
+ * Speed up tcmalloc by using __thread on systems that support TLS
+ * Total redesign of heap-checker to improve liveness checking
+ * More portable stack-frame analysis -- no more hard-coded constants!
+ * Disentangled heap-profiler code and heap-checker code
+ * Several new unittests to test, e.g., thread-contention costs
+ * Lots of small (but important!) bug fixes: e.g., fixing GetPC on amd64
+ *** KNOWN PROBLEMS:
+ * CPU-profiling may crash on x86_64 (64-bit) systems. See the README
+ * Profiling/heap-checking may deadlock on x86_64 systems. See README
+
+ -- Google Inc. <opensource@google.com> Fri, 13 Apr 2007 14:50:51 -0700
+
+google-perftools (0.8-1) unstable; urgency=low
+
+ * google-perftools: version 0.8 release
+ * Experimental support for remote profiling added to pprof (many)
+ * Fixed race condition in ProfileData::FlushTable (etune)
+ * Better support for weird /proc maps (maxim, mec)
+ * Fix heap-checker interaction with gdb (markus)
+ * Better 64-bit support in pprof (aruns)
+ * Reduce scavenging cost in tcmalloc by capping NumMoveSize (sanjay)
+ * Cast syscall(SYS_mmap); works on more 64-bit systems now (menage)
+ * Document the text output of pprof! (csilvers)
+ * Better compiler support for no-THREADS and for old compilers (csilvers)
+ * Make libunwind the default stack unwinder for x86-64 (aruns)
+ * Somehow the COPYING file got erased. Regenerate it (csilvers)
+
+ -- Google Inc. <opensource@google.com> Wed, 14 Jun 2006 15:11:14 -0700
+
+google-perftools (0.7-1) unstable; urgency=low
+
+ * google-perftools: version 0.7 release
+ * Major rewrite of thread introspection for new kernels (markus)
+ * Major rewrite of heap-checker to use new thread tools (maxim)
+ * Add proper support for following data in thread registers (maxim)
+ * Syscall support for older kernels, including _syscall6 (markus)
+ * Support PIC mode (markus, mbland, iant)
+ * Better support for running in non-threaded contexts (csilvers)
+
+ -- Google Inc. <opensource@google.com> Thu, 13 Apr 2006 20:59:09 -0700
+
+google-perftools (0.6-1) unstable; urgency=low
+
+ * google-perftools: version 0.6 release
+ * More sophisticated stacktrace usage, possibly using libunwind (aruns)
+ * Update pprof to handle 64-bit profiles (dehnert)
+ * Fix GetStackTrace to correctly return top stackframe (sanjay)
+ * Add ANSI compliance for new and new[], including new_handler (jkearney)
+ * More accuracy by reading ELF files directly rather than objdump (mec)
+ * Add readline support for pprof (addi)
+ * Add #includes for PPC (csilvers)
+ * New PC-detection routine for ibook powerpc (asbestoshead)
+ * Vastly improved tcmalloc unittest (csilvers)
+ * Move documentation from /usr/doc to /usr/share/doc
+
+ -- Google Inc. <opensource@google.com> Fri, 27 Jan 2006 14:04:27 -0800
+
+google-perftools (0.5-1) unstable; urgency=low
+
+ * google-perftools: version 0.5 release
+ * Add va_start/va_end calls around vsnprintf() (csilvers)
+ * Write our own __syscall_return(), since it's not defined
+ consistently on all 64-bit linux distros (markus)
+
+ -- Google Inc. <opensource@google.com> Mon Nov 14 17:28:59 2005
+
+google-perftools (0.4-1) unstable; urgency=low
+
+ * google-perftools: version 0.4 release
+ * Decrease fragmentation in tcmalloc (lefevere)
+ * Support for ARM in some of the thread-specific code (markus)
+ * Turn off heap-checker for statically-linked binaries, which
+ cause error leak reports now (etune)
+ * Many pprof improvements, including a command-line interface (jeff)
+ * CPU profiling now automatically affects all threads in linux 2.6.
+ (Kernel bugs break CPU profiling and threads in linux 2.4 a bit.)
+ ProfilerEnable() and ProfilerDisable() are deprecated. (sanjay)
+ * tcmalloc now correctly intercepts memalign (m3b, maxim)
+ * Syntax fix: added missing va_end()s. Helps non-gcc compiling (etune)
+ * Fixed a few coredumper bugs: race condition after PTRACE_DETACH,
+ ignore non-aligned stackframe pointers (markus, menage)
+ * 64-bit cleanup, especially for spinlock code (etune) and mmap (sanjay)
+ * Better support for finding threads in linux (markus)
+ * tcmalloc now tracks those stack traces that allocate memory (sanjay)
+ * Work around a weird setspecific problem (sanjay)
+ * Fix tcmalloc overflow problems when an alloc is close to 2G/4G (sanjay)
+
+ -- Google Inc. <opensource@google.com> Wed, 26 Oct 2005 15:19:16 -0700
+
+google-perftools (0.3-1) unstable; urgency=low
+
+ * google-perftools: version 0.3 release
+ * Add missing errno include for one of the unittests (csilvers)
+ * Reduce tcmalloc startup memory from 5M to 256K (sanjay)
+ * Add support for mallopt() and mallinfo (sanjay)
+ * Improve stacktrace's performance on some 64-bit systems (etune)
+ * Improve the stacktrace unittest (etune)
+
+ -- Google Inc. <opensource@google.com> Fri, 24 Jun 2005 18:02:26 -0700
+
+google-perftools (0.2-1) unstable; urgency=low
+
+ * google-perftools: version 0.2 release
+ * Use mmap2() instead of mmap(), to map more memory (menage)
+ * Do correct pthread-local checking in heap-checker! (maxim)
+ * Avoid overflow on 64-bit machines in pprof (sanjay)
+ * Add a few more GetPC() functions, including for AMD (csilvers)
+ * Better method for overriding pthread functions (menage)
+ * (Hacky) fix to avoid overwriting profile files after fork() (csilvers)
+ * Crashing bugfix involving dumping heaps on small-stack threads (tudor)
+ * Allow library versions with letters at the end (csilvers)
+ * Config fixes for systems that don't define PATH_MAX (csilvers)
+ * Confix fixes so we no longer need config.h after install (csilvers)
+ * Fix to pprof to correctly read very big cpu profiles (csilvers)
+ * Fix to pprof to deal with new commandline flags in modern gv's
+ * Better error reporting when we can't access /proc/maps (etune)
+ * Get rid of the libc-preallocate code (which could crash on some
+ systems); no longer needed with local-threads fix (csilvers)
+
+ -- Google Inc. <opensource@google.com> Tue, 31 May 2005 08:14:38 -0700
+
google-perftools (0.1-1) unstable; urgency=low
* Initial release.
+ The google-perftools package contains some utilities to improve
+ and analyze the performance of C++ programs. This includes an
+ optimized thread-caching malloc() and cpu and heap profiling
+ utilities.
-- Google Inc. <opensource@google.com> Fri, 11 Mar 2005 08:07:33 -0800
diff --git a/packages/deb/docs b/packages/deb/docs
new file mode 100644
index 0000000..d43c7dc
--- /dev/null
+++ b/packages/deb/docs
@@ -0,0 +1,46 @@
+AUTHORS
+COPYING
+ChangeLog
+INSTALL
+NEWS
+README
+TODO
+doc/cpuprofile.html
+doc/designstyle.css
+doc/heap-example1.png
+doc/heap_checker.html
+doc/heapprofile.html
+doc/index.html
+doc/overview.gif
+doc/pageheap.gif
+doc/pprof-test-big.gif
+doc/pprof-test.gif
+doc/pprof-vsnprintf-big.gif
+doc/pprof-vsnprintf.gif
+doc/pprof.1
+doc/pprof_remote_servers.html
+doc/spanmap.gif
+doc/t-test1.times.txt
+doc/tcmalloc-opspercpusec.vs.threads.1024.bytes.png
+doc/tcmalloc-opspercpusec.vs.threads.128.bytes.png
+doc/tcmalloc-opspercpusec.vs.threads.131072.bytes.png
+doc/tcmalloc-opspercpusec.vs.threads.16384.bytes.png
+doc/tcmalloc-opspercpusec.vs.threads.2048.bytes.png
+doc/tcmalloc-opspercpusec.vs.threads.256.bytes.png
+doc/tcmalloc-opspercpusec.vs.threads.32768.bytes.png
+doc/tcmalloc-opspercpusec.vs.threads.4096.bytes.png
+doc/tcmalloc-opspercpusec.vs.threads.512.bytes.png
+doc/tcmalloc-opspercpusec.vs.threads.64.bytes.png
+doc/tcmalloc-opspercpusec.vs.threads.65536.bytes.png
+doc/tcmalloc-opspercpusec.vs.threads.8192.bytes.png
+doc/tcmalloc-opspersec.vs.size.1.threads.png
+doc/tcmalloc-opspersec.vs.size.12.threads.png
+doc/tcmalloc-opspersec.vs.size.16.threads.png
+doc/tcmalloc-opspersec.vs.size.2.threads.png
+doc/tcmalloc-opspersec.vs.size.20.threads.png
+doc/tcmalloc-opspersec.vs.size.3.threads.png
+doc/tcmalloc-opspersec.vs.size.4.threads.png
+doc/tcmalloc-opspersec.vs.size.5.threads.png
+doc/tcmalloc-opspersec.vs.size.8.threads.png
+doc/tcmalloc.html
+doc/threadheap.gif
diff --git a/packages/rpm/rpm.spec b/packages/rpm/rpm.spec
index 60e903a..06c2853 100644
--- a/packages/rpm/rpm.spec
+++ b/packages/rpm/rpm.spec
@@ -51,7 +51,7 @@ rm -rf $RPM_BUILD_ROOT
%files
%defattr(-,root,root)
-%doc AUTHORS COPYING ChangeLog INSTALL NEWS README TODO doc/cpu_profiler.html doc/heap-example1.png doc/heap_checker.html doc/heap_profiler.html doc/index.html doc/overview.dot doc/overview.gif doc/pageheap.dot doc/pageheap.gif doc/pprof-test-big.gif doc/pprof-test.gif doc/pprof-vsnprintf-big.gif doc/pprof-vsnprintf.gif doc/spanmap.dot doc/spanmap.gif doc/t-test1.times.txt doc/tcmalloc-opspercpusec.vs.threads.1024.bytes.png doc/tcmalloc-opspercpusec.vs.threads.128.bytes.png doc/tcmalloc-opspercpusec.vs.threads.131072.bytes.png doc/tcmalloc-opspercpusec.vs.threads.16384.bytes.png doc/tcmalloc-opspercpusec.vs.threads.2048.bytes.png doc/tcmalloc-opspercpusec.vs.threads.256.bytes.png doc/tcmalloc-opspercpusec.vs.threads.32768.bytes.png doc/tcmalloc-opspercpusec.vs.threads.4096.bytes.png doc/tcmalloc-opspercpusec.vs.threads.512.bytes.png doc/tcmalloc-opspercpusec.vs.threads.64.bytes.png doc/tcmalloc-opspercpusec.vs.threads.65536.bytes.png doc/tcmalloc-opspercpusec.vs.threads.8192.bytes.png doc/tcmalloc-opspersec.vs.size.1.threads.png doc/tcmalloc-opspersec.vs.size.12.threads.png doc/tcmalloc-opspersec.vs.size.16.threads.png doc/tcmalloc-opspersec.vs.size.2.threads.png doc/tcmalloc-opspersec.vs.size.20.threads.png doc/tcmalloc-opspersec.vs.size.3.threads.png doc/tcmalloc-opspersec.vs.size.4.threads.png doc/tcmalloc-opspersec.vs.size.5.threads.png doc/tcmalloc-opspersec.vs.size.8.threads.png doc/tcmalloc.html doc/threadheap.dot doc/threadheap.gif
+%doc AUTHORS COPYING ChangeLog INSTALL NEWS README TODO doc/cpuprofile.html doc/designstyle.css doc/heap-example1.png doc/heap_checker.html doc/heapprofile.html doc/index.html doc/overview.dot doc/overview.gif doc/pageheap.dot doc/pageheap.gif doc/pprof-test-big.gif doc/pprof-test.gif doc/pprof-vsnprintf-big.gif doc/pprof-vsnprintf.gif doc/pprof.1 doc/pprof_remote_servers.html doc/spanmap.dot doc/spanmap.gif doc/t-test1.times.txt doc/tcmalloc-opspercpusec.vs.threads.1024.bytes.png doc/tcmalloc-opspercpusec.vs.threads.128.bytes.png doc/tcmalloc-opspercpusec.vs.threads.131072.bytes.png doc/tcmalloc-opspercpusec.vs.threads.16384.bytes.png doc/tcmalloc-opspercpusec.vs.threads.2048.bytes.png doc/tcmalloc-opspercpusec.vs.threads.256.bytes.png doc/tcmalloc-opspercpusec.vs.threads.32768.bytes.png doc/tcmalloc-opspercpusec.vs.threads.4096.bytes.png doc/tcmalloc-opspercpusec.vs.threads.512.bytes.png doc/tcmalloc-opspercpusec.vs.threads.64.bytes.png doc/tcmalloc-opspercpusec.vs.threads.65536.bytes.png doc/tcmalloc-opspercpusec.vs.threads.8192.bytes.png doc/tcmalloc-opspersec.vs.size.1.threads.png doc/tcmalloc-opspersec.vs.size.12.threads.png doc/tcmalloc-opspersec.vs.size.16.threads.png doc/tcmalloc-opspersec.vs.size.2.threads.png doc/tcmalloc-opspersec.vs.size.20.threads.png doc/tcmalloc-opspersec.vs.size.3.threads.png doc/tcmalloc-opspersec.vs.size.4.threads.png doc/tcmalloc-opspersec.vs.size.5.threads.png doc/tcmalloc-opspersec.vs.size.8.threads.png doc/tcmalloc.html doc/threadheap.dot doc/threadheap.gif
%{prefix}/lib/libstacktrace.so.0
%{prefix}/lib/libstacktrace.so.0.0.0
diff --git a/src/addressmap-inl.h b/src/addressmap-inl.h
index 93fe0a0..2241b9b 100644
--- a/src/addressmap-inl.h
+++ b/src/addressmap-inl.h
@@ -97,7 +97,6 @@ class AddressMap {
typedef void* (*Allocator)(size_t);
typedef void (*DeAllocator)(void*);
typedef void* Key;
- typedef void (*IteratorCallback)(Key, Value);
// Create an AddressMap that uses the specified allocator/deallocator.
// The allocator/deallocator should behave like malloc/free.
@@ -119,8 +118,11 @@ class AddressMap {
bool FindAndRemove(Key key, Value* removed_value);
// Iterate over the address map calling 'callback'
- // for all stored key-value pairs.
- void Iterate(IteratorCallback callback) const;
+ // for all stored key-value pairs and passing 'arg' to it.
+ // We don't use full Closure/Callback machinery not to add
+ // unnecessary dependencies to this class with low-level uses.
+ template<class Type>
+ void Iterate(void (*callback)(Key, Value, Type), Type arg) const;
private:
typedef uintptr_t Number;
@@ -328,12 +330,14 @@ bool AddressMap<Value>::FindAndRemove(Key key, Value* removed_value) {
}
template <class Value>
-void AddressMap<Value>::Iterate(IteratorCallback callback) const {
+template <class Type>
+void AddressMap<Value>::Iterate(void (*callback)(Key, Value, Type),
+ Type arg) const {
for (int h = 0; h < kHashSize; ++h) {
for (const Cluster* c = hashtable_[h]; c != NULL; c = c->next) {
for (int b = 0; b < kClusterBlocks; ++b) {
for (const Entry* e = c->blocks[b]; e != NULL; e = e->next) {
- callback(e->key, e->value);
+ callback(e->key, e->value, arg);
}
}
}
diff --git a/src/base/atomicops-internals-macosx.h b/src/base/atomicops-internals-macosx.h
new file mode 100644
index 0000000..9d3a486
--- /dev/null
+++ b/src/base/atomicops-internals-macosx.h
@@ -0,0 +1,212 @@
+/* Copyright (c) 2006, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ---
+ * Author: Mike Burrows
+ */
+
+// Implementation of atomic operations for Mac OS X. This file should not
+// be included directly. Clients should instead include
+// "base/atomicops.h".
+
+#ifndef BASE_ATOMICOPS_INTERNALS_MACOSX_H__
+#define BASE_ATOMICOPS_INTERNALS_MACOSX_H__
+
+typedef int32_t Atomic32;
+typedef intptr_t AtomicWord;
+
+#include <libkern/OSAtomic.h>
+
+#ifdef __LP64__ // Indicates 64-bit pointers under OS
+#define OSAtomicCastIntPtr(p) \
+ reinterpret_cast<int64_t *>(const_cast<AtomicWord *>(p))
+#define OSAtomicCompareAndSwapIntPtr OSAtomicCompareAndSwap64
+#define OSAtomicAddIntPtr OSAtomicAdd64
+#define OSAtomicCompareAndSwapIntPtrBarrier OSAtomicCompareAndSwap64Barrier
+#else
+#define OSAtomicCastIntPtr(p) \
+ reinterpret_cast<int32_t *>(const_cast<AtomicWord *>(p))
+#define OSAtomicCompareAndSwapIntPtr OSAtomicCompareAndSwap32
+#define OSAtomicAddIntPtr OSAtomicAdd32
+#define OSAtomicCompareAndSwapIntPtrBarrier OSAtomicCompareAndSwap32Barrier
+#endif
+
+inline void MemoryBarrier() {
+ OSMemoryBarrier();
+}
+
+inline AtomicWord CompareAndSwap(volatile AtomicWord *ptr,
+ AtomicWord old_value,
+ AtomicWord new_value) {
+ AtomicWord prev_value;
+ do {
+ if (OSAtomicCompareAndSwapIntPtr(old_value, new_value,
+ OSAtomicCastIntPtr(ptr))) {
+ return old_value;
+ }
+ prev_value = *ptr;
+ } while (prev_value == old_value);
+ return prev_value;
+}
+
+inline AtomicWord AtomicExchange(volatile AtomicWord *ptr,
+ AtomicWord new_value) {
+ AtomicWord old_value;
+ do {
+ old_value = *ptr;
+ } while (!OSAtomicCompareAndSwapIntPtr(old_value, new_value,
+ OSAtomicCastIntPtr(ptr)));
+ return old_value;
+}
+
+
+inline AtomicWord AtomicIncrement(volatile AtomicWord *ptr, AtomicWord increment) {
+ return OSAtomicAddIntPtr(increment, OSAtomicCastIntPtr(ptr));
+}
+
+inline AtomicWord Acquire_CompareAndSwap(volatile AtomicWord *ptr,
+ AtomicWord old_value,
+ AtomicWord new_value) {
+ AtomicWord prev_value;
+ do {
+ if (OSAtomicCompareAndSwapIntPtrBarrier(old_value, new_value,
+ OSAtomicCastIntPtr(ptr))) {
+ return old_value;
+ }
+ prev_value = *ptr;
+ } while (prev_value == old_value);
+ return prev_value;
+}
+
+inline AtomicWord Release_CompareAndSwap(volatile AtomicWord *ptr,
+ AtomicWord old_value,
+ AtomicWord new_value) {
+ // The lib kern interface does not distinguish between
+ // Acquire and Release memory barriers; they are equivalent.
+ return Acquire_CompareAndSwap(ptr, old_value, new_value);
+}
+
+
+inline void Acquire_Store(volatile AtomicWord *ptr, AtomicWord value) {
+ *ptr = value;
+ MemoryBarrier();
+}
+
+inline void Release_Store(volatile AtomicWord *ptr, AtomicWord value) {
+ MemoryBarrier();
+ *ptr = value;
+}
+
+inline AtomicWord Acquire_Load(volatile const AtomicWord *ptr) {
+ AtomicWord value = *ptr;
+ MemoryBarrier();
+ return value;
+}
+
+inline AtomicWord Release_Load(volatile const AtomicWord *ptr) {
+ MemoryBarrier();
+ return *ptr;
+}
+
+
+// MacOS uses long for intptr_t, AtomicWord and Atomic32 are always different
+// on the Mac, even when they are the same size. Thus, we always provide
+// Atomic32 versions.
+
+inline Atomic32 CompareAndSwap(volatile Atomic32 *ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ Atomic32 prev_value;
+ do {
+ if (OSAtomicCompareAndSwap32(old_value, new_value,
+ const_cast<Atomic32*>(ptr))) {
+ return old_value;
+ }
+ prev_value = *ptr;
+ } while (prev_value == old_value);
+ return prev_value;
+}
+
+inline Atomic32 AtomicExchange(volatile Atomic32 *ptr,
+ Atomic32 new_value) {
+ Atomic32 old_value;
+ do {
+ old_value = *ptr;
+ } while (!OSAtomicCompareAndSwap32(old_value, new_value,
+ const_cast<Atomic32*>(ptr)));
+ return old_value;
+}
+
+inline Atomic32 AtomicIncrement(volatile Atomic32 *ptr, Atomic32 increment) {
+ return OSAtomicAdd32(increment, const_cast<Atomic32*>(ptr));
+}
+
+inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32 *ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ Atomic32 prev_value;
+ do {
+ if (OSAtomicCompareAndSwap32Barrier(old_value, new_value,
+ const_cast<Atomic32*>(ptr))) {
+ return old_value;
+ }
+ prev_value = *ptr;
+ } while (prev_value == old_value);
+ return prev_value;
+}
+
+inline Atomic32 Release_CompareAndSwap(volatile Atomic32 *ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ return Acquire_CompareAndSwap(ptr, old_value, new_value);
+}
+
+
+inline void Acquire_Store(volatile Atomic32 *ptr, Atomic32 value) {
+ *ptr = value;
+ MemoryBarrier();
+}
+
+inline void Release_Store(volatile Atomic32 *ptr, Atomic32 value) {
+ MemoryBarrier();
+ *ptr = value;
+}
+
+inline Atomic32 Acquire_Load(volatile const Atomic32 *ptr) {
+ Atomic32 value = *ptr;
+ MemoryBarrier();
+ return value;
+}
+
+inline Atomic32 Release_Load(volatile const Atomic32 *ptr) {
+ MemoryBarrier();
+ return *ptr;
+}
+
+#endif // BASE_ATOMICOPS_INTERNALS_MACOSX_H__
diff --git a/src/base/atomicops-internals-x86-msvc.h b/src/base/atomicops-internals-x86-msvc.h
new file mode 100644
index 0000000..43ca751
--- /dev/null
+++ b/src/base/atomicops-internals-x86-msvc.h
@@ -0,0 +1,132 @@
+/* Copyright (c) 2006, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ---
+ * Author: Sanjay Ghemawat
+ */
+
+// Implementation of atomic operations for x86. This file should not
+// be included directly. Clients should instead include
+// "thread/atomicops.h".
+
+#ifndef BASE_ATOMICOPS_INTERNALS_X86_MSVC_H__
+#define BASE_ATOMICOPS_INTERNALS_X86_MSVC_H__
+#include "base/basictypes.h" // For COMPILE_ASSERT
+
+typedef intptr_t AtomicWord;
+#ifdef _WIN64
+typedef LONG Atomic32;
+#else
+typedef AtomicWord Atomic32;
+#endif
+
+COMPILE_ASSERT(sizeof(AtomicWord) == sizeof(PVOID), atomic_word_is_atomic);
+
+inline AtomicWord CompareAndSwap(volatile AtomicWord* ptr,
+ AtomicWord old_value,
+ AtomicWord new_value) {
+ PVOID result = InterlockedCompareExchangePointer(
+ reinterpret_cast<volatile PVOID*>(ptr),
+ reinterpret_cast<PVOID>(new_value), reinterpret_cast<PVOID>(old_value));
+ return reinterpret_cast<AtomicWord>(result);
+}
+
+inline AtomicWord AtomicExchange(volatile AtomicWord* ptr,
+ AtomicWord new_value) {
+ PVOID result = InterlockedExchangePointer(
+ const_cast<PVOID*>(reinterpret_cast<volatile PVOID*>(ptr)),
+ reinterpret_cast<PVOID>(new_value));
+ return reinterpret_cast<AtomicWord>(result);
+}
+
+#ifdef _WIN64
+inline Atomic32 AtomicIncrement(volatile Atomic32* ptr, Atomic32 increment) {
+ // InterlockedExchangeAdd returns *ptr before being incremented
+ // and we must return nonzero iff *ptr is nonzero after being
+ // incremented.
+ return InterlockedExchangeAdd(ptr, increment) + increment;
+}
+
+inline AtomicWord AtomicIncrement(volatile AtomicWord* ptr, AtomicWord increment) {
+ return InterlockedExchangeAdd64(
+ reinterpret_cast<volatile LONGLONG*>(ptr),
+ static_cast<LONGLONG>(increment)) + increment;
+}
+#else
+inline AtomicWord AtomicIncrement(volatile AtomicWord* ptr, AtomicWord increment) {
+ return InterlockedExchangeAdd(
+ reinterpret_cast<volatile LONG*>(ptr),
+ static_cast<LONG>(increment)) + increment;
+}
+#endif
+
+inline AtomicWord Acquire_CompareAndSwap(volatile AtomicWord* ptr,
+ AtomicWord old_value,
+ AtomicWord new_value) {
+ return CompareAndSwap(ptr, old_value, new_value);
+}
+
+inline AtomicWord Release_CompareAndSwap(volatile AtomicWord* ptr,
+ AtomicWord old_value,
+ AtomicWord new_value) {
+ return CompareAndSwap(ptr, old_value, new_value);
+}
+
+inline void MemoryBarrier() {
+ AtomicWord value = 0;
+ AtomicExchange(&value, 0); // acts as a barrier
+}
+
+inline void Acquire_Store(volatile AtomicWord* ptr, AtomicWord value) {
+ AtomicExchange(ptr, value);
+}
+
+inline void Release_Store(volatile AtomicWord* ptr, AtomicWord value) {
+ *ptr = value; // works w/o barrier for current Intel chips as of June 2005
+
+ // When new chips come out, check:
+ // IA-32 Intel Architecture Software Developer's Manual, Volume 3:
+ // System Programming Guide, Chatper 7: Multiple-processor management,
+ // Section 7.2, Memory Ordering.
+ // Last seen at:
+ // http://developer.intel.com/design/pentium4/manuals/index_new.htm
+}
+
+inline AtomicWord Acquire_Load(volatile const AtomicWord* ptr) {
+ AtomicWord value = *ptr;
+ MemoryBarrier();
+ return value;
+}
+
+inline AtomicWord Release_Load(volatile const AtomicWord* ptr) {
+ MemoryBarrier();
+ return *ptr;
+}
+
+#endif // BASE_ATOMICOPS_INTERNALS_X86_MSVC_H__
diff --git a/src/base/atomicops-internals-x86.cc b/src/base/atomicops-internals-x86.cc
new file mode 100644
index 0000000..9d61fd7
--- /dev/null
+++ b/src/base/atomicops-internals-x86.cc
@@ -0,0 +1,119 @@
+/* Copyright (c) 2007, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ---
+ * Author: Mike Burrows
+ *
+ * This module gets enough CPU information to optimize the
+ * atomicops module on x86.
+ */
+
+#include "base/atomicops.h"
+#include "base/basictypes.h"
+#include "base/googleinit.h"
+#include "base/logging.h"
+#include <string.h>
+
+// Inline cpuid instruction. In PIC compilations, %ebx contains the address
+// of the global offset table. To avoid breaking such executables, this code
+// must preserve that register's value across cpuid instructions.
+#if defined(__i386__)
+#define cpuid(a, b, c, d, inp) \
+ asm ("mov %%ebx, %%edi\n" \
+ "cpuid\n" \
+ "xchg %%edi, %%ebx\n" \
+ : "=a" (a), "=D" (b), "=c" (c), "=d" (d) : "a" (inp))
+#elif defined (__x86_64__)
+#define cpuid(a, b, c, d, inp) \
+ asm ("mov %%rbx, %%rdi\n" \
+ "cpuid\n" \
+ "xchg %%rdi, %%rbx\n" \
+ : "=a" (a), "=D" (b), "=c" (c), "=d" (d) : "a" (inp))
+#endif
+
+#if defined(cpuid) // initialize the struct only on x86
+
+// Set the flags so that code will run correctly and conservatively
+// until InitGoogle() is called.
+struct AtomicOps_x86CPUFeatureStruct AtomicOps_Internalx86CPUFeatures = {
+ false, // bug can't exist before process spawns multiple threads
+ false, // no SSE2
+ false, // no cmpxchg16b
+};
+
+// Initialize the AtomicOps_Internalx86CPUFeatures struct.
+static void AtomicOps_Internalx86CPUFeaturesInit() {
+ uint32 eax;
+ uint32 ebx;
+ uint32 ecx;
+ uint32 edx;
+
+ // Get vendor string (issue CPUID with eax = 0)
+ cpuid(eax, ebx, ecx, edx, 0);
+ char vendor[13];
+ memcpy(vendor, &ebx, 4);
+ memcpy(vendor + 4, &edx, 4);
+ memcpy(vendor + 8, &ecx, 4);
+ vendor[12] = 0;
+
+ // get feature flags in ecx/edx, and family/model in eax
+ cpuid(eax, ebx, ecx, edx, 1);
+
+ int family = (eax >> 8) & 0xf; // family and model fields
+ int model = (eax >> 4) & 0xf;
+ if (family == 0xf) { // use extended family and model fields
+ family += (eax >> 20) & 0xff;
+ model += ((eax >> 16) & 0xf) << 4;
+ }
+
+ // Opteron Rev E has a bug in which on very rare occasions a locked
+ // instruction doesn't act as a read-acquire barrier if followed by a
+ // non-locked read-modify-write instruction. Rev F has this bug in
+ // pre-release versions, but not in versions released to customers,
+ // so we test only for Rev E, which is family 15, model 32..63 inclusive.
+ if (strcmp(vendor, "AuthenticAMD") == 0 && // AMD
+ family == 15 &&
+ 32 <= model && model <= 63) {
+ AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug = true;
+ } else {
+ AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug = false;
+ }
+
+ // edx bit 26 is SSE2 which we use to tell use whether we can use mfence
+ AtomicOps_Internalx86CPUFeatures.has_sse2 = ((edx >> 26) & 1);
+
+ // ecx bit 13 indicates whether the cmpxchg16b instruction is supported
+ AtomicOps_Internalx86CPUFeatures.has_cmpxchg16b = ((ecx >> 13) & 1);
+}
+
+REGISTER_MODULE_INITIALIZER(atomicops_x86, {
+ AtomicOps_Internalx86CPUFeaturesInit();
+});
+
+#endif
diff --git a/src/base/atomicops-internals-x86.h b/src/base/atomicops-internals-x86.h
new file mode 100644
index 0000000..117d374
--- /dev/null
+++ b/src/base/atomicops-internals-x86.h
@@ -0,0 +1,253 @@
+/* Copyright (c) 2006, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ---
+ * Author: Sanjay Ghemawat
+ */
+
+// Implementation of atomic operations for x86. This file should not
+// be included directly. Clients should instead include
+// "thread/atomicops.h".
+
+#ifndef BASE_ATOMICOPS_INTERNALS_X86_H__
+#define BASE_ATOMICOPS_INTERNALS_X86_H__
+
+typedef intptr_t AtomicWord;
+typedef int32_t Atomic32;
+
+// There are a couple places we need to specialize opcodes to account for the
+// different AtomicWord sizes on x86_64 and 32-bit platforms.
+// This macro is undefined after its last use, below.
+#if defined(__x86_64__)
+#define ATOMICOPS_WORD_SUFFIX "q"
+#else
+#define ATOMICOPS_WORD_SUFFIX "l"
+#endif
+
+// This struct is not part of the public API of this module; clients may not
+// use it.
+// Features of this x86. Values may not be correct before main() is run,
+// but are set conservatively.
+struct AtomicOps_x86CPUFeatureStruct {
+ bool has_amd_lock_mb_bug; // Processor has AMD memory-barrier bug; do lfence
+ // after acquire compare-and-swap.
+ bool has_sse2; // Processor has SSE2.
+ bool has_cmpxchg16b; // Processor supports cmpxchg16b instruction.
+};
+extern struct AtomicOps_x86CPUFeatureStruct AtomicOps_Internalx86CPUFeatures;
+
+inline AtomicWord CompareAndSwap(volatile AtomicWord* ptr,
+ AtomicWord old_value,
+ AtomicWord new_value) {
+ AtomicWord prev;
+ __asm__ __volatile__("lock; cmpxchg" ATOMICOPS_WORD_SUFFIX " %1,%2"
+ : "=a" (prev)
+ : "q" (new_value), "m" (*ptr), "0" (old_value)
+ : "memory");
+ return prev;
+}
+
+inline AtomicWord AtomicExchange(volatile AtomicWord* ptr,
+ AtomicWord new_value) {
+ __asm__ __volatile__("xchg" ATOMICOPS_WORD_SUFFIX " %1,%0" // The lock prefix
+ : "=r" (new_value) // is implicit for
+ : "m" (*ptr), "0" (new_value) // xchg.
+ : "memory");
+ return new_value; // Now it's the previous value.
+}
+
+inline AtomicWord AtomicIncrement(volatile AtomicWord* ptr, AtomicWord increment) {
+ AtomicWord temp = increment;
+ __asm__ __volatile__("lock; xadd" ATOMICOPS_WORD_SUFFIX " %0,%1"
+ : "+r" (temp), "+m" (*ptr)
+ : : "memory");
+ // temp now contains the previous value of *ptr
+ return temp + increment;
+}
+
+#undef ATOMICOPS_WORD_SUFFIX
+
+
+inline AtomicWord Acquire_CompareAndSwap(volatile AtomicWord* ptr,
+ AtomicWord old_value,
+ AtomicWord new_value) {
+ AtomicWord x = CompareAndSwap(ptr, old_value, new_value);
+ if (AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug) {
+ __asm__ __volatile__("lfence" : : : "memory");
+ }
+ return x;
+}
+
+inline AtomicWord Release_CompareAndSwap(volatile AtomicWord* ptr,
+ AtomicWord old_value,
+ AtomicWord new_value) {
+ return CompareAndSwap(ptr, old_value, new_value);
+}
+
+#define ATOMICOPS_COMPILER_BARRIER() __asm__ __volatile__("" : : : "memory")
+
+#if defined(__x86_64__)
+
+inline void MemoryBarrier() {
+ __asm__ __volatile__("mfence" : : : "memory");
+}
+
+inline void Acquire_Store(volatile AtomicWord* ptr, AtomicWord value) {
+ *ptr = value;
+ MemoryBarrier();
+}
+
+#else
+
+inline void MemoryBarrier() {
+ if (AtomicOps_Internalx86CPUFeatures.has_sse2) {
+ __asm__ __volatile__("mfence" : : : "memory");
+ } else { // mfence is faster but not present on PIII
+ AtomicWord x = 0;
+ AtomicExchange(&x, 0);
+ }
+}
+
+inline void Acquire_Store(volatile AtomicWord* ptr, AtomicWord value) {
+ if (AtomicOps_Internalx86CPUFeatures.has_sse2) {
+ *ptr = value;
+ __asm__ __volatile__("mfence" : : : "memory");
+ } else {
+ AtomicExchange(ptr, value);
+ }
+}
+
+#endif
+
+inline void Release_Store(volatile AtomicWord* ptr, AtomicWord value) {
+ ATOMICOPS_COMPILER_BARRIER();
+ *ptr = value; // works w/o barrier for current Intel chips as of June 2005
+
+ // When new chips come out, check:
+ // IA-32 Intel Architecture Software Developer's Manual, Volume 3:
+ // System Programming Guide, Chatper 7: Multiple-processor management,
+ // Section 7.2, Memory Ordering.
+ // Last seen at:
+ // http://developer.intel.com/design/pentium4/manuals/index_new.htm
+}
+
+inline AtomicWord Acquire_Load(volatile const AtomicWord* ptr) {
+ AtomicWord value = *ptr;
+ MemoryBarrier();
+ return value;
+}
+
+inline AtomicWord Release_Load(volatile const AtomicWord* ptr) {
+ MemoryBarrier();
+ return *ptr;
+}
+
+// On a 64-bit machine, Atomic32 and AtomicWord are different types,
+// so we need to copy the preceding methods for Atomic32.
+
+#if defined(__x86_64__)
+
+inline Atomic32 CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ Atomic32 prev;
+ __asm__ __volatile__("lock; cmpxchgl %1,%2"
+ : "=a" (prev)
+ : "q" (new_value), "m" (*ptr), "0" (old_value)
+ : "memory");
+ return prev;
+}
+
+inline Atomic32 AtomicExchange(volatile Atomic32* ptr,
+ Atomic32 new_value) {
+ __asm__ __volatile__("xchgl %1,%0" // The lock prefix is implicit for xchg.
+ : "=r" (new_value)
+ : "m" (*ptr), "0" (new_value)
+ : "memory");
+ return new_value; // Now it's the previous value.
+}
+
+inline Atomic32 AtomicIncrement(volatile Atomic32* ptr, Atomic32 increment) {
+ Atomic32 temp = increment;
+ __asm__ __volatile__("lock; xaddl %0,%1"
+ : "+r" (temp), "+m" (*ptr)
+ : : "memory");
+ // temp now holds the old value of *ptr
+ return temp + increment;
+}
+
+inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ Atomic32 x = CompareAndSwap(ptr, old_value, new_value);
+ if (AtomicOps_Internalx86CPUFeatures.has_amd_lock_mb_bug) {
+ __asm__ __volatile__("lfence" : : : "memory");
+ }
+ return x;
+}
+
+inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ return CompareAndSwap(ptr, old_value, new_value);
+}
+
+inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
+ *ptr = value;
+ MemoryBarrier();
+}
+
+inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
+ ATOMICOPS_COMPILER_BARRIER();
+ *ptr = value; // works w/o barrier for current Intel chips as of June 2005
+
+ // When new chips come out, check:
+ // IA-32 Intel Architecture Software Developer's Manual, Volume 3:
+ // System Programming Guide, Chatper 7: Multiple-processor management,
+ // Section 7.2, Memory Ordering.
+ // Last seen at:
+ // http://developer.intel.com/design/pentium4/manuals/index_new.htm
+}
+
+inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
+ Atomic32 value = *ptr;
+ MemoryBarrier();
+ return value;
+}
+
+inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
+ MemoryBarrier();
+ return *ptr;
+}
+
+#endif /* defined(__x86_64__) */
+
+#undef ATOMICOPS_COMPILER_BARRIER
+
+#endif // BASE_ATOMICOPS_INTERNALS_X86_H__
diff --git a/src/base/atomicops.h b/src/base/atomicops.h
new file mode 100644
index 0000000..ba9696b
--- /dev/null
+++ b/src/base/atomicops.h
@@ -0,0 +1,142 @@
+/* Copyright (c) 2006, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ---
+ * Author: Sanjay Ghemawat
+ */
+
+// Some fast atomic operations -- typically with machine-dependent
+// implementations. This file may need editing as Google code is
+// ported to different architectures.
+
+#ifndef THREAD_ATOMICOPS_H__
+#define THREAD_ATOMICOPS_H__
+
+#include <stdint.h>
+
+// ------------------------------------------------------------------------
+// Include the platform specific implementations of the types
+// and operations listed below.
+// ------------------------------------------------------------------------
+
+#if defined(OS_MACOSX)
+#include "base/atomicops-internals-macosx.h"
+#elif defined(__GNUC__) && (defined(ARCH_PIII) || defined(ARCH_K8))
+#include "base/atomicops-internals-x86.h"
+#elif defined(ARCH_PIII) && defined(COMPILER_MSVC)
+#include "base/atomicops-internals-x86-msvc.h"
+#else
+// Assume x86 for now. If you need to support a new architecture and
+// don't know how to implement atomic ops, you can probably get away
+// with using pthreads, since atomicops is only used by spinlock.h/cc
+//#error You need to implement atomic operations for this architecture
+#include "base/atomicops-internals-x86.h"
+#endif
+
+// ------------------------------------------------------------------------
+// Commented out type definitions and method declarations for documentation
+// of the interface provided by this module.
+// ------------------------------------------------------------------------
+
+#if 0
+
+// Signed type that can hold a pointer and supports the atomic ops below, as
+// well as atomic loads and stores. Instances must be naturally-aligned.
+typedef intptr_t AtomicWord;
+
+// Signed 32-bit type that supports the atomic ops below, as well as atomic
+// loads and stores. Instances must be naturally aligned. This type differs
+// from AtomicWord in 64-bit binaries where AtomicWord is 64-bits.
+typedef int32_t Atomic32;
+
+// Atomically execute:
+// result = *ptr;
+// if (*ptr == old_value)
+// *ptr = new_value;
+// return result;
+//
+// I.e., replace "*ptr" with "new_value" if "*ptr" used to be "old_value".
+// Always return the old value of "*ptr"
+//
+// This routine implies no memory barriers.
+AtomicWord CompareAndSwap(volatile AtomicWord* ptr,
+ AtomicWord old_value,
+ AtomicWord new_value);
+
+// Atomically store new_value into *ptr, returning the previous value held in
+// *ptr. This routine implies no memory barriers.
+AtomicWord AtomicExchange(volatile AtomicWord* ptr, AtomicWord new_value);
+
+// Atomically increment *ptr by "increment". Returns the new value of
+// *ptr with the increment applied. This routine implies no memory
+// barriers.
+AtomicWord AtomicIncrement(volatile AtomicWord* ptr, AtomicWord increment);
+
+// ------------------------------------------------------------------------
+// These following lower-level operations are typically useful only to people
+// implementing higher-level synchronization operations like spinlocks,
+// mutexes, and condition-variables. They combine CompareAndSwap(), a load, or
+// a store with appropriate memory-ordering instructions. "Acquire" operations
+// ensure that no later memory access can be reordered ahead of the operation.
+// "Release" operations ensure that no previous memory access can be reordered
+// after the operation.
+// ------------------------------------------------------------------------
+AtomicWord Acquire_CompareAndSwap(volatile AtomicWord* ptr,
+ AtomicWord old_value,
+ AtomicWord new_value);
+AtomicWord Release_CompareAndSwap(volatile AtomicWord* ptr,
+ AtomicWord old_value,
+ AtomicWord new_value);
+void Acquire_Store(volatile AtomicWord* ptr, AtomicWord value);
+void Release_Store(volatile AtomicWord* ptr, AtomicWord value);
+AtomicWord Acquire_Load(volatile const AtomicWord* ptr);
+AtomicWord Release_Load(volatile const AtomicWord* ptr);
+
+// Corresponding operations on Atomic32
+Atomic32 CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value);
+Atomic32 AtomicExchange(volatile Atomic32* ptr, Atomic32 new_value);
+Atomic32 AtomicIncrement(volatile Atomic32* ptr, Atomic32 increment);
+Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value);
+Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value);
+void Acquire_Store(volatile Atomic32* ptr, Atomic32 value);
+void Release_Store(volatile Atomic32* ptr, Atomic32 value);
+Atomic32 Acquire_Load(volatile const Atomic32* ptr);
+Atomic32 Release_Load(volatile const Atomic32* ptr);
+
+void MemoryBarrier();
+
+#endif
+
+#endif // THREAD_ATOMICOPS_H__
diff --git a/src/base/basictypes.h b/src/base/basictypes.h
index 37e0196..aec3ddc 100644
--- a/src/base/basictypes.h
+++ b/src/base/basictypes.h
@@ -37,13 +37,14 @@
// AC_HEADER_STDC /* for stdint_h and inttypes_h */
// AC_CHECK_TYPES([__int64]) /* defined in some windows platforms */
-#if defined HAVE_STDINT_H
+#ifdef HAVE_STDINT_H
#include <stdint.h> // to get uint16_t (ISO naming madness)
-#elif defined HAVE_INTTYPES_H
-#include <inttypes.h> // another place uint16_t might be defined
-#else
-#include <sys/types.h> // our last best hope
#endif
+#ifdef HAVE_INTTYPES_H
+#define __STDC_FORMAT_MACROS // gets us PRId64, etc.
+#include <inttypes.h> // uint16_t might be here; PRId64 too.
+#endif
+#include <sys/types.h> // our last best hope for uint16_t
// Standard typedefs
// All Google code is compiled with -funsigned-char to make "char"
@@ -88,10 +89,115 @@ const int16 kint16min = ( ( int16) 0x8000);
const int32 kint32min = ( ( int32) 0x80000000);
const int64 kint64min = ( ((( int64) kint32min) << 32) | 0 );
+// Define the "portable" printf and scanf macros, if they're not already there
+// We just do something that works on many systems, and hope for the best
+#ifndef PRIx64
+#define PRIx64 "llx"
+#endif
+#ifndef SCNx64
+#define SCNx64 "llx"
+#endif
+#ifndef PRId64
+#define PRId64 "lld"
+#endif
+#ifndef SCNd64
+#define SCNd64 "lld"
+#endif
+
+
// A macro to disallow the evil copy constructor and operator= functions
// This should be used in the private: declarations for a class
#define DISALLOW_EVIL_CONSTRUCTORS(TypeName) \
TypeName(const TypeName&); \
void operator=(const TypeName&)
+// The COMPILE_ASSERT macro can be used to verify that a compile time
+// expression is true. For example, you could use it to verify the
+// size of a static array:
+//
+// COMPILE_ASSERT(sizeof(num_content_type_names) == sizeof(int),
+// content_type_names_incorrect_size);
+//
+// or to make sure a struct is smaller than a certain size:
+//
+// COMPILE_ASSERT(sizeof(foo) < 128, foo_too_large);
+//
+// The second argument to the macro is the name of the variable. If
+// the expression is false, most compilers will issue a warning/error
+// containing the name of the variable.
+//
+// Implementation details of COMPILE_ASSERT:
+//
+// - COMPILE_ASSERT works by defining an array type that has -1
+// elements (and thus is invalid) when the expression is false.
+//
+// - The simpler definition
+//
+// #define COMPILE_ASSERT(expr, msg) typedef char msg[(expr) ? 1 : -1]
+//
+// does not work, as gcc supports variable-length arrays whose sizes
+// are determined at run-time (this is gcc's extension and not part
+// of the C++ standard). As a result, gcc fails to reject the
+// following code with the simple definition:
+//
+// int foo;
+// COMPILE_ASSERT(foo, msg); // not supposed to compile as foo is
+// // not a compile-time constant.
+//
+// - By using the type CompileAssert<(bool(expr))>, we ensures that
+// expr is a compile-time constant. (Template arguments must be
+// determined at compile-time.)
+//
+// - The outter parentheses in CompileAssert<(bool(expr))> are necessary
+// to work around a bug in gcc 3.4.4 and 4.0.1. If we had written
+//
+// CompileAssert<bool(expr)>
+//
+// instead, these compilers will refuse to compile
+//
+// COMPILE_ASSERT(5 > 0, some_message);
+//
+// (They seem to think the ">" in "5 > 0" marks the end of the
+// template argument list.)
+//
+// - The array size is (bool(expr) ? 1 : -1), instead of simply
+//
+// ((expr) ? 1 : -1).
+//
+// This is to avoid running into a bug in MS VC 7.1, which
+// causes ((0.0) ? 1 : -1) to incorrectly evaluate to 1.
+
+template <bool>
+struct CompileAssert {
+};
+
+#define COMPILE_ASSERT(expr, msg) \
+ typedef CompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1]
+
+#define ARRAYSIZE(a) (sizeof(a) / sizeof(*(a)))
+
+#define OFFSETOF_MEMBER(strct, field) \
+ (reinterpret_cast<char*>(&reinterpret_cast<strct*>(16)->field) - \
+ reinterpret_cast<char*>(16))
+
+#ifdef HAVE___ATTRIBUTE__
+# define ATTRIBUTE_WEAK __attribute__((weak))
+# define ATTRIBUTE_SECTION(name) __attribute__ ((section (#name)))
+# define DECLARE_ATTRIBUTE_SECTION(name) \
+ extern char __start_##name[] ATTRIBUTE_WEAK; \
+ extern char __stop_##name[] ATTRIBUTE_WEAK;
+// Return void* pointers to start/end of a section of code with
+// functions having ATTRIBUTE_SECTION(name).
+// Returns 0 if no such functions exits.
+// One must DECLARE_ATTRIBUTE_SECTION(name) for this to compile and link.
+# define ATTRIBUTE_SECTION_START(name) (reinterpret_cast<void*>(__start_##name))
+# define ATTRIBUTE_SECTION_STOP(name) (reinterpret_cast<void*>(__stop_##name))
+#else
+# define ATTRIBUTE_WEAK
+# define ATTRIBUTE_SECTION(name)
+# define DECLARE_ATTRIBUTE_SECTION(name)
+# define ATTRIBUTE_SECTION_START(name) (reinterpret_cast<void*>(0))
+# define ATTRIBUTE_SECTION_STOP(name) (reinterpret_cast<void*>(0))
+#endif
+
#endif // _BASICTYPES_H_
diff --git a/src/base/commandlineflags.h b/src/base/commandlineflags.h
index c0d11ca..c8dd1f0 100644
--- a/src/base/commandlineflags.h
+++ b/src/base/commandlineflags.h
@@ -49,6 +49,7 @@
#define BASE_COMMANDLINEFLAGS_H__
#include <string>
+#include <string.h> // for memchr
#include "base/basictypes.h"
#define DECLARE_VARIABLE(type, name) \
@@ -107,4 +108,19 @@
} \
using FLAG__namespace_do_not_use_directly_use_DECLARE_string_instead::FLAGS_##name
+// These macros (could be functions, but I don't want to bother with a .cc
+// file), make it easier to initialize flags from the environment.
+
+#define EnvToString(envname, dflt) \
+ (!getenv(envname) ? (dflt) : getenv(envname))
+
+#define EnvToBool(envname, dflt) \
+ (!getenv(envname) ? (dflt) : memchr("tTyY1\0", getenv(envname)[0], 6) != NULL)
+
+#define EnvToInt(envname, dflt) \
+ (!getenv(envname) ? (dflt) : strtol(getenv(envname), NULL, 10))
+
+#define EnvToInt64(envname, dflt) \
+ (!getenv(envname) ? (dflt) : strtoll(getenv(envname), NULL, 10))
+
#endif // BASE_COMMANDLINEFLAGS_H__
diff --git a/src/base/elfcore.h b/src/base/elfcore.h
index f0b2534..eb93e05 100644
--- a/src/base/elfcore.h
+++ b/src/base/elfcore.h
@@ -1,10 +1,10 @@
-/* Copyright (c) 2005, Google Inc.
+/* Copyright (c) 2005-2007, Google Inc.
* All rights reserved.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
- *
+ *
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
@@ -14,7 +14,7 @@
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
- *
+ *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -33,12 +33,15 @@
#ifndef _ELFCORE_H
#define _ELFCORE_H
+#ifdef __cplusplus
+extern "C" {
+#endif
-/* We currently only support x86-32 and x86-64 on Linux. Porting to
- * other related platforms should not be difficult.
+/* We currently only support x86-32, x86-64, ARM, and MIPS on Linux.
+ * Porting to other related platforms should not be difficult.
*/
-#if (defined(__i386__) || defined(__x86_64__) || defined(__ARM_ARCH_3__)) && \
- defined(__linux)
+#if (defined(__i386__) || defined(__x86_64__) || defined(__ARM_ARCH_3__) || \
+ defined(mips)) && defined(__linux)
#include <stdarg.h>
#include <stdint.h>
@@ -93,6 +96,18 @@
#define LR uregs[14] /* Link register */
long uregs[18];
} arm_regs;
+#elif defined(mips)
+ typedef struct mips_regs {
+ unsigned long pad[6]; /* Unused padding to match kernel structures */
+ unsigned long uregs[32]; /* General purpose registers. */
+ unsigned long cp0_status;
+ unsigned long lo; /* Used for multiplication and division. */
+ unsigned long hi;
+ unsigned long cp0_badvaddr;
+ unsigned long cp0_cause;
+ unsigned long cp0_epc; /* Program counter. */
+ unsigned long unused;
+ } mips_regs;
#endif
#if defined(__i386__) && defined(__GNUC__)
@@ -151,6 +166,69 @@
errno = (f).errno_; \
(r) = (f).uregs; \
} while (0)
+#elif defined(__x86_64__) && defined(__GNUC__)
+ /* The FRAME and SET_FRAME macros for x86_64. */
+ typedef struct Frame {
+ struct i386_regs uregs;
+ int errno_;
+ pid_t tid;
+ } Frame;
+ #define FRAME(f) Frame f; \
+ do { \
+ f.errno_ = errno; \
+ f.tid = sys_gettid(); \
+ __asm__ volatile ( \
+ "push %%rbp\n" \
+ "push %%rbx\n" \
+ "mov %%r15,0(%%rax)\n" \
+ "mov %%r14,8(%%rax)\n" \
+ "mov %%r13,16(%%rax)\n" \
+ "mov %%r12,24(%%rax)\n" \
+ "mov %%rbp,32(%%rax)\n" \
+ "mov %%rbx,40(%%rax)\n" \
+ "mov %%r11,48(%%rax)\n" \
+ "mov %%r10,56(%%rax)\n" \
+ "mov %%r9,64(%%rax)\n" \
+ "mov %%r8,72(%%rax)\n" \
+ "mov %%rax,80(%%rax)\n" \
+ "mov %%rcx,88(%%rax)\n" \
+ "mov %%rdx,96(%%rax)\n" \
+ "mov %%rsi,104(%%rax)\n" \
+ "mov %%rdi,112(%%rax)\n" \
+ "mov %%ds,%%rbx\n" \
+ "mov %%rbx,184(%%rax)\n" \
+ "mov %%es,%%rbx\n" \
+ "mov %%rbx,192(%%rax)\n" \
+ "mov %%fs,%%rbx\n" \
+ "mov %%rbx,200(%%rax)\n" \
+ "mov %%gs,%%rbx\n" \
+ "mov %%rbx,208(%%rax)\n" \
+ "call 0f\n" \
+ "0:pop %%rbx\n" \
+ "add $1f-0b,%%rbx\n" \
+ "mov %%rbx,128(%%rax)\n" \
+ "mov %%cs,%%rbx\n" \
+ "mov %%rbx,136(%%rax)\n" \
+ "pushf\n" \
+ "pop %%rbx\n" \
+ "mov %%rbx,144(%%rax)\n" \
+ "mov %%rsp,%%rbx\n" \
+ "add $16,%%ebx\n" \
+ "mov %%rbx,152(%%rax)\n" \
+ "mov %%ss,%%rbx\n" \
+ "mov %%rbx,160(%%rax)\n" \
+ "pop %%rbx\n" \
+ "pop %%rbp\n" \
+ "1:" \
+ : : "a" (&f) : "memory"); \
+ } while (0)
+ #define SET_FRAME(f,r) \
+ do { \
+ errno = (f).errno_; \
+ (f).uregs.fs_base = (r).fs_base; \
+ (f).uregs.gs_base = (r).gs_base; \
+ (r) = (f).uregs; \
+ } while (0)
#elif defined(__ARM_ARCH_3__) && defined(__GNUC__)
/* ARM calling conventions are a little more tricky. A little assembly
* helps in obtaining an accurate snapshot of all registers.
@@ -185,6 +263,67 @@
(r) = (f).arm; \
(r).uregs[16] = fps; \
} while (0)
+#elif defined(mips) && defined(__GNUC__)
+ typedef struct Frame {
+ struct mips_regs mips_regs;
+ int errno_;
+ pid_t tid;
+ } Frame;
+ #define MIPSREG(n) ({ register unsigned long r __asm__("$"#n); r; })
+ #define FRAME(f) Frame f = { 0 }; \
+ do { \
+ unsigned long hi, lo; \
+ register unsigned long pc __asm__("$31"); \
+ f.mips_regs.uregs[ 0] = MIPSREG( 0); \
+ f.mips_regs.uregs[ 1] = MIPSREG( 1); \
+ f.mips_regs.uregs[ 2] = MIPSREG( 2); \
+ f.mips_regs.uregs[ 3] = MIPSREG( 3); \
+ f.mips_regs.uregs[ 4] = MIPSREG( 4); \
+ f.mips_regs.uregs[ 5] = MIPSREG( 5); \
+ f.mips_regs.uregs[ 6] = MIPSREG( 6); \
+ f.mips_regs.uregs[ 7] = MIPSREG( 7); \
+ f.mips_regs.uregs[ 8] = MIPSREG( 8); \
+ f.mips_regs.uregs[ 9] = MIPSREG( 9); \
+ f.mips_regs.uregs[10] = MIPSREG(10); \
+ f.mips_regs.uregs[11] = MIPSREG(11); \
+ f.mips_regs.uregs[12] = MIPSREG(12); \
+ f.mips_regs.uregs[13] = MIPSREG(13); \
+ f.mips_regs.uregs[14] = MIPSREG(14); \
+ f.mips_regs.uregs[15] = MIPSREG(15); \
+ f.mips_regs.uregs[16] = MIPSREG(16); \
+ f.mips_regs.uregs[17] = MIPSREG(17); \
+ f.mips_regs.uregs[18] = MIPSREG(18); \
+ f.mips_regs.uregs[19] = MIPSREG(19); \
+ f.mips_regs.uregs[20] = MIPSREG(20); \
+ f.mips_regs.uregs[21] = MIPSREG(21); \
+ f.mips_regs.uregs[22] = MIPSREG(22); \
+ f.mips_regs.uregs[23] = MIPSREG(23); \
+ f.mips_regs.uregs[24] = MIPSREG(24); \
+ f.mips_regs.uregs[25] = MIPSREG(25); \
+ f.mips_regs.uregs[26] = MIPSREG(26); \
+ f.mips_regs.uregs[27] = MIPSREG(27); \
+ f.mips_regs.uregs[28] = MIPSREG(28); \
+ f.mips_regs.uregs[29] = MIPSREG(29); \
+ f.mips_regs.uregs[30] = MIPSREG(30); \
+ f.mips_regs.uregs[31] = MIPSREG(31); \
+ __asm__ volatile ("mfhi %0" : "=r"(hi)); \
+ __asm__ volatile ("mflo %0" : "=r"(lo)); \
+ __asm__ volatile ("jal 1f; 1:nop" : "=r"(pc)); \
+ f.mips_regs.hi = hi; \
+ f.mips_regs.lo = lo; \
+ f.mips_regs.cp0_epc = pc; \
+ f.errno_ = errno; \
+ f.tid = sys_gettid(); \
+ } while (0)
+ #define SET_FRAME(f,r) \
+ do { \
+ errno = (f).errno_; \
+ memcpy((r).uregs, (f).mips_regs.uregs, \
+ 32*sizeof(unsigned long)); \
+ (r).hi = (f).mips_regs.hi; \
+ (r).lo = (f).mips_regs.lo; \
+ (r).cp0_epc = (f).mips_regs.cp0_epc; \
+ } while (0)
#else
/* If we do not have a hand-optimized assembly version of the FRAME()
* macro, we cannot reliably unroll the stack. So, we show a few additional
@@ -239,4 +378,7 @@ int InternalGetCoreDump(void *frame, int num_threads, pid_t *thread_pids,
#endif
+#ifdef __cplusplus
+}
+#endif
#endif /* _ELFCORE_H */
diff --git a/src/base/googleinit.h b/src/base/googleinit.h
index 029bc81..62ad84c 100644
--- a/src/base/googleinit.h
+++ b/src/base/googleinit.h
@@ -41,9 +41,11 @@ class GoogleInitializer {
}
};
-#define REGISTER_MODULE_INITIALIZER(name,body) \
- static void google_init_module_##name () { body; } \
- GoogleInitializer google_initializer_module_##name(#name, \
- google_init_module_##name)
+#define REGISTER_MODULE_INITIALIZER(name, body) \
+ namespace { \
+ static void google_init_module_##name () { body; } \
+ GoogleInitializer google_initializer_module_##name(#name, \
+ google_init_module_##name); \
+ }
#endif /* _GOOGLEINIT_H */
diff --git a/src/base/linux_syscall_support.h b/src/base/linux_syscall_support.h
index 0dfdd8d..b308ced 100644
--- a/src/base/linux_syscall_support.h
+++ b/src/base/linux_syscall_support.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2005, Google Inc.
+/* Copyright (c) 2005-2007, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -35,16 +35,51 @@
* coredumper and the thread lister; primarily, this is a collection
* of direct system calls, and a couple of symbols missing from
* standard header files.
+ * There are a few options that the including file can set to control
+ * the behavior of this file:
+ *
+ * SYS_CPLUSPLUS:
+ * The entire header file will normally be wrapped in 'extern "C" { }",
+ * making it suitable for compilation as both C and C++ source. If you
+ * do not want to do this, you can set the SYS_CPLUSPLUS macro to inhibit
+ * the wrapping. N.B. doing so will suppress inclusion of all prerequisite
+ * system header files, too. It is the caller's responsibility to provide
+ * the necessary definitions.
+ *
+ * SYS_ERRNO:
+ * All system calls will update "errno" unless overriden by setting the
+ * SYS_ERRNO macro prior to including this file. SYS_ERRNO should be
+ * an l-value.
+ *
+ * SYS_INLINE:
+ * New symbols will be defined "static inline", unless overridden by
+ * the SYS_INLINE macro.
+ *
+ * SYS_LINUX_SYSCALL_SUPPORT_H
+ * This macro is used to avoid multiple inclusions of this header file.
+ * If you need to include this file more than once, make sure to
+ * unset SYS_LINUX_SYSCALL_SUPPORT_H before each inclusion.
+ *
+ * SYS_PREFIX:
+ * New system calls will have a prefix of "sys_" unless overridden by
+ * the SYS_PREFIX macro. Valid values for this macro are [0..9] which
+ * results in prefixes "sys[0..9]_". It is also possible to set this
+ * macro to -1, which avoids all prefixes.
+ *
+ * This file defines a few internal symbols that all start with "LSS_".
+ * Do not access these symbols from outside this file. They are not part
+ * of the supported API.
*/
-#ifndef _LINUX_CORE_SUPPORT_H
-#define _LINUX_CORE_SUPPORT_H
+#ifndef SYS_LINUX_SYSCALL_SUPPORT_H
+#define SYS_LINUX_SYSCALL_SUPPORT_H
-/* We currently only support x86-32, x86-64, and ARM on Linux. Porting to
- * other related platforms should not be difficult.
+/* We currently only support x86-32, x86-64, ARM, and MIPS on Linux.
+ * Porting to other related platforms should not be difficult.
*/
-#if (defined(__i386__) || defined(__x86_64__) || defined(__ARM_ARCH_3__)) && \
- defined(__linux)
+#if (defined(__i386__) || defined(__x86_64__) || defined(__ARM_ARCH_3__) || \
+ defined(mips)) && defined(__linux)
+#ifndef SYS_CPLUSPLUS
#ifdef __cplusplus
/* Some system header files in older versions of gcc neglect to properly
* handle being included from C++. As it appears to be harmless to have
@@ -64,28 +99,78 @@ extern "C" {
#include <unistd.h>
#include <linux/unistd.h>
+/* libc defines versions of stat, dirent, and dirent64 that are incompatible
+ * with the structures that the kernel API expects. If you wish to use
+ * sys_fstat(), sys_stat(), sys_getdents(), or sys_getdents64(), you will
+ * need to include the kernel headers in your code.
+ *
+ * asm/posix_types.h
+ * asm/stat.h
+ * asm/types.h
+ * linux/dirent.h
+ */
+struct dirent64;
+struct dirent;
+struct iovec;
+struct msghdr;
+struct pollfd;
+struct rlimit;
+struct sockaddr;
+struct stat;
+struct stat64;
+
+#endif
+
+
/* Definitions missing from the standard header files */
#ifndef O_DIRECTORY
#if defined(__ARM_ARCH_3__)
-#define O_DIRECTORY 0040000
+#define O_DIRECTORY 0040000
#else
-#define O_DIRECTORY 0200000
+#define O_DIRECTORY 0200000
#endif
#endif
-#ifndef NT_PRFPXREG
-#define NT_PRFPXREG 20
+#ifndef NT_PRXFPREG
+#define NT_PRXFPREG 0x46e62b7f
#endif
#ifndef PTRACE_GETFPXREGS
-#define PTRACE_GETFPXREGS ((enum __ptrace_request)18)
+#define PTRACE_GETFPXREGS ((enum __ptrace_request)18)
#endif
#ifndef PR_GET_DUMPABLE
-#define PR_GET_DUMPABLE 3
+#define PR_GET_DUMPABLE 3
#endif
#ifndef PR_SET_DUMPABLE
-#define PR_SET_DUMPABLE 4
+#define PR_SET_DUMPABLE 4
+#endif
+#ifndef AT_FDCWD
+#define AT_FDCWD (-100)
+#endif
+#ifndef AT_SYMLINK_NOFOLLOW
+#define AT_SYMLINK_NOFOLLOW 0x100
+#endif
+#ifndef AT_REMOVEDIR
+#define AT_REMOVEDIR 0x200
+#endif
+#ifndef MREMAP_FIXED
+#define MREMAP_FIXED 2
#endif
#if defined(__i386__)
+#ifndef __NR_setresuid
+#define __NR_setresuid 164
+#define __NR_setresgid 170
+#endif
+#ifndef __NR_ugetrlimit
+#define __NR_ugetrlimit 191
+#endif
+#ifndef __NR_setresuid32
+#define __NR_setresuid32 208
+#define __NR_setresgid32 210
+#endif
+#ifndef __NR_setfsuid32
+#define __NR_setfsuid32 215
+#define __NR_setfsgid32 216
+#endif
#ifndef __NR_getdents64
#define __NR_getdents64 220
#endif
@@ -99,8 +184,38 @@ extern "C" {
#define __NR_sched_setaffinity 241
#define __NR_sched_getaffinity 242
#endif
+#ifndef __NR_set_tid_address
+#define __NR_set_tid_address 258
+#endif
+#ifndef __NR_openat
+#define __NR_openat 295
+#endif
+#ifndef __NR_fstatat64
+#define __NR_fstatat64 300
+#endif
+#ifndef __NR_unlinkat
+#define __NR_unlinkat 301
+#endif
+#ifndef __NR_move_pages
+#define __NR_move_pages 317
+#endif
/* End of i386 definitions */
#elif defined(__ARM_ARCH_3__)
+#ifndef __NR_setresuid
+#define __NR_setresuid (__NR_SYSCALL_BASE + 164)
+#define __NR_setresgid (__NR_SYSCALL_BASE + 170)
+#endif
+#ifndef __NR_ugetrlimit
+#define __NR_ugetrlimit (__NR_SYSCALL_BASE + 191)
+#endif
+#ifndef __NR_setresuid32
+#define __NR_setresuid32 (__NR_SYSCALL_BASE + 208)
+#define __NR_setresgid32 (__NR_SYSCALL_BASE + 210)
+#endif
+#ifndef __NR_setfsuid32
+#define __NR_setfsuid32 (__NR_SYSCALL_BASE + 215)
+#define __NR_setfsgid32 (__NR_SYSCALL_BASE + 216)
+#endif
#ifndef __NR_getdents64
#define __NR_getdents64 (__NR_SYSCALL_BASE + 217)
#endif
@@ -114,10 +229,17 @@ extern "C" {
#define __NR_sched_setaffinity (__NR_SYSCALL_BASE + 241)
#define __NR_sched_getaffinity (__NR_SYSCALL_BASE + 242)
#endif
+#ifndef __NR_set_tid_address
+#define __NR_set_tid_address (__NR_SYSCALL_BASE + 256)
+#endif
+#ifndef __NR_move_pages
+#define __NR_move_pages (__NR_SYSCALL_BASE + 344)
+#endif
/* End of ARM 3 definitions */
#elif defined(__x86_64__)
-#ifndef __NR_getdents64
-#define __NR_getdents64 217
+#ifndef __NR_setresuid
+#define __NR_setresuid 117
+#define __NR_setresgid 119
#endif
#ifndef __NR_gettid
#define __NR_gettid 186
@@ -129,22 +251,126 @@ extern "C" {
#define __NR_sched_setaffinity 203
#define __NR_sched_getaffinity 204
#endif
+#ifndef __NR_getdents64
+#define __NR_getdents64 217
+#endif
+#ifndef __NR_set_tid_address
+#define __NR_set_tid_address 218
+#endif
+#ifndef __NR_openat
+#define __NR_openat 257
+#endif
+#ifndef __NR_newfstatat
+#define __NR_newfstatat 262
+#endif
+#ifndef __NR_unlinkat
+#define __NR_unlinkat 263
+#endif
+#ifndef __NR_move_pages
+#define __NR_move_pages 279
+#endif
/* End of x86-64 definitions */
+#elif defined(mips)
+#if _MIPS_SIM == _MIPS_SIM_ABI32
+#ifndef __NR_setresuid
+#define __NR_setresuid (__NR_Linux + 185)
+#define __NR_setresgid (__NR_Linux + 190)
+#endif
+#ifndef __NR_getdents64
+#define __NR_getdents64 (__NR_Linux + 219)
+#endif
+#ifndef __NR_gettid
+#define __NR_gettid (__NR_Linux + 222)
+#endif
+#ifndef __NR_futex
+#define __NR_futex (__NR_Linux + 238)
+#endif
+#ifndef __NR_sched_setaffinity
+#define __NR_sched_setaffinity (__NR_Linux + 239)
+#define __NR_sched_getaffinity (__NR_Linux + 240)
+#endif
+#ifndef __NR_set_tid_address
+#define __NR_set_tid_address (__NR_Linux + 252)
+#endif
+#ifndef __NR_openat
+#define __NR_openat (__NR_Linux + 288)
+#endif
+#ifndef __NR_fstatat
+#define __NR_fstatat (__NR_Linux + 293)
+#endif
+#ifndef __NR_unlinkat
+#define __NR_unlinkat (__NR_Linux + 294)
+#endif
+#ifndef __NR_move_pages
+#define __NR_move_pages (__NR_Linux + 308)
+#endif
+/* End of MIPS (old 32bit API) definitions */
+#elif _MIPS_SIM == _MIPS_SIM_ABI64
+#ifndef __NR_setresuid
+#define __NR_setresuid (__NR_Linux + 115)
+#define __NR_setresgid (__NR_Linux + 117)
+#endif
+#ifndef __NR_gettid
+#define __NR_gettid (__NR_Linux + 178)
+#endif
+#ifndef __NR_futex
+#define __NR_futex (__NR_Linux + 194)
+#endif
+#ifndef __NR_sched_setaffinity
+#define __NR_sched_setaffinity (__NR_Linux + 195)
+#define __NR_sched_getaffinity (__NR_Linux + 196)
+#endif
+#ifndef __NR_set_tid_address
+#define __NR_set_tid_address (__NR_Linux + 212)
+#endif
+#ifndef __NR_openat
+#define __NR_openat (__NR_Linux + 247)
+#endif
+#ifndef __NR_fstatat
+#define __NR_fstatat (__NR_Linux + 252)
+#endif
+#ifndef __NR_unlinkat
+#define __NR_unlinkat (__NR_Linux + 253)
+#endif
+#ifndef __NR_move_pages
+#define __NR_move_pages (__NR_Linux + 267)
+#endif
+/* End of MIPS (64bit API) definitions */
+#else
+#ifndef __NR_setresuid
+#define __NR_setresuid (__NR_Linux + 115)
+#define __NR_setresgid (__NR_Linux + 117)
+#endif
+#ifndef __NR_gettid
+#define __NR_gettid (__NR_Linux + 178)
+#endif
+#ifndef __NR_futex
+#define __NR_futex (__NR_Linux + 194)
+#endif
+#ifndef __NR_sched_setaffinity
+#define __NR_sched_setaffinity (__NR_Linux + 195)
+#define __NR_sched_getaffinity (__NR_Linux + 196)
+#endif
+#ifndef __NR_set_tid_address
+#define __NR_set_tid_address (__NR_Linux + 213)
+#endif
+#ifndef __NR_openat
+#define __NR_openat (__NR_Linux + 251)
+#endif
+#ifndef __NR_fstatat
+#define __NR_fstatat (__NR_Linux + 256)
+#endif
+#ifndef __NR_unlinkat
+#define __NR_unlinkat (__NR_Linux + 257)
+#endif
+#ifndef __NR_move_pages
+#define __NR_move_pages (__NR_Linux + 271)
+#endif
+/* End of MIPS (new 32bit API) definitions */
+#endif
+/* End of MIPS definitions */
#endif
-/* libc defines versions of stat, dirent, and dirent64 that are incompatible
- * with the structures that the kernel API expects. If you wish to use
- * sys_fstat(), sys_stat(), sys_getdents(), or sys_getdents64(), you will
- * need to include the kernel headers in your code.
- *
- * asm/posix_types.h
- * asm/stat.h
- * asm/types.h
- * linux/dirent.h
- */
-struct stat;
-struct dirent;
-struct dirent64;
/* After forking, we must make sure to only call system calls. */
#if __BOUNDED_POINTERS__
@@ -157,14 +383,79 @@ struct dirent64;
* cancellable), which means we cannot call these functions. Instead,
* we have to call syscall() directly.
*/
- #define RETURN(type, res) \
+ #undef LSS_ERRNO
+ #ifdef SYS_ERRNO
+ /* Allow the including file to override the location of errno. This can
+ * be useful when using clone() with the CLONE_VM option.
+ */
+ #define LSS_ERRNO SYS_ERRNO
+ #else
+ #define LSS_ERRNO errno
+ #endif
+
+ #undef LSS_INLINE
+ #ifdef SYS_INLINE
+ #define LSS_INLINE SYS_INLINE
+ #else
+ #define LSS_INLINE static inline
+ #endif
+
+ /* Allow the including file to override the prefix used for all new
+ * system calls. By default, it will be set to "sys_".
+ */
+ #undef LSS_NAME
+ #ifndef SYS_PREFIX
+ #define LSS_NAME(name) sys_##name
+ #elif SYS_PREFIX < 0
+ #define LSS_NAME(name) name
+ #elif SYS_PREFIX == 0
+ #define LSS_NAME(name) sys0_##name
+ #elif SYS_PREFIX == 1
+ #define LSS_NAME(name) sys1_##name
+ #elif SYS_PREFIX == 2
+ #define LSS_NAME(name) sys2_##name
+ #elif SYS_PREFIX == 3
+ #define LSS_NAME(name) sys3_##name
+ #elif SYS_PREFIX == 4
+ #define LSS_NAME(name) sys4_##name
+ #elif SYS_PREFIX == 5
+ #define LSS_NAME(name) sys5_##name
+ #elif SYS_PREFIX == 6
+ #define LSS_NAME(name) sys6_##name
+ #elif SYS_PREFIX == 7
+ #define LSS_NAME(name) sys7_##name
+ #elif SYS_PREFIX == 8
+ #define LSS_NAME(name) sys8_##name
+ #elif SYS_PREFIX == 9
+ #define LSS_NAME(name) sys9_##name
+ #endif
+
+ #undef LSS_RETURN
+ #ifndef mips
+ /* Failing system calls return a negative result in the range of
+ * -1..-4095. These are "errno" values with the sign inverted.
+ */
+ #define LSS_RETURN(type, res) \
do { \
if ((unsigned long)(res) >= (unsigned long)(-4095)) { \
- errno = -(res); \
+ LSS_ERRNO = -(res); \
res = -1; \
} \
return (type) (res); \
} while (0)
+ #else
+ /* On MIPS, failing system calls return -1, and set errno in a
+ * separate CPU register.
+ */
+ #define LSS_RETURN(type, res, err) \
+ do { \
+ if (err) { \
+ LSS_ERRNO = (res); \
+ res = -1; \
+ } \
+ return (type) (res); \
+ } while (0)
+ #endif
#if defined(__i386__)
/* In PIC mode (e.g. when building shared libraries), gcc for i386
* reserves ebx. Unfortunately, most distribution ship with implementations
@@ -174,7 +465,8 @@ struct dirent64;
* at optimizing across __asm__ calls.
* So, we just have to redefine all of the _syscallX() macros.
*/
- #define BODY(type,args...) \
+ #undef LSS_BODY
+ #define LSS_BODY(type,args...) \
long __res; \
__asm__ __volatile__("push %%ebx\n" \
"movl %2,%%ebx\n" \
@@ -182,85 +474,315 @@ struct dirent64;
"pop %%ebx" \
args \
: "memory"); \
- RETURN(type,__res)
+ LSS_RETURN(type,__res)
#undef _syscall0
#define _syscall0(type,name) \
- type name(void) { \
- long __res; \
- __asm__ volatile("int $0x80" \
- : "=a" (__res) \
- : "0" (__NR_##name) \
- : "memory"); \
- RETURN(type,__res); \
+ type LSS_NAME(name)(void) { \
+ long __res; \
+ __asm__ volatile("int $0x80" \
+ : "=a" (__res) \
+ : "0" (__NR_##name) \
+ : "memory"); \
+ LSS_RETURN(type,__res); \
}
#undef _syscall1
#define _syscall1(type,name,type1,arg1) \
- type name(type1 arg1) { \
- BODY(type, \
- : "=a" (__res) \
- : "0" (__NR_##name), "ri" ((long)(arg1))); \
+ type LSS_NAME(name)(type1 arg1) { \
+ LSS_BODY(type, \
+ : "=a" (__res) \
+ : "0" (__NR_##name), "ri" ((long)(arg1))); \
}
#undef _syscall2
#define _syscall2(type,name,type1,arg1,type2,arg2) \
- type name(type1 arg1,type2 arg2) { \
- BODY(type, \
- : "=a" (__res) \
- : "0" (__NR_##name),"ri" ((long)(arg1)), "c" ((long)(arg2))); \
+ type LSS_NAME(name)(type1 arg1,type2 arg2) { \
+ LSS_BODY(type, \
+ : "=a" (__res) \
+ : "0" (__NR_##name),"ri" ((long)(arg1)), "c" ((long)(arg2))); \
}
#undef _syscall3
#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
- type name(type1 arg1,type2 arg2,type3 arg3) { \
- BODY(type, \
- : "=a" (__res) \
- : "0" (__NR_##name), "ri" ((long)(arg1)), "c" ((long)(arg2)), \
- "d" ((long)(arg3))); \
- }
+ type LSS_NAME(name)(type1 arg1,type2 arg2,type3 arg3) { \
+ LSS_BODY(type, \
+ : "=a" (__res) \
+ : "0" (__NR_##name), "ri" ((long)(arg1)), "c" ((long)(arg2)), \
+ "d" ((long)(arg3))); \
+ }
#undef _syscall4
#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
- type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
- BODY(type, \
- : "=a" (__res) \
- : "0" (__NR_##name), "ri" ((long)(arg1)), "c" ((long)(arg2)), \
- "d" ((long)(arg3)),"S" ((long)(arg4))); \
- }
+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
+ LSS_BODY(type, \
+ : "=a" (__res) \
+ : "0" (__NR_##name), "ri" ((long)(arg1)), "c" ((long)(arg2)), \
+ "d" ((long)(arg3)),"S" ((long)(arg4))); \
+ }
#undef _syscall5
#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
type5,arg5) \
- type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) { \
- long __res; \
- __asm__ __volatile__("push %%ebx\n" \
- "movl %2,%%ebx\n" \
- "movl %1,%%eax\n" \
- "int $0x80\n" \
- "pop %%ebx" \
- : "=a" (__res) \
- : "i" (__NR_##name), "ri" ((long)(arg1)), \
- "c" ((long)(arg2)), "d" ((long)(arg3)), \
- "S" ((long)(arg4)), "D" ((long)(arg5)) \
- : "memory"); \
- RETURN(type,__res); \
- }
+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
+ type5 arg5) { \
+ long __res; \
+ __asm__ __volatile__("push %%ebx\n" \
+ "movl %2,%%ebx\n" \
+ "movl %1,%%eax\n" \
+ "int $0x80\n" \
+ "pop %%ebx" \
+ : "=a" (__res) \
+ : "i" (__NR_##name), "ri" ((long)(arg1)), \
+ "c" ((long)(arg2)), "d" ((long)(arg3)), \
+ "S" ((long)(arg4)), "D" ((long)(arg5)) \
+ : "memory"); \
+ LSS_RETURN(type,__res); \
+ }
#undef _syscall6
#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
type5,arg5,type6,arg6) \
- type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
- type5 arg5, type6 arg6) { \
- long __res; \
- struct { long __a1; long __a6; } __s = { (long)arg1, (long) arg6 }; \
- __asm__ __volatile__("push %%ebp\n" \
- "push %%ebx\n" \
- "movl 4(%2),%%ebp\n" \
- "movl 0(%2), %%ebx\n" \
- "movl %1,%%eax\n" \
- "int $0x80\n" \
- "pop %%ebx\n" \
- "pop %%ebp" \
- : "=a" (__res) \
- : "i" (__NR_##name), "0" ((long)(&__s)), \
- "c" ((long)(arg2)), "d" ((long)(arg3)), \
- "S" ((long)(arg4)), "D" ((long)(arg5)) \
- : "memory"); \
- RETURN(type,__res); \
+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
+ type5 arg5, type6 arg6) { \
+ long __res; \
+ struct { long __a1; long __a6; } __s = { (long)arg1, (long) arg6 }; \
+ __asm__ __volatile__("push %%ebp\n" \
+ "push %%ebx\n" \
+ "movl 4(%2),%%ebp\n" \
+ "movl 0(%2), %%ebx\n" \
+ "movl %1,%%eax\n" \
+ "int $0x80\n" \
+ "pop %%ebx\n" \
+ "pop %%ebp" \
+ : "=a" (__res) \
+ : "i" (__NR_##name), "0" ((long)(&__s)), \
+ "c" ((long)(arg2)), "d" ((long)(arg3)), \
+ "S" ((long)(arg4)), "D" ((long)(arg5)) \
+ : "memory"); \
+ LSS_RETURN(type,__res); \
+ }
+ LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
+ int flags, void *arg, int *parent_tidptr,
+ void *newtls, int *child_tidptr) {
+ long __res;
+ __asm__ __volatile__(/* if (fn == NULL)
+ * return -EINVAL;
+ */
+ "movl %3,%%ecx\n"
+ "jecxz 1f\n"
+
+ /* if (child_stack == NULL)
+ * return -EINVAL;
+ */
+ "movl %4,%%ecx\n"
+ "jecxz 1f\n"
+
+ /* Set up alignment of the child stack:
+ * child_stack = (child_stack & ~0xF) - 20;
+ */
+ "andl $-16,%%ecx\n"
+ "subl $20,%%ecx\n"
+
+ /* Push "arg" and "fn" onto the stack that will be
+ * used by the child.
+ */
+ "movl %6,%%eax\n"
+ "movl %%eax,4(%%ecx)\n"
+ "movl %3,%%eax\n"
+ "movl %%eax,(%%ecx)\n"
+
+ /* %eax = syscall(%eax = __NR_clone,
+ * %ebx = flags,
+ * %ecx = child_stack,
+ * %edx = parent_tidptr,
+ * %esi = newtls,
+ * %edi = child_tidptr)
+ * Also, make sure that %ebx gets preserved as it is
+ * used in PIC mode.
+ */
+ "movl %8,%%esi\n"
+ "movl %7,%%edx\n"
+ "movl %5,%%eax\n"
+ "movl %9,%%edi\n"
+ "pushl %%ebx\n"
+ "movl %%eax,%%ebx\n"
+ "movl %2,%%eax\n"
+ "int $0x80\n"
+
+ /* In the parent: restore %ebx
+ * In the child: move "fn" into %ebx
+ */
+ "popl %%ebx\n"
+
+ /* if (%eax != 0)
+ * return %eax;
+ */
+ "test %%eax,%%eax\n"
+ "jnz 1f\n"
+
+ /* In the child, now. Terminate frame pointer chain.
+ */
+ "movl $0,%%ebp\n"
+
+ /* Call "fn". "arg" is already on the stack.
+ */
+ "call *%%ebx\n"
+
+ /* Call _exit(%ebx). Unfortunately older versions
+ * of gcc restrict the number of arguments that can
+ * be passed to asm(). So, we need to hard-code the
+ * system call number.
+ */
+ "movl %%eax,%%ebx\n"
+ "movl $1,%%eax\n"
+ "int $0x80\n"
+
+ /* Return to parent.
+ */
+ "1:\n"
+ : "=a" (__res)
+ : "0"(-EINVAL), "i"(__NR_clone),
+ "m"(fn), "m"(child_stack), "m"(flags), "m"(arg),
+ "m"(parent_tidptr), "m"(newtls), "m"(child_tidptr)
+ : "memory", "ecx", "edx", "esi", "edi");
+ LSS_RETURN(int, __res);
+ }
+ #elif defined(__x86_64__)
+ /* There are no known problems with any of the _syscallX() macros
+ * currently shipping for x86_64, but we still need to be able to define
+ * our own version so that we can override the location of the errno
+ * location (e.g. when using the clone() system call with the CLONE_VM
+ * option).
+ */
+ #undef LSS_BODY
+ #define LSS_BODY(type,name, ...) \
+ long __res; \
+ __asm__ __volatile__("syscall" : "=a" (__res) : "0" (__NR_##name), \
+ ##__VA_ARGS__ : "r11", "rcx", "memory"); \
+ LSS_RETURN(type, __res)
+ #undef _syscall0
+ #define _syscall0(type,name) \
+ type LSS_NAME(name)() { \
+ LSS_BODY(type, name); \
+ }
+ #undef _syscall1
+ #define _syscall1(type,name,type1,arg1) \
+ type LSS_NAME(name)(type1 arg1) { \
+ LSS_BODY(type, name, "D" ((long)(arg1))); \
+ }
+ #undef _syscall2
+ #define _syscall2(type,name,type1,arg1,type2,arg2) \
+ type LSS_NAME(name)(type1 arg1, type2 arg2) { \
+ LSS_BODY(type, name, "D" ((long)(arg1)), "S" ((long)(arg2))); \
+ }
+ #undef _syscall3
+ #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
+ LSS_BODY(type, name, "D" ((long)(arg1)), "S" ((long)(arg2)), \
+ "d" ((long)(arg3))); \
+ }
+ #undef _syscall4
+ #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
+ long __res; \
+ __asm__ __volatile__("movq %5,%%r10; syscall" : \
+ "=a" (__res) : "0" (__NR_##name), \
+ "D" ((long)(arg1)), "S" ((long)(arg2)), "d" ((long)(arg3)), \
+ "g" ((long)(arg4)) : "r10", "r11", "rcx", "memory"); \
+ LSS_RETURN(type, __res); \
+ }
+ #undef _syscall5
+ #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
+ type5,arg5) \
+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
+ type5 arg5) { \
+ long __res; \
+ __asm__ __volatile__("movq %5,%%r10; movq %6,%%r8; syscall" : \
+ "=a" (__res) : "0" (__NR_##name), \
+ "D" ((long)(arg1)), "S" ((long)(arg2)), "d" ((long)(arg3)), \
+ "g" ((long)(arg4)), "g" ((long)(arg5)) : \
+ "r8", "r10", "r11", "rcx", "memory"); \
+ LSS_RETURN(type, __res); \
+ }
+ #undef _syscall6
+ #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
+ type5,arg5,type6,arg6) \
+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
+ type5 arg5, type6 arg6) { \
+ long __res; \
+ __asm__ __volatile__("movq %5,%%r10; movq %6,%%r8; movq %7,%%r9;" \
+ "syscall" : \
+ "=a" (__res) : "0" (__NR_##name), \
+ "D" ((long)(arg1)), "S" ((long)(arg2)), "d" ((long)(arg3)), \
+ "g" ((long)(arg4)), "g" ((long)(arg5)), "g" ((long)(arg6)) : \
+ "r8", "r9", "r10", "r11", "rcx", "memory"); \
+ LSS_RETURN(type, __res); \
+ }
+ LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
+ int flags, void *arg, int *parent_tidptr,
+ void *newtls, int *child_tidptr) {
+ long __res;
+ {
+ register void *__tls __asm__("r8") = newtls;
+ register int *__ctid __asm__("r10") = child_tidptr;
+ __asm__ __volatile__(/* if (fn == NULL)
+ * return -EINVAL;
+ */
+ "testq %4,%4\n"
+ "jz 1f\n"
+
+ /* if (child_stack == NULL)
+ * return -EINVAL;
+ */
+ "testq %5,%5\n"
+ "jz 1f\n"
+
+ /* childstack -= 2*sizeof(void *);
+ */
+ "subq $16,%5\n"
+
+ /* Push "arg" and "fn" onto the stack that will be
+ * used by the child.
+ */
+ "movq %7,8(%5)\n"
+ "movq %4,0(%5)\n"
+
+ /* %rax = syscall(%rax = __NR_clone,
+ * %rdi = flags,
+ * %rsi = child_stack,
+ * %rdx = parent_tidptr,
+ * %r8 = new_tls,
+ * %r10 = child_tidptr)
+ */
+ "movq %2,%%rax\n"
+ "syscall\n"
+
+ /* if (%rax != 0)
+ * return;
+ */
+ "testq %%rax,%%rax\n"
+ "jnz 1f\n"
+
+ /* In the child. Terminate frame pointer chain.
+ */
+ "xorq %%rbp,%%rbp\n"
+
+ /* Call "fn(arg)".
+ */
+ "popq %%rax\n"
+ "popq %%rdi\n"
+ "call *%%rax\n"
+
+ /* Call _exit(%ebx).
+ */
+ "movq %%rax,%%rdi\n"
+ "movq %3,%%rax\n"
+ "syscall\n"
+
+ /* Return to parent.
+ */
+ "1:\n"
+ : "=a" (__res)
+ : "0"(-EINVAL), "i"(__NR_clone), "i"(__NR_exit),
+ "r"(fn), "S"(child_stack), "D"(flags), "r"(arg),
+ "d"(parent_tidptr), "r"(__tls), "r"(__ctid)
+ : "memory", "r11", "rcx");
+ }
+ LSS_RETURN(int, __res);
}
#elif defined(__ARM_ARCH_3__)
/* Most definitions of _syscallX() neglect to mark "memory" as being
@@ -268,270 +790,689 @@ struct dirent64;
* at optimizing across __asm__ calls.
* So, we just have to redefine all fo the _syscallX() macros.
*/
- #define REG(r,a) register long __r##r __asm__("r"#r) = (long)a
- #define BODY(type,name,args...) \
+ #undef LSS_REG
+ #define LSS_REG(r,a) register long __r##r __asm__("r"#r) = (long)a
+ #undef LSS_BODY
+ #define LSS_BODY(type,name,args...) \
register long __res_r0 __asm__("r0"); \
long __res; \
__asm__ __volatile__ (__syscall(name) \
: "=r"(__res_r0) : args : "lr", "memory"); \
__res = __res_r0; \
- RETURN(type, __res)
+ LSS_RETURN(type, __res)
#undef _syscall0
#define _syscall0(type, name) \
- type name() { \
- BODY(type, name); \
- }
+ type LSS_NAME(name)() { \
+ LSS_BODY(type, name); \
+ }
#undef _syscall1
#define _syscall1(type, name, type1, arg1) \
- type name(type1 arg1) { \
- REG(0, arg1); BODY(type, name, "r"(__r0)); \
- }
+ type LSS_NAME(name)(type1 arg1) { \
+ LSS_REG(0, arg1); LSS_BODY(type, name, "r"(__r0)); \
+ }
#undef _syscall2
#define _syscall2(type, name, type1, arg1, type2, arg2) \
- type name(type1 arg1, type2 arg2) { \
- REG(0, arg1); REG(1, arg2); BODY(type, name, "r"(__r0), "r"(__r1)); \
- }
+ type LSS_NAME(name)(type1 arg1, type2 arg2) { \
+ LSS_REG(0, arg1); LSS_REG(1, arg2); \
+ LSS_BODY(type, name, "r"(__r0), "r"(__r1)); \
+ }
#undef _syscall3
#define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
- type name(type1 arg1, type2 arg2, type3 arg3) { \
- REG(0, arg1); REG(1, arg2); REG(2, arg3); \
- BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2)); \
- }
+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
+ LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
+ LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2)); \
+ }
#undef _syscall4
#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
- type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
- REG(0, arg1); REG(1, arg2); REG(2, arg3); REG(3, arg4); \
- BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3)); \
- }
+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
+ LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
+ LSS_REG(3, arg4); \
+ LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3)); \
+ }
#undef _syscall5
#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
type5,arg5) \
- type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
- type5 arg5) { \
- REG(0, arg1); REG(1, arg2); REG(2, arg3); REG(3, arg4); \
- REG(4, arg5); \
- BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
- "r"(__r4)); \
- }
+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
+ type5 arg5) { \
+ LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
+ LSS_REG(3, arg4); LSS_REG(4, arg5); \
+ LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
+ "r"(__r4)); \
+ }
#undef _syscall6
#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
type5,arg5,type6,arg6) \
- type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
- type5 arg5, type6 arg6) { \
- REG(0, arg1); REG(1, arg2); REG(2, arg3); REG(3, arg4); \
- REG(4, arg5); REG(5, arg6); \
- BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
- "r"(__r4), "r"(__r5)); \
- }
+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
+ type5 arg5, type6 arg6) { \
+ LSS_REG(0, arg1); LSS_REG(1, arg2); LSS_REG(2, arg3); \
+ LSS_REG(3, arg4); LSS_REG(4, arg5); LSS_REG(5, arg6); \
+ LSS_BODY(type, name, "r"(__r0), "r"(__r1), "r"(__r2), "r"(__r3), \
+ "r"(__r4), "r"(__r5)); \
+ }
+ LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
+ int flags, void *arg, int *parent_tidptr,
+ void *newtls, int *child_tidptr) {
+ long __res;
+ {
+ register int __flags __asm__("r0") = flags;
+ register void *__stack __asm__("r1") = child_stack;
+ register void *__ptid __asm__("r2") = parent_tidptr;
+ register void *__tls __asm__("r3") = newtls;
+ register int *__ctid __asm__("r4") = child_tidptr;
+ __asm__ __volatile__(/* if (fn == NULL || child_stack == NULL)
+ * return -EINVAL;
+ */
+ "cmp %2,#0\n"
+ "cmpne %3,#0\n"
+ "moveq %0,%1\n"
+ "beq 1f\n"
+
+ /* Push "arg" and "fn" onto the stack that will be
+ * used by the child.
+ */
+ "str %5,[%3,#-4]!\n"
+ "str %2,[%3,#-4]!\n"
+
+ /* %r0 = syscall(%r0 = flags,
+ * %r1 = child_stack,
+ * %r2 = parent_tidptr,
+ * %r3 = newtls,
+ * %r4 = child_tidptr)
+ */
+ __syscall(clone)"\n"
+
+ /* if (%r0 != 0)
+ * return %r0;
+ */
+ "movs %0,r0\n"
+ "bne 1f\n"
+
+ /* In the child, now. Call "fn(arg)".
+ */
+ "ldr r0,[sp, #4]\n"
+ "mov lr,pc\n"
+ "ldr pc,[sp]\n"
+
+ /* Call _exit(%r0).
+ */
+ __syscall(exit)"\n"
+ "1:\n"
+ : "=r" (__res)
+ : "i"(-EINVAL),
+ "r"(fn), "r"(__stack), "r"(__flags), "r"(arg),
+ "r"(__ptid), "r"(__tls), "r"(__ctid)
+ : "lr", "memory");
+ }
+ LSS_RETURN(int, __res);
+ }
+ #elif defined(mips)
+ #undef LSS_REG
+ #define LSS_REG(r,a) register unsigned long __r##r __asm__("$"#r) = \
+ (unsigned long)(a)
+ #undef LSS_BODY
+ #define LSS_BODY(type,name,r7,...) \
+ register unsigned long __v0 __asm__("$2") = __NR_##name; \
+ __asm__ __volatile__ ("syscall\n" \
+ : "=&r"(__v0), r7 (__r7) \
+ : "0"(__v0), ##__VA_ARGS__ \
+ : "$8", "$9", "$10", "$11", "$12", \
+ "$13", "$14", "$15", "$24", "memory"); \
+ LSS_RETURN(type, __v0, __r7)
+ #undef _syscall0
+ #define _syscall0(type, name) \
+ type LSS_NAME(name)() { \
+ register unsigned long __r7 __asm__("$7"); \
+ LSS_BODY(type, name, "=r"); \
+ }
+ #undef _syscall1
+ #define _syscall1(type, name, type1, arg1) \
+ type LSS_NAME(name)(type1 arg1) { \
+ register unsigned long __r7 __asm__("$7"); \
+ LSS_REG(4, arg1); LSS_BODY(type, name, "=r", "r"(__r4)); \
+ }
+ #undef _syscall2
+ #define _syscall2(type, name, type1, arg1, type2, arg2) \
+ type LSS_NAME(name)(type1 arg1, type2 arg2) { \
+ register unsigned long __r7 __asm__("$7"); \
+ LSS_REG(4, arg1); LSS_REG(5, arg2); \
+ LSS_BODY(type, name, "=r", "r"(__r4), "r"(__r5)); \
+ }
+ #undef _syscall3
+ #define _syscall3(type, name, type1, arg1, type2, arg2, type3, arg3) \
+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3) { \
+ register unsigned long __r7 __asm__("$7"); \
+ LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
+ LSS_BODY(type, name, "=r", "r"(__r4), "r"(__r5), "r"(__r6)); \
+ }
+ #undef _syscall4
+ #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \
+ LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
+ LSS_REG(7, arg4); \
+ LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6)); \
+ }
+ #undef _syscall5
+ #if _MIPS_SIM == _MIPS_SIM_ABI32
+ /* The old 32bit MIPS system call API passes the fifth and sixth argument
+ * on the stack, whereas the new APIs use registers "r8" and "r9".
+ */
+ #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
+ type5,arg5) \
+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
+ type5 arg5) { \
+ LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
+ LSS_REG(7, arg4); \
+ register unsigned long __v0 __asm__("$2"); \
+ __asm__ __volatile__ (".set noreorder\n" \
+ "lw $2, %6\n" \
+ "subu $29, 32\n" \
+ "sw $2, 16($29)\n" \
+ "li $2, %2\n" \
+ "syscall\n" \
+ "addiu $29, 32\n" \
+ ".set reorder\n" \
+ : "=&r"(__v0), "+r" (__r7) \
+ : "i" (__NR_##name), "r"(__r4), "r"(__r5), \
+ "r"(__r6), "m" ((unsigned long)arg5) \
+ : "$8", "$9", "$10", "$11", "$12", \
+ "$13", "$14", "$15", "$24", "memory"); \
+ LSS_RETURN(type, __v0, __r7); \
+ }
+ #else
+ #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
+ type5,arg5) \
+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
+ type5 arg5) { \
+ LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
+ LSS_REG(7, arg4); LSS_REG(8, arg5); \
+ LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6), \
+ "r"(__r8)); \
+ }
+ #endif
+ #undef _syscall6
+ #if _MIPS_SIM == _MIPS_SIM_ABI32
+ /* The old 32bit MIPS system call API passes the fifth and sixth argument
+ * on the stack, whereas the new APIs use registers "r8" and "r9".
+ */
+ #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
+ type5,arg5,type6,arg6) \
+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
+ type5 arg5, type6 arg6) { \
+ LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
+ LSS_REG(7, arg4); \
+ register unsigned long __v0 __asm__("$2"); \
+ __asm__ __volatile__ (".set noreorder\n" \
+ "lw $2, %6\n" \
+ "lw $8, %7\n" \
+ "subu $29, 32\n" \
+ "sw $2, 16($29)\n" \
+ "sw $8, 20($29)\n" \
+ "li $2, %2\n" \
+ "syscall\n" \
+ "addiu $29, 32\n" \
+ ".set reorder\n" \
+ : "=&r"(__v0), "+r" (__r7) \
+ : "i" (__NR_##name), "r"(__r4), "r"(__r5), \
+ "r"(__r6), "m" ((unsigned long)arg5), \
+ "m" ((unsigned long)arg6) \
+ : "$8", "$9", "$10", "$11", "$12", \
+ "$13", "$14", "$15", "$24", "memory"); \
+ LSS_RETURN(type, __v0, __r7); \
+ }
+ #else
+ #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
+ type5,arg5,type6,arg6) \
+ type LSS_NAME(name)(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \
+ type5 arg5,type6 arg6) { \
+ LSS_REG(4, arg1); LSS_REG(5, arg2); LSS_REG(6, arg3); \
+ LSS_REG(7, arg4); LSS_REG(8, arg5); LSS_REG(9, arg6); \
+ LSS_BODY(type, name, "+r", "r"(__r4), "r"(__r5), "r"(__r6), \
+ "r"(__r8), "r"(__r9)); \
+ }
+ #endif
+ LSS_INLINE int LSS_NAME(clone)(int (*fn)(void *), void *child_stack,
+ int flags, void *arg, int *parent_tidptr,
+ void *newtls, int *child_tidptr) {
+ register unsigned long __v0 __asm__("$2");
+ register unsigned long __r7 __asm__("$7") = (unsigned long)newtls;
+ {
+ register int __flags __asm__("$4") = flags;
+ register void *__stack __asm__("$5") = child_stack;
+ register void *__ptid __asm__("$6") = parent_tidptr;
+ register int *__ctid __asm__("$8") = child_tidptr;
+ __asm__ __volatile__(
+ #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32
+ "subu $29,24\n"
+ #elif _MIPS_SIM == _MIPS_SIM_NABI32
+ "sub $29,16\n"
+ #else
+ "dsubu $29,16\n"
+ #endif
+
+ /* if (fn == NULL || child_stack == NULL)
+ * return -EINVAL;
+ */
+ "li %0,%2\n"
+ "beqz %5,1f\n"
+ "beqz %6,1f\n"
+
+ /* Push "arg" and "fn" onto the stack that will be
+ * used by the child.
+ */
+ #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32
+ "subu %6,32\n"
+ "sw %5,0(%6)\n"
+ "sw %8,4(%6)\n"
+ #elif _MIPS_SIM == _MIPS_SIM_NABI32
+ "sub %6,32\n"
+ "sw %5,0(%6)\n"
+ "sw %8,8(%6)\n"
+ #else
+ "dsubu %6,32\n"
+ "sd %5,0(%6)\n"
+ "sd %8,8(%6)\n"
+ #endif
+
+ /* $7 = syscall($4 = flags,
+ * $5 = child_stack,
+ * $6 = parent_tidptr,
+ * $7 = newtls,
+ * $8 = child_tidptr)
+ */
+ "li $2,%3\n"
+ "syscall\n"
+
+ /* if ($7 != 0)
+ * return $2;
+ */
+ "bnez $7,1f\n"
+ "bnez $2,1f\n"
+
+ /* In the child, now. Call "fn(arg)".
+ */
+ #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32
+ "lw $25,0($29)\n"
+ "lw $4,4($29)\n"
+ #elif _MIPS_SIM == _MIPS_SIM_NABI32
+ "lw $25,0($29)\n"
+ "lw $4,8($29)\n"
+ #else
+ "ld $25,0($29)\n"
+ "ld $4,8($29)\n"
+ #endif
+ "jalr $25\n"
+
+ /* Call _exit($2)
+ */
+ "move $4,$2\n"
+ "li $2,%4\n"
+ "syscall\n"
+
+ "1:\n"
+ #if _MIPS_SIM == _MIPS_SIM_ABI32 && _MIPS_SZPTR == 32
+ "addu $29, 24\n"
+ #elif _MIPS_SIM == _MIPS_SIM_NABI32
+ "add $29, 16\n"
+ #else
+ "daddu $29,16\n"
+ #endif
+ : "=&r" (__v0), "=r" (__r7)
+ : "i"(-EINVAL), "i"(__NR_clone), "i"(__NR_exit),
+ "r"(fn), "r"(__stack), "r"(__flags), "r"(arg),
+ "r"(__ptid), "r"(__r7), "r"(__ctid)
+ : "$9", "$10", "$11", "$12", "$13", "$14", "$15",
+ "$24", "memory");
+ }
+ LSS_RETURN(int, __v0, __r7);
+ }
#endif
- #if defined(__x86_64__)
- struct msghdr;
- struct sockaddr;
- #define __NR_sys_mmap __NR_mmap
- #define __NR_sys_recvmsg __NR_recvmsg
- #define __NR_sys_sendmsg __NR_sendmsg
- #define __NR_sys_sendto __NR_sendto
- #define __NR_sys_shutdown __NR_shutdown
- #define __NR_sys_rt_sigaction __NR_rt_sigaction
- #define __NR_sys_rt_sigprocmask __NR_rt_sigprocmask
- #define __NR_sys_socket __NR_socket
- #define __NR_sys_socketpair __NR_socketpair
- static inline _syscall6(void*, sys_mmap, void*, s,
- size_t, l, int, p,
- int, f, int, d,
- __off64_t, o);
- static inline _syscall3(int, sys_recvmsg, int, s,
- struct msghdr*, m, int, f);
- static inline _syscall3(int, sys_sendmsg, int, s,
- const struct msghdr*, m, int, f);
- static inline _syscall6(int, sys_sendto, int, s,
- const void*, m, size_t, l,
- int, f,
- const struct sockaddr*, a, int, t);
- static inline _syscall2(int, sys_shutdown, int, s,
- int, h);
- static inline _syscall4(int, sys_rt_sigaction, int, s,
- const struct sigaction*, a,
- struct sigaction*, o, int, c);
- static inline _syscall4(int, sys_rt_sigprocmask, int, h,
- const sigset_t*, s, sigset_t*, o, int, c);
- static inline _syscall3(int, sys_socket, int, d,
- int, t, int, p);
- static inline _syscall4(int, sys_socketpair, int, d,
- int, t, int, p, int*, s);
- #define sys_sigaction(s,a,o) sys_rt_sigaction((s), (a), (o), \
- (_NSIG+7)/8)
- #define sys_sigprocmask(h,s,o) sys_rt_sigprocmask((h), (s),(o), \
- (_NSIG+7)/8)
+ #define __NR__exit __NR_exit
+ #define __NR__gettid __NR_gettid
+ #define __NR__mremap __NR_mremap
+ LSS_INLINE _syscall1(int, chdir, const char *,p)
+ LSS_INLINE _syscall1(int, close, int, f)
+ LSS_INLINE _syscall1(int, dup, int, f)
+ LSS_INLINE _syscall2(int, dup2, int, s,
+ int, d)
+ LSS_INLINE _syscall3(int, execve, const char*, f,
+ const char*const*,a,const char*const*, e)
+ LSS_INLINE _syscall1(int, _exit, int, e)
+ LSS_INLINE _syscall3(int, fcntl, int, f,
+ int, c, long, a)
+ LSS_INLINE _syscall0(pid_t, fork)
+ LSS_INLINE _syscall2(int, fstat, int, f,
+ struct stat*, b)
+ LSS_INLINE _syscall4(int, futex, int*, a,
+ int, o, int, v, struct timespec *, t)
+ LSS_INLINE _syscall3(int, getdents, int, f,
+ struct dirent*, d, int, c)
+ LSS_INLINE _syscall3(int, getdents64, int, f,
+ struct dirent64*, d, int, c)
+ LSS_INLINE _syscall0(gid_t, getegid)
+ LSS_INLINE _syscall0(uid_t, geteuid)
+ LSS_INLINE _syscall0(pid_t, getpgrp)
+ LSS_INLINE _syscall0(pid_t, getpid)
+ LSS_INLINE _syscall0(pid_t, getppid)
+ LSS_INLINE _syscall2(int, getpriority, int, a,
+ int, b)
+ LSS_INLINE _syscall2(int, getrlimit, int, r,
+ struct rlimit*, l)
+ LSS_INLINE _syscall1(pid_t, getsid, pid_t, p)
+ LSS_INLINE _syscall0(pid_t, _gettid)
+ LSS_INLINE _syscall2(int, kill, pid_t, p,
+ int, s)
+ LSS_INLINE _syscall3(off_t, lseek, int, f,
+ off_t, o, int, w)
+ LSS_INLINE _syscall2(int, munmap, void*, s,
+ size_t, l)
+ LSS_INLINE _syscall6(long, move_pages, pid_t, p,
+ unsigned long, n, void **,g, int *, d,
+ int *, s, int, f)
+ LSS_INLINE _syscall5(void*, _mremap, void*, o,
+ size_t, os, size_t, ns,
+ unsigned long, f, void *, a)
+ LSS_INLINE _syscall3(int, open, const char*, p,
+ int, f, int, m)
+ LSS_INLINE _syscall3(int, poll, struct pollfd*, u,
+ unsigned int, n, int, t)
+ LSS_INLINE _syscall2(int, prctl, int, o,
+ long, a)
+ LSS_INLINE _syscall4(long, ptrace, int, r,
+ pid_t, p, void *, a, void *, d)
+ LSS_INLINE _syscall3(ssize_t, read, int, f,
+ void *, b, size_t, c)
+ LSS_INLINE _syscall3(int, readlink, const char*, p,
+ char*, b, size_t, s)
+ LSS_INLINE _syscall3(int, sched_getaffinity,pid_t, p,
+ unsigned int, l, unsigned long *, m)
+ LSS_INLINE _syscall3(int, sched_setaffinity,pid_t, p,
+ unsigned int, l, unsigned long *, m)
+ LSS_INLINE _syscall0(int, sched_yield)
+ LSS_INLINE _syscall1(long, set_tid_address, int *, t)
+ LSS_INLINE _syscall1(int, setfsgid, gid_t, g)
+ LSS_INLINE _syscall1(int, setfsuid, uid_t, u)
+ LSS_INLINE _syscall2(int, setpgid, pid_t, p,
+ pid_t, g)
+ LSS_INLINE _syscall3(int, setpriority, int, a,
+ int, b, int, p)
+ LSS_INLINE _syscall3(int, setresgid, gid_t, r,
+ gid_t, e, gid_t, s)
+ LSS_INLINE _syscall3(int, setresuid, uid_t, r,
+ uid_t, e, uid_t, s)
+ LSS_INLINE _syscall2(int, setrlimit, int, r,
+ const struct rlimit*, l)
+ LSS_INLINE _syscall2(int, sigaltstack, const stack_t*, s,
+ const stack_t*, o)
+ LSS_INLINE _syscall2(int, stat, const char*, f,
+ struct stat*, b)
+ LSS_INLINE _syscall3(ssize_t, write, int, f,
+ const void *, b, size_t, c)
+ LSS_INLINE _syscall3(ssize_t, writev, int, f,
+ const struct iovec *, v, size_t, c)
+ #if defined(__x86_64__) || \
+ (defined(mips) && _MIPS_SIM != _MIPS_SIM_ABI32)
+ LSS_INLINE _syscall3(int, recvmsg, int, s,
+ struct msghdr*, m, int, f)
+ LSS_INLINE _syscall3(int, sendmsg, int, s,
+ const struct msghdr*, m, int, f)
+ LSS_INLINE _syscall6(int, sendto, int, s,
+ const void*, m, size_t, l,
+ int, f,
+ const struct sockaddr*, a, int, t)
+ LSS_INLINE _syscall2(int, shutdown, int, s,
+ int, h)
+ LSS_INLINE _syscall3(int, socket, int, d,
+ int, t, int, p)
+ LSS_INLINE _syscall4(int, socketpair, int, d,
+ int, t, int, p, int*, s)
#endif
- #if defined(__x86_64__) || defined(__ARM_ARCH_3__)
- #define __NR_sys_wait4 __NR_wait4
+ #if defined(__x86_64__)
+ LSS_INLINE _syscall6(void*, mmap, void*, s,
+ size_t, l, int, p,
+ int, f, int, d,
+ __off64_t, o)
+ LSS_INLINE _syscall4(int, newfstatat, int, d,
+ const char *, p,
+ struct stat *, b, int, f)
+ LSS_INLINE _syscall4(int, rt_sigaction, int, s,
+ const struct sigaction*, a,
+ struct sigaction*, o, int, c)
+ LSS_INLINE _syscall2(int, rt_sigpending, sigset_t*, s,
+ int, c)
+ LSS_INLINE _syscall4(int, rt_sigprocmask, int, h,
+ const sigset_t*, s, sigset_t*, o, int, c);
- static inline _syscall4(pid_t, sys_wait4, pid_t, p,
- int*, s, int, o,
- struct rusage*, r);
+ LSS_INLINE int LSS_NAME(setfsgid32)(gid_t gid) {
+ return LSS_NAME(setfsgid)(gid);
+ }
- #define sys_waitpid(p,s,o) sys_wait4((p), (s), (o), 0)
+ LSS_INLINE int LSS_NAME(setfsuid32)(uid_t uid) {
+ return LSS_NAME(setfsuid)(uid);
+ }
+
+ LSS_INLINE int LSS_NAME(setresgid32)(gid_t rgid, gid_t egid, gid_t sgid) {
+ return LSS_NAME(setresgid)(rgid, egid, sgid);
+ }
+
+ LSS_INLINE int LSS_NAME(setresuid32)(uid_t ruid, uid_t euid, uid_t suid) {
+ return LSS_NAME(setresuid)(ruid, euid, suid);
+ }
+
+ LSS_INLINE int LSS_NAME(sigaction)(int signum,
+ const struct sigaction *act,
+ struct sigaction *oldact) {
+ return LSS_NAME(rt_sigaction)(signum, act, oldact, (_NSIG+6)/8);
+ }
+
+ LSS_INLINE int LSS_NAME(sigpending)(sigset_t *set) {
+ return LSS_NAME(rt_sigpending)(set, (_NSIG+6)/8);
+ }
+
+ LSS_INLINE int LSS_NAME(sigprocmask)(int how, const sigset_t *set,
+ sigset_t *oldset) {
+ return LSS_NAME(rt_sigprocmask)(how, set, oldset, (_NSIG+6)/8);
+ }
+ #endif
+ #if defined(__x86_64__) || defined(__ARM_ARCH_3__) || \
+ (defined(mips) && _MIPS_SIM != _MIPS_SIM_ABI32)
+ LSS_INLINE _syscall4(pid_t, wait4, pid_t, p,
+ int*, s, int, o,
+ struct rusage*, r)
+
+ LSS_INLINE pid_t LSS_NAME(waitpid)(pid_t pid, int *status, int options){
+ return LSS_NAME(wait4)(pid, status, options, 0);
+ }
+ #endif
+ #if defined(__i386__) || defined(__x86_64__)
+ LSS_INLINE _syscall4(int, openat, int, d, const char *, p, int, f, int, m)
+ LSS_INLINE _syscall3(int, unlinkat, int, d, const char *, p, int, f)
#endif
#if defined(__i386__) || defined(__ARM_ARCH_3__)
- #define __NR_sys__llseek __NR__llseek
- #define __NR_sys_mmap __NR_mmap
- #define __NR_sys_mmap2 __NR_mmap2
- #define __NR_sys_sigaction __NR_sigaction
- #define __NR_sys_sigprocmask __NR_sigprocmask
- #define __NR_sys__socketcall __NR_socketcall
-
- static inline _syscall5(int, sys__llseek, uint, fd, ulong, hi, ulong, lo,
- loff_t *, res, uint, wh);
- static inline _syscall1(void*, sys_mmap, void*, a);
- static inline _syscall6(void*, sys_mmap2, void*, s,
- size_t, l, int, p,
- int, f, int, d,
- __off64_t, o);
- static inline _syscall3(int, sys_sigaction, int, s,
- const struct sigaction*, a, struct sigaction*, o);
- static inline _syscall3(int, sys_sigprocmask, int, h,
- const sigset_t*, s, sigset_t*, o);
- static inline _syscall2(int, sys__socketcall,int, c,
- va_list, a);
- static inline int sys_socketcall(int op, ...) {
+ #define __NR__setfsgid32 __NR_setfsgid32
+ #define __NR__setfsuid32 __NR_setfsuid32
+ #define __NR__setresgid32 __NR_setresgid32
+ #define __NR__setresuid32 __NR_setresuid32
+ LSS_INLINE _syscall2(int, ugetrlimit, int, r,struct rlimit*,l)
+ LSS_INLINE _syscall1(int, _setfsgid32, gid_t, f)
+ LSS_INLINE _syscall1(int, _setfsuid32, uid_t, f)
+ LSS_INLINE _syscall3(int, _setresgid32, gid_t, r,
+ gid_t, e, gid_t, s)
+ LSS_INLINE _syscall3(int, _setresuid32, uid_t, r,
+ uid_t, e, uid_t, s)
+
+ LSS_INLINE int LSS_NAME(setfsgid32)(gid_t gid) {
+ int rc;
+ if ((rc = LSS_NAME(_setfsgid32)(gid)) < 0 &&
+ LSS_ERRNO == ENOSYS) {
+ if ((unsigned int)gid & ~0xFFFFu) {
+ rc = EINVAL;
+ } else {
+ rc = LSS_NAME(setfsgid)(gid);
+ }
+ }
+ return rc;
+ }
+
+ LSS_INLINE int LSS_NAME(setfsuid32)(uid_t uid) {
+ int rc;
+ if ((rc = LSS_NAME(_setfsuid32)(uid)) < 0 &&
+ LSS_ERRNO == ENOSYS) {
+ if ((unsigned int)uid & ~0xFFFFu) {
+ rc = EINVAL;
+ } else {
+ rc = LSS_NAME(setfsuid)(uid);
+ }
+ }
+ return rc;
+ }
+
+ LSS_INLINE int LSS_NAME(setresgid32)(gid_t rgid, gid_t egid, gid_t sgid) {
+ int rc;
+ if ((rc = LSS_NAME(_setresgid32)(rgid, egid, sgid)) < 0 &&
+ LSS_ERRNO == ENOSYS) {
+ if ((unsigned int)rgid & ~0xFFFFu ||
+ (unsigned int)egid & ~0xFFFFu ||
+ (unsigned int)sgid & ~0xFFFFu) {
+ rc = EINVAL;
+ } else {
+ rc = LSS_NAME(setresgid)(rgid, egid, sgid);
+ }
+ }
+ return rc;
+ }
+
+ LSS_INLINE int LSS_NAME(setresuid32)(uid_t ruid, uid_t euid, uid_t suid) {
+ int rc;
+ if ((rc = LSS_NAME(_setresuid32)(ruid, euid, suid)) < 0 &&
+ LSS_ERRNO == ENOSYS) {
+ if ((unsigned int)ruid & ~0xFFFFu ||
+ (unsigned int)euid & ~0xFFFFu ||
+ (unsigned int)suid & ~0xFFFFu) {
+ rc = EINVAL;
+ } else {
+ rc = LSS_NAME(setresuid)(ruid, euid, suid);
+ }
+ }
+ return rc;
+ }
+ #endif
+ #if defined(__i386__) || defined(__ARM_ARCH_3__) || \
+ (defined(mips) && _MIPS_SIM == _MIPS_SIM_ABI32)
+ #define __NR__socketcall __NR_socketcall
+ LSS_INLINE _syscall5(int, _llseek, uint, fd, ulong, hi, ulong, lo,
+ loff_t *, res, uint, wh)
+ LSS_INLINE _syscall1(void*, mmap, void*, a)
+ LSS_INLINE _syscall6(void*, mmap2, void*, s,
+ size_t, l, int, p,
+ int, f, int, d,
+ __off64_t, o)
+ LSS_INLINE _syscall3(int, sigaction, int, s,
+ const struct sigaction*, a, struct sigaction*, o)
+ LSS_INLINE _syscall1(int, sigpending, sigset_t*, s)
+ LSS_INLINE _syscall3(int, sigprocmask, int, h,
+ const sigset_t*, s, sigset_t*, o)
+ LSS_INLINE _syscall2(int, _socketcall, int, c,
+ va_list, a)
+
+ LSS_INLINE int LSS_NAME(socketcall)(int op, ...) {
int rc;
va_list ap;
va_start(ap, op);
- rc = sys__socketcall(op, ap);
+ rc = LSS_NAME(_socketcall)(op, ap);
va_end(ap);
return rc;
}
- #define sys_recvmsg(s,m,f) sys_socketcall(17, (s), (m), (f))
- #define sys_sendmsg(s,m,f) sys_socketcall(16, (s), (m), (f))
- #define sys_sendto(s,m,l,f,a,t) sys_socketcall(11, (s), (m), (l),(f),\
- (a), (t))
- #define sys_shutdown(s,h) sys_socketcall(13, (s), (h))
- #define sys_socket(d,t,p) sys_socketcall(1, (d), (t), (p))
- #define sys_socketpair(d,t,p,s) sys_socketcall(8, (d), (t), (p),(s))
+
+ LSS_INLINE ssize_t LSS_NAME(recvmsg)(int s,struct msghdr*msg,int flags){
+ return (ssize_t)LSS_NAME(socketcall)(17, s, msg, flags);
+ }
+
+ LSS_INLINE ssize_t LSS_NAME(sendmsg)(int s, const struct msghdr *msg,
+ int flags) {
+ return (ssize_t)LSS_NAME(socketcall)(16, s, msg, flags);
+ }
+
+ LSS_INLINE ssize_t LSS_NAME(sendto)(int s, const void *buf, size_t len,
+ int flags, const struct sockaddr*to,
+ unsigned int tolen) {
+ return (ssize_t)LSS_NAME(socketcall)(11, s, buf, len, flags, to, tolen);
+ }
+
+ LSS_INLINE int LSS_NAME(shutdown)(int s, int how) {
+ return LSS_NAME(socketcall)(13, s, how);
+ }
+
+ LSS_INLINE int LSS_NAME(socket)(int domain, int type, int protocol) {
+ return LSS_NAME(socketcall)(1, domain, type, protocol);
+ }
+
+ LSS_INLINE int LSS_NAME(socketpair)(int d, int type, int protocol,
+ int sv[2]) {
+ return LSS_NAME(socketcall)(8, d, type, protocol, sv);
+ }
#endif
#if defined(__i386__)
- #define __NR_sys_waitpid __NR_waitpid
- static inline _syscall3(pid_t, sys_waitpid, pid_t, p,
- int*, s, int, o);
+ LSS_INLINE _syscall4(int, fstatat64, int, d,
+ const char *, p,
+ struct stat64 *, b, int, f)
#endif
- #define __NR_sys_close __NR_close
- #define __NR_sys_dup __NR_dup
- #define __NR_sys_dup2 __NR_dup2
- #define __NR_sys_execve __NR_execve
- #define __NR_sys__exit __NR_exit
- #define __NR_sys_fcntl __NR_fcntl
- #define __NR_sys_fork __NR_fork
- #define __NR_sys_fstat __NR_fstat
- #define __NR_sys_futex __NR_futex
- #define __NR_sys_getdents __NR_getdents
- #define __NR_sys_getdents64 __NR_getdents64
- #define __NR_sys_getegid __NR_getegid
- #define __NR_sys_geteuid __NR_geteuid
- #define __NR_sys_getpgrp __NR_getpgrp
- #define __NR_sys_getpid __NR_getpid
- #define __NR_sys_getppid __NR_getppid
- #define __NR_sys_getpriority __NR_getpriority
- #define __NR_sys_getrlimit __NR_getrlimit
- #define __NR_sys_getsid __NR_getsid
- #define __NR__gettid __NR_gettid
- #define __NR_sys_kill __NR_kill
- #define __NR_sys_lseek __NR_lseek
- #define __NR_sys_munmap __NR_munmap
- #define __NR_sys_open __NR_open
- #define __NR_sys_pipe __NR_pipe
- #define __NR_sys_prctl __NR_prctl
- #define __NR_sys_ptrace __NR_ptrace
- #define __NR_sys_read __NR_read
- #define __NR_sys_readlink __NR_readlink
- #define __NR_sys_sched_getaffinity __NR_sched_getaffinity
- #define __NR_sys_sched_setaffinity __NR_sched_setaffinity
- #define __NR_sys_sched_yield __NR_sched_yield
- #define __NR_sys_sigaltstack __NR_sigaltstack
- #define __NR_sys_stat __NR_stat
- #define __NR_sys_write __NR_write
- static inline _syscall1(int, sys_close, int, f);
- static inline _syscall1(int, sys_dup, int, f);
- static inline _syscall2(int, sys_dup2, int, s,
- int, d);
- static inline _syscall3(int, sys_execve, const char*, f,
- const char*const*,a,const char*const*, e);
- static inline _syscall1(int, sys__exit, int, e);
- static inline _syscall3(int, sys_fcntl, int, f,
- int, c, long, a);
- static inline _syscall0(pid_t, sys_fork);
- static inline _syscall2(int, sys_fstat, int, f,
- struct stat*, b);
- static inline _syscall4(int, sys_futex, int*, addrx, int, opx, int, valx,
- struct timespec *, timeoutx);
- static inline _syscall3(int, sys_getdents, int, f,
- struct dirent*, d, int, c);
- static inline _syscall3(int, sys_getdents64, int, f,
- struct dirent64*, d, int, c);
- static inline _syscall0(gid_t, sys_getegid);
- static inline _syscall0(uid_t, sys_geteuid);
- static inline _syscall0(pid_t, sys_getpgrp);
- static inline _syscall0(pid_t, sys_getpid);
- static inline _syscall0(pid_t, sys_getppid);
- static inline _syscall2(int, sys_getpriority, int, a,
- int, b);
- static inline _syscall2(int, sys_getrlimit, int, r,
- struct rlimit*, l);
- static inline _syscall1(pid_t, sys_getsid, pid_t, p);
- static inline _syscall0(pid_t, _gettid);
- static inline _syscall2(int, sys_kill, pid_t, p,
- int, s);
- static inline _syscall3(off_t, sys_lseek, int, f,
- off_t, o, int, w);
- static inline _syscall2(int, sys_munmap, void*, s,
- size_t, l);
- static inline _syscall3(int, sys_open, const char*, p,
- int, f, int, m);
- static inline _syscall1(int, sys_pipe, int*, p);
- static inline _syscall2(int, sys_prctl, int, o,
- long, a);
- static inline _syscall4(long, sys_ptrace, int, r,
- pid_t, p, void *, a, void *, d);
- static inline _syscall3(ssize_t, sys_read, int, f,
- void *, b, size_t, c);
- static inline _syscall3(int, sys_readlink, const char*, p,
- char*, b, size_t, s);
- static inline _syscall3(int, sys_sched_getaffinity, pid_t, pid,
- unsigned int, len, unsigned long *, mask);
- static inline _syscall3(int, sys_sched_setaffinity, pid_t, pid,
- unsigned int, len, unsigned long *, mask);
- static inline _syscall0(int, sys_sched_yield);
- static inline _syscall2(int, sys_sigaltstack, const stack_t*, s,
- const stack_t*, o);
- static inline _syscall2(int, sys_stat, const char*, f,
- struct stat*, b);
- static inline _syscall3(ssize_t, sys_write, int, f,
- const void *, b, size_t, c);
-
- static inline int sys_sysconf(int name) {
- extern int __getpagesize(void);
- switch (name) {
- case _SC_OPEN_MAX: {
- struct rlimit ru;
- return sys_getrlimit(RLIMIT_NOFILE, &ru) < 0 ? 8192 : ru.rlim_cur;
- }
- case _SC_PAGESIZE:
- return __getpagesize();
- default:
- errno = ENOSYS;
+ #if defined(__i386__) || \
+ (defined(mips) && _MIPS_SIM == _MIPS_SIM_ABI32)
+ LSS_INLINE _syscall3(pid_t, waitpid, pid_t, p,
+ int*, s, int, o)
+ #endif
+ #if defined(mips)
+ /* sys_pipe() on MIPS has non-standard calling conventions, as it returns
+ * both file handles through CPU registers.
+ */
+ LSS_INLINE int LSS_NAME(pipe)(int *p) {
+ register unsigned long __v0 __asm__("$2") = __NR_pipe;
+ register unsigned long __v1 __asm__("$3");
+ register unsigned long __r7 __asm__("$7");
+ __asm__ __volatile__ ("syscall\n"
+ : "=&r"(__v0), "=&r"(__v1), "+r" (__r7)
+ : "0"(__v0)
+ : "$8", "$9", "$10", "$11", "$12",
+ "$13", "$14", "$15", "$24", "memory");
+ if (__r7) {
+ LSS_ERRNO = __v0;
return -1;
+ } else {
+ p[0] = __v0;
+ p[1] = __v1;
+ return 0;
+ }
}
+ #else
+ LSS_INLINE _syscall1(int, pipe, int*, p)
+ #endif
+
+ LSS_INLINE int LSS_NAME(execv)(const char *path, const char * const argv[]) {
+ extern char **environ;
+ return LSS_NAME(execve)(path, argv, (const char * const *)environ);
}
- static inline pid_t sys_gettid() {
- pid_t tid = _gettid();
+ LSS_INLINE pid_t LSS_NAME(gettid)() {
+ pid_t tid = LSS_NAME(_gettid)();
if (tid != -1) {
return tid;
}
- return sys_getpid();
+ return LSS_NAME(getpid)();
}
- static inline int sys_ptrace_detach(pid_t pid) {
+ LSS_INLINE void *LSS_NAME(mremap)(void *old_address, size_t old_size,
+ size_t new_size, int flags, ...) {
+ va_list ap;
+ void *new_address, *rc;
+ va_start(ap, flags);
+ new_address = va_arg(ap, void *);
+ rc = LSS_NAME(_mremap)(old_address, old_size, new_size,
+ flags, new_address);
+ va_end(ap);
+ return rc;
+ }
+
+ LSS_INLINE int LSS_NAME(ptrace_detach)(pid_t pid) {
/* PTRACE_DETACH can sometimes forget to wake up the tracee and it
* then sends job control signals to the real parent, rather than to
* the tracer. We reduce the risk of this happening by starting a
@@ -539,19 +1480,40 @@ struct dirent64;
* right after detaching from the tracee.
*/
int rc, err;
- sys_sched_yield();
- rc = sys_ptrace(PTRACE_DETACH, pid, (void *)0, (void *)0);
- err = errno;
- sys_kill(pid, SIGCONT);
- errno = err;
+ LSS_NAME(sched_yield)();
+ rc = LSS_NAME(ptrace)(PTRACE_DETACH, pid, (void *)0, (void *)0);
+ err = LSS_ERRNO;
+ LSS_NAME(kill)(pid, SIGCONT);
+ LSS_ERRNO = err;
return rc;
}
- #undef REG
- #undef BODY
- #undef RETURN
+
+ LSS_INLINE int LSS_NAME(raise)(int sig) {
+ return LSS_NAME(kill)(LSS_NAME(getpid)(), sig);
+ }
+
+ LSS_INLINE int LSS_NAME(setpgrp)() {
+ return LSS_NAME(setpgid)(0, 0);
+ }
+
+ LSS_INLINE int LSS_NAME(sysconf)(int name) {
+ extern int __getpagesize(void);
+ switch (name) {
+ case _SC_OPEN_MAX: {
+ unsigned long limit[2];
+ return LSS_NAME(getrlimit)(RLIMIT_NOFILE, (struct rlimit *)limit)<0
+ ? 8192 : limit[0];
+ }
+ case _SC_PAGESIZE:
+ return __getpagesize();
+ default:
+ errno = ENOSYS;
+ return -1;
+ }
+ }
#endif
-#ifdef __cplusplus
+#if defined(__cplusplus) && !defined(SYS_CPLUSPLUS)
}
#endif
diff --git a/src/base/linuxthreads.c b/src/base/linuxthreads.c
index 3696987..2f9d547 100644
--- a/src/base/linuxthreads.c
+++ b/src/base/linuxthreads.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2005, Google Inc.
+/* Copyright (c) 2005-2007, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -34,9 +34,11 @@
#include "base/linuxthreads.h"
#ifdef THREADS
+#ifdef __cplusplus
+extern "C" {
+#endif
#include <asm/stat.h>
-#include <fcntl.h>
#include <sched.h>
#include <signal.h>
#include <stdlib.h>
@@ -44,6 +46,7 @@
#include <sys/socket.h>
#include <sys/wait.h>
+#include <asm/fcntl.h>
#include <asm/posix_types.h>
#include <asm/types.h>
#include <linux/dirent.h>
@@ -56,6 +59,11 @@
#endif
+/* Synchronous signals that should not be blocked while in the lister thread.
+ */
+static const int sync_signals[] = { SIGABRT, SIGILL, SIGFPE, SIGSEGV, SIGBUS,
+ SIGXCPU, SIGXFSZ };
+
/* itoa() is not a standard function, and we cannot safely call printf()
* after suspending threads. So, we just implement our own copy. A
* recursive approach is the easiest here.
@@ -92,13 +100,7 @@ static int local_clone (int (*fn)(void *), void *arg, ...)
#endif
static int local_clone (int (*fn)(void *), void *arg, ...) {
- /* Current versions of libc do not wrap any code around the clone()
- * system call. So, it is safe to call the libc version of clone(). If
- * that ever changes, we need to provide our own assembly version of this
- * function. Unfortunately, calling conventions for clone() are somewhat
- * unusual, and we cannot use the generic _syscallX() macros.
- *
- * Leave 4kB of gap between the callers stack and the new clone. This
+ /* Leave 4kB of gap between the callers stack and the new clone. This
* should be more than sufficient for the caller to call waitpid() until
* the cloned thread terminates.
*
@@ -112,8 +114,8 @@ static int local_clone (int (*fn)(void *), void *arg, ...) {
* is being debugged. This is OK and the error code will be reported
* correctly.
*/
- return clone(fn, (char *)&arg - 4096,
- CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_UNTRACED, arg);
+ return sys_clone(fn, (char *)&arg - 4096,
+ CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_UNTRACED, arg, 0, 0, 0);
}
@@ -137,6 +139,31 @@ static int local_atoi(const char *s) {
#define NO_INTR(fn) do {} while ((fn) < 0 && errno == EINTR)
+/* Wrap a class around system calls, in order to give us access to
+ * a private copy of errno. This only works in C++, but it has the
+ * advantage of not needing nested functions, which are a non-standard
+ * language extension.
+ */
+#ifdef __cplusplus
+namespace {
+ class SysCalls {
+ public:
+ #define SYS_CPLUSPLUS
+ #define SYS_ERRNO my_errno
+ #define SYS_INLINE inline
+ #define SYS_PREFIX -1
+ #undef SYS_LINUX_SYSCALL_SUPPORT_H
+ #include "linux_syscall_support.h"
+ SysCalls() : my_errno(0) { }
+ int my_errno;
+ };
+}
+#define ERRNO sys.my_errno
+#else
+#define ERRNO my_errno
+#endif
+
+
/* Wrapper for open() which is guaranteed to never return EINTR.
*/
static int c_open(const char *fname, int flags, int mode) {
@@ -222,8 +249,6 @@ struct ListerParams {
static void ListerThread(struct ListerParams *args) {
- static const int signals[] = { SIGABRT, SIGILL, SIGFPE, SIGSEGV, SIGBUS,
- SIGXCPU, SIGXFSZ };
int found_parent = 0;
pid_t clone_pid = sys_gettid(), ppid = sys_getppid();
char proc_self_task[80], marker_name[48], *marker_path;
@@ -256,7 +281,8 @@ static void ListerThread(struct ListerParams *args) {
/* Compute search paths for finding thread directories in /proc */
local_itoa(strrchr(strcpy(proc_self_task, "/proc/"), '\000'), ppid);
- marker_path = strrchr(strcpy(marker_name, proc_self_task), '\000');
+ strcpy(marker_name, proc_self_task);
+ marker_path = marker_name + strlen(marker_name);
strcat(proc_self_task, "/task/");
proc_paths[0] = proc_self_task; /* /proc/$$/task/ */
proc_paths[1] = "/proc/"; /* /proc/ */
@@ -275,7 +301,7 @@ static void ListerThread(struct ListerParams *args) {
altstack.ss_sp = args->altstack_mem;
altstack.ss_flags = 0;
altstack.ss_size = ALT_STACKSIZE;
- sys_sigaltstack(&altstack, (void *)NULL);
+ sys_sigaltstack(&altstack, (const stack_t *)NULL);
/* Some kernels forget to wake up traced processes, when the
* tracer dies. So, intercept synchronous signals and make sure
@@ -285,13 +311,13 @@ static void ListerThread(struct ListerParams *args) {
*/
sig_marker = marker;
sig_proc = -1;
- for (sig = 0; sig < sizeof(signals)/sizeof(*signals); sig++) {
+ for (sig = 0; sig < sizeof(sync_signals)/sizeof(*sync_signals); sig++) {
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_sigaction = SignalHandler;
sigfillset(&sa.sa_mask);
sa.sa_flags = SA_ONSTACK|SA_SIGINFO|SA_RESETHAND;
- sys_sigaction(signals[sig], &sa, (void *)NULL);
+ sys_sigaction(sync_signals[sig], &sa, (struct sigaction *)NULL);
}
/* Read process directories in /proc/... */
@@ -413,7 +439,7 @@ static void ListerThread(struct ListerParams *args) {
sig_num_threads = num_threads;
goto next_entry;
}
- while (sys_waitpid(pid, (void *)0, __WALL) < 0) {
+ while (sys_waitpid(pid, (int *)0, __WALL) < 0) {
if (errno != EINTR) {
sys_ptrace_detach(pid);
num_threads--;
@@ -513,7 +539,8 @@ int ListAllProcessThreads(void *parameter,
char altstack_mem[ALT_STACKSIZE];
struct ListerParams args;
pid_t clone_pid;
- int dumpable = 1;
+ int dumpable = 1, sig;
+ sigset_t sig_blocked, sig_old;
va_start(args.ap, callback);
@@ -544,35 +571,77 @@ int ListAllProcessThreads(void *parameter,
args.parameter = parameter;
args.callback = callback;
- if ((clone_pid = local_clone((int (*)(void *))ListerThread, &args)) >= 0) {
- int status;
- while (sys_waitpid(clone_pid, &status, __WALL) < 0 &&
- errno == EINTR) {
- // Keep waiting
- }
- if (WIFEXITED(status)) {
- switch (WEXITSTATUS(status)) {
- case 0: break; /* Normal process termination */
- case 2: args.err = EFAULT; /* Some fault (e.g. SIGSEGV) detected */
- args.result = -1;
- break;
- case 3: args.err = EPERM; /* Process is already being traced */
- args.result = -1;
- break;
- default:args.err = ECHILD; /* Child died unexpectedly */
- args.result = -1;
- break;
+ /* Before cloning the thread lister, block all asynchronous signals, as we */
+ /* are not prepared to handle them. */
+ sigfillset(&sig_blocked);
+ for (sig = 0; sig < sizeof(sync_signals)/sizeof(*sync_signals); sig++) {
+ sigdelset(&sig_blocked, sync_signals[sig]);
+ }
+ if (sys_sigprocmask(SIG_BLOCK, &sig_blocked, &sig_old)) {
+ args.err = errno;
+ args.result = -1;
+ goto failed;
+ }
+
+ /* scope */ {
+ /* After cloning, both the parent and the child share the same instance
+ * of errno. We must make sure that at least one of these processes
+ * (in our case, the parent) uses modified syscall macros that update
+ * a local copy of errno, instead.
+ */
+ #ifdef __cplusplus
+ #define sys0_sigprocmask sys.sigprocmask
+ #define sys0_waitpid sys.waitpid
+ SysCalls sys;
+ #else
+ int my_errno;
+ #define SYS_ERRNO my_errno
+ #define SYS_INLINE inline
+ #define SYS_PREFIX 0
+ #undef SYS_LINUX_SYSCALL_SUPPORT_H
+ #include "linux_syscall_support.h"
+ #endif
+
+ int clone_errno;
+ clone_pid = local_clone((int (*)(void *))ListerThread, &args);
+ clone_errno = errno;
+
+ sys0_sigprocmask(SIG_SETMASK, &sig_old, &sig_old);
+
+ if (clone_pid >= 0) {
+ int status, rc;
+ while ((rc = sys0_waitpid(clone_pid, &status, __WALL)) < 0 &&
+ ERRNO == EINTR) {
+ /* Keep waiting */
+ }
+ if (rc < 0) {
+ args.err = ERRNO;
+ args.result = -1;
+ } else if (WIFEXITED(status)) {
+ switch (WEXITSTATUS(status)) {
+ case 0: break; /* Normal process termination */
+ case 2: args.err = EFAULT; /* Some fault (e.g. SIGSEGV) detected */
+ args.result = -1;
+ break;
+ case 3: args.err = EPERM; /* Process is already being traced */
+ args.result = -1;
+ break;
+ default:args.err = ECHILD; /* Child died unexpectedly */
+ args.result = -1;
+ break;
+ }
+ } else if (!WIFEXITED(status)) {
+ args.err = EFAULT; /* Terminated due to an unhandled signal*/
+ args.result = -1;
}
- } else if (!WIFEXITED(status)) {
- args.err = EFAULT; /* Terminated due to an unhandled signal */
+ } else {
args.result = -1;
+ args.err = clone_errno;
}
- } else {
- args.result = -1;
- args.err = errno;
}
/* Restore the "dumpable" state of the process */
+failed:
if (!dumpable)
sys_prctl(PR_SET_DUMPABLE, dumpable);
@@ -595,5 +664,7 @@ int ResumeAllProcessThreads(int num_threads, pid_t *thread_pids) {
return detached_at_least_one;
}
+#ifdef __cplusplus
+}
+#endif
#endif
-
diff --git a/src/base/linuxthreads.h b/src/base/linuxthreads.h
index a6d4298..829fd79 100644
--- a/src/base/linuxthreads.h
+++ b/src/base/linuxthreads.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2005, Google Inc.
+/* Copyright (c) 2005-2007, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -40,8 +40,8 @@
/* We currently only support x86-32 and x86-64 on Linux. Porting to other
* related platforms should not be difficult.
*/
-#if (defined(__i386__) || defined(__x86_64__) || defined(__ARM_ARCH_3__)) && \
- defined(__linux)
+#if (defined(__i386__) || defined(__x86_64__) || defined(__ARM_ARCH_3__) || \
+ defined(mips)) && defined(__linux)
/* Define the THREADS symbol to make sure that there is exactly one core dumper
* built into the library.
diff --git a/src/base/logging.cc b/src/base/logging.cc
new file mode 100644
index 0000000..9bb596a
--- /dev/null
+++ b/src/base/logging.cc
@@ -0,0 +1,37 @@
+// Copyright (c) 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// ---
+// This file just provides storage for FLAGS_verbose.
+
+#include "base/commandlineflags.h"
+
+DEFINE_int32(verbose, EnvToInt("PERFTOOLS_VERBOSE", 0),
+ "Set to numbers >0 for more verbose output, or <0 for less. "
+ "--verbose == -4 means we log fatal errors only.");
diff --git a/src/base/logging.h b/src/base/logging.h
index ae00e5e..9ecb138 100644
--- a/src/base/logging.h
+++ b/src/base/logging.h
@@ -36,20 +36,65 @@
#define _LOGGING_H_
#include <stdarg.h>
-#include <stdio.h>
#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h> // for write()
+#include <string.h> // for strlen()
+#include <assert.h>
+#include <errno.h> // for errno
+#include "base/commandlineflags.h"
+
+// We log all messages at this log-level and below.
+// INFO == -1, WARNING == -2, ERROR == -3, FATAL == -4
+DECLARE_int32(verbose);
// CHECK dies with a fatal error if condition is not true. It is *not*
// controlled by NDEBUG, so the check will be executed regardless of
// compilation mode. Therefore, it is safe to do things like:
// CHECK(fp->Write(x) == 4)
-#define CHECK(condition) \
- do { \
- if (!(condition)) { \
- fprintf(stderr, "Check failed: %s\n", #condition); \
- exit(1); \
- } \
- } while (0) \
+// Note we use write instead of printf/puts to avoid the risk we'll
+// call malloc().
+#define CHECK(condition) \
+ do { \
+ if (!(condition)) { \
+ write(STDERR_FILENO, "Check failed: " #condition "\n", \
+ sizeof("Check failed: " #condition "\n")-1); \
+ exit(1); \
+ } \
+ } while (0)
+
+// This takes a message to print. The name is historical.
+#define RAW_CHECK(condition, message) \
+ do { \
+ if (!(condition)) { \
+ write(STDERR_FILENO, "Check failed: " #condition ": " message "\n", \
+ sizeof("Check failed: " #condition ": " message "\n")-1); \
+ exit(1); \
+ } \
+ } while (0)
+
+// This is like RAW_CHECK, but only in debug-mode
+#ifdef NDEBUG
+enum { DEBUG_MODE = 0 };
+#define RAW_DCHECK(condition, message)
+#else
+enum { DEBUG_MODE = 1 };
+#define RAW_DCHECK(condition, message) RAW_CHECK(condition, message)
+#endif
+
+// This prints errno as well. Note we use write instead of printf/puts to
+// avoid the risk we'll call malloc().
+#define PCHECK(condition) \
+ do { \
+ if (!(condition)) { \
+ const int err_no = errno; \
+ write(STDERR_FILENO, "Check failed: " #condition ": ", \
+ sizeof("Check failed: " #condition ": ")-1); \
+ write(STDERR_FILENO, strerror(err_no), strlen(strerror(err_no))); \
+ write(STDERR_FILENO, "\n", sizeof("\n")-1); \
+ exit(1); \
+ } \
+ } while (0)
// Helper macro for binary operators; prints the two values on error
// Don't use this macro directly in your code, use CHECK_EQ et al below
@@ -60,12 +105,12 @@
// TODO(jandrews): Also print the values in case of failure. Requires some
// sort of type-sensitive ToString() function.
-#define CHECK_OP(op, val1, val2) \
- do { \
- if (!((val1) op (val2))) { \
- fprintf(stderr, "Check failed: %s %s %s\n", #val1, #op, #val2); \
- exit(1); \
- } \
+#define CHECK_OP(op, val1, val2) \
+ do { \
+ if (!((val1) op (val2))) { \
+ fprintf(stderr, "Check failed: %s %s %s\n", #val1, #op, #val2); \
+ exit(1); \
+ } \
} while (0)
#define CHECK_EQ(val1, val2) CHECK_OP(==, val1, val2)
@@ -75,16 +120,39 @@
#define CHECK_GE(val1, val2) CHECK_OP(>=, val1, val2)
#define CHECK_GT(val1, val2) CHECK_OP(> , val1, val2)
-enum {INFO, WARNING, ERROR, FATAL, NUM_SEVERITIES};
+enum {INFO = -1, WARNING = -2, ERROR = -3, FATAL = -4};
+// NOTE: we add a newline to the end of the output if it's not there already
inline void LogPrintf(int severity, const char* pat, ...) {
va_list ap;
va_start(ap, pat);
- vfprintf(stderr, pat, ap);
+ // We write directly to the stderr file descriptor and avoid FILE
+ // buffering because that may invoke malloc()
+ char buf[600];
+ vsnprintf(buf, sizeof(buf)-1, pat, ap);
va_end(ap);
- fprintf(stderr, "\n");
+ if (buf[0] != '\0' && buf[strlen(buf)-1] != '\n') {
+ assert(strlen(buf)+1 < sizeof(buf));
+ strcat(buf, "\n");
+ }
+ write(STDERR_FILENO, buf, strlen(buf));
if ((severity) == FATAL)
- exit(1);
+ abort(); // LOG(FATAL) indicates a big problem, so don't run atexit() calls
}
+// Note that since the order of global constructors is unspecified,
+// global code that calls RAW_LOG may execute before FLAGS_verbose is set.
+// Such code will run with verbosity == 0 no matter what.
+#define RAW_LOG(severity, pat...) do { \
+ if (FLAGS_verbose >= severity) LogPrintf(INFO, pat); \
+} while (0)
+
+// Some synonyms used in unittests
+#define RAW_VLOG(severity, pat...) RAW_LOG(severity, pat)
+#define LOG(severity, pat...) RAW_LOG(severity, pat)
+#define VLOG(severity, pat...) RAW_VLOG(severity, pat)
+#define LOG_IF(severity, cond, pat...) if (cond) LOG(severity, pat)
+
+#define VLOG_IS_ON(severity) (FLAGS_verbose >= severity)
+
#endif // _LOGGING_H_
diff --git a/src/base/low_level_alloc.cc b/src/base/low_level_alloc.cc
new file mode 100644
index 0000000..24816e2
--- /dev/null
+++ b/src/base/low_level_alloc.cc
@@ -0,0 +1,411 @@
+/* Copyright (c) 2006, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ---
+ * Author: Mike Burrows
+ */
+
+// A low-level allocator that can be used by other low-level
+// modules without introducing dependency cycles.
+// This allocator is slow and wasteful of memory;
+// it should not be used when performance is key.
+
+#include "base/low_level_alloc.h"
+#include "base/spinlock.h"
+#include "base/logging.h"
+#include <google/malloc_hook.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/mman.h>
+#include <new> // for placement-new
+
+// A first-fit allocator with amortized logarithmic free() time.
+
+// ---------------------------------------------------------------------------
+static const int kMaxLevel = 30;
+
+namespace {
+ // This struct describes one allocated block, or one free block.
+ struct AllocList {
+ struct Header {
+ intptr_t size; // size of entire region, including this field. Must be
+ // first. Valid in both allocated and unallocated blocks
+ intptr_t magic; // kMagicAllocated or kMagicUnallocated xor this
+ LowLevelAlloc::Arena *arena; // pointer to parent arena
+ void *dummy_for_alignment; // aligns regions to 0 mod 2*sizeof(void*)
+ } header;
+
+ // Next two fields: in unallocated blocks: freelist skiplist data
+ // in allocated blocks: overlaps with client data
+ int levels; // levels in skiplist used
+ AllocList *next[kMaxLevel]; // actually has levels elements.
+ // The AllocList node may not have room for
+ // all kMaxLevel entries. See max_fit in
+ // LLA_SkiplistLevels()
+ };
+}
+
+// ---------------------------------------------------------------------------
+// A trivial skiplist implementation. This is used to keep the freelist
+// in address order while taking only logarithmic time per insert and delete.
+
+// An integer approximation of log2(size/base)
+// Requires size >= base.
+static int IntLog2(size_t size, size_t base) {
+ int result = 0;
+ for (size_t i = size; i > base; i >>= 1) { // i == floor(size/2**result)
+ result++;
+ }
+ // floor(size / 2**result) <= base < floor(size / 2**(result-1))
+ // => log2(size/(base+1)) <= result < 1+log2(size/base)
+ // => result ~= log2(size/base)
+ return result;
+}
+
+// Return a random integer n: p(n)=1/(2**n) if 1 <= n; p(n)=0 if n < 1.
+static int Random() {
+ static int32 r = 1; // no locking---it's not critical
+ int result = 1;
+ while ((((r = r*1103515245 + 12345) >> 30) & 1) == 0) {
+ result++;
+ }
+ return result;
+}
+
+// Return a number of skiplist levels for a node of size bytes, where
+// base is the minimum node size. Compute level=log2(size / base)+n
+// where n is 1 if random is false and otherwise a random number generated with
+// the standard distribution for a skiplist: See Random() above.
+// Bigger nodes tend to have more skiplist levels due to the log2(size / base)
+// term, so first-fit searches touch fewer nodes. "level" is clipped so
+// level<kMaxLevel and next[level-1] will fit in the node.
+// 0 < LLA_SkiplistLevels(x,y,false) <= LLA_SkiplistLevels(x,y,true) < kMaxLevel
+static int LLA_SkiplistLevels(size_t size, size_t base, bool random) {
+ // max_fit is the maximum number of levels that will fit in a node for the
+ // given size. We can't return more than max_fit, no matter what the
+ // random number generator says.
+ int max_fit = (size-OFFSETOF_MEMBER(AllocList, next)) / sizeof (AllocList *);
+ int level = IntLog2(size, base) + (random? Random() : 1);
+ if (level > max_fit) level = max_fit;
+ if (level > kMaxLevel-1) level = kMaxLevel - 1;
+ RAW_CHECK(level >= 1, "block not big enough for even one level");
+ return level;
+}
+
+// Return "atleast", the first element of AllocList *head s.t. *atleast >= *e.
+// For 0 <= i < head->levels, set prev[i] to "no_greater", where no_greater
+// points to the last element at level i in the AllocList less than *e, or is
+// head if no such element exists.
+static AllocList *LLA_SkiplistSearch(AllocList *head,
+ AllocList *e, AllocList **prev) {
+ AllocList *p = head;
+ for (int level = head->levels - 1; level >= 0; level--) {
+ for (AllocList *n; (n = p->next[level]) != 0 && n < e; p = n) {
+ }
+ prev[level] = p;
+ }
+ return (head->levels == 0) ? 0 : prev[0]->next[0];
+}
+
+// Insert element *e into AllocList *head. Set prev[] as LLA_SkiplistSearch.
+// Requires that e->levels be previously set by the caller (using
+// LLA_SkiplistLevels())
+static void LLA_SkiplistInsert(AllocList *head, AllocList *e,
+ AllocList **prev) {
+ LLA_SkiplistSearch(head, e, prev);
+ for (; head->levels < e->levels; head->levels++) { // extend prev pointers
+ prev[head->levels] = head; // to all *e's levels
+ }
+ for (int i = 0; i != e->levels; i++) { // add element to list
+ e->next[i] = prev[i]->next[i];
+ prev[i]->next[i] = e;
+ }
+}
+
+// Remove element *e from AllocList *head. Set prev[] as LLA_SkiplistSearch().
+// Requires that e->levels be previous set by the caller (using
+// LLA_SkiplistLevels())
+static void LLA_SkiplistDelete(AllocList *head, AllocList *e,
+ AllocList **prev) {
+ AllocList *found = LLA_SkiplistSearch(head, e, prev);
+ RAW_CHECK(e == found, "element not in freelist");
+ for (int i = 0; i != e->levels && prev[i]->next[i] == e; i++) {
+ prev[i]->next[i] = e->next[i];
+ }
+ while (head->levels > 0 && head->next[head->levels - 1] == 0) {
+ head->levels--; // reduce head->levels if level unused
+ }
+}
+
+// ---------------------------------------------------------------------------
+// Arena implementation
+
+struct LowLevelAlloc::Arena {
+ Arena() : mu(SpinLock::LINKER_INITIALIZED) {} // does nothing; for static init
+ explicit Arena(int) : pagesize(0) {} // set pagesize to zero explicitly
+ // for non-static init
+
+ SpinLock mu; // protects freelist, allocation_count,
+ // pagesize, roundup, min_size
+ AllocList freelist; // head of free list; sorted by addr (under mu)
+ int32 allocation_count; // count of allocated blocks (under mu)
+ int32 flags; // flags passed to NewArena (ro after init)
+ size_t pagesize; // ==getpagesize() (init under mu, then ro)
+ size_t roundup; // lowest power of 2 >= max(16,sizeof (AllocList))
+ // (init under mu, then ro)
+ size_t min_size; // smallest allocation block size
+ // (init under mu, then ro)
+};
+
+// The default arena, which is used when 0 is passed instead of an Arena
+// pointer.
+static struct LowLevelAlloc::Arena default_arena;
+
+// magic numbers to identify allocated and unallocated blocks
+static const intptr_t kMagicAllocated = 0x4c833e95;
+static const intptr_t kMagicUnallocated = ~kMagicAllocated;
+
+// create an appropriate magic number for an object at "ptr"
+// "magic" should be kMagicAllocated or kMagicUnallocated
+inline static intptr_t Magic(intptr_t magic, AllocList::Header *ptr) {
+ return magic ^ reinterpret_cast<intptr_t>(ptr);
+}
+
+// Initialize the fields of an Arena
+static void ArenaInit(LowLevelAlloc::Arena *arena) {
+ if (arena->pagesize == 0) {
+ arena->pagesize = getpagesize();
+ // Round up block sizes to a power of two close to the header size.
+ arena->roundup = 16;
+ while (arena->roundup < sizeof (arena->freelist.header)) {
+ arena->roundup += arena->roundup;
+ }
+ // Don't allocate blocks less than twice the roundup size to avoid tiny
+ // free blocks.
+ arena->min_size = 2 * arena->roundup;
+ arena->freelist.header.size = 0;
+ arena->freelist.header.magic =
+ Magic(kMagicUnallocated, &arena->freelist.header);
+ arena->freelist.header.arena = arena;
+ arena->freelist.levels = 0;
+ memset(arena->freelist.next, 0, sizeof (arena->freelist.next));
+ arena->allocation_count = 0;
+ arena->flags = 0;
+ }
+}
+
+// L < meta_data_arena->mu
+LowLevelAlloc::Arena *LowLevelAlloc::NewArena(int32 flags,
+ Arena *meta_data_arena) {
+ if (meta_data_arena == 0) {
+ meta_data_arena = &default_arena;
+ }
+ // Arena(0) uses the constructor for non-static contexts
+ Arena *result = new (Alloc(sizeof (*result), meta_data_arena)) Arena(0);
+ ArenaInit(result);
+ result->flags = flags;
+ return result;
+}
+
+// L < arena->mu, L < arena->arena->mu
+bool LowLevelAlloc::DeleteArena(Arena *arena) {
+ RAW_CHECK(arena != 0 && arena != &default_arena,
+ "may not delete default arena");
+ arena->mu.Lock();
+ bool empty = (arena->allocation_count == 0);
+ arena->mu.Unlock();
+ if (empty) {
+ while (arena->freelist.next[0] != 0) {
+ AllocList *region = arena->freelist.next[0];
+ size_t size = region->header.size;
+ arena->freelist.next[0] = region->next[0];
+ RAW_CHECK(region->header.magic ==
+ Magic(kMagicUnallocated, &region->header),
+ "bad magic number in DeleteArena()");
+ RAW_CHECK(region->header.arena == arena,
+ "bad arena pointer in DeleteArena()");
+ RAW_CHECK(size % arena->pagesize == 0,
+ "empty arena has non-page-aligned block size");
+ RAW_CHECK(reinterpret_cast<intptr_t>(region) % arena->pagesize == 0,
+ "empty arena has non-page-aligned block");
+ RAW_CHECK(munmap(region, size) == 0,
+ "LowLevelAlloc::DeleteArena: munmap failed address");
+ }
+ Free(arena);
+ }
+ return empty;
+}
+
+// ---------------------------------------------------------------------------
+
+// Return value rounded up to next multiple of align.
+// align must be a power of two.
+static intptr_t RoundUp(intptr_t addr, intptr_t align) {
+ return (addr + align - 1) & ~(align - 1);
+}
+
+// Equivalent to "return prev->next[i]" but with sanity checking
+// that the freelist is in the correct order, that it
+// consists of regions marked "unallocated", and that no two regions
+// are adjacent in memory (they should have been coalesced).
+// L < arena->mu
+static AllocList *Next(int i, AllocList *prev, LowLevelAlloc::Arena *arena) {
+ RAW_CHECK(i < prev->levels, "too few levels in Next()");
+ AllocList *next = prev->next[i];
+ if (next != 0) {
+ RAW_CHECK(next->header.magic == Magic(kMagicUnallocated, &next->header),
+ "bad magic number in Next()");
+ RAW_CHECK(next->header.arena == arena,
+ "bad arena pointer in Next()");
+ if (prev != &arena->freelist) {
+ RAW_CHECK(prev < next, "unordered freelist");
+ RAW_CHECK(reinterpret_cast<char *>(prev) + prev->header.size <
+ reinterpret_cast<char *>(next), "malformed freelist");
+ }
+ }
+ return next;
+}
+
+// Coalesce list item "a" with its successor if they are adjacent.
+static void Coalesce(AllocList *a) {
+ AllocList *n = a->next[0];
+ if (n != 0 && reinterpret_cast<char *>(a) + a->header.size ==
+ reinterpret_cast<char *>(n)) {
+ LowLevelAlloc::Arena *arena = a->header.arena;
+ a->header.size += n->header.size;
+ n->header.magic = 0;
+ n->header.arena = 0;
+ AllocList *prev[kMaxLevel];
+ LLA_SkiplistDelete(&arena->freelist, n, prev);
+ LLA_SkiplistDelete(&arena->freelist, a, prev);
+ a->levels = LLA_SkiplistLevels(a->header.size, arena->min_size, true);
+ LLA_SkiplistInsert(&arena->freelist, a, prev);
+ }
+}
+
+// Adds block at location "v" to the free list
+// L >= arena->mu
+static void AddToFreelist(void *v, LowLevelAlloc::Arena *arena) {
+ AllocList *f = reinterpret_cast<AllocList *>(
+ reinterpret_cast<char *>(v) - sizeof (f->header));
+ RAW_CHECK(f->header.magic == Magic(kMagicAllocated, &f->header),
+ "bad magic number in AddToFreelist()");
+ RAW_CHECK(f->header.arena == arena,
+ "bad arena pointer in AddToFreelist()");
+ f->levels = LLA_SkiplistLevels(f->header.size, arena->min_size, true);
+ AllocList *prev[kMaxLevel];
+ LLA_SkiplistInsert(&arena->freelist, f, prev);
+ f->header.magic = Magic(kMagicUnallocated, &f->header);
+ Coalesce(f); // maybe coalesce with successor
+ Coalesce(prev[0]); // maybe coalesce with predecessor
+}
+
+// Frees storage allocated by LowLevelAlloc::Alloc().
+// L < arena->mu
+void LowLevelAlloc::Free(void *v) {
+ if (v != 0) {
+ AllocList *f = reinterpret_cast<AllocList *>(
+ reinterpret_cast<char *>(v) - sizeof (f->header));
+ RAW_CHECK(f->header.magic == Magic(kMagicAllocated, &f->header),
+ "bad magic number in Free()");
+ LowLevelAlloc::Arena *arena = f->header.arena;
+ if ((arena->flags & kCallMallocHook) != 0) {
+ MallocHook::InvokeDeleteHook(v);
+ }
+ arena->mu.Lock();
+ AddToFreelist(v, arena);
+ RAW_CHECK(arena->allocation_count > 0, "nothing in arena to free");
+ arena->allocation_count--;
+ arena->mu.Unlock();
+ }
+}
+
+// allocates and returns a block of size bytes, to be freed with Free()
+// L < arena->mu
+void *LowLevelAlloc::Alloc(size_t request, Arena *arena) {
+ void *result = 0;
+ if (arena == 0) {
+ arena = &default_arena;
+ }
+ if (request != 0) {
+ AllocList *s; // will point to region that satisfies request
+ arena->mu.Lock();
+ ArenaInit(arena);
+ // round up with header
+ size_t req_rnd = RoundUp(request + sizeof (s->header), arena->roundup);
+ for (;;) { // loop until we find a suitable region
+ // find the minimum levels that a block of this size must have
+ int i = LLA_SkiplistLevels(req_rnd, arena->min_size, false) - 1;
+ if (i < arena->freelist.levels) { // potential blocks exist
+ AllocList *before = &arena->freelist; // predecessor of s
+ while ((s = Next(i, before, arena)) != 0 && s->header.size < req_rnd) {
+ before = s;
+ }
+ if (s != 0) { // we found a region
+ break;
+ }
+ }
+ // we unlock before mmap() both because mmap() may call a callback hook,
+ // and because it may be slow.
+ arena->mu.Unlock();
+ size_t new_pages_size = RoundUp(req_rnd, arena->pagesize);
+ void *new_pages = mmap(0, new_pages_size,
+ PROT_WRITE|PROT_READ, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
+ RAW_CHECK(new_pages != MAP_FAILED, "mmap error");
+ s = reinterpret_cast<AllocList *>(new_pages);
+ s->header.size = new_pages_size;
+ // Pretend the block is allocated; call AddToFreelist() to free it.
+ s->header.magic = Magic(kMagicAllocated, &s->header);
+ s->header.arena = arena;
+ arena->mu.Lock();
+ AddToFreelist(&s->levels, arena); // insert new region into free list
+ }
+ AllocList *prev[kMaxLevel];
+ LLA_SkiplistDelete(&arena->freelist, s, prev); // remove from free list
+ // s points to the first free region that's big enough
+ if (req_rnd + arena->min_size <= s->header.size) { // big enough to split
+ AllocList *n = reinterpret_cast<AllocList *>
+ (req_rnd + reinterpret_cast<char *>(s));
+ n->header.size = s->header.size - req_rnd;
+ n->header.magic = Magic(kMagicAllocated, &n->header);
+ n->header.arena = arena;
+ s->header.size = req_rnd;
+ AddToFreelist(&n->levels, arena);
+ }
+ s->header.magic = Magic(kMagicAllocated, &s->header);
+ RAW_CHECK(s->header.arena == arena, "");
+ arena->allocation_count++;
+ arena->mu.Unlock();
+ result = &s->levels;
+ }
+ if ((arena->flags & kCallMallocHook) != 0) {
+ MallocHook::InvokeNewHook(result, request);
+ }
+ return result;
+}
diff --git a/src/base/low_level_alloc.h b/src/base/low_level_alloc.h
new file mode 100644
index 0000000..0aed634
--- /dev/null
+++ b/src/base/low_level_alloc.h
@@ -0,0 +1,90 @@
+/* Copyright (c) 2006, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ---
+ * Author: Mike Burrows
+ */
+
+#if !defined(_BASE_LOW_LEVEL_ALLOC_H_)
+#define _BASE_LOW_LEVEL_ALLOC_H_
+
+// A simple memory allocator that does not depend on mutexes or
+// thread-specific data. It is intended to be used sparingly,
+// and only when malloc() would introduce an unwanted dependency,
+// such as inside the heap-checker.
+
+#include <stddef.h> // for size_t
+#include "base/basictypes.h"
+
+class LowLevelAlloc {
+ public:
+ struct Arena; // an arena from which memory may be allocated
+
+ // Returns a pointer to a block of at least "request" bytes
+ // that have been newly allocated from the specific arena.
+ // The arena may be 0, in which case a default arena is used.
+ // Returns 0 if passed request==0.
+ // Does not return 0 under other circumstances; it crashes if memory
+ // is not available.
+ static void *Alloc(size_t request, Arena *arena)
+ ATTRIBUTE_SECTION(malloc_hook_callers);
+
+ // Deallocates a region of memory that was previously allocated with
+ // Alloc(). Does nothing if passed 0. "s" must be either 0,
+ // or must have been returned from a call to Alloc() and not yet passed to
+ // Free() since that call to Alloc(). The space is returned to the arena
+ // from which it was allocated.
+ static void Free(void *s) ATTRIBUTE_SECTION(malloc_hook_callers);
+
+ // ATTRIBUTE_SECTION(malloc_hook_callers) for Alloc and Free
+ // are to put all callers of MallocHook::Invoke* in this module
+ // into special section,
+ // so that MallocHook::GetCallerStackTrace can function accurately.
+
+ // Create a new arena.
+ // The root metadata for the new arena is allocated in the
+ // meta_data_arena; the default arena is used if meta_data_arena==0.
+ // These values may be ored into flags:
+ enum { kCallMallocHook = 0x0001 }; // calls to Alloc() and Free()
+ // will be reported via the MallocHook
+ // interface.
+ static Arena *NewArena(int32 flags, Arena *meta_data_arena);
+
+ // Destroys an arena allocated by NewArena and returns true,
+ // provided no allocated blocks remain in the arena.
+ // If allocated blocks remain in the arena, does nothing and
+ // returns false.
+ // It is illegal to attempt to destroy the default arena.
+ static bool DeleteArena(Arena *arena);
+
+ private:
+ LowLevelAlloc(); // no instances
+};
+
+#endif
diff --git a/src/base/mutex.cc b/src/base/mutex.cc
new file mode 100644
index 0000000..d5b7c73
--- /dev/null
+++ b/src/base/mutex.cc
@@ -0,0 +1,79 @@
+/* Copyright (c) 2007, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ---
+ * Author: Craig Silverstein
+ *
+ * A simple mutex wrapper. Right now, it's implemented in terms of
+ * pthreads, but is meant to be easy to extend to other threads impls.
+ */
+
+#include "config.h"
+#include "mutex.h"
+
+#if defined(NO_THREADS)
+
+Mutex::Mutex() {}
+Mutex::~Mutex() {}
+void Mutex::Lock() {}
+void Mutex::Unlock() {}
+void Mutex::ReaderLock() {}
+void Mutex::ReaderUnlock() {}
+
+#elif defined(HAVE_PTHREAD) && defined(HAVE_RWLOCK)
+
+#include <stdlib.h> // for abort()
+#include <pthread.h>
+#define SAFE_PTHREAD(fncall) do { if ((fncall) != 0) abort(); } while (0)
+
+Mutex::Mutex() { SAFE_PTHREAD(pthread_rwlock_init(&mutex_, NULL)); }
+Mutex::~Mutex() { SAFE_PTHREAD(pthread_rwlock_destroy(&mutex_)); }
+void Mutex::Lock() { SAFE_PTHREAD(pthread_rwlock_wrlock(&mutex_)); }
+void Mutex::Unlock() { SAFE_PTHREAD(pthread_rwlock_unlock(&mutex_)); }
+void Mutex::ReaderLock() { SAFE_PTHREAD(pthread_rwlock_rdlock(&mutex_)); }
+void Mutex::ReaderUnlock() { SAFE_PTHREAD(pthread_rwlock_unlock(&mutex_)); }
+
+#elif defined(HAVE_PTHREAD)
+
+#include <stdlib.h> // for abort()
+#include <pthread.h>
+#define SAFE_PTHREAD(fncall) do { if ((fncall) != 0) abort(); } while (0)
+
+Mutex::Mutex() { SAFE_PTHREAD(pthread_mutex_init(&mutex_, NULL)); }
+Mutex::~Mutex() { SAFE_PTHREAD(pthread_mutex_destroy(&mutex_)); }
+void Mutex::Lock() { SAFE_PTHREAD(pthread_mutex_lock(&mutex_)); }
+void Mutex::Unlock() { SAFE_PTHREAD(pthread_mutex_unlock(&mutex_)); }
+void Mutex::ReaderLock() { Lock(); } // we don't have read-write locks
+void Mutex::ReaderUnlock() { Unlock(); }
+
+#else
+
+#error Need to implement mutex.h/cc for your architecture, or #define NO_THREADS
+
+#endif
diff --git a/src/base/mutex.h b/src/base/mutex.h
new file mode 100644
index 0000000..ef9f7e7
--- /dev/null
+++ b/src/base/mutex.h
@@ -0,0 +1,131 @@
+/* Copyright (c) 2007, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ---
+ * Author: Craig Silverstein.
+ *
+ * A simple mutex wrapper, supporting locks and read-write locks.
+ *
+ * To use: you should define the following macros in your configure.ac:
+ * ACX_PTHREAD
+ * AC_RWLOCK
+ * The latter is defined in ../autoconf.
+ *
+ * This class is meant to be internal-only, so it's defined in the
+ * global namespace. If you want to expose it, you'll want to move
+ * it to the Google namespace.
+ */
+
+#include "config.h" // to figure out pthreads support
+
+#if defined(NO_THREADS)
+ typedef int MutexType; // some dummy type; it won't be used
+#elif defined(HAVE_PTHREAD) && defined(HAVE_RWLOCK)
+ // Needed for pthread_rwlock_*. If it causes problems, you could take
+ // it out, but then you'd have to unset HAVE_RWLOCK (at least on linux).
+# define _XOPEN_SOURCE 500 // needed to get the rwlock calls
+# include <pthread.h>
+ typedef pthread_rwlock_t MutexType;
+#elif defined(HAVE_PTHREAD)
+# include <pthread.h>
+ typedef pthread_mutex_t MutexType;
+#else
+# error Need to implement mutex.h/cc for your architecture, or #define NO_THREADS
+#endif
+
+class Mutex {
+ public:
+ // Create a Mutex that is not held by anybody.
+ Mutex();
+
+ // Destructor
+ ~Mutex();
+
+ void Lock(); // Block if necessary until free, then acquire exclusively
+ void Unlock(); // Release. Caller must hold it exclusively (via Lock())
+
+ // Note that on systems that don't support read-write locks, these may
+ // be implemented as synonyms to Lock() and Unlock(). So you can use
+ // these for efficiency, but don't use them anyplace where being able
+ // to do shared reads is necessary to avoid deadlock.
+ void ReaderLock(); // Block until free or shared, then acquire a share
+ void ReaderUnlock(); // Release a read share of this Mutex
+ void WriterLock() { Lock(); } // Block until free, then acquire exclusively
+ void WriterUnlock() { Unlock(); } // Release the exclusive lock of this Mutex
+
+ private:
+ MutexType mutex_;
+
+ // Catch the error of writing Mutex when intending MutexLock.
+ Mutex(Mutex *ignored) {}
+ // Disallow "evil" constructors
+ Mutex(const Mutex&);
+ void operator=(const Mutex&);
+};
+
+
+// MutexLock(mu) acquires mu when constructed and releases it when destroyed.
+class MutexLock {
+ public:
+ explicit MutexLock(Mutex *mu) : mu_(mu) { mu_->Lock(); }
+ ~MutexLock() { mu_->Unlock(); }
+ private:
+ Mutex * const mu_;
+ // Disallow "evil" constructors
+ MutexLock(const MutexLock&);
+ void operator=(const MutexLock&);
+};
+
+// ReaderMutexLock and WriterMutexLock do the same, for rwlocks
+class ReaderMutexLock {
+ public:
+ explicit ReaderMutexLock(Mutex *mu) : mu_(mu) { mu_->ReaderLock(); }
+ ~ReaderMutexLock() { mu_->ReaderUnlock(); }
+ private:
+ Mutex * const mu_;
+ // Disallow "evil" constructors
+ ReaderMutexLock(const ReaderMutexLock&);
+ void operator=(const ReaderMutexLock&);
+};
+
+class WriterMutexLock {
+ public:
+ explicit WriterMutexLock(Mutex *mu) : mu_(mu) { mu_->WriterLock(); }
+ ~WriterMutexLock() { mu_->WriterUnlock(); }
+ private:
+ Mutex * const mu_;
+ // Disallow "evil" constructors
+ WriterMutexLock(const WriterMutexLock&);
+ void operator=(const WriterMutexLock&);
+};
+
+// Catch bug where variable name is omitted, e.g. MutexLock (&mu);
+#define MutexLock(x) COMPILE_ASSERT(0, mutex_lock_decl_missing_var_name)
+#define ReaderMutexLock(x) COMPILE_ASSERT(0, rmutex_lock_decl_missing_var_name)
+#define WriterMutexLock(x) COMPILE_ASSERT(0, wmutex_lock_decl_missing_var_name)
diff --git a/src/base/spinlock.cc b/src/base/spinlock.cc
new file mode 100644
index 0000000..e5cc400
--- /dev/null
+++ b/src/base/spinlock.cc
@@ -0,0 +1,120 @@
+/* Copyright (c) 2006, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ---
+ * Author: Sanjay Ghemawat
+ */
+
+#include <time.h> /* For nanosleep() */
+#include <sched.h> /* For sched_yield() */
+#include <unistd.h> /* For nanosleep() on Windows, read() */
+#include <fcntl.h> /* for open(), O_RDONLY */
+#include <string.h> /* for strncmp */
+#include <errno.h>
+#include "base/spinlock.h"
+
+static int adaptive_spin_count = 0;
+static int num_cpus = -1;
+
+// It's important this not call malloc! -- it is called at global-construct
+// time, before we've set up all our proper malloc hooks and such.
+static int NumCPUs() {
+ if (num_cpus >= 0)
+ return num_cpus; // value is cached
+
+ const char* pname = "/proc/cpuinfo";
+ int fd = open(pname, O_RDONLY);
+ if (fd == -1) {
+ num_cpus = 1; // conservative assumption; TODO: do better
+ return num_cpus;
+ }
+ char line[1024];
+ int chars_read;
+ num_cpus = 0;
+ do { // a line at a time
+ chars_read = 0;
+ char* linepos = line;
+ while (linepos - line < sizeof(line)-1 &&
+ (chars_read=read(fd, linepos, 1)) == 1 &&
+ *linepos != '\n') // read one line
+ linepos++;
+ *linepos = '\0'; // terminate the line at the \n
+ if (strncmp(line, "processor ", sizeof("processor ")-1) == 0)
+ num_cpus++;
+ } while (chars_read > 0); // stop when we get to EOF
+ close(fd);
+ return num_cpus == 0 ? 1 : num_cpus;
+}
+
+struct SpinLock_InitHelper {
+ SpinLock_InitHelper() {
+ // On multi-cpu machines, spin for longer before yielding
+ // the processor or sleeping. Reduces idle time significantly.
+ if (NumCPUs() > 1) {
+ adaptive_spin_count = 1000;
+ }
+ }
+};
+
+// Hook into global constructor execution:
+// We do not do adaptive spinning before that,
+// but nothing lock-intensive should be going on at that time.
+static SpinLock_InitHelper init_helper;
+
+void SpinLock::SlowLock() {
+ int saved_errno = errno; // save and restore errno for signal safety
+ int c = adaptive_spin_count;
+
+ // Spin a few times in the hope that the lock holder releases the lock
+ while ((c > 0) && (lockword_ != 0)) {
+ c--;
+ }
+
+ if (lockword_ == 1) {
+ sched_yield(); // Spinning failed. Let's try to be gentle.
+ }
+
+ while (Acquire_CompareAndSwap(&lockword_, 0, 1) != 0) {
+ // This code was adapted from the ptmalloc2 implementation of
+ // spinlocks which would sched_yield() upto 50 times before
+ // sleeping once for a few milliseconds. Mike Burrows suggested
+ // just doing one sched_yield() outside the loop and always
+ // sleeping after that. This change helped a great deal on the
+ // performance of spinlocks under high contention. A test program
+ // with 10 threads on a dual Xeon (four virtual processors) went
+ // from taking 30 seconds to 16 seconds.
+
+ // Sleep for a few milliseconds
+ struct timespec tm;
+ tm.tv_sec = 0;
+ tm.tv_nsec = 2000001;
+ nanosleep(&tm, NULL);
+ }
+ errno = saved_errno;
+}
diff --git a/src/base/spinlock.h b/src/base/spinlock.h
new file mode 100644
index 0000000..c82fa06
--- /dev/null
+++ b/src/base/spinlock.h
@@ -0,0 +1,107 @@
+/* Copyright (c) 2006, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ---
+ * Author: Sanjay Ghemawat
+ */
+
+//
+// Fast spinlocks (at least on x86, a lock/unlock pair is approximately
+// half the cost of a Mutex because the unlock just does a store instead
+// of a compare-and-swap which is expensive).
+
+// Spinlock is async signal safe.
+// If used within a signal handler, all lock holders
+// should block the signal even outside the signal handler.
+
+#ifndef BASE_SPINLOCK_H__
+#define BASE_SPINLOCK_H__
+
+#include "base/basictypes.h"
+#include "base/atomicops.h"
+
+class SpinLock {
+ public:
+ SpinLock() : lockword_(0) { }
+
+ // Special constructor for use with static SpinLock objects. E.g.,
+ //
+ // static SpinLock lock(SpinLock::LINKER_INITIALIZED);
+ //
+ // When intialized using this constructor, we depend on the fact
+ // that the linker has already initialized the memory appropriately.
+ // A SpinLock constructed like this can be freely used from global
+ // initializers without worrying about the order in which global
+ // initializers run.
+ enum StaticInitializer { LINKER_INITIALIZED };
+ explicit SpinLock(StaticInitializer x) {
+ // Does nothing; lockword_ is already initialized
+ }
+
+ inline void Lock() {
+ if (Acquire_CompareAndSwap(&lockword_, 0, 1) != 0) {
+ SlowLock();
+ }
+ }
+
+ inline void Unlock() {
+ Release_Store(&lockword_, 0);
+ }
+
+ // Report if we think the lock can be held by this thread.
+ // When the lock is truly held by the invoking thread
+ // we will always return true.
+ // Indended to be used as CHECK(lock.IsHeld());
+ inline bool IsHeld() const {
+ return lockword_ != 0;
+ }
+
+ private:
+ // Lock-state: 0 means unlocked, 1 means locked
+ volatile AtomicWord lockword_;
+
+ void SlowLock();
+
+ DISALLOW_EVIL_CONSTRUCTORS(SpinLock);
+};
+
+// Corresponding locker object that arranges to acquire a spinlock for
+// the duration of a C++ scope.
+class SpinLockHolder {
+ private:
+ SpinLock* lock_;
+ public:
+ inline explicit SpinLockHolder(SpinLock* l) : lock_(l) { l->Lock(); }
+ inline ~SpinLockHolder() { lock_->Unlock(); }
+};
+// Catch bug where variable name is omitted, e.g. SpinLockHolder (&lock);
+#define SpinLockHolder(x) COMPILE_ASSERT(0, spin_lock_decl_missing_var_name)
+
+
+#endif // BASE_SPINLOCK_H__
diff --git a/src/base/stl_allocator.h b/src/base/stl_allocator.h
new file mode 100644
index 0000000..c0bb64e
--- /dev/null
+++ b/src/base/stl_allocator.h
@@ -0,0 +1,90 @@
+/* Copyright (c) 2006, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ---
+ * Author: Maxim Lifantsev
+ */
+
+
+#ifndef BASE_STL_ALLOCATOR_H__
+#define BASE_STL_ALLOCATOR_H__
+
+#include <limits>
+
+#include "base/basictypes.h"
+#include "base/logging.h"
+
+// Generic allocator class for STL objects
+// that uses a given type-less allocator Alloc, which must provide:
+// static void* Alloc::Allocate(size_t size);
+// static void Alloc::Free(void* ptr);
+// Usage example:
+// set<T, less<T>, STL_Allocator<T, MyAlloc> > my_set;
+// CAVEAT: Parts of the code below are probably specific
+// to the STL version(s) we are using.
+// The code is simply lifted from what std::allocator<> provides.
+template <typename T, class Alloc>
+class STL_Allocator {
+ public:
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+ typedef T* pointer;
+ typedef const T* const_pointer;
+ typedef T& reference;
+ typedef const T& const_reference;
+ typedef T value_type;
+
+ template <class T1> struct rebind {
+ typedef STL_Allocator<T1, Alloc> other;
+ };
+
+ STL_Allocator() { }
+ STL_Allocator(const STL_Allocator&) { }
+ template <class T1> STL_Allocator(const STL_Allocator<T1, Alloc>&) { }
+ ~STL_Allocator() { }
+
+ pointer address(reference x) const { return &x; }
+ const_pointer address(const_reference x) const { return &x; }
+
+ pointer allocate(size_type n, const void* = 0) {
+ RAW_DCHECK(n < std::numeric_limits<size_t>::max() / sizeof(T), "");
+ return static_cast<T*>(Alloc::Allocate(n * sizeof(T)));
+ }
+ void deallocate(pointer p, size_type n) { Alloc::Free(p); }
+
+ size_type max_size() const { return size_t(-1) / sizeof(T); }
+
+ void construct(pointer p, const T& val) { ::new(p) T(val); }
+ void destroy(pointer p) { p->~T(); }
+
+ // There's no state, so these allocators are always equal
+ bool operator==(const STL_Allocator&) const { return true; }
+};
+
+#endif // BASE_STL_ALLOCATOR_H__
diff --git a/src/base/sysinfo.cc b/src/base/sysinfo.cc
new file mode 100644
index 0000000..77de531
--- /dev/null
+++ b/src/base/sysinfo.cc
@@ -0,0 +1,177 @@
+// Copyright (c) 2006, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// ---
+// Author: Mike Burrows
+
+#include <stdlib.h> // for getenv()
+#include <stdio.h> // for snprintf(), sscanf()
+#include <string.h> // for memmove(), memchr(), etc.
+#include <fcntl.h> // for open()
+#include <unistd.h> // for read()
+#include "base/sysinfo.h"
+#include "base/logging.h"
+
+// open/read/close can set errno, which may be illegal at this
+// time, so prefer making the syscalls directly if we can.
+#ifdef HAVE_SYSCALL_H
+# include <syscall.h>
+# define safeopen(filename, mode) syscall(SYS_open, filename, mode)
+# define saferead(fd, buffer, size) syscall(SYS_read, fd, buffer, size)
+# define safeclose(fd) syscall(SYS_close, fd)
+#else
+# define safeopen(filename, mode) open(filename, mode)
+# define saferead(fd, buffer, size) read(fd, buffer, size)
+# define safeclose(fd) close(fd)
+#endif
+
+const char* GetenvBeforeMain(const char* name) {
+ // static is ok because this function should only be called before
+ // main(), when we're single-threaded.
+ static char envbuf[16<<10];
+ if (*envbuf == '\0') { // haven't read the environ yet
+ int fd = safeopen("/proc/self/environ", O_RDONLY);
+ if (fd == -1) { // unable to open the file, fall back onto libc
+ RAW_LOG(WARNING, "Unable to open /proc/self/environ, falling back "
+ "on getenv(\"%s\"), which may not work", name);
+ return getenv(name);
+ }
+ // The -2 here guarantees the last two bytes of the buffer will be \0\0
+ if (saferead(fd, envbuf, sizeof(envbuf) - 2) < 0) { // error reading file
+ safeclose(fd);
+ RAW_LOG(WARNING, "Unable to read from /proc/self/environ, falling back "
+ "on getenv(\"%s\"), which may not work", name);
+ return getenv(name);
+ }
+ safeclose(fd);
+ }
+ const int namelen = strlen(name);
+ const char* p = envbuf;
+ while (*p != '\0') { // will happen at the \0\0 that terminates the buffer
+ // proc file has the format NAME=value\0NAME=value\0NAME=value\0...
+ const char* endp = (char*)memchr(p, '\0', sizeof(envbuf) - (p - envbuf));
+ if (endp == NULL) // this entry isn't NUL terminated
+ return NULL;
+ else if (!memcmp(p, name, namelen) && p[namelen] == '=') // it's a match
+ return p + namelen+1; // point after =
+ p = endp + 1;
+ }
+ return NULL; // env var never found
+}
+
+ProcMapsIterator::ProcMapsIterator(pid_t pid) {
+ Init(pid, NULL);
+}
+
+ProcMapsIterator::ProcMapsIterator(pid_t pid, char *buffer) {
+ Init(pid, buffer);
+}
+
+void ProcMapsIterator::Init(pid_t pid, char *buffer) {
+ ibuf_ = buffer;
+ dynamic_ibuf_ = NULL;
+ if (!ibuf_) {
+ // If the user didn't pass in any buffer storage, allocate it
+ // now. This is the normal case; the signal handler passes in a
+ // static buffer.
+ dynamic_ibuf_ = new char[kBufSize];
+ ibuf_ = dynamic_ibuf_;
+ }
+
+ stext_ = etext_ = nextline_ = ibuf_;
+ ebuf_ = ibuf_ + kBufSize - 1;
+ nextline_ = ibuf_;
+
+ char filename[64];
+ snprintf(filename, sizeof(filename), "/proc/%d/maps", pid?:getpid());
+ // No error logging since this can be called from the crash dump
+ // handler at awkward moments. Users should call Valid() before
+ // using.
+ fd_ = open(filename, O_RDONLY);
+}
+
+ProcMapsIterator::~ProcMapsIterator() {
+ delete[] dynamic_ibuf_;
+ if (fd_ != -1) close(fd_);
+}
+
+bool ProcMapsIterator::Next(uint64 *start, uint64 *end, char **flags,
+ uint64 *offset, int64 *inode, char **filename) {
+
+ do {
+ // Advance to the start of the next line
+ stext_ = nextline_;
+
+ // See if we have a complete line in the buffer already
+ nextline_ = static_cast<char *>(memchr (stext_, '\n', etext_ - stext_));
+ if (!nextline_) {
+ // Shift/fill the buffer so we do have a line
+ int count = etext_ - stext_;
+
+ // Move the current text to the start of the buffer
+ memmove(ibuf_, stext_, count);
+ stext_ = ibuf_;
+ etext_ = ibuf_ + count;
+
+ int nread = 0; // fill up buffer with text
+ while (etext_ < ebuf_ && (nread = read(fd_, etext_, ebuf_ - etext_)) > 0) {
+ etext_ += nread;
+ }
+
+ // Zero out remaining characters in buffer at EOF to avoid returning
+ // garbage from subsequent calls.
+ if (etext_ != ebuf_ && nread == 0) {
+ memset(etext_, 0, ebuf_ - etext_);
+ }
+ *etext_ = '\n'; // sentinel; safe because ibuf extends 1 char beyond ebuf
+ nextline_ = static_cast<char *>(memchr (stext_, '\n', etext_ + 1 - stext_));
+ }
+ *nextline_ = 0; // turn newline into nul
+ nextline_ += ((nextline_ < etext_)? 1 : 0); // skip nul if not end of text
+ // stext_ now points at a nul-terminated line
+ uint64 tmpstart, tmpend, tmpoffset;
+ int64 tmpinode;
+ int filename_offset;
+ if (sscanf(stext_, "%llx-%llx %4s %llx %*x:%*x %lld %n",
+ start ?: &tmpstart,
+ end ?: &tmpend,
+ flags_,
+ offset ?: &tmpoffset,
+ inode ?: &tmpinode, &filename_offset) != 5) continue;
+
+ // We found an entry
+
+ if (flags) *flags = flags_;
+ if (filename) *filename = stext_ + filename_offset;
+ return true;
+ } while (etext_ > ibuf_);
+
+ // We didn't find anything
+ return false;
+}
diff --git a/src/base/sysinfo.h b/src/base/sysinfo.h
new file mode 100644
index 0000000..ae99cb7
--- /dev/null
+++ b/src/base/sysinfo.h
@@ -0,0 +1,111 @@
+// Copyright (c) 2006, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// ---
+// Author: Mike Burrows
+
+#ifndef _SYSINFO_H_
+#define _SYSINFO_H_
+
+#include <time.h>
+#include <unistd.h> // for pid_t
+#include <stddef.h> // for size_t
+#include <limits.h> // for PATH_MAX
+#include "base/basictypes.h"
+
+// This getenv prefers using /proc/self/environ to calling getenv().
+// It's intended to be used in routines that run before main(), when
+// the state required for getenv() may not be set up yet. In particular,
+// errno isn't set up until relatively late (after the pthreads library
+// has a chance to make it threadsafe), and getenv() doesn't work until then.
+// Note that /proc only has the environment at the time the application was
+// started, so this routine ignores setenv() calls/etc. Also note it only
+// reads the first 16K of the environment.
+const char* GetenvBeforeMain(const char* name);
+
+
+// A ProcMapsIterator abstracts access to /proc/maps for a given
+// process. Needs to be stack-allocatable and avoid using stdio/malloc
+// so it can be used in the google stack dumper.
+class ProcMapsIterator {
+
+ public:
+
+ static const size_t kBufSize = PATH_MAX + 1024;
+
+ // Create a new iterator for the specified pid
+ explicit ProcMapsIterator(pid_t pid);
+
+ // Create an iterator with specified storage (for use in signal
+ // handler). "buffer" should point to an area of size kBufSize
+ ProcMapsIterator(pid_t pid, char *buffer);
+
+ // Returns true if the iterator successfully initialized;
+ bool Valid() const { return fd_ != -1; }
+
+ // Returns a pointer to the most recently parsed line. Only valid
+ // after Next() returns true, and until the iterator is destroyed or
+ // Next() is called again.
+ const char *CurrentLine() const { return stext_; }
+
+ // Find the next entry in /proc/maps; return true if found or false
+ // if at the end of the file.
+ //
+ // Any of the result pointers can be NULL if you're not interested
+ // in those values.
+ //
+ // If "flags" and "filename" are passed, they end up pointing to
+ // storage within the ProcMapsIterator that is valid only until the
+ // iterator is destroyed or Next() is called again. The caller may
+ // modify the contents of these strings (up as far as the first NUL,
+ // and only until the subsequent call to Next()) if desired.
+
+ // The offsets are all uint64 in order to handle the case of a
+ // 32-bit process running on a 64-bit kernel
+ bool Next(uint64 *start, uint64 *end, char **flags,
+ uint64 *offset, int64 *inode, char **filename);
+
+ ~ProcMapsIterator();
+
+ private:
+
+ void Init(pid_t pid, char *buffer);
+
+ char *ibuf_; // input buffer
+ char *stext_; // start of text
+ char *etext_; // end of text
+ char *nextline_; // start of next line
+ char *ebuf_; // end of buffer (1 char for a nul)
+ int fd_; // filehandle on /proc/*/maps
+ char flags_[10];
+ char* dynamic_ibuf_; // dynamically-allocated ibuf_
+
+};
+
+#endif /* #ifndef _SYSINFO_H_ */
diff --git a/src/base/thread_lister.c b/src/base/thread_lister.c
index f3df16b..8c19fde 100644
--- a/src/base/thread_lister.c
+++ b/src/base/thread_lister.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2005, Google Inc.
+/* Copyright (c) 2005-2007, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/src/base/thread_lister.h b/src/base/thread_lister.h
index b050343..6afe4dd 100644
--- a/src/base/thread_lister.h
+++ b/src/base/thread_lister.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2005, Google Inc.
+/* Copyright (c) 2005-2007, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/src/config.h.in b/src/config.h.in
index 2abb5bd..bf963bd 100644
--- a/src/config.h.in
+++ b/src/config.h.in
@@ -9,6 +9,10 @@
/* Define to 1 if you have the <conflict-signal.h> header file. */
#undef HAVE_CONFLICT_SIGNAL_H
+/* Define to 1 if you have the declaration of `uname', and to 0 if you don't.
+ */
+#undef HAVE_DECL_UNAME
+
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
@@ -60,6 +64,9 @@
/* Define if you have POSIX threads libraries and header files. */
#undef HAVE_PTHREAD
+/* Define to 1 if you have the <pwd.h> header file. */
+#undef HAVE_PWD_H
+
/* Define to 1 if you have the `sbrk' function. */
#undef HAVE_SBRK
@@ -75,6 +82,9 @@
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
+/* Define to 1 if the system has the type `struct mallinfo'. */
+#undef HAVE_STRUCT_MALLINFO
+
/* Define to 1 if `eip' is member of `struct sigcontext'. */
#undef HAVE_STRUCT_SIGCONTEXT_EIP
@@ -105,6 +115,9 @@
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
+/* Define to 1 if compiler supports __thread */
+#undef HAVE_TLS
+
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
@@ -138,9 +151,15 @@
/* Define to the version of this package. */
#undef PACKAGE_VERSION
-/* printf format code for printing a size_t */
+/* printf format code for printing a size_t and ssize_t */
+#undef PRIdS
+
+/* printf format code for printing a size_t and ssize_t */
#undef PRIuS
+/* printf format code for printing a size_t and ssize_t */
+#undef PRIxS
+
/* Define to necessary symbol if this constant uses a non-standard name on
your system. */
#undef PTHREAD_CREATE_JOINABLE
@@ -154,6 +173,8 @@
/* Version number of package */
#undef VERSION
-/* Define as `__inline' if that's what the C compiler calls it, or to nothing
- if it is not supported. */
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+ calls it, or to nothing if 'inline' is not supported under any name. */
+#ifndef __cplusplus
#undef inline
+#endif
diff --git a/src/google/heap-checker.h b/src/google/heap-checker.h
index f888ae0..9abe233 100644
--- a/src/google/heap-checker.h
+++ b/src/google/heap-checker.h
@@ -30,244 +30,68 @@
// ---
// Author: Maxim Lifantsev (with design ideas by Sanjay Ghemawat)
//
-// Heap memory leak checker (utilizes heap-profiler and pprof).
//
-// TODO(jandrews): rewrite this documentation
-// HeapLeakChecker, a heap memory leak checking class.
+// Module for detecing heap (memory) leaks.
//
-// Verifies that there are no memory leaks between its
-// construction and call to its *NoLeaks() or *SameHeap() member.
+// For full(er) information, see doc/heap-checker.html
//
-// It will dump two profiles at these two events
-// (named <prefix>.<name>-beg.heap and <prefix>.<name>-end.heap
-// where <prefix> is determined automatically to some temporary location
-// and <name> is given in the HeapLeakChecker's constructor)
-// and will return false in case the amount of in-use memory
-// is more at the time of *NoLeaks() call than
-// (or respectively differs at the time of *SameHeap())
-// from what it was at the time of our construction.
-// It will also in this case print a message on how to process the dumped
-// profiles to locate leaks.
+// This module can be linked into programs with
+// no slowdown caused by this unless you activate the leak-checker:
//
-// GUIDELINE: In addition to the local heap leak checking between two arbitrary
-// points in program's execution via an explicit HeapLeakChecker object,
-// we provide a way for overall whole-program heap leak checking,
-// which is WHAT ONE SHOULD NORMALLY USE.
+// 1. Set the environment variable HEAPCHEK to _type_ before
+// running the program.
//
-// Currently supported heap-check types, from less strict to more
-// strict, are:
-// "minimal", "normal", "strict", "draconian"
+// _type_ is usually "normal" but can also be "minimal", "strict", or
+// "draconian". (See the html file for other options, like 'local'.)
//
-// There are also two more types: "as-is" and "local".
-//
-// GUIDELINE CONT.: Depending on the value of the HEAPCHECK variable
-// -- as well as other flags of this module -- different modifications
-// of leak checking between different points in program's execution
-// take place. The "as-is" value leaves control to the other flags of
-// this module. The "local" value does not start whole-program heap
-// leak checking but activates all the machinery needed for local heap
-// leak checking via explicitly created HeapLeakChecker objects.
-//
-// For the case of "normal" everything from before execution of all
-// global variable constructors to normal program exit (namely after
-// main() returns and after all REGISTER_HEAPCHECK_CLEANUP's are
-// executed, but before any global variable destructors are executed)
-// is checked for the absence of heap memory leaks.
-//
-// NOTE: For all but "draconian" whole-program leak check we also
-// ignore all heap objects reachable (at the time of the check)
-// from any global variable or any live thread stack variable
-// or from any object identified by a HeapLeakChecker::IgnoreObject() call.
-//
-// CAVEAT: We do a liveness flood by traversing pointers to heap objects
-// starting from some initial memory regions we know to potentially
-// contain live pointer data.
-// -- It might potentially not find some (global)
-// live data region to start the flood from,
-// but we consider such cases to be our bugs to fix.
-// The liveness flood approach although not being very portable
-// and 100% exact works in most cases (see below)
-// and saves us from writing a lot of explicit clean up code
-// and other hassles when dealing with thread data.
-//
-// The liveness flood simply attempts to treat any properly aligned
-// byte sequences as pointers to heap objects and thinks that
-// it found a good pointer simply when the current heap memory map
-// contains an object with the address whose byte representation we found.
-// As a result of this simple approach, it's unlikely but very possible
-// for the flood to be inexact and occasionally result in leaked objects
-// being erroneously determined to be live.
-// Numerous reasons can lead to this, e.g.:
-// - Random bit patters can happen to look
-// like pointers to leaked heap objects.
-// - Stale pointer data not corresponding to any live program variables
-// can be still present in memory regions (e.g. thread stacks --see below)
-// that we consider to be live.
-// - Stale pointer data that we did not clear can point
-// to a now leaked heap object simply because the heap object
-// address got reused by the memory allocator, e.g.
-// char* p = new char[1];
-// delete p;
-// new char[1]; // this is leaked but p might be pointing to it
-//
-// The implications of these imprecisions of the liveness flood
-// are as follows:
-// - For any heap leak check we might miss some memory leaks.
-// - For a whole-program leak check, a leak report *does* always
-// correspond to a real leak (unless of course the heap-checker has a bug).
-// This is because in this case we start with an empty heap profile,
-// so there's never an issue of it saying that some heap objects
-// are live when they are not.
-// - For local leak checks, a leak report can be a partial false positive
-// in the sense that the reported leaks might have actually occurred
-// before this local leak check was started.
-// Here's an example scenario: When we start a local check
-// heap profile snapshot mistakenly says that some previously
-// leaked objects are live.
-// When we end the local check the heap profile snapshot now correctly
-// determines that those objects are unreachable and reports them as leaks
-// for this leak check, whereas they had been already leaked before
-// this leak check has started.
-//
-// THREADS and heap leak checking: At the time of HeapLeakChecker's
-// construction and during *NoLeaks()/*SameHeap() calls we grab a lock so that
-// heap activity in other threads is paused for the time
-// we are recording or analyzing the state of the heap.
-// For any heap leak check it is possible to have
-// other threads active and working with the heap
-// when we make the HeapLeakChecker object or do its leak checking
-// provided all these threads are discoverable with the implemetation
-// of thread_lister.h (e.g. are linux pthreads).
-// In this case leak checking should deterministically work fine.
-//
-// CAVEAT: Thread stack data ignoring (via thread_lister.h)
-// does not work if the program is running under gdb, probably becauce the
-// ptrace functionality needed for thread_lister is already hooked to by gdb.
-//
-// As mentioned above thread stack liveness determination
-// might miss-classify objects that very recently became unreachable (leaked)
-// as reachable in the cases when the values of the pointers
-// to the now unreachable objects are still present in the active stack frames,
-// while the pointers actually no longer correspond to any live program
-// variables.
-// For this reason trivial code like the following
-// might not produce the expected leak checking outcome
-// depending on how the compiled code works with the stack:
-//
-// int* foo = new int [20];
-// HeapLeakChecker check("a_check");
-// foo = NULL;
-// CHECK(check.NoLeaks()); // this might succeed
-//
-// HINT: If you are debugging detected leaks, you can try different
-// (e.g. less strict) values for HEAPCHECK to determine the cause of
-// the reported leaks (see the code of
-// HeapLeakChecker::InternalInitStart for details).
-//
-// GUIDELINE: Below are the preferred ways of making your (test)
-// binary pass the above recommended overall heap leak check in the
-// order of decreasing preference:
-//
-// 1. Fix the leaks if they are real leaks.
-//
-// 2. If you are sure that the reported leaks are not dangerous
-// and there is no good way to fix them, then you can use
-// HeapLeakChecker::DisableChecks(Up|In|At) calls (see below) in
-// the relevant modules to disable certain stack traces for the
-// purpose of leak checking. You can also use
-// HeapLeakChecker::IgnoreObject() call to ignore certain leaked
-// heap objects and everythign reachable from them.
-//
-// 3. If the leaks are due to some initialization in a third-party
-// package, you might be able to force that initialization before
-// the heap checking starts.
-//
-// I.e. if HEAPCHECK == "minimal" or less strict, if you put the
-// initialization in a global constructor the heap-checker will
-// ignore it. If HEAPCHECK == "normal" or stricter, only
-// HeapLeakChecker::LibCPreallocate() happens before heap checking
-// starts.
-//
-// Making a binary pass at "strict" or "draconian" level is not
-// necessary or even desirable in the numerous cases when it requires
-// adding a lot of (otherwise unused) heap cleanup code to various
-// core libraries.
-//
-// NOTE: the following should apply only if
-// HEAPCHECK == "strict" or stricter
-//
-// 4. If the found leaks are due to incomplete cleanup in destructors
-// of global variables, extend or add those destructors or use a
-// REGISTER_HEAPCHECK_CLEANUP to do the deallocations instead to
-// avoid cleanup overhead during normal execution. This type of
-// leaks get reported when one goes from "normal" to "strict"
-// checking.
-//
-// NOTE: the following should apply only if
-// HEAPCHECK == "draconian" or stricter
-//
-// 5. If the found leaks are for global static pointers whose values are
-// allocated/grown (e.g on-demand) and never deallocated,
-// then you should be able to add REGISTER_HEAPCHECK_CLEANUP's
-// or appropriate destructors into these modules
-// to free those objects.
-//
-// Example of local usage (anywhere in the program):
-//
-// HeapLeakChecker heap_checker("test_foo");
-//
-// { <code that exercises some foo functionality
-// that should preserve memory allocation state> }
-//
-// CHECK(heap_checker.SameHeap());
-//
-// NOTE: One should set HEAPCHECK to a non-empty value e.g. "local"
-// to help suppress some false leaks for these local checks.
+// After that, just run your binary. If the heap-checker detects
+// a memory leak at program-exit, it will print instructions on how
+// to track down the leak.
#ifndef BASE_HEAP_CHECKER_H__
#define BASE_HEAP_CHECKER_H__
-#include <sys/types.h> // for size_t
+#include <sys/types.h> // for size_t
+#include <stdint.h> // for uintptr_t
#include <vector>
-// A macro to declare module heap check cleanup tasks
-// (they run only if we are doing heap leak checking.)
-// Use
-// public:
-// void Class::HeapCleanup();
-// if you need to do heap check cleanup on private members of a class.
-#define REGISTER_HEAPCHECK_CLEANUP(name, body) \
- namespace { \
- void heapcheck_cleanup_##name() { body; } \
- static HeapCleaner heapcheck_cleaner_##name(&heapcheck_cleanup_##name); \
- }
-
-// A class that exists solely to run its destructor. This class should not be
-// used directly, but instead by the REGISTER_HEAPCHECK_CLEANUP macro above.
-class HeapCleaner {
- public:
- typedef void (*void_function)(void);
- HeapCleaner(void_function f);
- static void RunHeapCleanups();
- private:
- static std::vector<void_function>* heap_cleanups_;
-};
class HeapLeakChecker {
public: // Static functions for working with (whole-program) leak checking.
-
+
// If heap leak checking is currently active in some mode
// e.g. if leak checking was started (and is still active now)
// due to any valid non-empty --heap_check flag value
// (including "local") on the command-line
// or via a dependency on //base:heapcheck.
- // The return value reflects iff HeapLeakChecker objects manually
+ // The return value reflects iff HeapLeakChecker objects manually
// constructed right now will be doing leak checking or nothing.
// Note that we can go from active to inactive state during InitGoogle()
// if FLAGS_heap_check gets set to "" by some code before/during InitGoogle().
static bool IsActive();
+ // Return pointer to the whole-program checker if (still) active
+ // and NULL otherwise.
+ // This is mainly to access BytesLeaked() and ObjectsLeaked() (see below)
+ // for the whole-program checker after one calls NoGlobalLeaks()
+ // or similar and gets false.
+ static HeapLeakChecker* GlobalChecker();
+
+ // Do whole-program leak check now (if it was activated for this binary);
+ // return false only if it was activated and has failed.
+ // The mode of the check is controlled by the command-line flags.
+ // This method can be called repeatedly.
+ // Things like GlobalChecker()->SameHeap() can also be called explicitly
+ // to do the desired flavor of the check.
+ static bool NoGlobalLeaks();
+
+ // If whole-program checker if active,
+ // cancel its automatic execution after main() exits.
+ // This requires that some leak check (e.g. NoGlobalLeaks())
+ // has been called at least once on the whole-program checker.
+ static void CancelGlobalCheck();
+
public: // Non-static functions for starting and doing leak checking.
// Start checking and name the leak check performed.
@@ -288,27 +112,30 @@ class HeapLeakChecker {
// and thus is not detected by BriefNoLeaks.)
// CAVEAT: pprof will do no checking over stripped binaries
// (our automatic test binaries are stripped)
- bool NoLeaks() { return DoNoLeaks(false, true, true); }
+ // NOTE: All *NoLeaks() and *SameHeap() methods can be called many times
+ // to check for leaks at different end-points in program's execution.
+ bool NoLeaks() { return DoNoLeaks(NO_LEAKS, USE_PPROF, PPROF_REPORT); }
// Return true iff the heap does not seem to have more objects allocated
// w.r.t. its state at the time of our construction
// by looking at the number of objects & bytes allocated.
// This also tries to do pprof reporting of detected leaks.
- bool QuickNoLeaks() { return DoNoLeaks(false, false, true); }
+ bool QuickNoLeaks() { return DoNoLeaks(NO_LEAKS, USE_COUNTS, PPROF_REPORT); }
// Return true iff the heap does not seem to have more objects allocated
// w.r.t. its state at the time of our construction
// by looking at the number of objects & bytes allocated.
// This does not try to use pprof at all.
- bool BriefNoLeaks() { return DoNoLeaks(false, false, false); }
+ bool BriefNoLeaks() { return DoNoLeaks(NO_LEAKS, USE_COUNTS, NO_REPORT); }
// These are similar to their *NoLeaks counterparts,
// but they in addition require no negative leaks,
// i.e. the state of the heap must be exactly the same
// as at the time of our construction.
- bool SameHeap() { return DoNoLeaks(true, true, true); }
- bool QuickSameHeap() { return DoNoLeaks(true, false, true); }
- bool BriefSameHeap() { return DoNoLeaks(true, false, false); }
+ bool SameHeap() { return DoNoLeaks(SAME_HEAP, USE_PPROF, PPROF_REPORT); }
+ bool QuickSameHeap()
+ { return DoNoLeaks(SAME_HEAP, USE_COUNTS, PPROF_REPORT); }
+ bool BriefSameHeap() { return DoNoLeaks(SAME_HEAP, USE_COUNTS, NO_REPORT); }
// Detailed information about the number of leaked bytes and objects
// (both of these can be negative as well).
@@ -321,24 +148,10 @@ class HeapLeakChecker {
ssize_t BytesLeaked() const;
ssize_t ObjectsLeaked() const;
- // Destructor
- // (verifies that some *SameHeap or *NoLeaks method has been called).
+ // Destructor (verifies that some *NoLeaks or *SameHeap method
+ // has been called at least once).
~HeapLeakChecker();
- // Accessors to determine various internal parameters. These should
- // be set as early as possible.
-
- // If overall heap check reports found leaks via pprof. Default: true
- static void set_heap_check_report(bool);
- // Location of pprof script. Default: $prefix/bin/pprof
- static void set_pprof_path(const char*);
- // Location to write profile dumps. Default: /tmp
- static void set_dump_directory(const char*);
-
- static bool heap_check_report();
- static const char* pprof_path();
- static const char* dump_directory();
-
private: // data
char* name_; // our remembered name
@@ -348,9 +161,6 @@ class HeapLeakChecker {
ssize_t inuse_bytes_increase_; // bytes-in-use increase for this checker
ssize_t inuse_allocs_increase_; // allocations-in-use increase for this checker
- static pid_t main_thread_pid_; // For naming output files
- static std::string* dump_directory_; // Location to write profile dumps
-
public: // Static helpers to make us ignore certain leaks.
// NOTE: All calls to DisableChecks* affect all later heap profile generation
@@ -358,7 +168,7 @@ class HeapLeakChecker {
// They do nothing when heap leak checking is turned off.
// CAVEAT: Disabling via all the DisableChecks* functions happens only
- // up to kMaxStackTrace stack frames (see heap-profiler.cc)
+ // up to kMaxStackTrace stack frames (see heap-profile-table.h)
// down from the stack frame identified by the function.
// Hence, this disabling will stop working for very deep call stacks
// and you might see quite wierd leak profile dumps in such cases.
@@ -455,28 +265,35 @@ class HeapLeakChecker {
public: // Initializations; to be called from main() only.
- // Full starting of recommended whole-program checking. This runs after
- // HeapChecker::BeforeConstructors and can do initializations which may
- // depend on configuration parameters set by initialization code.
- // Valid values of heap_check type are:
- // - "minimal"
- // - "normal"
- // - "strict"
- // - "draconian"
- // - "local"
- static void InternalInitStart(const std::string& heap_check_type);
+ // Full starting of recommended whole-program checking.
+ static void InternalInitStart();
+
+ public: // Internal types defined in .cc
+ struct Allocator;
struct RangeValue;
- struct StackExtent;
private: // Various helpers
- // Helper for dumping start/end heap leak checking profiles.
- void DumpProfileLocked(bool start, const StackExtent& self_stack);
+ // Type for DumpProfileLocked
+ enum ProfileType { START_PROFILE, END_PROFILE };
+ // Helper for dumping start/end heap leak checking profiles
+ // and getting the byte/object counts.
+ void DumpProfileLocked(ProfileType profile_type, void* self_stack_top,
+ size_t* alloc_bytes, size_t* alloc_objects);
// Helper for constructors
void Create(const char *name);
- // Helper for *NoLeaks and *SameHeap
- bool DoNoLeaks(bool same_heap, bool do_full, bool do_report);
+ // Types for DoNoLeaks and its helpers.
+ enum CheckType { SAME_HEAP, NO_LEAKS };
+ enum CheckFullness { USE_PPROF, USE_COUNTS };
+ enum ReportMode { PPROF_REPORT, NO_REPORT };
+ // Helpers for *NoLeaks and *SameHeap
+ bool DoNoLeaks(CheckType check_type,
+ CheckFullness fullness,
+ ReportMode report_mode);
+ bool DoNoLeaksOnce(CheckType check_type,
+ CheckFullness fullness,
+ ReportMode report_mode);
// Helper for IgnoreObject
static void IgnoreObjectLocked(void* ptr);
// Helper for DisableChecksAt
@@ -484,11 +301,11 @@ class HeapLeakChecker {
// Helper for DisableChecksIn
static void DisableChecksInLocked(const char* pattern);
// Helper for DisableChecksToHereFrom
- static void DisableChecksFromTo(void* start_address,
- void* end_address,
- int max_depth);
+ static void DisableChecksFromToLocked(void* start_address,
+ void* end_address,
+ int max_depth);
// Helper for DoNoLeaks to ignore all objects reachable from all live data
- static void IgnoreAllLiveObjectsLocked(const StackExtent& self_stack);
+ static void IgnoreAllLiveObjectsLocked(void* self_stack_top);
// Callback we pass to ListAllProcessThreads (see thread_lister.h)
// that is invoked when all threads of our process are found and stopped.
// The call back does the things needed to ignore live data reachable from
@@ -519,44 +336,89 @@ class HeapLeakChecker {
// in a debug message to describe what kind of live object sources
// are being used.
static void IgnoreLiveObjectsLocked(const char* name, const char* name2);
+ // Heap profile object filtering callback to filter out live objects.
+ static bool HeapProfileFilter(void* ptr, size_t size);
// Runs REGISTER_HEAPCHECK_CLEANUP cleanups and potentially
// calls DoMainHeapCheck
static void RunHeapCleanups();
// Do the overall whole-program heap leak check
static void DoMainHeapCheck();
- // Type of task for UseProcMaps
- enum ProcMapsTask {
- RECORD_GLOBAL_DATA_LOCKED,
- DISABLE_LIBRARY_ALLOCS
+ // Type of task for UseProcMapsLocked
+ enum ProcMapsTask {
+ RECORD_GLOBAL_DATA,
+ DISABLE_LIBRARY_ALLOCS
+ };
+ // Success/Error Return codes for UseProcMapsLocked.
+ enum ProcMapsResult {
+ PROC_MAPS_USED,
+ CANT_OPEN_PROC_MAPS,
+ NO_SHARED_LIBS_IN_PROC_MAPS
};
- // Success/Error Return codes for UseProcMaps.
- enum ProcMapsResult { PROC_MAPS_USED, CANT_OPEN_PROC_MAPS,
- NO_SHARED_LIBS_IN_PROC_MAPS };
// Read /proc/self/maps, parse it, and do the 'proc_maps_task' for each line.
- static ProcMapsResult UseProcMaps(ProcMapsTask proc_maps_task);
+ static ProcMapsResult UseProcMapsLocked(ProcMapsTask proc_maps_task);
// A ProcMapsTask to disable allocations from 'library'
// that is mapped to [start_address..end_address)
// (only if library is a certain system library).
- static void DisableLibraryAllocs(const char* library,
- void* start_address,
- void* end_address);
+ static void DisableLibraryAllocsLocked(const char* library,
+ uintptr_t start_address,
+ uintptr_t end_address);
+
+ // Return true iff "*ptr" points to a heap object;
+ // we also fill *object_size for this object then.
+ // If yes, we might move "*ptr" to point to the very start of the object
+ // (this needs to happen for C++ class array allocations
+ // and for basic_string-s of C++ library that comes with gcc 3.4).
+ static bool HaveOnHeapLocked(void** ptr, size_t* object_size);
private:
+ // Helper for VerifyHeapProfileTableStackGet in the unittest
+ // to get the recorded allocation caller for ptr,
+ // which must be a heap object.
+ static void* GetAllocCaller(void* ptr);
+ friend void VerifyHeapProfileTableStackGet();
+
// This gets to execute before constructors for all global objects
static void BeforeConstructors();
friend void HeapLeakChecker_BeforeConstructors();
// This gets to execute after destructors for all global objects
friend void HeapLeakChecker_AfterDestructors();
+ // Helper to shutdown heap leak checker when it's not needed
+ // or can't function properly.
+ static void TurnItselfOff();
private:
+
// Start whole-executable checking.
HeapLeakChecker();
- // Don't allow copy constructors -- these are declared but not defined
+ private:
+ // Disallow "evil" constructors.
HeapLeakChecker(const HeapLeakChecker&);
void operator=(const HeapLeakChecker&);
};
+
+// A class that exists solely to run its destructor. This class should not be
+// used directly, but instead by the REGISTER_HEAPCHECK_CLEANUP macro below.
+class HeapCleaner {
+ public:
+ typedef void (*void_function)(void);
+ HeapCleaner(void_function f);
+ static void RunHeapCleanups();
+ private:
+ static std::vector<void_function>* heap_cleanups_;
+};
+
+// A macro to declare module heap check cleanup tasks
+// (they run only if we are doing heap leak checking.)
+// 'body' should be the cleanup code to run. 'name' doesn't matter,
+// but must be unique amongst all REGISTER_HEAPCHECK_CLEANUP calls.
+#define REGISTER_HEAPCHECK_CLEANUP(name, body) \
+ namespace { \
+ void heapcheck_cleanup_##name() { body; } \
+ static HeapCleaner heapcheck_cleaner_##name(&heapcheck_cleanup_##name); \
+ }
+
#endif // BASE_HEAP_CHECKER_H__
diff --git a/src/google/heap-profiler.h b/src/google/heap-profiler.h
index b62056e..b603ca7 100644
--- a/src/google/heap-profiler.h
+++ b/src/google/heap-profiler.h
@@ -32,55 +32,25 @@
//
// Module for heap-profiling.
//
-// This module is safe to link into any program you may wish to
-// profile at some point. It will not cause any noticeable slowdowns
-// unless you activate by setting the environment variable
-// HEAPPROFILE, e.g.:
-// $ export HEAPPROFILE=/tmp/my_program_profile ; ./my_program
-// $ ls /tmp/my_program_profile.*
-// /tmp/my_program_profile.0000.heap
-// /tmp/my_program_profile.0001.heap
-// /tmp/my_program_profile.0002.heap
-// ...
+// For full(er) information, see doc/heapprofile.html
//
-// This allows you to easily profile your program at any time without
-// having to recompile, and doesn't slow things down if HEAPPROFILE is
-// unset. We refuse to do profiling if uid != euid, to avoid
-// environment-based security issues if your program is accidentally
-// setuid. Note that this library should generally not be linked into
-// setuid programs. It has not been reviewed or tested for security
-// under setuid conditions.
+// This module can be linked into your program with
+// no slowdown caused by this unless you activate the profiler
+// using one of the following methods:
//
-// If heap-profiling is turned on, a profile file is dumped every GB
-// of allocated data. You can override this behavior by calling
-// HeapProfilerSetAllocationInterval() to a number of bytes N. If
-// you do that, a profile file will be dumped after every N bytes of
-// allocations.
+// 1. Before starting the program, set the environment variable
+// "HEAPPROFILE" to be the name of the file to which the profile
+// data should be written.
//
-// If heap profiling is on, we also dump a profile when the
-// in-use-bytes reach a new high-water-mark. Only increases of at
-// least 100MB are considered significant changes in the
-// high-water-mark. This number can be changed by calling
-// HeapProfilerSetInuseInterval() with a different byte-value.
+// 2. Programmatically, start and stop the profiler using the
+// routines "HeapProfilerStart(filename)" and "HeapProfilerStop()".
//
-// STL WARNING: The HeapProfiler does not accurately track allocations
-// in many STL implementations. This is because it is common for the
-// default STL allocator to keep an internal pool of memory and nevery
-// return it to the system. This means that large allocations may be
-// attributed to an object that you know was destroyed. For a simple
-// example, see TestHeapLeakCheckerSTL in
-// src/tests/heap-checker_unittest.cc.
-//
-// This issue is resolved for GCC 3.3 and 3.4 by setting the
-// environment variable GLIBCXX_FORCE_NEW, which forces the STL
-// allocator to call `new' and `delete' explicitly for every
-// allocation and deallocation. For GCC 3.2 and previous you will
-// need to compile your source with -D__USE_MALLOC. For other
-// compilers / STL libraries, there may be a similar solution; See
-// your implementation's documentation for information.
+// Use pprof to view the resulting profile output.
+// % google3/perftools/pprof <path_to_executable> <profile_file_name>
+// % google3/perftools/pprof --gv <path_to_executable> <profile_file_name>
-#ifndef _HEAP_PROFILER_H
-#define _HEAP_PROFILER_H
+#ifndef BASE_HEAP_PROFILER_H__
+#define BASE_HEAP_PROFILER_H__
#include <stddef.h>
@@ -102,19 +72,4 @@ extern void HeapProfilerDump(const char *reason);
// free()-ed as soon as the caller does not need it anymore.
extern char* GetHeapProfile();
-// ---- Configuration accessors ----
-
-// Level of logging used by the heap profiler and heap checker (if applicable)
-// Default: 0
-extern void HeapProfilerSetLogLevel(int level);
-
-// Dump heap profiling information once every specified number of bytes
-// allocated by the program. Default: 1GB
-extern void HeapProfilerSetAllocationInterval(size_t interval);
-
-// Dump heap profiling information whenever the high-water
-// memory usage mark increases by the specified number of
-// bytes. Default: 100MB
-extern void HeapProfilerSetInuseInterval(size_t interval);
-
-#endif /* _HEAP_PROFILER_H */
+#endif /* BASE_HEAP_PROFILER_H__ */
diff --git a/src/google/malloc_extension.h b/src/google/malloc_extension.h
index e088154..5244aa1 100644
--- a/src/google/malloc_extension.h
+++ b/src/google/malloc_extension.h
@@ -30,13 +30,13 @@
// ---
// Author: Sanjay Ghemawat <opensource@google.com>
//
-// Extra interfaces exported by some malloc implementations. These
-// interfaces are accessed through a virtual base class so an
+// Extra extensions exported by some malloc implementations. These
+// extensions are accessed through a virtual base class so an
// application can link against a malloc that does not implement these
-// interfaces, and it will get default versions that do nothing.
+// extensions, and it will get default versions that do nothing.
-#ifndef _GOOGLE_MALLOC_EXTENSION_H__
-#define _GOOGLE_MALLOC_EXTENSION_H__
+#ifndef BASE_MALLOC_EXTENSION_H__
+#define BASE_MALLOC_EXTENSION_H__
#include <stddef.h>
#include <string>
@@ -137,6 +137,26 @@ class MallocExtension {
// REQUIRES: property != NULL
virtual bool SetNumericProperty(const char* property, size_t value);
+ // Mark the current thread as "idle". This routine may optionally
+ // be called by threads as a hint to the malloc implementation that
+ // any thread-specific resources should be released. Note: this may
+ // be an expensive routine, so it should not be called too often.
+ //
+ // Also, if the code that calls this routine will go to sleep for
+ // a while, it should take care to not allocate anything between
+ // the call to this routine and the beginning of the sleep.
+ //
+ // Most malloc implementations ignore this routine.
+ virtual void MarkThreadIdle();
+
+ // Try to free memory back to the operating system for reuse. Only
+ // use this extension if the application has recently freed a lot of
+ // memory, and does not anticipate using it again for a long time --
+ // to get this memory back may require faulting pages back in by the
+ // OS, and that may be slow. (Currently only implemented in
+ // tcmalloc.)
+ virtual void ReleaseFreeMemory();
+
// The current malloc implementation. Always non-NULL.
static MallocExtension* instance();
@@ -170,4 +190,4 @@ class MallocExtension {
virtual void** ReadHeapGrowthStackTraces();
};
-#endif // _GOOGLE_MALLOC_EXTENSION_H__
+#endif // BASE_MALLOC_EXTENSION_H__
diff --git a/src/google/malloc_hook.h b/src/google/malloc_hook.h
index 799658e..aadb9dc 100644
--- a/src/google/malloc_hook.h
+++ b/src/google/malloc_hook.h
@@ -35,9 +35,14 @@
// NULL, they are not invoked.
//
// One important user of these hooks is the heap profiler.
+//
+// CAVEAT: If you add new MallocHook::Invoke* calls (not for chaining hooks),
+// then those calls must be directly in the code of the (de)allocation
+// function that is provided to the user and that function must have
+// an ATTRIBUTE_SECTION(malloc_hook_callers) attribute.
-#ifndef _GOOGLE_MALLOC_HOOK_H
-#define _GOOGLE_MALLOC_HOOK_H
+#ifndef _MALLOC_HOOK_H
+#define _MALLOC_HOOK_H
#include <stddef.h>
#include <sys/types.h>
@@ -72,7 +77,7 @@ class MallocHook {
// The MmapHook is invoked whenever a region of memory is mapped.
// It may be passed MAP_FAILED if the mmap failed.
- typedef void (*MmapHook)(void* result,
+ typedef void (*MmapHook)(void* result,
void* start,
size_t size,
int protection,
@@ -98,7 +103,7 @@ class MallocHook {
fd, offset);
}
- // The MunmapHook is invoked whenever an object is deallocated.
+ // The MunmapHook is invoked whenever a region of memory is unmapped.
typedef void (*MunmapHook)(void* ptr, size_t size);
inline static MunmapHook GetMunmapHook() { return munmap_hook_; }
inline static MunmapHook SetMunmapHook(MunmapHook hook) {
@@ -110,12 +115,57 @@ class MallocHook {
if (munmap_hook_ != NULL) (*munmap_hook_)(p, size);
}
+ // The MremapHook is invoked whenever a region of memory is remapped.
+ typedef void (*MremapHook)(void* result,
+ void* old_addr,
+ size_t old_size,
+ size_t new_size,
+ int flags,
+ void* new_addr);
+ inline static MremapHook GetMremapHook() { return mremap_hook_; }
+ inline static MremapHook SetMremapHook(MremapHook hook) {
+ MremapHook result = mremap_hook_;
+ mremap_hook_ = hook;
+ return result;
+ }
+ inline static void InvokeMremapHook(void* result,
+ void* old_addr,
+ size_t old_size,
+ size_t new_size,
+ int flags,
+ void* new_addr) {
+ if (mremap_hook_ != NULL) (*mremap_hook_)(result,
+ old_addr, old_size,
+ new_size, flags, new_addr);
+ }
+
+ // The SbrkHook is invoked whenever sbrk is called.
+ typedef void (*SbrkHook)(void* result, ptrdiff_t increment);
+ inline static SbrkHook GetSbrkHook() { return sbrk_hook_; }
+ inline static SbrkHook SetSbrkHook(SbrkHook hook) {
+ SbrkHook result = sbrk_hook_;
+ sbrk_hook_ = hook;
+ return result;
+ }
+ inline static void InvokeSbrkHook(void* result, ptrdiff_t increment) {
+ if (sbrk_hook_ != NULL) (*sbrk_hook_)(result, increment);
+ }
+
+ // Get the current stack trace. Try to skip all routines up to and
+ // and including the caller of MallocHook::Invoke*.
+ // Use "skip_count" (similarly to GetStackTrace from stacktrace.h)
+ // as a hint about how many routines to skip if better information
+ // is not available.
+ static int GetCallerStackTrace(void** result, int max_depth, int skip_count);
+
private:
+
static NewHook new_hook_;
static DeleteHook delete_hook_;
static MmapHook mmap_hook_;
static MunmapHook munmap_hook_;
-
+ static MremapHook mremap_hook_;
+ static SbrkHook sbrk_hook_;
};
-#endif /* _GOOGLE_MALLOC_HOOK_H */
+#endif /* _MALLOC_HOOK_H */
diff --git a/src/google/profiler.h b/src/google/profiler.h
index 5eea0de..29404fa 100644
--- a/src/google/profiler.h
+++ b/src/google/profiler.h
@@ -32,37 +32,29 @@
//
// Module for CPU profiling based on periodic pc-sampling.
//
-// To use this module, link it into your program. There should
-// be no slowdown caused by this unless you activate the profiler
-// using one of the steps given below.
+// For full(er) information, see doc/cpuprofile.html
//
-// To activate the profiler, do one of the following:
+// This module is linked into your program with
+// no slowdown caused by this unless you activate the profiler
+// using one of the following methods:
//
// 1. Before starting the program, set the environment variable
-// "CPUPROFILE" to be the name of the file to which the profile
+// "PROFILE" to be the name of the file to which the profile
// data should be written.
//
-// 2. Programmatically, start and stop the profiler using
-// the routines "ProfilerStart(filename)" and "ProfilerStop()".
+// 2. Programmatically, start and stop the profiler using the
+// routines "ProfilerStart(filename)" and "ProfilerStop()".
//
// All threads in the program are profiled whenever profiling is on.
-// There used to be a mechanism where a subset of the threads could be
-// profiled, but that functionality no longer exists (it would not
-// work correctly in new systems since the interval timer used by the
-// profiler is a per-address-space setting in new systems instead of
-// being a per-thread setting in 2.4 and earlier systems).
+// (Note: if using linux 2.4 or earlier, only the main thread may be
+// profiled.)
//
-// Limitation: on 2.4 and earlier kernels, just the main thread will
-// be profiled.
-//
-// Use pprof to view the resulting profile output. If you have dot and
-// gv installed, you can also get a graphical representation of CPU usage.
+// Use pprof to view the resulting profile output.
// % pprof <path_to_executable> <profile_file_name>
-// % pprof --dot <path_to_executable> <profile_file_name>
// % pprof --gv <path_to_executable> <profile_file_name>
-#ifndef _GOOGLE_PROFILER_H
-#define _GOOGLE_PROFILER_H
+#ifndef BASE_PROFILER_H__
+#define BASE_PROFILER_H__
#include <time.h> // For time_t
@@ -122,4 +114,4 @@ class ProfilerThreadState {
void ThreadCheck() { }
};
-#endif /* _GOOGLE_PROFILER_H */
+#endif /* BASE_PROFILER_H__ */
diff --git a/src/google/stacktrace.h b/src/google/stacktrace.h
index a70ade2..c0259f8 100644
--- a/src/google/stacktrace.h
+++ b/src/google/stacktrace.h
@@ -60,22 +60,4 @@
// Linux/x86 machines.
extern int GetStackTrace(void** result, int max_depth, int skip_count);
-// Compute the extent of the function call stack by traversing it up.
-// Input: "sp" is either NULL, or is a stack pointer
-// (e.g., a value of the ebp register for x86).
-// If "sp == NULL", the stack pointer for the current thread is implied.
-//
-// Stores the range of addresses covered by the specified stack
-// in *stack_top and *stack_bottom. Returns true if successful,
-// false on failure (e.g., an inability to walk the stack).
-//
-// If it returns true, *stack_top and *stack_bottom respectively correspond
-// to the most-recetly pushed frame of the call stack
-// and the intial frame that started the call stack.
-// Their relative ordering as integers though
-// depends on the underlying machine's architecture.
-extern bool GetStackExtent(void* sp,
- void** stack_top,
- void** stack_bottom);
-
#endif /* _GOOGLE_STACKTRACE_H */
diff --git a/src/heap-checker-bcad.cc b/src/heap-checker-bcad.cc
index 64cfbb1..87d3d87 100644
--- a/src/heap-checker-bcad.cc
+++ b/src/heap-checker-bcad.cc
@@ -45,9 +45,10 @@
// the allocated object is reachable from global data and hence "live").
#include <stdlib.h> // for abort()
+#include <google/malloc_extension.h>
-// A dummy variable to refer from heap-checker.cc.
-// This is to make sure this file is not optimized out by the linker.
+// A dummy variable to refer from heap-checker.cc. This is to make
+// sure this file is not optimized out by the linker.
bool heap_leak_checker_bcad_variable;
extern void HeapLeakChecker_BeforeConstructors(); // in heap-checker.cc
@@ -59,7 +60,15 @@ extern void HeapLeakChecker_AfterDestructors(); // in heap-checker.cc
class HeapLeakCheckerGlobalPrePost {
public:
HeapLeakCheckerGlobalPrePost() {
- if (count_ == 0) HeapLeakChecker_BeforeConstructors();
+ if (count_ == 0) {
+ HeapLeakChecker_BeforeConstructors();
+ // This needs to be called before the first allocation of an STL
+ // object, but after libc is done setting up threads (because it
+ // calls setenv, which requires a thread-aware errno). By
+ // putting it here, we hope it's the first bit of code executed
+ // after the libc global-constructor code.
+ MallocExtension::Initialize();
+ }
++count_;
}
~HeapLeakCheckerGlobalPrePost() {
diff --git a/src/heap-checker.cc b/src/heap-checker.cc
index 4e8e2dc..5a920a8 100644
--- a/src/heap-checker.cc
+++ b/src/heap-checker.cc
@@ -33,18 +33,8 @@
// Author: Maxim Lifantsev
//
-// NOTE: We almost never use CHECK and LOG in this module
-// because we might be running before/after the logging susbystem
-// is set up correctly.
-
#include "config.h"
-#include <string>
-#include <vector>
-#include <map>
-#include <google/perftools/hash_set.h>
-#include <algorithm>
-
#include <fcntl.h>
#include <string.h>
#include <errno.h>
@@ -62,164 +52,203 @@
#include <syscall.h>
#endif
-#include <elf.h>
+#include <string>
+#include <vector>
+#include <map>
+#include <set>
+#include <algorithm>
-#include <google/stacktrace.h>
-#include <google/heap-profiler.h>
#include <google/heap-checker.h>
-#include "heap-profiler-inl.h"
-#include "addressmap-inl.h"
#include "base/basictypes.h"
-#include "base/commandlineflags.h"
+#include "base/googleinit.h"
#include "base/logging.h"
+#include <google/stacktrace.h>
+#include "base/commandlineflags.h"
#include "base/elfcore.h" // for i386_regs
#include "base/thread_lister.h"
-#include "maybe_threads.h"
-
-#ifdef HAVE_INTTYPES_H
-#define __STDC_FORMAT_MACROS
-#include <inttypes.h>
-// TODO: have both SCNd64 and PRId64. We don't bother since they're the same
-#define LLX "%"SCNx64 // how to read 64-bit hex
-#define LLD "%"SCNd64 // how to read 64-bit deciman
-#else
-#define LLX "%llx" // hope for the best
-#define LLD "%lld"
-#endif
-
-#ifndef PATH_MAX
-#ifdef MAXPATHLEN
-#define PATH_MAX MAXPATHLEN
-#else
-#define PATH_MAX 4096 // seems conservative for max filename len!
-#endif
-#endif
+#include "heap-profile-table.h"
+#include "base/low_level_alloc.h"
+#include <google/malloc_hook.h>
+#include <google/malloc_extension.h>
+#include "memory_region_map.h"
+#include "base/spinlock.h"
+#include "base/sysinfo.h"
+#include "base/stl_allocator.h"
using std::string;
+using std::basic_string;
+using std::pair;
using std::map;
+using std::set;
using std::vector;
using std::swap;
using std::make_pair;
using std::min;
using std::max;
-using HASH_NAMESPACE::hash_set;
+using std::less;
+using std::char_traits;
//----------------------------------------------------------------------
// Flags that control heap-checking
//----------------------------------------------------------------------
-DEFINE_bool(heap_check_report, true,
+DEFINE_string(heap_check,
+ EnvToString("HEAPCHECK", ""),
+ "The heap leak checking to be done over the whole executable: "
+ "\"minimal\", \"normal\", \"strict\", "
+ "\"draconian\", \"as-is\", and \"local\" "
+ " or the empty string are the supported choices. "
+ "(See HeapLeakChecker::InternalInitStart for details.)");
+
+DEFINE_bool(heap_check_report,
+ EnvToBool("HEAP_CHECK_REPORT", true),
"If overall heap check should report the found leaks via pprof");
-// These are not so much flags as internal configuration parameters that
-// are set based on the argument to StartFromMain().
-DEFINE_bool(heap_check_before_constructors, true,
+DEFINE_bool(heap_check_before_constructors,
+ true,
"deprecated; pretty much always true now");
-DEFINE_bool(heap_check_after_destructors, false,
+DEFINE_bool(heap_check_after_destructors,
+ EnvToBool("HEAP_CHECK_AFTER_DESTRUCTORS", false),
"If overall heap check is to end after global destructors "
"or right after all REGISTER_HEAPCHECK_CLEANUP's");
-DEFINE_bool(heap_check_strict_check, true,
+DEFINE_bool(heap_check_strict_check,
+ EnvToBool("HEAP_CHECK_STRICT_CHECK", true),
"If overall heap check is to be done "
"via HeapLeakChecker::*SameHeap "
"or HeapLeakChecker::*NoLeaks call");
// heap_check_strict_check == false
// is useful only when heap_check_before_constructors == false
-DEFINE_bool(heap_check_ignore_global_live, true,
+DEFINE_bool(heap_check_ignore_global_live,
+ EnvToBool("HEAP_CHECK_IGNORE_GLOBAL_LIVE", true),
"If overall heap check is to ignore heap objects reachable "
"from the global data");
-DEFINE_bool(heap_check_ignore_thread_live, true,
+DEFINE_bool(heap_check_identify_leaks,
+ EnvToBool("HEAP_CHECK_IDENTIFY_LEAKS", false),
+ "If heap check should generate the addresses of the leaked objects "
+ "in the memory leak profiles");
+
+DEFINE_bool(heap_check_ignore_thread_live,
+ EnvToBool("HEAP_CHECK_IGNORE_THREAD_LIVE", true),
"If set to true, objects reachable from thread stacks "
"and registers are not reported as leaks");
-// Normally we'd make this a flag, but we can't do that in this case
-// because it may need to be accessed after global destructors have
-// started to run, which would delete flags. Instead we make it a pointer,
-// which will never get destroyed.
-static string* flags_heap_profile_pprof = NULL;
+DEFINE_bool(heap_check_test_pointer_alignment,
+ EnvToBool("HEAP_CHECK_TEST_POINTER_ALIGNMENT", false),
+ "Set to true to check if the found leak can be due to "
+ "use of unaligned pointers");
-// External accessors for the above
-void HeapLeakChecker::set_heap_check_report(bool b) {
- FLAGS_heap_check_report = b;
-}
-void HeapLeakChecker::set_pprof_path(const char* s) {
- if (flags_heap_profile_pprof == NULL) {
- flags_heap_profile_pprof = new string(s);
- } else {
- flags_heap_profile_pprof->assign(s);
- }
-}
-
-void HeapLeakChecker::set_dump_directory(const char* s) {
- if (dump_directory_ == NULL) dump_directory_ = new string;
- dump_directory_->assign(s);
-}
+//----------------------------------------------------------------------
-bool HeapLeakChecker::heap_check_report() {
- return FLAGS_heap_check_report;
-}
-const char* HeapLeakChecker::pprof_path() {
- if (flags_heap_profile_pprof == NULL) {
- return INSTALL_PREFIX "/bin/pprof"; // our default value
- } else {
- return flags_heap_profile_pprof->c_str();
- }
-}
-const char* HeapLeakChecker::dump_directory() {
- if (dump_directory_ == NULL) {
- return "/tmp"; // our default value
- } else {
- return dump_directory_->c_str();
- }
-}
+DEFINE_string(heap_profile_pprof,
+ EnvToString("PPROF_PATH", "pprof"),
+ "Path to pprof to call for full leak checking.");
-//----------------------------------------------------------------------
+DEFINE_string(heap_check_dump_directory,
+ EnvToString("HEAP_CHECK_DUMP_DIRECTORY", "/tmp"),
+ "Directory to put heap-checker leak dump information");
-DECLARE_int32(heap_profile_log); // in heap-profiler.cc
+// Copy of FLAGS_heap_profile_pprof.
+// Need this since DoNoLeaks can happen
+// after FLAGS_heap_profile_pprof is destroyed.
+static string* flags_heap_profile_pprof = &FLAGS_heap_profile_pprof;
//----------------------------------------------------------------------
// HeapLeakChecker global data
//----------------------------------------------------------------------
-// Global lock for the global data of this module
-static pthread_mutex_t heap_checker_lock = PTHREAD_MUTEX_INITIALIZER;
-
-// the disabled regexp accumulated
-// via HeapLeakChecker::DisableChecksIn
-static string* disabled_regexp = NULL;
+// Global lock for (most of) the global data of this module.
+// We could use pthread's lock here, but spinlock is faster.
+static SpinLock heap_checker_lock(SpinLock::LINKER_INITIALIZED);
//----------------------------------------------------------------------
-// Heap profile prefix for leak checking profiles,
+// Heap profile prefix for leak checking profiles
static string* profile_prefix = NULL;
-// whole-program heap leak checker
+// Whole-program heap leak checker
static HeapLeakChecker* main_heap_checker = NULL;
+// Whether we will use main_heap_checker to do a check at program exit
+static bool do_main_heap_check = false;
-// if we are doing (or going to do) any kind of heap-checking
-// heap_checker_on == true implies HeapProfiler::is_on_ == true
+// The heap profile we use to collect info about the heap.
+static HeapProfileTable* heap_profile = NULL;
+
+// If we are doing (or going to do) any kind of heap-checking.
static bool heap_checker_on = false;
// pid of the process that does whole-program heap leak checking
static pid_t heap_checker_pid = 0;
-// if we did heap profiling during global constructors execution
+// If we did heap profiling during global constructors execution
static bool constructor_heap_profiling = false;
//----------------------------------------------------------------------
+// HeapLeakChecker's own memory allocator that is
+// independent of the normal program allocator.
+//----------------------------------------------------------------------
+
+// Wrapper of LowLevelAlloc for STL_Allocator and direct use.
+// We always access Allocate/Free in this class under held heap_checker_lock,
+// this allows us to protect the period when threads are stopped
+// at random spots with ListAllProcessThreads by heap_checker_lock,
+// w/o worrying about the lock in LowLevelAlloc::Arena.
+// We rely on the fact that we use an own arena with an own lock here.
+class HeapLeakChecker::Allocator {
+ public:
+ static void Init() {
+ RAW_DCHECK(arena_ == NULL, "");
+ arena_ = LowLevelAlloc::NewArena(0, 0);
+ }
+ static void Shutdown() {
+ if (!LowLevelAlloc::DeleteArena(arena_) || alloc_count_ != 0) {
+ RAW_LOG(FATAL, "Internal heap checker leak of %d objects", alloc_count_);
+ }
+ }
+ static int alloc_count() { return alloc_count_; }
+ static void* Allocate(size_t n) {
+ RAW_DCHECK(arena_ && heap_checker_lock.IsHeld(), "");
+ void* p = LowLevelAlloc::Alloc(n, arena_);
+ if (p) alloc_count_ += 1;
+ return p;
+ }
+ static void Free(void* p) {
+ RAW_DCHECK(heap_checker_lock.IsHeld(), "");
+ if (p) alloc_count_ -= 1;
+ LowLevelAlloc::Free(p);
+ }
+ // destruct, free, and make *p to be NULL
+ template<typename T> static void DeleteAndNull(T** p) {
+ (*p)->~T();
+ Free(*p);
+ *p = NULL;
+ }
+ template<typename T> static void DeleteAndNullIfNot(T** p) {
+ if (*p != NULL) DeleteAndNull(p);
+ }
+ private:
+ static LowLevelAlloc::Arena* arena_;
+ static int alloc_count_;
+};
+
+LowLevelAlloc::Arena* HeapLeakChecker::Allocator::arena_ = NULL;
+int HeapLeakChecker::Allocator::alloc_count_ = 0;
+
+//----------------------------------------------------------------------
// HeapLeakChecker live object tracking components
//----------------------------------------------------------------------
// Cases of live object placement we distinguish
enum ObjectPlacement {
MUST_BE_ON_HEAP, // Must point to a live object of the matching size in the
- // map of the heap in HeapProfiler when we get to it.
- IGNORED_ON_HEAP, // Is a live (ignored) object on heap.
- IN_GLOBAL_DATA, // Is part of global data region of the executable.
- THREAD_STACK, // Part of a thread stack
+ // heap_profile map of the heap when we get to it
+ IGNORED_ON_HEAP, // Is a live (ignored) object on heap
+ MAYBE_LIVE, // Is simply a piece of writable memory from /proc/self/maps
+ IN_GLOBAL_DATA, // Is part of global data region of the executable
+ THREAD_DATA, // Part of a thread stack (and a thread descriptor with TLS)
THREAD_REGISTERS, // Values in registers of some thread
};
@@ -233,9 +262,19 @@ struct AllocObject {
: ptr(p), size(s), place(l) { }
};
+typedef basic_string<char, char_traits<char>,
+ STL_Allocator<char, HeapLeakChecker::Allocator>
+ > HCL_string;
+// the disabled regexp accumulated
+// via HeapLeakChecker::DisableChecksIn
+static HCL_string* disabled_regexp = NULL;
+
// All objects (memory ranges) ignored via HeapLeakChecker::IgnoreObject
// Key is the object's address; value is its size.
-typedef map<uintptr_t, size_t> IgnoredObjectsMap;
+typedef map<uintptr_t, size_t, less<uintptr_t>,
+ STL_Allocator<pair<const uintptr_t, size_t>,
+ HeapLeakChecker::Allocator>
+ > IgnoredObjectsMap;
static IgnoredObjectsMap* ignored_objects = NULL;
// All objects (memory ranges) that we consider to be the sources of pointers
@@ -243,21 +282,34 @@ static IgnoredObjectsMap* ignored_objects = NULL;
// At different times this holds (what can be reached from) global data regions
// and the objects we've been told to ignore.
// For any AllocObject::ptr "live_objects" is supposed to contain at most one
-// record at any time. We maintain this by checking with HeapProfiler's map
+// record at any time. We maintain this by checking with the heap_profile map
// of the heap and removing the live heap objects we've handled from it.
// This vector is maintained as a stack and the frontier of reachable
// live heap objects in our flood traversal of them.
-typedef vector<AllocObject> LiveObjectsStack;
+typedef vector<AllocObject,
+ STL_Allocator<AllocObject, HeapLeakChecker::Allocator>
+ > LiveObjectsStack;
static LiveObjectsStack* live_objects = NULL;
// A placeholder to fill-in the starting values for live_objects
// for each library so we can keep the library-name association for logging.
-typedef map<string, LiveObjectsStack> LibraryLiveObjectsStacks;
+typedef map<HCL_string, LiveObjectsStack, less<HCL_string>,
+ STL_Allocator<pair<const HCL_string, LiveObjectsStack>,
+ HeapLeakChecker::Allocator>
+ > LibraryLiveObjectsStacks;
static LibraryLiveObjectsStacks* library_live_objects = NULL;
+// Objects to be removed from the heap profile when we dump it.
+typedef set<void*, less<void*>,
+ STL_Allocator<void*, HeapLeakChecker::Allocator>
+ > ProfileAdjustObjectSet;
+static ProfileAdjustObjectSet* profile_adjust_objects = NULL;
+
// The disabled program counter addresses for profile dumping
// that are registered with HeapLeakChecker::DisableChecksUp
-typedef hash_set<uintptr_t> DisabledAddressSet;
+typedef set<uintptr_t, less<uintptr_t>,
+ STL_Allocator<uintptr_t, HeapLeakChecker::Allocator>
+ > DisabledAddressSet;
static DisabledAddressSet* disabled_addresses = NULL;
// Value stored in the map of disabled address ranges;
@@ -268,40 +320,197 @@ struct HeapLeakChecker::RangeValue {
uintptr_t start_address; // the start of the range
int max_depth; // the maximal stack depth to disable at
};
-typedef map<uintptr_t, HeapLeakChecker::RangeValue> DisabledRangeMap;
+typedef map<uintptr_t, HeapLeakChecker::RangeValue, less<uintptr_t>,
+ STL_Allocator<pair<const uintptr_t, HeapLeakChecker::RangeValue>,
+ HeapLeakChecker::Allocator>
+ > DisabledRangeMap;
// The disabled program counter address ranges for profile dumping
-// that are registered with HeapLeakChecker::DisableChecksFromTo.
+// that are registered with HeapLeakChecker::DisableChecksFromToLocked.
static DisabledRangeMap* disabled_ranges = NULL;
-// Stack range map: maps from the start address to the end address.
-// These are used to not disable all allocated memory areas
-// that are used for stacks so that we do treat stack pointers
-// from dead stack frames as live.
-typedef map<uintptr_t, uintptr_t> StackRangeMap;
-static StackRangeMap* stack_ranges = NULL;
-
-// This routine is called for every thread stack we know about.
-static void RegisterStackRange(void* top, void* bottom) {
- char* p1 = min(reinterpret_cast<char*>(top),
- reinterpret_cast<char*>(bottom));
- char* p2 = max(reinterpret_cast<char*>(top),
- reinterpret_cast<char*>(bottom));
- if (HeapProfiler::kMaxLogging) {
- HeapProfiler::MESSAGE(1, "HeapChecker: Thread stack %p..%p (%d bytes)\n",
- p1, p2, int(p2-p1));
- }
- live_objects->push_back(AllocObject(p1, uintptr_t(p2-p1), THREAD_STACK));
- stack_ranges->insert(make_pair(reinterpret_cast<uintptr_t>(p1),
- reinterpret_cast<uintptr_t>(p2)));
+// Set of stack tops.
+// These are used to consider live only appropriate chunks of the memory areas
+// that are used for stacks (and maybe thread-specific data as well)
+// so that we do not treat pointers from outdated stack frames as live.
+typedef set<uintptr_t, less<uintptr_t>,
+ STL_Allocator<uintptr_t, HeapLeakChecker::Allocator>
+ > StackTopSet;
+static StackTopSet* stack_tops = NULL;
+
+// A map of ranges of code addresses for the system libraries
+// that can mmap/mremap/sbrk-allocate memory regions for stacks
+// and thread-local storage that we want to consider as live global data.
+// Maps from the end address to the start address.
+typedef map<uintptr_t, uintptr_t, less<uintptr_t>,
+ STL_Allocator<pair<const uintptr_t, uintptr_t>,
+ HeapLeakChecker::Allocator>
+ > GlobalRegionCallerRangeMap;
+static GlobalRegionCallerRangeMap* global_region_caller_ranges = NULL;
+
+// TODO(maxim): make our big data structs into own modules
+
+//----------------------------------------------------------------------
+
+// Simple hook into execution of global object constructors,
+// so that we do not call pthread_self() when it does not yet work.
+static bool libpthread_initialized = false;
+static bool initializer = (libpthread_initialized = true, true);
+
+// Safe version of pthread_self() for logging that works
+// even when libpthread is not yet properly initialized.
+static inline pthread_t safe_pthread_self() {
+ if (!libpthread_initialized) return static_cast<pthread_t>(-1);
+ // this starts working only sometime well into global constructor execution:
+ return pthread_self();
+}
+
+// Our hooks for MallocHook
+static void NewHook(void* ptr, size_t size) {
+ if (ptr != NULL) {
+ RAW_VLOG(7, "Recording Alloc: %p of %"PRIuS" from %ld",
+ ptr, size, safe_pthread_self());
+ heap_checker_lock.Lock();
+ heap_profile->RecordAlloc(ptr, size, 0);
+ heap_checker_lock.Unlock();
+ RAW_VLOG(8, "Alloc Recorded: %p of %"PRIuS"", ptr, size);
+ }
+}
+
+static void DeleteHook(void* ptr) {
+ if (ptr != NULL) {
+ RAW_VLOG(7, "Recording Free %p from %ld", ptr, safe_pthread_self());
+ heap_checker_lock.Lock();
+ heap_profile->RecordFree(ptr);
+ heap_checker_lock.Unlock();
+ RAW_VLOG(8, "Free Recorded: %p", ptr);
+ }
+}
+
+//----------------------------------------------------------------------
+
+enum StackDirection {
+ GROWS_TOWARDS_HIGH_ADDRESSES,
+ GROWS_TOWARDS_LOW_ADDRESSES,
+ UNKNOWN_DIRECTION
+};
+
+static StackDirection GetStackDirection(int* ptr); // defined below
+
+// Function pointer to trick compiler into not inlining a call:
+static StackDirection (*do_stack_direction)(int* ptr) = GetStackDirection;
+
+// Determine which way the stack grows:
+// Call with NULL argument.
+static StackDirection GetStackDirection(int* ptr) {
+ int a_local;
+ if (ptr == NULL) return do_stack_direction(&a_local);
+ if (&a_local > ptr) return GROWS_TOWARDS_HIGH_ADDRESSES;
+ if (&a_local < ptr) return GROWS_TOWARDS_LOW_ADDRESSES;
+ RAW_CHECK(0, ""); // &a_local == ptr, i.e. the recursive call got inlined
+ // and we can't do it (need more hoops to prevent inlining)
+ return UNKNOWN_DIRECTION;
}
-// Iterator for HeapProfiler::allocation_ to make objects allocated from
-// disabled code regions live.
-static void MakeDisabledLiveCallback(void* ptr, HeapProfiler::AllocValue v) {
+// Direction of stack growth (will initialize via GetStackDirection())
+static StackDirection stack_direction = UNKNOWN_DIRECTION;
+
+// This routine is called for every thread stack we know about to register it.
+static void RegisterStack(void* top_ptr) {
+ RAW_VLOG(1, "Thread stack at %p", top_ptr);
+ uintptr_t top = reinterpret_cast<uintptr_t>(top_ptr);
+ stack_tops->insert(top); // add for later use
+
+ // make sure stack_direction is initialized
+ if (stack_direction == UNKNOWN_DIRECTION) {
+ stack_direction = GetStackDirection(NULL);
+ }
+
+ // Find memory region with this stack
+ MemoryRegionMap::Region region;
+ if (MemoryRegionMap::FindStackRegion(top, &region)) {
+ // Make the proper portion of the stack live:
+ if (stack_direction == GROWS_TOWARDS_LOW_ADDRESSES) {
+ RAW_VLOG(2, "Live stack at %p of %"PRIuS" bytes",
+ top_ptr, region.end_addr - top);
+ live_objects->push_back(AllocObject(top_ptr, region.end_addr - top,
+ THREAD_DATA));
+ } else { // GROWS_TOWARDS_HIGH_ADDRESSES
+ RAW_VLOG(2, "Live stack at %p of %"PRIuS" bytes",
+ (void*)region.start_addr, top - region.start_addr);
+ live_objects->push_back(AllocObject((void*)region.start_addr,
+ top - region.start_addr,
+ THREAD_DATA));
+ }
+ } else { // not in MemoryRegionMap, look in library_live_objects
+ for (LibraryLiveObjectsStacks::iterator lib = library_live_objects->begin();
+ lib != library_live_objects->end(); ++lib) {
+ for (LiveObjectsStack::iterator span = lib->second.begin();
+ span != lib->second.end(); ++span) {
+ uintptr_t start = reinterpret_cast<uintptr_t>(span->ptr);
+ uintptr_t end = start + span->size;
+ if (start <= top && top < end) {
+ RAW_VLOG(2, "Stack at %p is inside /proc/self/maps chunk %p..%p",
+ top_ptr, (void*)start, (void*)end);
+ // Shrink start..end region by chopping away the memory regions in
+ // MemoryRegionMap that land in it to undo merging of regions
+ // in /proc/self/maps, so that we correctly identify what portion
+ // of start..end is actually the stack region.
+ uintptr_t stack_start = start;
+ uintptr_t stack_end = end;
+ // can optimize-away this loop, but it does not run often
+ for (MemoryRegionMap::RegionIterator r =
+ MemoryRegionMap::BeginRegionLocked();
+ r != MemoryRegionMap::EndRegionLocked(); ++r) {
+ if (top < r->start_addr && r->start_addr < stack_end) {
+ stack_end = r->start_addr;
+ }
+ if (stack_start < r->end_addr && r->end_addr <= top) {
+ stack_start = r->end_addr;
+ }
+ }
+ if (stack_start != start || stack_end != end) {
+ RAW_VLOG(2, "Stack at %p is actually inside memory chunk %p..%p",
+ top_ptr, (void*)stack_start, (void*)stack_end);
+ }
+ // Make the proper portion of the stack live:
+ if (stack_direction == GROWS_TOWARDS_LOW_ADDRESSES) {
+ RAW_VLOG(2, "Live stack at %p of %"PRIuS" bytes",
+ top_ptr, stack_end - top);
+ live_objects->push_back(
+ AllocObject(top_ptr, stack_end - top, THREAD_DATA));
+ } else { // GROWS_TOWARDS_HIGH_ADDRESSES
+ RAW_VLOG(2, "Live stack at %p of %"PRIuS" bytes",
+ (void*)stack_start, top - stack_start);
+ live_objects->push_back(
+ AllocObject((void*)stack_start, top - stack_start, THREAD_DATA));
+ }
+ lib->second.erase(span); // kill the rest of the region
+ // Put the non-stack part(s) of the region back:
+ if (stack_start != start) {
+ lib->second.push_back(AllocObject((void*)start, stack_start - start,
+ MAYBE_LIVE));
+ }
+ if (stack_end != end) {
+ lib->second.push_back(AllocObject((void*)stack_end, end - stack_end,
+ MAYBE_LIVE));
+ }
+ return;
+ }
+ }
+ }
+ RAW_LOG(ERROR, "Memory region for stack at %p not found. "
+ "Will likely report false leak positives.", top_ptr);
+ }
+}
+
+// Iterator for heap allocation map data to make objects allocated from
+// disabled regions of code to be live.
+static void MakeDisabledLiveCallback(void* ptr,
+ const HeapProfileTable::AllocInfo& info) {
bool stack_disable = false;
bool range_disable = false;
- for (int depth = 0; depth < v.bucket->depth_; depth++) {
- uintptr_t addr = reinterpret_cast<uintptr_t>(v.bucket->stack_[depth]);
+ for (int depth = 0; depth < info.stack_depth; depth++) {
+ uintptr_t addr = reinterpret_cast<uintptr_t>(info.call_stack[depth]);
if (disabled_addresses &&
disabled_addresses->find(addr) != disabled_addresses->end()) {
stack_disable = true; // found; dropping
@@ -311,7 +520,7 @@ static void MakeDisabledLiveCallback(void* ptr, HeapProfiler::AllocValue v) {
DisabledRangeMap::const_iterator iter
= disabled_ranges->upper_bound(addr);
if (iter != disabled_ranges->end()) {
- assert(iter->first > addr);
+ RAW_DCHECK(iter->first > addr, "");
if (iter->second.start_address < addr &&
iter->second.max_depth > depth) {
range_disable = true; // in range; dropping
@@ -322,303 +531,58 @@ static void MakeDisabledLiveCallback(void* ptr, HeapProfiler::AllocValue v) {
}
if (stack_disable || range_disable) {
uintptr_t start_address = reinterpret_cast<uintptr_t>(ptr);
- uintptr_t end_address = start_address + v.bytes;
- StackRangeMap::const_iterator iter
- = stack_ranges->lower_bound(start_address);
- if (iter != stack_ranges->end()) {
- assert(iter->first >= start_address);
- if (iter->second <= end_address) {
+ uintptr_t end_address = start_address + info.object_size;
+ StackTopSet::const_iterator iter
+ = stack_tops->lower_bound(start_address);
+ if (iter != stack_tops->end()) {
+ RAW_DCHECK(*iter >= start_address, "");
+ if (*iter < end_address) {
// We do not disable (treat as live) whole allocated regions
// if they are used to hold thread call stacks
// (i.e. when we find a stack inside).
// The reason is that we'll treat as live the currently used
- // stack portions anyway (see RegisterStackRange),
+ // stack portions anyway (see RegisterStack),
// and the rest of the region where the stack lives can well
// contain outdated stack variables which are not live anymore,
// hence should not be treated as such.
- HeapProfiler::MESSAGE(2, "HeapChecker: "
- "Not %s-disabling %"PRIuS" bytes at %p"
- ": have stack inside: %p-%p\n",
- (stack_disable ? "stack" : "range"),
- v.bytes, ptr,
- (void*)iter->first, (void*)iter->second);
+ RAW_VLOG(2, "Not %s-disabling %"PRIuS" bytes at %p"
+ ": have stack inside: %p",
+ (stack_disable ? "stack" : "range"),
+ info.object_size, ptr, (void*)*iter);
return;
}
}
- if (HeapProfiler::kMaxLogging) {
- HeapProfiler::MESSAGE(2, "HeapChecker: "
- "%s-disabling %"PRIuS" bytes at %p\n",
- (stack_disable ? "stack" : "range"),
- v.bytes, ptr);
- }
- live_objects->push_back(AllocObject(ptr, v.bytes, MUST_BE_ON_HEAP));
+ RAW_VLOG(2, "%s-disabling %"PRIuS" bytes at %p",
+ (stack_disable ? "Stack" : "Range"), info.object_size, ptr);
+ live_objects->push_back(AllocObject(ptr, info.object_size,
+ MUST_BE_ON_HEAP));
}
}
-static int GetStatusOutput(const char* command, string* output) {
- // We don't want the heapchecker to run in the child helper
- // processes that we fork() as part of this process' heap check.
-
- // setenv() can call realloc(), so we don't want to call it while
- // the heap profiling is disabled. Instead just overwrite the final
- // char of the env var name, so it has a different name and gets
- // ignored in the child. We assume the env looks like 'VAR=VALUE\0VAR=VALUE'
- char *env_heapcheck = getenv("HEAPCHECK");
- char *env_ldpreload = getenv("LD_PRELOAD");
-
- if (env_heapcheck) {
- assert(env_heapcheck[-1] == '=');
- env_heapcheck[-2] = '?';
- }
- if (env_ldpreload) {
- assert(env_ldpreload[-1] == '=');
- env_ldpreload[-2] = '?';
- }
-
- FILE* f = popen(command, "r");
- if (f == NULL) {
- fprintf(stderr, "popen returned NULL!!!\n"); // This shouldn't happen
- exit(1);
- }
-
- if (env_heapcheck) env_heapcheck[-2] = 'K';
- if (env_ldpreload) env_heapcheck[-2] = 'D';
-
- const int kMaxOutputLine = 10000;
- char line[kMaxOutputLine];
- while (fgets(line, sizeof(line), f) != NULL) {
- if (output)
- *output += line;
- }
-
- return pclose(f);
-}
-
-// RAII class for a file descriptor.
-
-class FileDescriptor {
- public:
- FileDescriptor(int fd) : fd_(fd) { ; }
- ~FileDescriptor() { if (fd_ >= 0) close(fd_); }
- int Close() { int fd = fd_; fd_ = -1; return close(fd); }
- operator int() { return fd_; }
- private:
- int fd_;
-};
-
-// This function takes the fields from a /proc/self/maps line:
+// This function takes some fields from a /proc/self/maps line:
//
// start_address start address of a memory region.
// end_address end address of a memory region
// permissions rwx + private/shared bit
-// file_offset file offset within the mapped file
-// (major:minor) major and minor device number of the mapped file
-// inode inode number of the mapped file
// filename filename of the mapped file
//
-// First, if the region is not writeable, then it cannot have any heap
-// pointers in it.
-//
-// It would be simple to just mark every writeable memory region as live.
-// However, that would pick up unused bottom pieces of thread stacks
-// and other rot. So we need more complexity:
-//
-// Second, if the region is anonymous, we ignore it. That skips the
-// main stack and the thread stacks which are picked up elsewhere.
-// Unfortunately that also skips the BSS portions of shared library
-// segments, and we need to pick those up.
-//
-// So, for each writable memory region that is mapped to a file,
-// we recover the original segment information from that file
-// (segment headers, not section headers). We pick out the segment
-// that contains the given "file_offset", figure out where that
-// segment was loaded into memory, and register all of the memory
-// addresses for that segment.
-//
-// Picking out the right segment is a bit of a mess because the
-// same file offset can appear in multiple segments! For example:
-//
-// LOAD 0x000000 0x08048000 0x08048000 0x231a8 0x231a8 R E 0x1000
-// LOAD 0x0231a8 0x0806c1a8 0x0806c1a8 0x01360 0x014e8 RW 0x1000
-//
-// File offset 0x23000 appears in both segments. The second segment
-// stars at 0x23000 because of rounding. Fortunately, we skip the
-// first segment because it is not writeable. Most of the shared
-// objects we see have one read-executable segment and one read-write
-// segment so we really skate.
-//
-// If a shared library has no initialized data, only BSS, then the
-// size of the read-write LOAD segment will be zero, the dynamic loader
-// will create an anonymous memory region for the BSS but no named
-// segment [I think -- gotta check ld-linux.so -- mec]. We will
-// overlook that segment and never get here. This is a bug.
-
-static bool RecordGlobalDataLocked(uint64 start_address,
- uint64 end_address,
+// If the region is not writeable, then it cannot have any heap
+// pointers in it, otherwise we record it as a candidate live region
+// to get filtered later.
+
+static void RecordGlobalDataLocked(uintptr_t start_address,
+ uintptr_t end_address,
const char* permissions,
- uint64 file_offset,
- int64 inode,
const char* filename) {
// Ignore non-writeable regions.
- if (strchr(permissions, 'w') == NULL)
- return true;
-
- // Ignore anonymous regions.
- // This drops BSS regions which causes us much work later.
- if (inode == 0)
- return true;
-
- // Sometimes people mmap their own files read-write. That would cause
- // the strict ELF checker later to reject them. We do not want to loosen
- // up the ELF checker, because we need to catch freaky files if they
- // show up. So, make an exception for common files that we have seen.
- //
- // TODO(mec): the longer this gets, the more attractive it is to
- // check for the ELF header and just accept all non-ELF files.
- if (inode != 0) {
- if (filename && strcmp(filename, "/dev/zero") == 0)
- return true;
- }
-
- // Grab some ELF types.
-#ifdef _LP64
- typedef Elf64_Ehdr ElfFileHeader;
- typedef Elf64_Phdr ElfProgramHeader;
-#else
- typedef Elf32_Ehdr ElfFileHeader;
- typedef Elf32_Phdr ElfProgramHeader;
-#endif
-
- // Cannot mmap the ELF file because of the live ProcMapsIterator.
- // Have to read little pieces. Fortunately there are just two.
- HeapProfiler::MESSAGE(2, "HeapChecker: Looking into %s\n", filename);
- FileDescriptor fd_elf(open(filename, O_RDONLY));
- if (fd_elf < 0)
- return false;
-
- // Read and validate the file header.
- ElfFileHeader efh;
- if (read(fd_elf, &efh, sizeof(efh)) != sizeof(efh))
- return false;
- if (memcmp(&efh.e_ident[0], ELFMAG, SELFMAG) != 0)
- return false;
- if (efh.e_version != EV_CURRENT)
- return false;
- if (efh.e_type != ET_EXEC && efh.e_type != ET_DYN)
- return false;
-
- // Read the segment headers.
- if (efh.e_phentsize != sizeof(ElfProgramHeader))
- return false;
- if (lseek(fd_elf, efh.e_phoff, SEEK_SET) != efh.e_phoff)
- return false;
- const size_t phsize = efh.e_phnum * efh.e_phentsize;
- ElfProgramHeader* eph = new ElfProgramHeader[efh.e_phnum];
- if (read(fd_elf, eph, phsize) != phsize) {
- delete[] eph;
- return false;
- }
-
- // Gonna need this page size for page boundary considerations.
- // Better be a power of 2.
- const int int_page_size = getpagesize();
- if (int_page_size <= 0 || int_page_size & (int_page_size-1))
- abort();
- const uint64 page_size = int_page_size;
-
- // Walk the segment headers.
- // Find the segment header that contains the given file offset.
- bool found_load_segment = false;
- for (int iph = 0; iph < efh.e_phnum; ++iph) {
- HeapProfiler::MESSAGE(3, "HeapChecker: %s %d: p_type: %d p_flags: %x\n",
- filename, iph, eph[iph].p_type, eph[iph].p_flags);
- if (eph[iph].p_type == PT_LOAD && eph[iph].p_flags & PF_W) {
- // Sanity check the segment header.
- if (eph[iph].p_vaddr != eph[iph].p_paddr) {
- delete[] eph;
- return false;
- }
- if ((eph[iph].p_vaddr & (page_size-1)) !=
- (eph[iph].p_offset & (page_size-1))) {
- delete[] eph;
- return false;
- }
-
- // The segment is not aligned in the ELF file, but will be
- // aligned in memory. So round it to page boundaries.
- // Note: we lose if p_end is on the last page.
- const uint64 p_start = eph[iph].p_offset &~ (page_size-1);
- const uint64 p_end = ((eph[iph].p_offset + eph[iph].p_memsz)
- + (page_size-1)) &~ (page_size-1);
- if (p_end < p_start) {
- delete[] eph;
- return false;
- }
- if (file_offset >= p_start && file_offset < p_end) {
- // Found it.
- if (found_load_segment) {
- delete[] eph;
- return false;
- }
- found_load_segment = true;
-
- // [p_start, p_end) is the file segment, where p_end is extended
- // for BSS (which does not actually come from the file).
- //
- // [start_address, end_address) is the memory region from
- // /proc/self/maps.
- //
- // The point of correspondence is:
- // file_offset in filespace <-> start_address in memoryspace
- //
- // This point of correspondence is reliable because the kernel
- // virtual memory system actually uses this information for
- // demand-paging the file.
- //
- // A single file segment can get loaded into several contiguous
- // memory regions with different permissions. I have seen as
- // many as four regions: no-permission alignment region +
- // read-only-after-relocation region + read-write data region +
- // read-write anonymous bss region. So file_offset from the
- // memory region may not equal to p_start from the file segement;
- // file_offset can be anywhere in [p_start, p_end).
-
- // Check that [start_address, end_address) is wholly contained
- // in [p_start, p_end).
- if (end_address < start_address ||
- end_address - start_address > p_end - file_offset) {
- delete[] eph;
- return false;
- }
-
- // Calculate corresponding address and length for [p_start, p_end).
- if (file_offset - p_start > start_address) {
- delete[] eph;
- return false;
- }
- void* addr = reinterpret_cast<void*>(start_address -
- (file_offset - p_start));
- const uintptr_t length = p_end - p_start;
-
- // That is what we need.
- (*library_live_objects)[filename].
- push_back(AllocObject(addr, length, IN_GLOBAL_DATA));
- }
- }
- }
- delete[] eph;
-
- if (!found_load_segment) {
- HeapProfiler::MESSAGE(-1,
- "HeapChecker: no LOAD segment found in %s\n",
- filename);
- return false;
- }
-
- if (fd_elf.Close() < 0)
- return false;
-
- return true;
+ if (strchr(permissions, 'w') == NULL) return;
+ if (filename == NULL || *filename == '\0') filename = "UNNAMED";
+ RAW_VLOG(2, "Looking into %s: 0x%" PRIxPTR "..0x%" PRIxPTR,
+ filename, start_address, end_address);
+ (*library_live_objects)[filename].
+ push_back(AllocObject(reinterpret_cast<void*>(start_address),
+ end_address - start_address,
+ MAYBE_LIVE));
}
// See if 'library' from /proc/self/maps has base name 'library_base'
@@ -629,9 +593,10 @@ static bool IsLibraryNamed(const char* library, const char* library_base) {
return p != NULL && (p[sz] == '.' || p[sz] == '-');
}
-void HeapLeakChecker::DisableLibraryAllocs(const char* library,
- void* start_address,
- void* end_address) {
+void HeapLeakChecker::DisableLibraryAllocsLocked(const char* library,
+ uintptr_t start_address,
+ uintptr_t end_address) {
+ RAW_DCHECK(heap_checker_lock.IsHeld(), "");
int depth = 0;
// TODO(maxim): maybe this should be extended to also use objdump
// and pick the text portion of the library more precisely.
@@ -642,10 +607,13 @@ void HeapLeakChecker::DisableLibraryAllocs(const char* library,
IsLibraryNamed(library, "/libdl") ||
// library loaders leak some "system" heap that we don't care about
IsLibraryNamed(library, "/libcrypto")
- // Sometimes libcrypto of OpenSSH is compiled with -fomit-frame-pointer
- // (any library can be, of course, but this one often is because speed
- // is so important for making crypto usable). We ignore all its
- // allocations because we can't see the call stacks.
+ // Sometimes libcrypto of OpenSSH is compiled with -fomit-frame-pointer
+ // (any library can be, of course, but this one often is because speed
+ // is so important for making crypto usable). We ignore all its
+ // allocations because we can't see the call stacks. We'd prefer
+ // HeapLeakChecker::DisableChecksIn("default_malloc_ex"
+ // "|default_realloc_ex")
+ // but that doesn't work when the end-result binary is stripped.
) {
depth = 1; // only disable allocation calls directly from the library code
} else if (IsLibraryNamed(library, "/ld")
@@ -667,83 +635,84 @@ void HeapLeakChecker::DisableLibraryAllocs(const char* library,
// does not call user code.
}
if (depth) {
- HeapProfiler::MESSAGE(1, "HeapChecker: "
- "Disabling allocations from %s at depth %d:\n",
- library, depth);
- DisableChecksFromTo(start_address, end_address,
- depth);
+ RAW_VLOG(1, "Disabling allocations from %s at depth %d:", library, depth);
+ DisableChecksFromToLocked(reinterpret_cast<void*>(start_address),
+ reinterpret_cast<void*>(end_address),
+ depth);
+ if (IsLibraryNamed(library, "/libpthread") ||
+ IsLibraryNamed(library, "/libdl") ||
+ IsLibraryNamed(library, "/ld")) {
+ RAW_VLOG(1, "Global memory regions made by %s will be live data",
+ library);
+ if (global_region_caller_ranges == NULL) {
+ global_region_caller_ranges =
+ new (Allocator::Allocate(sizeof(GlobalRegionCallerRangeMap)))
+ GlobalRegionCallerRangeMap;
+ }
+ global_region_caller_ranges
+ ->insert(make_pair(end_address, start_address));
+ }
}
}
-HeapLeakChecker::ProcMapsResult
-HeapLeakChecker::UseProcMaps(ProcMapsTask proc_maps_task) {
- FILE* const fp = fopen("/proc/self/maps", "r");
- if (!fp) {
+HeapLeakChecker::ProcMapsResult HeapLeakChecker::UseProcMapsLocked(
+ ProcMapsTask proc_maps_task) {
+ RAW_DCHECK(heap_checker_lock.IsHeld(), "");
+ // Need to provide own scratch memory to ProcMapsIterator:
+ char* buffer =
+ reinterpret_cast<char*>(Allocator::Allocate(ProcMapsIterator::kBufSize));
+ ProcMapsIterator it(0, buffer);
+ if (!it.Valid()) {
int errsv = errno;
- HeapProfiler::MESSAGE(-1, "HeapChecker: "
- "Could not open /proc/self/maps: errno=%d. "
- "Libraries will not be handled correctly.\n",
- errsv);
+ RAW_LOG(ERROR, "Could not open /proc/self/maps: errno=%d. "
+ "Libraries will not be handled correctly.", errsv);
+ Allocator::Free(buffer);
return CANT_OPEN_PROC_MAPS;
}
- char proc_map_line[1024];
+ uint64 start_address, end_address, file_offset;
+ int64 inode;
+ char *permissions, *filename;
bool saw_shared_lib = false;
- while (fgets(proc_map_line, sizeof(proc_map_line), fp) != NULL) {
- // All lines starting like
- // "401dc000-4030f000 r??p 00132000 03:01 13991972 lib/bin"
- // identify a data and code sections of a shared library or our binary
- uint64 start_address, end_address, file_offset, inode;
- int size;
- char permissions[5], *filename;
- if (sscanf(proc_map_line, LLX"-"LLX" %4s "LLX" %*x:%*x "LLD" %n",
- &start_address, &end_address, permissions,
- &file_offset, &inode, &size) != 5) continue;
- proc_map_line[strlen(proc_map_line) - 1] = '\0'; // zap the newline
- filename = proc_map_line + size;
- HeapProfiler::MESSAGE(4, "HeapChecker: "
- "Looking at /proc/self/maps line:\n %s\n",
- proc_map_line);
-
+ while (it.Next(&start_address, &end_address, &permissions,
+ &file_offset, &inode, &filename)) {
if (start_address >= end_address) {
- // Crash if a line we can be interested in is ill-formed:
- if (inode != 0) abort();
- // Skip other ill-formed lines: some are possible
+ // Warn if a line we can be interested in is ill-formed:
+ if (inode != 0) {
+ RAW_LOG(ERROR, "Errors reading /proc/self/maps. "
+ "Some global memory regions will not "
+ "be handled correctly.");
+ }
+ // Silently skip other ill-formed lines: some are possible
// probably due to the interplay of how /proc/self/maps is updated
// while we read it in chunks in ProcMapsIterator and
// do things in this loop.
continue;
}
-
// Determine if any shared libraries are present.
if (inode != 0 && strstr(filename, "lib") && strstr(filename, ".so")) {
saw_shared_lib = true;
}
-
- if (proc_maps_task == DISABLE_LIBRARY_ALLOCS) {
- if (inode != 0 && strncmp(permissions, "r-xp", 4) == 0) {
- DisableLibraryAllocs(filename,
- reinterpret_cast<void*>(start_address),
- reinterpret_cast<void*>(end_address));
- }
- }
-
- if (proc_maps_task == RECORD_GLOBAL_DATA_LOCKED) {
- if (!RecordGlobalDataLocked(start_address, end_address, permissions,
- file_offset, inode, filename)) {
- HeapProfiler::MESSAGE(
- -1, "HeapChecker: failed RECORD_GLOBAL_DATA_LOCKED on %s\n",
- filename);
- abort();
- }
+ switch (proc_maps_task) {
+ case DISABLE_LIBRARY_ALLOCS:
+ // All lines starting like
+ // "401dc000-4030f000 r??p 00132000 03:01 13991972 lib/bin"
+ // identify a data and code sections of a shared library or our binary
+ if (inode != 0 && strncmp(permissions, "r-xp", 4) == 0) {
+ DisableLibraryAllocsLocked(filename, start_address, end_address);
+ }
+ break;
+ case RECORD_GLOBAL_DATA:
+ RecordGlobalDataLocked(start_address, end_address,
+ permissions, filename);
+ break;
+ default:
+ RAW_CHECK(0, "");
}
}
- fclose(fp);
-
+ Allocator::Free(buffer);
if (!saw_shared_lib) {
- HeapProfiler::MESSAGE(-1, "HeapChecker: "
- "No shared libs detected. "
- "Will likely report false leak positives "
- "for statically linked executables.\n");
+ RAW_LOG(ERROR, "No shared libs detected. Will likely report false leak "
+ "positives for statically linked executables.");
return NO_SHARED_LIBS_IN_PROC_MAPS;
}
return PROC_MAPS_USED;
@@ -770,79 +739,56 @@ static enum {
// It is called when all threads of a process are stopped
// at arbitrary points thus potentially holding those locks.
//
-// In practice we are calling some simple i/o functions
-// for logging messages and use the memory allocator in here.
-// This is known to be buggy: It is able to cause deadlocks
-// when we request a lock that a stopped thread happens to hold.
-// But both of the above as far as we know have so far
-// not resulted in any deadlocks in practice,
-// so for now we are taking our change that the deadlocks
+// In practice we are calling some simple i/o and sprintf-type library functions
+// for logging messages, but use only our own LowLevelAlloc::Arena allocator.
+//
+// This is known to be buggy: the library i/o function calls are able to cause
+// deadlocks when they request a lock that a stopped thread happens to hold.
+// This issue as far as we know have so far not resulted in any deadlocks
+// in practice, so for now we are taking our chance that the deadlocks
// have insignificant frequency.
//
// If such deadlocks become a problem we should make the i/o calls
// into appropriately direct system calls (or eliminate them),
// in particular write() is not safe and vsnprintf() is potentially dangerous
-// due to reliance on locale functions
-// (these are called through HeapProfiler::MESSAGE()).
-//
-// Eliminating the potential for deadlocks in
-// (or the need itself for) the memory allocator is more involved.
-// With some lock-all-allocator's-locks helper hooks into our allocator
-// implementations we can avoid deadlocks in our allocator code itself,
-// but the potential for deadlock in a libc functions the allocator uses
-// is still there as long as there are such lock-using functions that
-// can also be called on their own e.g. by third-party code.
-// This is e.g. the case for __libc_malloc that debugallocation.cc uses.
-// It might be a better idea to reorganize the data structures so that
-// everything that happens within IgnoreLiveThreads does not need to
-// allocate more memory.
+// due to reliance on locale functions (these are called through RAW_LOG
+// and in other ways).
//
int HeapLeakChecker::IgnoreLiveThreads(void* parameter,
int num_threads,
pid_t* thread_pids,
va_list ap) {
thread_listing_status = CALLBACK_STARTED;
- if (HeapProfiler::kMaxLogging) {
- HeapProfiler::MESSAGE(2, "HeapChecker: Found %d threads (from pid %d)\n",
- num_threads, getpid());
+ RAW_VLOG(2, "Found %d threads (from pid %d)", num_threads, getpid());
+
+ if (FLAGS_heap_check_ignore_global_live) {
+ UseProcMapsLocked(RECORD_GLOBAL_DATA);
}
// We put the registers from other threads here
// to make pointers stored in them live.
- vector<void*> thread_registers;
+ vector<void*, STL_Allocator<void*, Allocator> > thread_registers;
int failures = 0;
for (int i = 0; i < num_threads; ++i) {
// the leak checking thread itself is handled
// specially via self_thread_stack, not here:
if (thread_pids[i] == self_thread_pid) continue;
- if (HeapProfiler::kMaxLogging) {
- HeapProfiler::MESSAGE(2, "HeapChecker: Handling thread with pid %d\n",
- thread_pids[i]);
- }
+ RAW_VLOG(2, "Handling thread with pid %d", thread_pids[i]);
#if defined(HAVE_LINUX_PTRACE_H) && defined(HAVE_SYSCALL_H) && defined(DUMPER)
i386_regs thread_regs;
-#define sys_ptrace(r,p,a,d) syscall(SYS_ptrace, (r), (p), (a), (d))
+#define sys_ptrace(r, p, a, d) syscall(SYS_ptrace, (r), (p), (a), (d))
// We use sys_ptrace to avoid thread locking
// because this is called from ListAllProcessThreads
// when all but this thread are suspended.
if (sys_ptrace(PTRACE_GETREGS, thread_pids[i], NULL, &thread_regs) == 0) {
- void* stack_top;
- void* stack_bottom;
- if (GetStackExtent((void*) thread_regs.BP, &stack_top, &stack_bottom)) {
- // Need to use SP, not BP here to also get the data
- // from the very last stack frame:
- RegisterStackRange((void*) thread_regs.SP, stack_bottom);
- } else {
- failures += 1;
- }
+ // Need to use SP to get all the data from the very last stack frame:
+ RegisterStack((void*) thread_regs.SP);
// Make registers live (just in case PTRACE_ATTACH resulted in some
// register pointers still being in the registers and not on the stack):
for (void** p = (void**)&thread_regs;
p < (void**)(&thread_regs + 1); ++p) {
- if (HeapProfiler::kMaxLogging) {
- HeapProfiler::MESSAGE(3, "HeapChecker: Thread register %p\n", *p);
- }
+ RAW_VLOG(3, "Thread register %p", *p);
thread_registers.push_back(*p);
}
} else {
@@ -857,6 +803,8 @@ int HeapLeakChecker::IgnoreLiveThreads(void* parameter,
if (thread_registers.size()) {
// Make thread registers be live heap data sources.
// we rely here on the fact that vector is in one memory chunk:
+ RAW_VLOG(2, "Live registers at %p of %"PRIuS" bytes",
+ &thread_registers[0], thread_registers.size() * sizeof(void*));
live_objects->push_back(AllocObject(&thread_registers[0],
thread_registers.size() * sizeof(void*),
THREAD_REGISTERS));
@@ -870,155 +818,222 @@ int HeapLeakChecker::IgnoreLiveThreads(void* parameter,
return failures;
}
-// Info about the self thread stack extent
-struct HeapLeakChecker::StackExtent {
- bool have;
- void* top;
- void* bottom;
-};
-
-// Stack info of the thread that is doing the current leak check
+// Stack top of the thread that is doing the current leak check
// (protected by our lock; IgnoreAllLiveObjectsLocked sets it)
-static HeapLeakChecker::StackExtent self_thread_stack;
+static void* self_thread_stack_top;
void HeapLeakChecker::IgnoreNonThreadLiveObjectsLocked() {
+ RAW_VLOG(2, "Handling self thread with pid %d", self_thread_pid);
// Register our own stack:
- if (HeapProfiler::kMaxLogging) {
- HeapProfiler::MESSAGE(2, "HeapChecker: Handling self thread with pid %d\n",
- self_thread_pid);
- }
- if (self_thread_stack.have) {
- // important that all stack ranges
- // (including the one from the check initiator here)
- // are known before we start looking at them in MakeDisabledLiveCallback:
- RegisterStackRange(self_thread_stack.top, self_thread_stack.bottom);
- IgnoreLiveObjectsLocked("stack data", "");
- } else {
- HeapProfiler::MESSAGE(0, "HeapChecker: Stack not found "
- "for this thread; may get false leak reports\n");
- }
+
+ // Important that all stack ranges (including the one here)
+ // are known before we start looking at them in MakeDisabledLiveCallback:
+ RegisterStack(self_thread_stack_top);
+ IgnoreLiveObjectsLocked("stack data", "");
+
// Make objects we were told to ignore live:
if (ignored_objects) {
- HeapProfiler::AllocValue alloc_value;
for (IgnoredObjectsMap::const_iterator object = ignored_objects->begin();
object != ignored_objects->end(); ++object) {
void* ptr = reinterpret_cast<void*>(object->first);
+ RAW_VLOG(2, "Ignored live object at %p of %"PRIuS" bytes",
+ ptr, object->second);
live_objects->
push_back(AllocObject(ptr, object->second, MUST_BE_ON_HEAP));
// we do this liveness check for ignored_objects before doing any
// live heap walking to make sure it does not fail needlessly:
- bool have_on_heap =
- HeapProfiler::HaveOnHeapLocked(&ptr, &alloc_value);
- if (!(have_on_heap && object->second == alloc_value.bytes)) {
- HeapProfiler::MESSAGE(-1, "HeapChecker: "
- "%p of %"PRIuS" bytes "
- "from an IgnoreObject() disappeared\n",
- ptr, object->second);
- abort();
+ size_t object_size;
+ if (!(HaveOnHeapLocked(&ptr, &object_size) &&
+ object->second == object_size)) {
+ RAW_LOG(FATAL, "Object at %p of %"PRIuS" bytes from an"
+ " IgnoreObject() has disappeared", ptr, object->second);
}
}
IgnoreLiveObjectsLocked("ignored objects", "");
}
+
// Make code-address-disabled objects live and ignored:
// This in particular makes all thread-specific data live
// because the basic data structure to hold pointers to thread-specific data
// is allocated from libpthreads and we have range-disabled that
- // library code with UseProcMaps(DISABLE_LIBRARY_ALLOCS);
+ // library code with UseProcMapsLocked(DISABLE_LIBRARY_ALLOCS);
// so now we declare all thread-specific data reachable from there as live.
- HeapProfiler::allocation_->Iterate(MakeDisabledLiveCallback);
+ heap_profile->IterateAllocs(MakeDisabledLiveCallback);
IgnoreLiveObjectsLocked("disabled code", "");
+
// Actually make global data live:
if (FLAGS_heap_check_ignore_global_live) {
+ bool have_null_region_callers = false;
for (LibraryLiveObjectsStacks::iterator l = library_live_objects->begin();
l != library_live_objects->end(); ++l) {
- if (live_objects->size()) abort();
+ RAW_CHECK(live_objects->empty(), "");
+ // Process library_live_objects in l->second
+ // filtering them by MemoryRegionMap:
+ // It's safe to iterate over MemoryRegionMap
+ // w/o locks here as we are inside MemoryRegionMap::Lock().
+ // The only change to MemoryRegionMap possible in this loop
+ // is region addition as a result of allocating more memory
+ // for live_objects. This won't invalidate the RegionIterator
+ // or the intent of the loop.
+ // --see the comment by MemoryRegionMap::BeginRegionLocked().
+ for (MemoryRegionMap::RegionIterator region =
+ MemoryRegionMap::BeginRegionLocked();
+ region != MemoryRegionMap::EndRegionLocked(); ++region) {
+ // "region" from MemoryRegionMap is to be subtracted from
+ // (tentatively live) regions in l->second
+ // if it has a stack inside or it was allocated by
+ // a non-special caller (not one covered by a range
+ // in global_region_caller_ranges).
+ // This will in particular exclude all memory chunks used
+ // by the heap itself as well as what's been allocated with
+ // any allocator on top of mmap.
+ bool subtract = true;
+ if (!region->is_stack && global_region_caller_ranges) {
+ if (region->caller == static_cast<uintptr_t>(NULL)) {
+ have_null_region_callers = true;
+ } else {
+ GlobalRegionCallerRangeMap::const_iterator iter
+ = global_region_caller_ranges->upper_bound(region->caller);
+ if (iter != global_region_caller_ranges->end()) {
+ RAW_DCHECK(iter->first > region->caller, "");
+ if (iter->second < region->caller) { // in special region
+ subtract = false;
+ }
+ }
+ }
+ }
+ if (subtract) {
+ // The loop puts the result of filtering l->second into live_objects:
+ for (LiveObjectsStack::const_iterator i = l->second.begin();
+ i != l->second.end(); ++i) {
+ // subtract *region from *i
+ uintptr_t start = reinterpret_cast<uintptr_t>(i->ptr);
+ uintptr_t end = start + i->size;
+ if (region->start_addr <= start && end <= region->end_addr) {
+ // full deletion due to subsumption
+ } else if (start < region->start_addr &&
+ region->end_addr < end) { // cutting-out split
+ live_objects->push_back(AllocObject(i->ptr,
+ region->start_addr - start,
+ IN_GLOBAL_DATA));
+ live_objects->push_back(AllocObject((void*)region->end_addr,
+ end - region->end_addr,
+ IN_GLOBAL_DATA));
+ } else if (region->end_addr > start &&
+ region->start_addr <= start) { // cut from start
+ live_objects->push_back(AllocObject((void*)region->end_addr,
+ end - region->end_addr,
+ IN_GLOBAL_DATA));
+ } else if (region->start_addr > start &&
+ region->start_addr < end) { // cut from end
+ live_objects->push_back(AllocObject(i->ptr,
+ region->start_addr - start,
+ IN_GLOBAL_DATA));
+ } else { // pass: no intersection
+ live_objects->push_back(AllocObject(i->ptr, i->size,
+ IN_GLOBAL_DATA));
+ }
+ }
+ // Move live_objects back into l->second
+ // for filtering by the next region.
+ live_objects->swap(l->second);
+ live_objects->clear();
+ }
+ }
+ // Now get and use live_objects from the final version of l->second:
+ if (VLOG_IS_ON(2)) {
+ for (LiveObjectsStack::const_iterator i = l->second.begin();
+ i != l->second.end(); ++i) {
+ RAW_VLOG(2, "Library live region at %p of %"PRIuS" bytes",
+ i->ptr, i->size);
+ }
+ }
live_objects->swap(l->second);
IgnoreLiveObjectsLocked("in globals of\n ", l->first.c_str());
}
- delete library_live_objects;
+ if (have_null_region_callers) {
+ RAW_LOG(ERROR, "Have memory regions w/o callers: "
+ "might report false leaks");
+ }
+ Allocator::DeleteAndNull(&library_live_objects);
}
}
-// For this call we are free to call new/delete from this thread:
-// heap profiler will ignore them without acquiring its lock:
-void HeapLeakChecker::
-IgnoreAllLiveObjectsLocked(const StackExtent& self_stack) {
- if (live_objects) abort();
- live_objects = new LiveObjectsStack;
- stack_ranges = new StackRangeMap;
- if (HeapProfiler::ignored_objects_) abort();
- HeapProfiler::ignored_objects_ = new HeapProfiler::IgnoredObjectSet;
+void HeapLeakChecker::IgnoreAllLiveObjectsLocked(void* self_stack_top) {
+ RAW_CHECK(live_objects == NULL, "");
+ live_objects = new (Allocator::Allocate(sizeof(LiveObjectsStack)))
+ LiveObjectsStack;
+ stack_tops = new (Allocator::Allocate(sizeof(StackTopSet))) StackTopSet;
// Record global data as live:
- // We need to do it before we stop the threads in ListAllProcessThreads
- // below; otherwise deadlocks are possible
- // when we try to fork to execute objdump in UseProcMaps.
if (FLAGS_heap_check_ignore_global_live) {
- library_live_objects = new LibraryLiveObjectsStacks;
- UseProcMaps(RECORD_GLOBAL_DATA_LOCKED);
+ library_live_objects =
+ new (Allocator::Allocate(sizeof(LibraryLiveObjectsStacks)))
+ LibraryLiveObjectsStacks;
}
// Ignore all thread stacks:
thread_listing_status = CALLBACK_NOT_STARTED;
bool need_to_ignore_non_thread_objects = true;
self_thread_pid = getpid();
- self_thread_stack = self_stack;
+ self_thread_stack_top = self_stack_top;
if (FLAGS_heap_check_ignore_thread_live) {
// We fully suspend the threads right here before any liveness checking
// and keep them suspended for the whole time of liveness checking
// inside of the IgnoreLiveThreads callback.
- // (The threads can't (de)allocate due to profiler's lock but
+ // (The threads can't (de)allocate due to lock on the delete hook but
// if not suspended they could still mess with the pointer
// graph while we walk it).
int r = ListAllProcessThreads(NULL, IgnoreLiveThreads);
need_to_ignore_non_thread_objects = r < 0;
if (r < 0) {
- HeapProfiler::MESSAGE(0, "HeapChecker: thread finding failed "
- "with %d errno=%d\n", r, errno);
+ RAW_LOG(WARNING, "Thread finding failed with %d errno=%d", r, errno);
if (thread_listing_status == CALLBACK_COMPLETED) {
- HeapProfiler::MESSAGE(0, "HeapChecker: thread finding callback "
- "finished ok; hopefully everything is fine\n");
+ RAW_LOG(INFO, "Thread finding callback "
+ "finished ok; hopefully everything is fine");
need_to_ignore_non_thread_objects = false;
} else if (thread_listing_status == CALLBACK_STARTED) {
- HeapProfiler::MESSAGE(0, "HeapChecker: thread finding callback was "
- "interrupted or crashed; can't fix this\n");
- abort();
+ RAW_LOG(FATAL, "Thread finding callback was "
+ "interrupted or crashed; can't fix this");
} else { // CALLBACK_NOT_STARTED
- HeapProfiler::MESSAGE(0, "HeapChecker: Could not find thread stacks; "
- "may get false leak reports\n");
+ RAW_LOG(ERROR, "Could not find thread stacks. "
+ "Will likely report false leak positives.");
}
} else if (r != 0) {
- HeapProfiler::MESSAGE(0, "HeapChecker: Thread stacks not found "
- "for %d threads; may get false leak reports\n",
- r);
+ RAW_LOG(ERROR, "Thread stacks not found for %d threads. "
+ "Will likely report false leak positives.", r);
} else {
- if (HeapProfiler::kMaxLogging) {
- HeapProfiler::MESSAGE(2, "HeapChecker: Thread stacks appear"
- " to be found for all threads\n");
- }
+ RAW_VLOG(2, "Thread stacks appear to be found for all threads");
}
} else {
- HeapProfiler::MESSAGE(0, "HeapChecker: Not looking for thread stacks; "
- "objects reachable only from there "
- "will be reported as leaks\n");
+ RAW_LOG(WARNING, "Not looking for thread stacks; "
+ "objects reachable only from there "
+ "will be reported as leaks");
}
// Do all other live data ignoring here if we did not do it
// within thread listing callback with all threads stopped.
- if (need_to_ignore_non_thread_objects) IgnoreNonThreadLiveObjectsLocked();
+ if (need_to_ignore_non_thread_objects) {
+ if (FLAGS_heap_check_ignore_global_live) {
+ UseProcMapsLocked(RECORD_GLOBAL_DATA);
+ }
+ IgnoreNonThreadLiveObjectsLocked();
+ }
if (live_objects_total) {
- HeapProfiler::MESSAGE(0, "HeapChecker: "
- "Ignoring "LLD" reachable "
- "objects of "LLD" bytes\n",
- live_objects_total, live_bytes_total);
- }
- // Free these: we made them here and heap profiler never saw them
- delete live_objects;
- live_objects = NULL;
- delete stack_ranges;
- stack_ranges = NULL;
+ RAW_VLOG(0, "Ignoring %"PRId64" reachable objects of %"PRId64" bytes",
+ live_objects_total, live_bytes_total);
+ }
+ // Free these: we made them here and heap_profile never saw them
+ Allocator::DeleteAndNull(&live_objects);
+ Allocator::DeleteAndNull(&stack_tops);
}
-// This function does not change HeapProfiler's state:
-// we record ignored live objects in HeapProfiler::ignored_objects_
-// instead of modifying the heap profile.
+// Alignment at which we should consider pointer positions
+// in IgnoreLiveObjectsLocked. Use 1 if any alignment is ok.
+static size_t pointer_alignment = sizeof(void*);
+// Global lock for HeapLeakChecker::DoNoLeaks to protect pointer_alignment.
+static SpinLock alignment_checker_lock(SpinLock::LINKER_INITIALIZED);
+
+// This function does not change heap_profile's state:
+// we only record live objects to be skipped into profile_adjust_objects
+// instead of modifying the heap_profile itself.
void HeapLeakChecker::IgnoreLiveObjectsLocked(const char* name,
const char* name2) {
int64 live_object_count = 0;
@@ -1028,26 +1043,22 @@ void HeapLeakChecker::IgnoreLiveObjectsLocked(const char* name,
size_t size = live_objects->back().size;
const ObjectPlacement place = live_objects->back().place;
live_objects->pop_back();
- HeapProfiler::AllocValue alloc_value;
+ size_t object_size;
if (place == MUST_BE_ON_HEAP &&
- HeapProfiler::HaveOnHeapLocked(&object, &alloc_value) &&
- HeapProfiler::ignored_objects_
- ->insert(reinterpret_cast<uintptr_t>(object)).second) {
+ HaveOnHeapLocked(&object, &object_size) &&
+ profile_adjust_objects->insert(object).second) {
live_object_count += 1;
live_byte_count += size;
}
- HeapProfiler::MESSAGE(5, "HeapChecker: "
- "Looking for heap pointers "
- "in %p of %"PRIuS" bytes\n", object, size);
- // Try interpretting any byte sequence in object,size as a heap pointer
- const size_t alignment = sizeof(void*);
- // alignment at which we should consider pointer positions here
- // use 1 if any alignment is ok
- const size_t remainder = reinterpret_cast<uintptr_t>(object) % alignment;
+ RAW_VLOG(4, "Looking for heap pointers in %p of %"PRIuS" bytes",
+ object, size);
+ // Try interpretting any byte sequence in object,size as a heap pointer:
+ const size_t remainder =
+ reinterpret_cast<uintptr_t>(object) % pointer_alignment;
if (remainder) {
- reinterpret_cast<char*&>(object) += alignment - remainder;
- if (size >= alignment - remainder) {
- size -= alignment - remainder;
+ object = reinterpret_cast<char*>(object) + pointer_alignment-remainder;
+ if (size >= pointer_alignment - remainder) {
+ size -= pointer_alignment - remainder;
} else {
size = 0;
}
@@ -1057,43 +1068,42 @@ void HeapLeakChecker::IgnoreLiveObjectsLocked(const char* name,
#define UNALIGNED_LOAD32(_p) (*reinterpret_cast<const uint32 *>(_p))
void* ptr = reinterpret_cast<void*>(UNALIGNED_LOAD32(object));
void* current_object = object;
- reinterpret_cast<char*&>(object) += alignment;
- size -= alignment;
+ object = reinterpret_cast<char*>(object) + pointer_alignment;
+ size -= pointer_alignment;
if (ptr == NULL) continue;
- HeapProfiler::MESSAGE(8, "HeapChecker: "
- "Trying pointer to %p at %p\n",
- ptr, current_object);
- // Do not need the following since the data for these
- // is not recorded by heap-profiler:
- // if (ptr == live_objects ||
- // ptr == HeapProfiler::ignored_objects_) continue;
- if (HeapProfiler::HaveOnHeapLocked(&ptr, &alloc_value) &&
- HeapProfiler::ignored_objects_
- ->insert(reinterpret_cast<uintptr_t>(ptr)).second) {
+ RAW_VLOG(8, "Trying pointer to %p at %p", ptr, current_object);
+ size_t object_size;
+ if (HaveOnHeapLocked(&ptr, &object_size) &&
+ profile_adjust_objects->insert(ptr).second) {
// We take the (hopefully low) risk here of encountering by accident
// a byte sequence in memory that matches an address of
// a heap object which is in fact leaked.
// I.e. in very rare and probably not repeatable/lasting cases
// we might miss some real heap memory leaks.
- HeapProfiler::MESSAGE(5, "HeapChecker: "
- "Found pointer to %p"
- " of %"PRIuS" bytes at %p\n",
- ptr, alloc_value.bytes, current_object);
+ RAW_VLOG(5, "Found pointer to %p of %"PRIuS" bytes at %p",
+ ptr, object_size, current_object);
live_object_count += 1;
- live_byte_count += alloc_value.bytes;
- live_objects->push_back(AllocObject(ptr, alloc_value.bytes,
- IGNORED_ON_HEAP));
+ live_byte_count += object_size;
+ live_objects->push_back(AllocObject(ptr, object_size, IGNORED_ON_HEAP));
}
}
}
live_objects_total += live_object_count;
live_bytes_total += live_byte_count;
if (live_object_count) {
- HeapProfiler::MESSAGE(1, "HeapChecker: "
- "Removed "LLD" live heap objects"
- " of "LLD" bytes: %s%s\n",
- live_object_count, live_byte_count, name, name2);
+ RAW_VLOG(1, "Removed %"PRId64" live heap objects of %"PRId64" bytes: %s%s",
+ live_object_count, live_byte_count, name, name2);
+ }
+}
+
+bool HeapLeakChecker::HeapProfileFilter(void* ptr, size_t size) {
+ if (profile_adjust_objects->find(ptr) != profile_adjust_objects->end()) {
+ RAW_VLOG(4, "Ignoring object at %p of %"PRIuS" bytes", ptr, size);
+ // erase so we can later test that all adjust-objects got utilized
+ profile_adjust_objects->erase(ptr);
+ return true;
}
+ return false;
}
//----------------------------------------------------------------------
@@ -1102,161 +1112,166 @@ void HeapLeakChecker::IgnoreLiveObjectsLocked(const char* name,
void HeapLeakChecker::DisableChecksUp(int stack_frames) {
if (!heap_checker_on) return;
- if (stack_frames < 1) abort();
+ RAW_CHECK(stack_frames >= 1, "");
void* stack[1];
- if (GetStackTrace(stack, 1, stack_frames+1) != 1) abort();
+ if (GetStackTrace(stack, 1, stack_frames + 1) != 1) {
+ RAW_LOG(FATAL, "Can't get stack trace");
+ }
DisableChecksAt(stack[0]);
}
void HeapLeakChecker::DisableChecksAt(void* address) {
if (!heap_checker_on) return;
- if (pthread_mutex_lock(&heap_checker_lock) != 0) abort();
+ heap_checker_lock.Lock();
DisableChecksAtLocked(address);
- if (pthread_mutex_unlock(&heap_checker_lock) != 0) abort();
+ heap_checker_lock.Unlock();
}
bool HeapLeakChecker::HaveDisabledChecksUp(int stack_frames) {
if (!heap_checker_on) return false;
- if (stack_frames < 1) abort();
+ RAW_CHECK(stack_frames >= 1, "");
void* stack[1];
- if (GetStackTrace(stack, 1, stack_frames+1) != 1) abort();
+ if (GetStackTrace(stack, 1, stack_frames + 1) != 1) {
+ RAW_LOG(FATAL, "Can't get stack trace");
+ }
return HaveDisabledChecksAt(stack[0]);
}
bool HeapLeakChecker::HaveDisabledChecksAt(void* address) {
if (!heap_checker_on) return false;
- if (pthread_mutex_lock(&heap_checker_lock) != 0) abort();
+ heap_checker_lock.Lock();
bool result = disabled_addresses != NULL &&
disabled_addresses->
find(reinterpret_cast<uintptr_t>(address)) !=
disabled_addresses->end();
- if (pthread_mutex_unlock(&heap_checker_lock) != 0) abort();
+ heap_checker_lock.Unlock();
return result;
}
void HeapLeakChecker::DisableChecksIn(const char* pattern) {
if (!heap_checker_on) return;
- if (pthread_mutex_lock(&heap_checker_lock) != 0) abort();
+ heap_checker_lock.Lock();
DisableChecksInLocked(pattern);
- if (pthread_mutex_unlock(&heap_checker_lock) != 0) abort();
+ heap_checker_lock.Unlock();
}
void* HeapLeakChecker::GetDisableChecksStart() {
if (!heap_checker_on) return NULL;
- void* start_address;
- if (GetStackTrace(&start_address, 1, 1) != 1) abort();
+ void* start_address = NULL;
+ if (GetStackTrace(&start_address, 1, 1) != 1) {
+ RAW_LOG(FATAL, "Can't get stack trace");
+ }
return start_address;
}
void HeapLeakChecker::DisableChecksToHereFrom(void* start_address) {
if (!heap_checker_on) return;
- void* end_address;
- if (GetStackTrace(&end_address, 1, 1) != 1) abort();
+ void* end_address = NULL;
+ if (GetStackTrace(&end_address, 1, 1) != 1) {
+ RAW_LOG(FATAL, "Can't get stack trace");
+ }
if (start_address > end_address) swap(start_address, end_address);
- DisableChecksFromTo(start_address, end_address,
- 10000); // practically no stack depth limit:
- // heap profiler keeps much shorter stack traces
+ heap_checker_lock.Lock();
+ DisableChecksFromToLocked(start_address, end_address, 10000);
+ // practically no stack depth limit:
+ // our heap_profile keeps much shorter stack traces
+ heap_checker_lock.Unlock();
}
void HeapLeakChecker::IgnoreObject(void* ptr) {
if (!heap_checker_on) return;
- if (pthread_mutex_lock(&heap_checker_lock) != 0) abort();
+ heap_checker_lock.Lock();
IgnoreObjectLocked(ptr);
- if (pthread_mutex_unlock(&heap_checker_lock) != 0) abort();
+ heap_checker_lock.Unlock();
}
void HeapLeakChecker::IgnoreObjectLocked(void* ptr) {
- HeapProfiler::AllocValue alloc_value;
- if (HeapProfiler::HaveOnHeap(&ptr, &alloc_value)) {
- HeapProfiler::MESSAGE(1, "HeapChecker: "
- "Going to ignore live object "
- "at %p of %"PRIuS" bytes\n",
- ptr, alloc_value.bytes);
+ size_t object_size;
+ if (HaveOnHeapLocked(&ptr, &object_size)) {
+ RAW_VLOG(1, "Going to ignore live object at %p of %"PRIuS" bytes",
+ ptr, object_size);
if (ignored_objects == NULL) {
- ignored_objects = new IgnoredObjectsMap;
- IgnoreObjectLocked(ignored_objects);
- // ignore self in case we are not ignoring global data
+ ignored_objects = new (Allocator::Allocate(sizeof(IgnoredObjectsMap)))
+ IgnoredObjectsMap;
}
if (!ignored_objects->insert(make_pair(reinterpret_cast<uintptr_t>(ptr),
- alloc_value.bytes)).second) {
- HeapProfiler::MESSAGE(-1, "HeapChecker: "
- "%p is already being ignored\n", ptr);
- abort();
+ object_size)).second) {
+ RAW_LOG(FATAL, "Object at %p is already being ignored", ptr);
}
}
}
void HeapLeakChecker::UnIgnoreObject(void* ptr) {
if (!heap_checker_on) return;
- HeapProfiler::AllocValue alloc_value;
- if (pthread_mutex_lock(&heap_checker_lock) != 0) abort();
- bool ok = HeapProfiler::HaveOnHeap(&ptr, &alloc_value);
+ heap_checker_lock.Lock();
+ size_t object_size;
+ bool ok = HaveOnHeapLocked(&ptr, &object_size);
if (ok) {
ok = false;
if (ignored_objects) {
IgnoredObjectsMap::iterator object =
ignored_objects->find(reinterpret_cast<uintptr_t>(ptr));
- if (object != ignored_objects->end() &&
- alloc_value.bytes == object->second) {
+ if (object != ignored_objects->end() && object_size == object->second) {
ignored_objects->erase(object);
ok = true;
- HeapProfiler::MESSAGE(1, "HeapChecker: "
- "Now not going to ignore live object "
- "at %p of %"PRIuS" bytes\n",
- ptr, alloc_value.bytes);
+ RAW_VLOG(1, "Now not going to ignore live object "
+ "at %p of %"PRIuS" bytes", ptr, object_size);
}
}
}
- if (pthread_mutex_unlock(&heap_checker_lock) != 0) abort();
- if (!ok) {
- HeapProfiler::MESSAGE(-1, "HeapChecker: "
- "%p has not been ignored\n", ptr);
- abort();
- }
+ heap_checker_lock.Unlock();
+ if (!ok) RAW_LOG(FATAL, "Object at %p has not been ignored", ptr);
}
//----------------------------------------------------------------------
// HeapLeakChecker non-static functions
//----------------------------------------------------------------------
-void HeapLeakChecker::DumpProfileLocked(bool start,
- const StackExtent& self_stack) {
- assert(!HeapProfiler::dumping_); // not called from dumping code
- HeapProfiler::MESSAGE(0, "HeapChecker: %s check \"%s\"\n",
- (start ? "Starting" : "Ending"), name_);
- // Make the heap profile while letting our thread work with the heap
- // without profiling this activity into the regular heap profile,
- // while at the same time we hold the lock
- // and do not let other threads work with the heap:
- assert(!HeapProfiler::self_disable_);
- HeapProfiler::self_disabled_tid_ = pthread_self();
- // stop normal heap profiling in our thread:
- HeapProfiler::self_disable_ = true;
- { // scope
- IgnoreAllLiveObjectsLocked(self_stack);
- HeapProfiler::dump_for_leaks_ = true;
- string* file_name = new string(*profile_prefix + "." + name_ +
- (start ? "-beg.heap" : "-end.heap"));
- HeapProfiler::DumpLocked("leak check", file_name->c_str());
- delete file_name; // want explicit control of the destruction point
- HeapProfiler::dump_for_leaks_ = false;
- delete HeapProfiler::ignored_objects_;
- HeapProfiler::ignored_objects_ = NULL;
- }
- // resume normal heap profiling in our thread:
- HeapProfiler::self_disable_ = false;
- // Check that we made no heap changes ourselves
- // while normal heap profiling was paused:
- int64 self_disabled_bytes = HeapProfiler::self_disabled_.alloc_size_ -
- HeapProfiler::self_disabled_.free_size_;
- int64 self_disabled_allocs = HeapProfiler::self_disabled_.allocs_ -
- HeapProfiler::self_disabled_.frees_;
- if (self_disabled_bytes != 0 || self_disabled_allocs != 0) {
- HeapProfiler::MESSAGE(-1, "HeapChecker: "
- "internal HeapChecker leak of "LLD" objects "
- "and/or "LLD" bytes\n",
- self_disabled_allocs, self_disabled_bytes);
- abort();
+void HeapLeakChecker::DumpProfileLocked(ProfileType profile_type,
+ void* self_stack_top,
+ size_t* alloc_bytes,
+ size_t* alloc_objects) {
+ RAW_VLOG(0, "%s check \"%s\"%s",
+ (profile_type == START_PROFILE ? "Starting"
+ : "At an end point for"),
+ name_,
+ (pointer_alignment == 1 ? " w/o pointer alignment" : ""));
+ // Sanity check that nobody is messing with the hooks we need:
+ // Important to have it here: else we can misteriously SIGSEGV
+ // in IgnoreLiveObjectsLocked inside ListAllProcessThreads's callback
+ // by looking into a region that got unmapped w/o our knowledge.
+ MemoryRegionMap::CheckMallocHooks();
+ if (MallocHook::GetNewHook() != NewHook ||
+ MallocHook::GetDeleteHook() != DeleteHook) {
+ RAW_LOG(FATAL, "new/delete malloc hooks got changed");
+ }
+ // Make the heap profile, other threads are locked out.
+ RAW_CHECK(profile_adjust_objects == NULL, "");
+ const int alloc_count = Allocator::alloc_count();
+ profile_adjust_objects =
+ new (Allocator::Allocate(sizeof(ProfileAdjustObjectSet)))
+ ProfileAdjustObjectSet;
+ IgnoreAllLiveObjectsLocked(self_stack_top);
+ const int len = profile_prefix->size() + strlen(name_) + 10 + 2;
+ char* file_name = reinterpret_cast<char*>(Allocator::Allocate(len));
+ snprintf(file_name, len, "%s.%s%s%s",
+ profile_prefix->c_str(), name_,
+ profile_type == START_PROFILE ? "-beg" : "-end",
+ HeapProfileTable::kFileExt);
+ HeapProfileTable::Stats stats;
+ bool ok = heap_profile->DumpFilteredProfile(
+ file_name, HeapProfileFilter, FLAGS_heap_check_identify_leaks, &stats);
+ RAW_CHECK(ok, "No sense to continue");
+ *alloc_bytes = stats.alloc_size - stats.free_size;
+ *alloc_objects = stats.allocs - stats.frees;
+ Allocator::Free(file_name);
+ RAW_CHECK(profile_adjust_objects->empty(),
+ "Some objects to ignore are not on the heap");
+ Allocator::DeleteAndNull(&profile_adjust_objects);
+ // Check that we made no leaks ourselves:
+ if (Allocator::alloc_count() != alloc_count) {
+ RAW_LOG(FATAL, "Internal HeapChecker leak of %d objects",
+ Allocator::alloc_count() - alloc_count);
}
}
@@ -1265,38 +1280,29 @@ void HeapLeakChecker::Create(const char *name) {
has_checked_ = false;
char* n = new char[strlen(name) + 1]; // do this before we lock
IgnoreObject(n); // otherwise it might be treated as live due to our stack
- if (pthread_mutex_lock(&heap_checker_lock) != 0) abort();
+ alignment_checker_lock.Lock();
+ heap_checker_lock.Lock();
// Heap activity in other threads is paused for this whole function.
- HeapProfiler::Lock();
+ MemoryRegionMap::Lock();
if (heap_checker_on) {
- assert(strchr(name, '/') == NULL); // must be a simple name
- assert(name_ == NULL); // so this is not a memory leak
+ RAW_DCHECK(strchr(name, '/') == NULL, "must be a simple name");
name_ = n;
memcpy(name_, name, strlen(name) + 1);
- // get our stack range to make its proper portion live
- StackExtent self_stack;
- self_stack.have = GetStackExtent(NULL, &self_stack.top, &self_stack.bottom);
- DumpProfileLocked(true, self_stack); // start
- start_inuse_bytes_ = static_cast<size_t>(HeapProfiler::profile_.alloc_size_ -
- HeapProfiler::profile_.free_size_);
- start_inuse_allocs_ = static_cast<size_t>(HeapProfiler::profile_.allocs_ -
- HeapProfiler::profile_.frees_);
- if (HeapProfiler::kMaxLogging) {
- HeapProfiler::MESSAGE(1, "HeapChecker: "
- "Start check \"%s\" profile: "
- "%"PRIuS"d bytes in %"PRIuS"d objects\n",
- name_, start_inuse_bytes_, start_inuse_allocs_);
- }
+ // Use our stack ptr to make stack data live:
+ int a_local_var;
+ DumpProfileLocked(START_PROFILE, &a_local_var,
+ &start_inuse_bytes_, &start_inuse_allocs_);
+ RAW_VLOG(1, "Start check \"%s\" profile: %"PRIuS" bytes "
+ "in %"PRIuS" objects",
+ name_, start_inuse_bytes_, start_inuse_allocs_);
} else {
- HeapProfiler::MESSAGE(-1, "HeapChecker: "
- "Heap checker is not active, "
- "hence checker \"%s\" will do nothing!\n", name);
- HeapProfiler::MESSAGE(-1, "HeapChecker: "
- "To activate set the HEAPCHECK environment "
- "variable.\n");
- }
- HeapProfiler::Unlock();
- if (pthread_mutex_unlock(&heap_checker_lock) != 0) abort();
+ RAW_LOG(WARNING, "Heap checker is not active, "
+ "hence checker \"%s\" will do nothing!", name);
+ RAW_LOG(WARNING, "To activate set the HEAPCHECK environment variable.\n");
+ }
+ MemoryRegionMap::Unlock();
+ heap_checker_lock.Unlock();
+ alignment_checker_lock.Unlock();
if (name_ == NULL) {
UnIgnoreObject(n);
delete[] n; // must be done after we unlock
@@ -1304,259 +1310,318 @@ void HeapLeakChecker::Create(const char *name) {
}
HeapLeakChecker::HeapLeakChecker(const char *name) {
- assert(strcmp(name, "_main_") != 0); // reserved
+ RAW_DCHECK(strcmp(name, "_main_") != 0, "_main_ is reserved");
Create(name);
}
-DECLARE_int64(heap_profile_allocation_interval);
-DECLARE_int64(heap_profile_inuse_interval);
+HeapLeakChecker::HeapLeakChecker() {
+ Create("_main_");
+}
+
+ssize_t HeapLeakChecker::BytesLeaked() const {
+ if (!has_checked_) {
+ RAW_LOG(FATAL, "*NoLeaks|SameHeap must execute before this call");
+ }
+ return inuse_bytes_increase_;
+}
+
+ssize_t HeapLeakChecker::ObjectsLeaked() const {
+ if (!has_checked_) {
+ RAW_LOG(FATAL, "*NoLeaks|SameHeap must execute before this call");
+ }
+ return inuse_allocs_increase_;
+}
// Save pid of main thread for using in naming dump files
-int32 HeapLeakChecker::main_thread_pid_ = getpid();
-// Directory in which to dump profiles
-string* HeapLeakChecker::dump_directory_ = NULL;
+static int32 main_thread_pid = getpid();
#ifdef HAVE_PROGRAM_INVOCATION_NAME
extern char* program_invocation_name;
extern char* program_invocation_short_name;
static const char* invocation_name() { return program_invocation_short_name; }
static const char* invocation_path() { return program_invocation_name; }
#else
-static const char* invocation_name() { return "heap_checker"; }
-static const char* invocation_path() { return "heap_checker"; } // I guess?
+static const char* invocation_name() { return "<your binary>"; }
+static const char* invocation_path() { return "<your binary>"; }
#endif
-HeapLeakChecker::HeapLeakChecker() {
- Create("_main_");
+static void MakeCommand(const char* basename,
+ bool check_type_is_no_leaks,
+ bool use_initial_profile,
+ const string& prefix,
+ string* beg_profile,
+ string* end_profile,
+ string* command) {
+ string ignore_re;
+ if (disabled_regexp) {
+ ignore_re += " --ignore='^";
+ ignore_re += disabled_regexp->c_str();
+ ignore_re += "$'";
+ }
+ *command += *flags_heap_profile_pprof;
+ if (use_initial_profile) {
+ // compare against initial profile only if need to
+ *beg_profile = prefix + "." + basename +
+ "-beg" + HeapProfileTable::kFileExt;
+ *command += string(" --base=\"") + *beg_profile + "\"";
+ }
+ if (check_type_is_no_leaks) *command += string(" --drop_negative");
+ *end_profile = prefix + "." + basename + "-end" + HeapProfileTable::kFileExt;
+ *command += string(" ") +
+ invocation_path() +
+ " \"" + *end_profile + "\"" + ignore_re + " --inuse_objects";
+ if (!FLAGS_heap_check_identify_leaks) {
+ *command += " --lines"; // important to catch leaks when !see_leaks
+ } else {
+ *command += " --addresses"; // stronger than --lines and prints
+ // unresolvable object addresses
+ }
}
-ssize_t HeapLeakChecker::BytesLeaked() const {
- if (!has_checked_) {
- HeapProfiler::MESSAGE(-1, "HeapChecker: "
- "*NoLeaks|SameHeap must execute before this call\n");
- abort();
+static int GetStatusOutput(const char* command, string* output) {
+ // We don't want the heapchecker to run in the child helper
+ // processes that we fork() as part of this process' heap check.
+
+ // setenv() can call realloc(), so we don't want to call it while
+ // the heap profiling is disabled. Instead just overwrite the final
+ // char of the env var name, so it has a different name and gets
+ // ignored in the child. We assume the env looks like 'VAR=VALUE\0VAR=VALUE'
+ char *env_heapcheck = getenv("HEAPCHECK");
+ char *env_ldpreload = getenv("LD_PRELOAD");
+
+ if (env_heapcheck) {
+ assert(env_heapcheck[-1] == '=');
+ env_heapcheck[-2] = '?';
}
- return inuse_bytes_increase_;
+ if (env_ldpreload) {
+ assert(env_ldpreload[-1] == '=');
+ env_ldpreload[-2] = '?';
+ }
+
+ FILE* f = popen(command, "r");
+ if (f == NULL) {
+ fprintf(stderr, "popen(%s) failed!\n", command); // This shouldn't happen
+ exit(1);
+ }
+
+ if (env_heapcheck) env_heapcheck[-2] = 'K'; // last letter in heapchecK
+ if (env_ldpreload) env_heapcheck[-2] = 'D'; // last letter in ldpreloaD
+
+ const int kMaxOutputLine = 10000;
+ char line[kMaxOutputLine];
+ while (fgets(line, sizeof(line), f) != NULL) {
+ if (output)
+ *output += line;
+ }
+
+ return pclose(f);
}
-ssize_t HeapLeakChecker::ObjectsLeaked() const {
- if (!has_checked_) {
- HeapProfiler::MESSAGE(-1, "HeapChecker: "
- "*NoLeaks|SameHeap must execute before this call\n");
- abort();
+// RAW_LOG 'str' line by line to prevent its truncation in RAW_LOG:
+static void RawLogLines(const string& str) {
+ int p = 0;
+ while (1) {
+ int l = str.find('\n', p);
+ if (l == string::npos) {
+ if (str[p]) { // print last line if non empty
+ RAW_LOG(INFO, "%s", str.c_str() + p);
+ }
+ break;
+ }
+ const_cast<string&>(str)[l] = '\0'; // safe for our use case
+ RAW_LOG(INFO, "%s", str.c_str() + p);
+ const_cast<string&>(str)[l] = '\n';
+ p = l + 1;
}
- return inuse_allocs_increase_;
}
-bool HeapLeakChecker::DoNoLeaks(bool same_heap,
- bool do_full,
- bool do_report) {
+bool HeapLeakChecker::DoNoLeaks(CheckType check_type,
+ CheckFullness fullness,
+ ReportMode report_mode) {
+ // The locking also helps us keep the messages
+ // for the two checks close together.
+ alignment_checker_lock.Lock();
+ bool result;
+ if (FLAGS_heap_check_test_pointer_alignment) {
+ pointer_alignment = 1;
+ bool result_wo_align = DoNoLeaksOnce(check_type, fullness, NO_REPORT);
+ pointer_alignment = sizeof(void*);
+ result = DoNoLeaksOnce(check_type, fullness, report_mode);
+ if (!result) {
+ if (result_wo_align) {
+ RAW_LOG(WARNING, "Found no leaks without pointer alignment: "
+ "something might be placing pointers at "
+ "unaligned addresses! This needs to be fixed.");
+ } else {
+ RAW_LOG(INFO, "Found leaks without pointer alignment as well: "
+ "unaligned pointers must not be the cause of leaks.");
+ RAW_LOG(INFO, "--heap_check_test_pointer_alignment did not help to "
+ "diagnose the leaks.");
+ }
+ }
+ } else {
+ result = DoNoLeaksOnce(check_type, fullness, report_mode);
+ if (!result) {
+ if (!FLAGS_heap_check_identify_leaks) {
+ RAW_LOG(INFO, "setenv HEAP_CHECK_IDENTIFY_LEAKS=1 and rerun to identify "
+ "the addresses of all leaked objects; "
+ "will be reported as fake immediate allocation callers");
+ }
+ RAW_LOG(INFO, "If you are totally puzzled about why the leaks are there, "
+ "try rerunning it with "
+ "setenv HEAP_CHECK_TEST_POINTER_ALIGNMENT=1");
+ }
+ }
+ alignment_checker_lock.Unlock();
+ return result;
+}
+
+bool HeapLeakChecker::DoNoLeaksOnce(CheckType check_type,
+ CheckFullness fullness,
+ ReportMode report_mode) {
// Heap activity in other threads is paused for this function
// until we got all profile difference info.
- if (pthread_mutex_lock(&heap_checker_lock) != 0) abort();
- HeapProfiler::Lock();
+ heap_checker_lock.Lock();
+ MemoryRegionMap::Lock();
if (heap_checker_on) {
if (name_ == NULL) {
- HeapProfiler::MESSAGE(-1, "HeapChecker: "
- "*NoLeaks|SameHeap must be called only once"
- " and profiling must be not turned on "
- "after construction of a HeapLeakChecker\n");
- abort();
+ RAW_LOG(FATAL, "Heap profiling must be not turned on "
+ "after construction of a HeapLeakChecker");
}
- // get our stack range to make its proper portion live
- StackExtent self_stack;
- self_stack.have = GetStackExtent(NULL, &self_stack.top, &self_stack.bottom);
- DumpProfileLocked(false, self_stack); // end
+ // Use our stack ptr to make stack data live:
+ int a_local_var;
+ size_t end_inuse_bytes;
+ size_t end_inuse_allocs;
+ DumpProfileLocked(END_PROFILE, &a_local_var,
+ &end_inuse_bytes, &end_inuse_allocs);
const bool use_initial_profile =
!(FLAGS_heap_check_before_constructors && this == main_heap_checker);
if (!use_initial_profile) { // compare against empty initial profile
start_inuse_bytes_ = 0;
start_inuse_allocs_ = 0;
}
- int64 end_inuse_bytes = HeapProfiler::profile_.alloc_size_ -
- HeapProfiler::profile_.free_size_;
- int64 end_inuse_allocs = HeapProfiler::profile_.allocs_ -
- HeapProfiler::profile_.frees_;
- if (HeapProfiler::kMaxLogging) {
- HeapProfiler::MESSAGE(1, "HeapChecker: "
- "End check \"%s\" profile: "
- ""LLD" bytes in "LLD" objects\n",
- name_, end_inuse_bytes, end_inuse_allocs);
- }
- inuse_bytes_increase_ = (ssize_t)(end_inuse_bytes - start_inuse_bytes_);
- inuse_allocs_increase_ = (ssize_t)(end_inuse_allocs - start_inuse_allocs_);
+ RAW_VLOG(1, "End check \"%s\" profile: %"PRIuS" bytes in %"PRIuS" objects",
+ name_, end_inuse_bytes, end_inuse_allocs);
+ inuse_bytes_increase_ = static_cast<ssize_t>(end_inuse_bytes -
+ start_inuse_bytes_);
+ inuse_allocs_increase_ = static_cast<ssize_t>(end_inuse_allocs -
+ start_inuse_allocs_);
has_checked_ = true;
- HeapProfiler::Unlock();
- if (pthread_mutex_unlock(&heap_checker_lock) != 0) abort();
+ MemoryRegionMap::Unlock();
+ heap_checker_lock.Unlock();
bool see_leaks =
- (same_heap ? (inuse_bytes_increase_ != 0 || inuse_allocs_increase_ != 0)
- : (inuse_bytes_increase_ > 0 || inuse_allocs_increase_ > 0));
- if (see_leaks || do_full) {
- bool pprof_can_ignore = false;
- const char* command_tail = " --text 2>/dev/null"; // normal command
- const char* gv_command_tail
- = " --edgefraction=1e-10 --nodefraction=1e-10 --gv 2>/dev/null";
- string ignore_re;
- if (disabled_regexp) {
- pprof_can_ignore = true;
- ignore_re += " --ignore='^";
- ignore_re += *disabled_regexp;
- ignore_re += "$'";
- }
- // It would be easier to use a string here than a static buffer, but
- // some STLs can give us spurious leak alerts (since the STL tries to
- // do its own memory pooling), so we avoid it by using STL as little
- // as possible for "big" objects that might require "lots" of memory.
- char base_command[6 * PATH_MAX + 200];
- char beg_profile[PATH_MAX+1], end_profile[PATH_MAX+1];
- if (use_initial_profile) {
- snprintf(beg_profile, sizeof(beg_profile), "%s.%s-beg.heap",
- profile_prefix->c_str(), name_);
- // compare against initial profile only if need to
- const char* drop_negative = same_heap ? "" : " --drop_negative";
- snprintf(base_command, sizeof(base_command),
- "%s --base=\"%s\" %s ",
- pprof_path(), beg_profile, drop_negative);
- } else {
- beg_profile[0] = '\0';
- snprintf(base_command, sizeof(base_command), "%s",
- pprof_path());
- }
- snprintf(end_profile, sizeof(end_profile), "%s.%s-end.heap",
- profile_prefix->c_str(), name_);
- snprintf(base_command + strlen(base_command),
- sizeof(base_command) - strlen(base_command),
- " %s \"%s\" %s --inuse_objects --lines",
- invocation_path(), end_profile, ignore_re.c_str());
- // --lines is important here to catch leaks when !see_leaks
-
- char cwd[PATH_MAX+1];
- if (getcwd(cwd, sizeof(cwd)) != cwd) abort();
+ check_type == SAME_HEAP
+ ? (inuse_bytes_increase_ != 0 || inuse_allocs_increase_ != 0)
+ : (inuse_bytes_increase_ > 0 || inuse_allocs_increase_ > 0);
+ if (see_leaks || fullness == USE_PPROF) {
+ const bool pprof_can_ignore = disabled_regexp != NULL;
+ string beg_profile;
+ string end_profile;
+ string base_command;
+ MakeCommand(name_, check_type == NO_LEAKS,
+ use_initial_profile, *profile_prefix,
+ &beg_profile, &end_profile, &base_command);
+ // Make the two command lines out of the base command, with
+ // appropriate mode options
+ string command = base_command + " --text";
+ string gv_command;
+ gv_command = base_command;
+ gv_command +=
+ " --edgefraction=1e-10 --nodefraction=1e-10 --heapcheck --gv";
+
if (see_leaks) {
- HeapProfiler::MESSAGE(-1, "HeapChecker: "
- "Heap memory leaks of "LLD" bytes and/or "
- ""LLD" allocations detected by check \"%s\".\n\n",
- (int64)inuse_bytes_increase_,
- (int64)inuse_allocs_increase_,
- name_);
- HeapProfiler::MESSAGE(-1, "HeapChecker: "
- "To investigate leaks manually use e.g.\n"
- "cd %s; " // for proper symbol resolution
- "%s%s\n\n",
- cwd, base_command, gv_command_tail);
+ RAW_LOG(ERROR, "Heap memory leaks of %"PRIdS" bytes and/or "
+ "%"PRIdS" allocations detected by check \"%s\".",
+ inuse_bytes_increase_, inuse_allocs_increase_, name_);
+ RAW_LOG(ERROR, "TO INVESTIGATE leaks RUN e.g. THIS shell command:\n"
+ "\n%s\n", gv_command.c_str());
}
string output;
- int checked_leaks = 0;
- if ((see_leaks && do_report) || do_full) {
- if (access(pprof_path(), X_OK|R_OK) != 0) {
- HeapProfiler::MESSAGE(-1, "HeapChecker: "
- "WARNING: Skipping pprof check:"
- " could not run it at %s\n",
- pprof_path());
+ bool checked_leaks = true;
+ if ((see_leaks && report_mode == PPROF_REPORT) ||
+ fullness == USE_PPROF) {
+ if (access(flags_heap_profile_pprof->c_str(), X_OK|R_OK) != 0) {
+ RAW_LOG(WARNING, "Skipping pprof check: could not run it at %s",
+ flags_heap_profile_pprof->c_str());
+ checked_leaks = false;
} else {
// We don't care about pprof's stderr as long as it
// succeeds with empty report:
- char full_command[6 * PATH_MAX + 200]; // needed to concatenate
- snprintf(full_command, sizeof(full_command), "%s%s",
- base_command, command_tail);
- checked_leaks = GetStatusOutput(full_command, &output);
- if (checked_leaks != 0) {
- HeapProfiler::MESSAGE(-1, "ERROR: Could not run pprof at %s\n",
- pprof_path());
- abort();
- }
+ checked_leaks = GetStatusOutput((command + " 2>/dev/null").c_str(),
+ &output) == 0;
}
- if (see_leaks && pprof_can_ignore &&
- output.empty() && checked_leaks == 0) {
- HeapProfiler::MESSAGE(-1, "HeapChecker: "
- "These must be leaks that we disabled"
- " (pprof succeeded)! This check WILL FAIL"
- " if the binary is strip'ped!\n");
+ if (see_leaks && pprof_can_ignore && output.empty() && checked_leaks) {
+ RAW_LOG(WARNING, "These must be leaks that we disabled"
+ " (pprof succeeded)! This check WILL FAIL"
+ " if the binary is strip'ped!");
see_leaks = false;
}
// do not fail the check just due to us being a stripped binary
if (!see_leaks && strstr(output.c_str(), "nm: ") != NULL &&
- strstr(output.c_str(), ": no symbols") != NULL) output.resize(0);
+ strstr(output.c_str(), ": no symbols") != NULL) output.clear();
}
// Make sure the profiles we created are still there.
// They can get deleted e.g. if the program forks/executes itself
// and FLAGS_cleanup_old_heap_profiles was kept as true.
- if (access(end_profile, R_OK) != 0 ||
- (beg_profile[0] && access(beg_profile, R_OK) != 0)) {
- HeapProfiler::MESSAGE(-1, "HeapChecker: "
- "One of the heap profiles is gone: %s %s\n",
- beg_profile, end_profile);
- abort();
+ if (access(end_profile.c_str(), R_OK) != 0 ||
+ (!beg_profile.empty() && access(beg_profile.c_str(), R_OK) != 0)) {
+ RAW_LOG(FATAL, "One of the heap profiles is gone: %s %s",
+ beg_profile.c_str(), end_profile.c_str());
}
- if (!(see_leaks || checked_leaks == 0)) {
+ if (!(see_leaks || checked_leaks)) {
// Crash if something went wrong with executing pprof
// and we rely on pprof to do its work:
- HeapProfiler::MESSAGE(-1, "HeapChecker: "
- "pprof command failed: %s%s\n",
- base_command, command_tail);
- abort();
+ RAW_LOG(FATAL, "The pprof command failed: %s", command.c_str());
}
if (see_leaks && use_initial_profile) {
- HeapProfiler::MESSAGE(-1, "HeapChecker: "
- "CAVEAT: Some of the reported leaks might have "
- "occurred before check \"%s\" was started!\n",
- name_);
+ RAW_LOG(WARNING, "CAVEAT: Some of the reported leaks might have "
+ "occurred before check \"%s\" was started!", name_);
}
bool tricky_leaks = !output.empty();
- if (!see_leaks && tricky_leaks) {
- HeapProfiler::MESSAGE(-1, "HeapChecker: "
- "Tricky heap memory leaks of"
- " no bytes and no allocations "
- "detected by check \"%s\".\n", name_);
- HeapProfiler::MESSAGE(-1, "HeapChecker: "
- "To investigate leaks manually uge e.g.\n"
- "cd %s; " // for proper symbol resolution
- "%s%s\n\n",
- name_, cwd, base_command, gv_command_tail);
+ if (!see_leaks && tricky_leaks) {
+ RAW_LOG(WARNING, "Tricky heap memory leaks of"
+ " no bytes and no allocations "
+ "detected by check \"%s\".", name_);
+ RAW_LOG(WARNING, "TO INVESTIGATE leaks RUN e.g. THIS shell command:\n"
+ "\n%s\n", gv_command.c_str());
if (use_initial_profile) {
- HeapProfiler::MESSAGE(-1, "HeapChecker: "
- "CAVEAT: Some of the reported leaks might have "
- "occurred before check \"%s\" was started!\n",
- name_);
+ RAW_LOG(WARNING, "CAVEAT: Some of the reported leaks might have "
+ "occurred before check \"%s\" was started!", name_);
}
see_leaks = true;
}
- if (see_leaks && do_report) {
- if (checked_leaks == 0) {
- HeapProfiler::MESSAGE(-1, "HeapChecker: "
- "Below is this pprof's output:\n\n");
- write(STDERR_FILENO, output.data(), output.size());
- HeapProfiler::MESSAGE(-1, "\n\n");
+ if (see_leaks && report_mode == PPROF_REPORT) {
+ if (checked_leaks) {
+ RAW_LOG(INFO, "Below is (less informative) textual version "
+ "of this pprof command's output:");
+ RawLogLines(output);
} else {
- HeapProfiler::MESSAGE(-1, "HeapChecker: "
- "pprof has failed\n\n");
+ RAW_LOG(ERROR, "The pprof command has failed");
}
}
} else {
- HeapProfiler::MESSAGE(0, "HeapChecker: No leaks found\n");
+ RAW_VLOG(0, "No leaks found for check \"%s\" "
+ "(but no 100%% guarantee that there aren't any)", name_);
}
- UnIgnoreObject(name_);
- delete [] name_;
- name_ = NULL;
return !see_leaks;
} else {
if (name_ != NULL) {
- HeapProfiler::MESSAGE(-1, "HeapChecker: "
- "Profiling must stay enabled "
- "during leak checking\n");
- abort();
+ RAW_LOG(FATAL, "Profiling must stay enabled during leak checking");
}
- HeapProfiler::Unlock();
- if (pthread_mutex_unlock(&heap_checker_lock) != 0) abort();
+ MemoryRegionMap::Unlock();
+ heap_checker_lock.Unlock();
return true;
}
}
HeapLeakChecker::~HeapLeakChecker() {
- if (name_ != NULL) {
- HeapProfiler::MESSAGE(-1, "HeapChecker: "
- "Some *NoLeaks|SameHeap method"
- " must be called on the checker\n");
- abort();
+ if (name_ != NULL) { // had leak checking enabled when created the checker
+ if (!has_checked_) {
+ RAW_LOG(FATAL, "Some *NoLeaks|SameHeap method"
+ " must be called on any created checker");
+ }
+ UnIgnoreObject(name_);
+ delete[] name_;
+ name_ = NULL;
}
}
@@ -1596,145 +1661,202 @@ void HeapLeakChecker::RunHeapCleanups() {
if (heap_checker_pid == getpid()) { // can get here (via forks?)
// with other pids
HeapCleaner::RunHeapCleanups();
- if (!FLAGS_heap_check_after_destructors) {
+ if (!FLAGS_heap_check_after_destructors && do_main_heap_check) {
DoMainHeapCheck();
}
}
}
-// Called from main() immediately after setting any requisite parameters
-// from HeapChecker and HeapProfiler.
-void HeapLeakChecker::InternalInitStart(const string& heap_check_type) {
- if (heap_check_type.empty()) {
- heap_checker_on = false;
- } else {
- if (main_heap_checker) {
- // means this method was called twice. We'll just ignore the 2nd call
- return;
- }
- if (!constructor_heap_profiling) {
- HeapProfiler::MESSAGE(-1, "HeapChecker: Can not start so late. "
- "You have to enable heap checking by\n"
- "setting the environment variable HEAPCHECK.\n");
- abort();
- }
- // Set all flags
- if (heap_check_type == "minimal") {
- // The least we can check.
- FLAGS_heap_check_before_constructors = false; // (ignore more)
- FLAGS_heap_check_after_destructors = false; // to after cleanup
- // (most data is live)
- FLAGS_heap_check_strict_check = false; // < profile check (ignore more)
- FLAGS_heap_check_ignore_thread_live = true; // ignore all live
- FLAGS_heap_check_ignore_global_live = true; // ignore all live
- } else if (heap_check_type == "normal") {
- // Faster than 'minimal' and not much stricter.
- FLAGS_heap_check_before_constructors = true; // from no profile (fast)
- FLAGS_heap_check_after_destructors = false; // to after cleanup
- // (most data is live)
- FLAGS_heap_check_strict_check = true; // == profile check (fast)
- FLAGS_heap_check_ignore_thread_live = true; // ignore all live
- FLAGS_heap_check_ignore_global_live = true; // ignore all live
- } else if (heap_check_type == "strict") {
- // A bit stricter than 'normal': global destructors must fully clean up
- // after themselves if they are present.
- FLAGS_heap_check_before_constructors = true; // from no profile (fast)
- FLAGS_heap_check_after_destructors = true; // to after destructors
- // (less data live)
- FLAGS_heap_check_strict_check = true; // == profile check (fast)
- FLAGS_heap_check_ignore_thread_live = true; // ignore all live
- FLAGS_heap_check_ignore_global_live = true; // ignore all live
- } else if (heap_check_type == "draconian") {
- // Drop not very portable and not very exact live heap flooding.
- FLAGS_heap_check_before_constructors = true; // from no profile (fast)
- FLAGS_heap_check_after_destructors = true; // to after destructors
- // (need them)
- FLAGS_heap_check_strict_check = true; // == profile check (fast)
- FLAGS_heap_check_ignore_thread_live = false; // no live flood (stricter)
- FLAGS_heap_check_ignore_global_live = false; // no live flood (stricter)
- } else if (heap_check_type == "as-is") {
- // do nothing: use other flags as is
- } else if (heap_check_type == "local") {
- // do nothing
- } else {
- LogPrintf(FATAL, "Unsupported heap_check flag: %s",
- heap_check_type.c_str());
- }
- assert(heap_checker_pid == getpid());
- heap_checker_on = true;
- if (!HeapProfiler::is_on_) abort();
- ProcMapsResult pm_result = UseProcMaps(DISABLE_LIBRARY_ALLOCS);
- // might neeed to do this more than once
- // if one later dynamically loads libraries that we want disabled
- if (pm_result != HeapLeakChecker::PROC_MAPS_USED) {
- heap_checker_on = false;
- HeapProfiler::MESSAGE(0, "HeapChecker: Turning itself off\n");
- HeapProfiler::StopForLeaks();
+// defined below
+static int GetCommandLineFrom(const char* file, char* cmdline, int size);
+
+static bool internal_init_start_has_run = false;
+
+// Called exactly once, before main() (but hopefully just before).
+// This picks a good unique name for the dumped leak checking heap profiles.
+void HeapLeakChecker::InternalInitStart() {
+ RAW_CHECK(!internal_init_start_has_run, "Only one call is expected");
+ internal_init_start_has_run = true;
+
+ if (FLAGS_heap_check.empty()) {
+ // turns out we do not need checking in the end; can stop profiling
+ TurnItselfOff();
+ return;
+ }
+
+ // Changing this to false can be useful when debugging heap-checker itself:
+ const bool turn_off_under_gdb = true;
+ if (turn_off_under_gdb) {
+ // See if heap checker should turn itself off because we are
+ // running under gdb (to avoid conflicts over ptrace-ing rights):
+ char name_buf[15+15];
+ snprintf(name_buf, sizeof(name_buf), "/proc/%d/cmdline", int(getppid()));
+ char cmdline[1024*8];
+ int size = GetCommandLineFrom(name_buf, cmdline, sizeof(cmdline)-1);
+ cmdline[size] = '\0';
+ // look for "gdb" in the executable's name:
+ const char* last = strrchr(cmdline, '/');
+ if (last) last += 1;
+ else last = cmdline;
+ if (strncmp(last, "gdb", 3) == 0) {
+ RAW_LOG(WARNING, "We seem to be running under gdb; will turn itself off");
+ TurnItselfOff();
return;
}
+ }
- // make a good place and name for heap profile leak dumps
- profile_prefix = new string(dump_directory());
- *profile_prefix += "/";
- *profile_prefix += invocation_name();
- HeapProfiler::CleanupProfiles(profile_prefix->c_str());
-
- // Finalize prefix for dumping leak checking profiles.
- char pid_buf[15];
- if (main_thread_pid_ == 0) // possible if we're called before constructors
- main_thread_pid_ = getpid();
- snprintf(pid_buf, sizeof(pid_buf), ".%d", main_thread_pid_);
- *profile_prefix += pid_buf;
- assert(HeapProfiler::need_for_leaks_);
-
- // Make sure new/delete hooks are installed properly
- // and heap profiler is indeed able to keep track
- // of the objects being allocated.
- // We test this to make sure we are indeed checking for leaks.
- HeapProfiler::AllocValue alloc_value;
- char* test_str = new char[5];
- void* ptr = test_str;
- if (!HeapProfiler::HaveOnHeap(&ptr, &alloc_value)) abort();
- ptr = test_str;
- delete [] test_str;
- if (HeapProfiler::HaveOnHeap(&ptr, &alloc_value)) abort();
- // If we crash in the above code, it probably means that
- // "nm <this_binary> | grep new" will show that tcmalloc's new/delete
- // implementation did not get linked-in into this binary
- // (i.e. nm will list __builtin_new and __builtin_vec_new as undefined).
- // This is probably impossible.
-
- if (heap_check_type != "local") {
- // Schedule registered heap cleanup
- atexit(RunHeapCleanups);
- assert(main_heap_checker == NULL);
- main_heap_checker = new HeapLeakChecker();
- }
+ if (!constructor_heap_profiling) {
+ RAW_LOG(FATAL, "Can not start so late. You have to enable heap checking "
+ "with HEAPCHECK=<mode>.");
+ }
+
+ // make an indestructible copy for heap leak checking
+ // happening after global variable destruction
+ flags_heap_profile_pprof = new string(FLAGS_heap_profile_pprof);
+
+ // Set all flags
+ if (FLAGS_heap_check == "minimal") {
+ // The least we can check.
+ FLAGS_heap_check_before_constructors = false; // from after main
+ // (ignore more)
+ FLAGS_heap_check_after_destructors = false; // to after cleanup
+ // (most data is live)
+ FLAGS_heap_check_strict_check = false; // < profile check (ignore more)
+ FLAGS_heap_check_ignore_thread_live = true; // ignore all live
+ FLAGS_heap_check_ignore_global_live = true; // ignore all live
+ } else if (FLAGS_heap_check == "normal") {
+ // Faster than 'minimal' and not much stricter.
+ FLAGS_heap_check_before_constructors = true; // from no profile (fast)
+ FLAGS_heap_check_after_destructors = false; // to after cleanup
+ // (most data is live)
+ FLAGS_heap_check_strict_check = true; // == profile check (fast)
+ FLAGS_heap_check_ignore_thread_live = true; // ignore all live
+ FLAGS_heap_check_ignore_global_live = true; // ignore all live
+ } else if (FLAGS_heap_check == "strict") {
+ // A bit stricter than 'normal': global destructors must fully clean up
+ // after themselves if they are present.
+ FLAGS_heap_check_before_constructors = true; // from no profile (fast)
+ FLAGS_heap_check_after_destructors = true; // to after destructors
+ // (less data live)
+ FLAGS_heap_check_strict_check = true; // == profile check (fast)
+ FLAGS_heap_check_ignore_thread_live = true; // ignore all live
+ FLAGS_heap_check_ignore_global_live = true; // ignore all live
+ } else if (FLAGS_heap_check == "draconian") {
+ // Drop not very portable and not very exact live heap flooding.
+ FLAGS_heap_check_before_constructors = true; // from no profile (fast)
+ FLAGS_heap_check_after_destructors = true; // to after destructors
+ // (need them)
+ FLAGS_heap_check_strict_check = true; // == profile check (fast)
+ FLAGS_heap_check_ignore_thread_live = false; // no live flood (stricter)
+ FLAGS_heap_check_ignore_global_live = false; // no live flood (stricter)
+ } else if (FLAGS_heap_check == "as-is") {
+ // do nothing: use other flags as is
+ } else if (FLAGS_heap_check == "local") {
+ // do nothing
+ } else {
+ RAW_LOG(FATAL, "Unsupported heap_check flag: %s",
+ FLAGS_heap_check.c_str());
+ }
+ RAW_DCHECK(heap_checker_pid == getpid(), "");
+ heap_checker_on = true;
+ RAW_DCHECK(heap_profile, "");
+ heap_checker_lock.Lock();
+ ProcMapsResult pm_result = UseProcMapsLocked(DISABLE_LIBRARY_ALLOCS);
+ // might neeed to do this more than once
+ // if one later dynamically loads libraries that we want disabled
+ heap_checker_lock.Unlock();
+ if (pm_result != PROC_MAPS_USED) { // can't function
+ TurnItselfOff();
+ return;
}
- if (!heap_checker_on && constructor_heap_profiling) {
- // turns out do not need checking in the end; can stop profiling
- HeapProfiler::MESSAGE(0, "HeapChecker: Turning itself off\n");
- HeapProfiler::StopForLeaks();
+
+ // make a good place and name for heap profile leak dumps
+ profile_prefix = new string(FLAGS_heap_check_dump_directory);
+ *profile_prefix += "/";
+ *profile_prefix += invocation_name();
+ HeapProfileTable::CleanupOldProfiles(profile_prefix->c_str());
+
+ // Finalize prefix for dumping leak checking profiles.
+ char pid_buf[15];
+ if (main_thread_pid == 0) // possible if we're called before constructors
+ main_thread_pid = getpid();
+ snprintf(pid_buf, sizeof(pid_buf), ".%d", main_thread_pid);
+ *profile_prefix += pid_buf;
+
+ // Make sure new/delete hooks are installed properly
+ // and heap profiler is indeed able to keep track
+ // of the objects being allocated.
+ // We test this to make sure we are indeed checking for leaks.
+ char* test_str = new char[5];
+ size_t size;
+ RAW_CHECK(heap_profile->FindAlloc(test_str, &size),
+ "our own new/delete not linked?");
+ delete[] test_str;
+ RAW_CHECK(!heap_profile->FindAlloc(test_str, &size),
+ "our own new/delete not linked?");
+ // If we crash in the above code, it probably means that
+ // "nm <this_binary> | grep new" will show that tcmalloc's new/delete
+ // implementation did not get linked-in into this binary
+ // (i.e. nm will list __builtin_new and __builtin_vec_new as undefined).
+ // If this happens, it is a BUILD bug to be fixed.
+
+ if (FLAGS_heap_check != "local") {
+ // Schedule registered heap cleanup
+ atexit(RunHeapCleanups);
+ RAW_DCHECK(main_heap_checker == NULL,
+ "Repeated creation of main_heap_checker");
+ main_heap_checker = new HeapLeakChecker();
+ do_main_heap_check = true;
}
+
+ RAW_CHECK(heap_checker_on && constructor_heap_profiling,
+ "Leak checking is expected to be fully turned on now");
}
+// We want this to run early as well, but not so early as
+// ::BeforeConstructors (we want flag assignments to have already
+// happened, for instance). Initializer-registration does the trick.
+REGISTER_MODULE_INITIALIZER(init_start, HeapLeakChecker::InternalInitStart());
+
void HeapLeakChecker::DoMainHeapCheck() {
- assert(heap_checker_pid == getpid());
- if (main_heap_checker) {
- bool same_heap = FLAGS_heap_check_strict_check;
- if (FLAGS_heap_check_before_constructors) same_heap = true;
- // false here just would make it slower in this case
- // (we don't use the starting profile anyway)
- bool do_full = !same_heap; // do it if it can help ignore false leaks
- bool do_report = FLAGS_heap_check_report;
- HeapProfiler::MESSAGE(0, "HeapChecker: "
- "Checking for whole-program memory leaks\n");
- if (!main_heap_checker->DoNoLeaks(same_heap, do_full, do_report)) {
- HeapProfiler::MESSAGE(-1, "HeapChecker: crashing because of leaks\n");
- abort();
+ RAW_DCHECK(heap_checker_pid == getpid() && do_main_heap_check, "");
+ if (!NoGlobalLeaks()) {
+ if (FLAGS_heap_check_identify_leaks) {
+ RAW_LOG(FATAL, "Whole-program memory leaks found.");
}
- delete main_heap_checker;
- main_heap_checker = NULL;
+ RAW_LOG(ERROR, "Exiting with error code (instead of crashing) "
+ "because of whole-program memory leaks");
+ _exit(1); // we don't want to call atexit() routines!
+ }
+ do_main_heap_check = false; // just did it
+}
+
+HeapLeakChecker* HeapLeakChecker::GlobalChecker() {
+ return main_heap_checker;
+}
+
+bool HeapLeakChecker::NoGlobalLeaks() {
+ bool result = true;
+ HeapLeakChecker* main_hc = main_heap_checker;
+ if (main_hc) {
+ CheckType check_type = FLAGS_heap_check_strict_check ? SAME_HEAP : NO_LEAKS;
+ if (FLAGS_heap_check_before_constructors) check_type = SAME_HEAP;
+ // NO_LEAKS here just would make it slower in this case
+ // (we don't use the starting profile anyway)
+ CheckFullness fullness = check_type == NO_LEAKS ? USE_PPROF : USE_COUNTS;
+ // use pprof if it can help ignore false leaks
+ ReportMode report_mode = FLAGS_heap_check_report ? PPROF_REPORT : NO_REPORT;
+ RAW_VLOG(0, "Checking for whole-program memory leaks");
+ result = main_hc->DoNoLeaks(check_type, fullness, report_mode);
+ }
+ return result;
+}
+
+void HeapLeakChecker::CancelGlobalCheck() {
+ if (do_main_heap_check) {
+ RAW_VLOG(0, "Canceling the automatic at-exit "
+ "whole-program memory leak check");
+ do_main_heap_check = false;
}
}
@@ -1742,94 +1864,208 @@ void HeapLeakChecker::DoMainHeapCheck() {
// HeapLeakChecker global constructor/destructor ordering components
//----------------------------------------------------------------------
-// This is a workaround for nptl threads library in glibc
-// (that is e.g. commonly used for 2.6 linux kernel-based distributons).
-// nptl has an optimization for allocating thread-specific data,
-// that we have to work around here:
-// It preallocates (as specific_1stblock) the first second-level block
-// of PTHREAD_KEY_2NDLEVEL_SIZE pointers to thread-specific data
-// inside of the thread descriptor data structure itself.
-// Since we sometimes can't proclaim this first block as live data,
-// the workaround here simply uses up that block
-// (by allocating a bunch of pthread-specific keys and forgeting about them)
-// as to force allocation of new second-level thread-specific data pointer
-// blocks, which would be know to heap profiler/checker for sure
-// since it's active by now.
-static inline void PThreadSpecificHack() {
- // the value 32 corresponds to PTHREAD_KEY_2NDLEVEL_SIZE
- // in glibc's pthread implementation
- const int kKeyBlock = 32;
- for (int i = 0; i < kKeyBlock; ++i) {
- pthread_key_t key;
- if (perftools_pthread_key_create(&key, NULL) != 0) abort();
- }
+static bool in_initial_malloc_hook = false;
+
+#if (defined(__GNUC__) && __GNUC__ >= 3) \
+ && (defined(__i386__) || defined(__x86_64__)) \
+ && (!defined(SWIG))
+
+void HeapLeakChecker_BeforeConstructors(); // below
+
+// Helper for InitialMallocHook_* below
+static inline void InitHeapLeakCheckerFromMallocHook() {
+ RAW_CHECK(!in_initial_malloc_hook,
+ "Something did not reset initial MallocHook-s");
+ in_initial_malloc_hook = true;
+ // Initialize heap checker on the very first allocation/mmap/sbrk call:
+ HeapLeakChecker_BeforeConstructors();
+ in_initial_malloc_hook = false;
}
-void HeapLeakChecker::BeforeConstructors() {
- // The user indicates a desire for heap-checking via the HEAPCHECK
- // environment variable. If it's not set, there's no way to do
- // heap-checking.
- if (!getenv("HEAPCHECK")) {
- return;
- }
+// These will owerwrite the weak definitions in malloc_hook.cc:
- // heap-checker writes out files. Thus, for security reasons, we don't
- // recognize the env. var. to turn on heap-checking if we're setuid.
- if (getuid() != geteuid()) {
- HeapProfiler::MESSAGE(0, ("HeapChecker: ignoring HEAPCHECK because "
- "program seems to be setuid\n"));
- return;
- }
+// Important to have this to catch the first allocation call from the binary:
+extern void InitialMallocHook_New(void* ptr, size_t size) {
+ InitHeapLeakCheckerFromMallocHook();
+ // record this first allocation as well (if we need to):
+ MallocHook::InvokeNewHook(ptr, size);
+}
+
+// Important to have this to catch the first mmap call (say from tcmalloc):
+extern void InitialMallocHook_MMap(void* result,
+ void* start,
+ size_t size,
+ int protection,
+ int flags,
+ int fd,
+ off_t offset) {
+ InitHeapLeakCheckerFromMallocHook();
+ // record this first mmap as well (if we need to):
+ MallocHook::InvokeMmapHook(
+ result, start, size, protection, flags, fd, offset);
+}
+
+// Important to have this to catch the first sbrk call (say from tcmalloc):
+extern void InitialMallocHook_Sbrk(void* result, ptrdiff_t increment) {
+ InitHeapLeakCheckerFromMallocHook();
+ // record this first sbrk as well (if we need to):
+ MallocHook::InvokeSbrkHook(result, increment);
+}
- if (constructor_heap_profiling) abort();
+#endif
+
+// Optional silencing, it must be called shortly after leak checker activates
+// in HeapLeakChecker::BeforeConstructors not to let logging messages through,
+// but it can't be called when BeforeConstructors() is called from within
+// the first mmap/sbrk/alloc call (something deadlocks in this case).
+// Hence we arrange for this to be called from the first global c-tor
+// that calls HeapLeakChecker_BeforeConstructors.
+static void HeapLeakChecker_MaybeMakeSilent() {
+#if 0 // TODO(csilvers): see if we can get something like this to work
+ if (!VLOG_IS_ON(1)) // not on a verbose setting
+ FLAGS_verbose = WARNING; // only log WARNING and ERROR and FATAL
+#endif
+}
+
+void HeapLeakChecker::BeforeConstructors() {
+ RAW_CHECK(!constructor_heap_profiling,
+ "BeforeConstructors called multiple times");
+ // set hooks early to crash if 'new' gets called before we make heap_profile:
+ MallocHook::SetNewHook(NewHook);
+ MallocHook::SetDeleteHook(DeleteHook);
constructor_heap_profiling = true;
- HeapProfiler::Init(); // only necessary if our constructor runs before theirs
- // If the user has HEAPPROFILE set, Init() will have turned on profiling.
- // If not, we need to do it manually here.
- HeapProfiler::StartForLeaks();
+ MemoryRegionMap::Init(); // set up MemoryRegionMap
+ // (important that it's done before HeapProfileTable creation below)
+ Allocator::Init();
+ RAW_CHECK(heap_profile == NULL, "");
+ heap_checker_lock.Lock(); // Allocator expects it
+ heap_profile = new (Allocator::Allocate(sizeof(HeapProfileTable)))
+ HeapProfileTable(&Allocator::Allocate, &Allocator::Free);
+ heap_checker_lock.Unlock();
+ RAW_VLOG(0, "Starting tracking the heap");
heap_checker_on = true;
- PThreadSpecificHack();
-
-
- // The value of HEAPCHECK is the mode they want. If we don't
- // recognize it, we default to "normal".
- const char* heap_check_type = getenv("HEAPCHECK");
- assert(heap_check_type); // we checked that in the if above
- if ( heap_check_type[0] == '\0') {
- // don't turn on heap checking for missing or empty env. var.
- } else if ( !strcmp(heap_check_type, "minimal") ||
- !strcmp(heap_check_type, "normal") ||
- !strcmp(heap_check_type, "strict") ||
- !strcmp(heap_check_type, "draconian") ||
- !strcmp(heap_check_type, "local") ) {
- HeapLeakChecker::InternalInitStart(heap_check_type);
- } else {
- HeapLeakChecker::InternalInitStart("normal"); // the default
+ // Run silencing if we are called from the first global c-tor,
+ // not from the first mmap/sbrk/alloc call:
+ if (!in_initial_malloc_hook) HeapLeakChecker_MaybeMakeSilent();
+}
+
+void HeapLeakChecker::TurnItselfOff() {
+ FLAGS_heap_check = ""; // for users who test for it
+ if (constructor_heap_profiling) {
+ RAW_CHECK(heap_checker_on, "");
+ RAW_LOG(INFO, "Turning heap leak checking off");
+ heap_checker_on = false;
+ MallocHook::SetNewHook(NULL);
+ MallocHook::SetDeleteHook(NULL);
+ heap_checker_lock.Lock(); // Allocator expects it
+ Allocator::DeleteAndNull(&heap_profile);
+ // free our optional global data:
+ Allocator::DeleteAndNullIfNot(&disabled_regexp);
+ Allocator::DeleteAndNullIfNot(&ignored_objects);
+ Allocator::DeleteAndNullIfNot(&disabled_addresses);
+ Allocator::DeleteAndNullIfNot(&disabled_ranges);
+ Allocator::DeleteAndNullIfNot(&global_region_caller_ranges);
+ heap_checker_lock.Unlock();
+ Allocator::Shutdown();
+ MemoryRegionMap::Shutdown();
+ }
+ RAW_CHECK(!heap_checker_on, "");
+}
+
+// Read in the command line from 'file' into 'cmdline' and return the size read
+// 'size' is the space available in 'cmdline'
+// We need this because we don't yet have argv/argc.
+// CAVEAT: 'file' (some /proc/*/cmdline) might contain
+// the command line truncated.
+// Arguments in cmdline will be '\0'-terminated,
+// the first one will be the binary's name.
+static int GetCommandLineFrom(const char* file, char* cmdline, int size) {
+ // This function is called before memory allocation hooks are set up
+ // so we must not have any memory allocations in it. We use syscall
+ // versions of open/read/close here because we don't trust the non-syscall
+ // versions: they might 'accidentally' cause a memory allocation.
+ // Here's a real-life problem scenario we had:
+ // 1) A program LD_PRELOADed a library called list_file_used.a
+ // 2) list_file_used intercepted open/read/close and called dlsym()
+ // 3) dlsym() called pthread_setspecific() which called malloc().
+ // This malloced memory is 'hidden' from the heap-checker. By
+ // definition, this thread-local data is live, and everything it points
+ // to is live (not a memory leak) as well. But because this memory
+ // was hidden from the heap-checker, everything it points to was
+ // taken to be orphaned, and therefore, a memory leak.
+ int fd = syscall(SYS_open, file, O_RDONLY);
+ int result = 0;
+ if (fd >= 0) {
+ ssize_t r;
+ while ((r = syscall(SYS_read, fd, cmdline + result, size)) > 0) {
+ result += r;
+ size -= r;
+ }
+ syscall(SYS_close, fd);
}
+ return result;
}
extern bool heap_leak_checker_bcad_variable; // in heap-checker-bcad.cc
-// Whenever the heap checker library is linked in, this should be called before
-// all global object constructors run. This can be tricky and depends on
-// heap-checker-bcad.o being the last file linked in.
+static bool has_called_BeforeConstructors = false;
+
void HeapLeakChecker_BeforeConstructors() {
+ // We can be called from several places: the first mmap/sbrk/alloc call
+ // or the first global c-tor from heap-checker-bcad.cc:
+ if (has_called_BeforeConstructors) {
+ // Make sure silencing is done when we are called from first global c-tor:
+ if (heap_checker_on) HeapLeakChecker_MaybeMakeSilent();
+ return; // do not re-execure initialization
+ }
+ has_called_BeforeConstructors = true;
+
heap_checker_pid = getpid(); // set it always
- // just to reference it, so that heap-checker-bcad.o is linked in
heap_leak_checker_bcad_variable = true;
- HeapLeakChecker::BeforeConstructors();
+ // just to reference it, so that heap-checker-bcad.o is linked in
+
+ // This function can be called *very* early, before the normal
+ // global-constructor that sets FLAGS_verbose. Set it manually now,
+ // so the RAW_LOG messages here are controllable.
+ const char* verbose_str = GetenvBeforeMain("PERFTOOLS_VERBOSE");
+ if (verbose_str && atoi(verbose_str)) { // different than the default of 0?
+ FLAGS_verbose = atoi(verbose_str);
+ }
+
+ bool need_heap_check = true;
+ // The user indicates a desire for heap-checking via the HEAPCHECK
+ // environment variable. If it's not set, there's no way to do
+ // heap-checking.
+ if (!GetenvBeforeMain("HEAPCHECK")) {
+ need_heap_check = false;
+ } else if (getuid() != geteuid()) {
+ // heap-checker writes out files. Thus, for security reasons, we don't
+ // recognize the env. var. to turn on heap-checking if we're setuid.
+ RAW_LOG(WARNING, ("HeapChecker: ignoring HEAPCHECK because "
+ "program seems to be setuid\n"));
+ need_heap_check = false;
+ }
+ if (need_heap_check) {
+ HeapLeakChecker::BeforeConstructors();
+ } else { // cancel our initial hooks
+ MallocHook::SetNewHook(NULL);
+ MallocHook::SetMmapHook(NULL);
+ MallocHook::SetSbrkHook(NULL);
+ }
}
// This function is executed after all global object destructors run.
void HeapLeakChecker_AfterDestructors() {
if (heap_checker_pid == getpid()) { // can get here (via forks?)
// with other pids
- if (FLAGS_heap_check_after_destructors && main_heap_checker) {
+ if (FLAGS_heap_check_after_destructors && do_main_heap_check) {
HeapLeakChecker::DoMainHeapCheck();
poll(NULL, 0, 500);
- // Need this hack to wait for other pthreads to exit.
- // Otherwise tcmalloc finds errors on a free() call from pthreads.
+ // Need this hack to wait for other pthreads to exit.
+ // Otherwise tcmalloc find errors
+ // on a free() call from pthreads.
}
+ RAW_CHECK(!do_main_heap_check, "should have done it");
}
}
@@ -1842,26 +2078,22 @@ void HeapLeakChecker_AfterDestructors() {
void HeapLeakChecker::DisableChecksInLocked(const char* pattern) {
// make disabled_regexp
if (disabled_regexp == NULL) {
- disabled_regexp = new string;
- IgnoreObjectLocked(disabled_regexp);
- // in case we are not ignoring global data
+ disabled_regexp = new (Allocator::Allocate(sizeof(HCL_string))) HCL_string;
}
- HeapProfiler::MESSAGE(1, "HeapChecker: "
- "Disabling leaks checking in stack traces "
- "under frames maching \"%s\"\n", pattern);
+ RAW_VLOG(1, "Disabling leak checking in stack traces "
+ "under frames maching \"%s\"", pattern);
if (disabled_regexp->size()) *disabled_regexp += '|';
*disabled_regexp += pattern;
}
-void HeapLeakChecker::DisableChecksFromTo(void* start_address,
- void* end_address,
- int max_depth) {
- assert(start_address < end_address);
- if (pthread_mutex_lock(&heap_checker_lock) != 0) abort();
+void HeapLeakChecker::DisableChecksFromToLocked(void* start_address,
+ void* end_address,
+ int max_depth) {
+ RAW_DCHECK(heap_checker_lock.IsHeld(), "");
+ RAW_DCHECK(start_address < end_address, "");
if (disabled_ranges == NULL) {
- disabled_ranges = new DisabledRangeMap;
- IgnoreObjectLocked(disabled_ranges);
- // in case we are not ignoring global data
+ disabled_ranges = new (Allocator::Allocate(sizeof(DisabledRangeMap)))
+ DisabledRangeMap;
}
RangeValue value;
value.start_address = reinterpret_cast<uintptr_t>(start_address);
@@ -1869,25 +2101,83 @@ void HeapLeakChecker::DisableChecksFromTo(void* start_address,
if (disabled_ranges->
insert(make_pair(reinterpret_cast<uintptr_t>(end_address),
value)).second) {
- HeapProfiler::MESSAGE(1, "HeapChecker: "
- "Disabling leaks checking in stack traces "
- "under frame addresses between %p..%p\n",
- start_address, end_address);
+ RAW_VLOG(1, "Disabling leak checking in stack traces "
+ "under frame addresses between %p..%p",
+ start_address, end_address);
+ } else { // check that this is just a verbatim repetition
+ RangeValue const& val =
+ disabled_ranges->find(reinterpret_cast<uintptr_t>(end_address))->second;
+ if (val.max_depth != value.max_depth ||
+ val.start_address != value.start_address) {
+ RAW_LOG(FATAL, "Two DisableChecksToHereFrom calls conflict: "
+ "(%p, %p, %d) vs. (%p, %p, %d)",
+ (void*)value.start_address, end_address,
+ value.max_depth,
+ start_address, end_address, max_depth);
+ }
}
- if (pthread_mutex_unlock(&heap_checker_lock) != 0) abort();
}
void HeapLeakChecker::DisableChecksAtLocked(void* address) {
+ RAW_DCHECK(heap_checker_lock.IsHeld(), "");
if (disabled_addresses == NULL) {
- disabled_addresses = new DisabledAddressSet;
- IgnoreObjectLocked(disabled_addresses);
- // in case we are not ignoring global data
+ disabled_addresses = new (Allocator::Allocate(sizeof(DisabledAddressSet)))
+ DisabledAddressSet;
}
// disable the requested address
if (disabled_addresses->insert(reinterpret_cast<uintptr_t>(address)).second) {
- HeapProfiler::MESSAGE(1, "HeapChecker: "
- "Disabling leaks checking in stack traces "
- "under frame address %p\n",
- address);
+ RAW_VLOG(1, "Disabling leak checking in stack traces "
+ "under frame address %p", address);
+ }
+}
+
+bool HeapLeakChecker::HaveOnHeapLocked(void** ptr, size_t* object_size) {
+ RAW_DCHECK(heap_checker_lock.IsHeld(), "");
+ // Size of the C++ object array size integer
+ // (potentially compiler dependent; 4 on i386 and gcc; 8 on x86_64 and gcc)
+ const int kArraySizeOffset = sizeof(size_t);
+ // sizeof(basic_string<...>::_Rep) for C++ library of gcc 3.4
+ // (basically three integer counters;
+ // library/compiler dependent; 12 on i386 and gcc)
+ const int kStringOffset = sizeof(size_t) * 3;
+ // NOTE: One can add more similar offset cases below
+ // even when they do not happen for the used compiler/library;
+ // all that's impacted is
+ // - HeapLeakChecker's performace during live heap walking
+ // - and a slightly greater chance to mistake random memory bytes
+ // for a pointer and miss a leak in a particular run of a binary.
+ bool result = true;
+ if (heap_profile->FindAlloc(*ptr, object_size)) {
+ // done
+ } else if (heap_profile->FindAlloc(reinterpret_cast<char*>(*ptr)
+ - kArraySizeOffset,
+ object_size) &&
+ *object_size > kArraySizeOffset) {
+ // this case is to account for the array size stored inside of
+ // the memory allocated by new FooClass[size] for classes with destructors
+ *ptr = reinterpret_cast<char*>(*ptr) - kArraySizeOffset;
+ RAW_VLOG(7, "Got poiter into %p at +%d", ptr, kArraySizeOffset);
+ } else if (heap_profile->FindAlloc(reinterpret_cast<char*>(*ptr)
+ - kStringOffset,
+ object_size) &&
+ *object_size > kStringOffset) {
+ // this case is to account for basic_string<> representation in
+ // newer C++ library versions when the kept pointer points to inside of
+ // the allocated region
+ *ptr = reinterpret_cast<char*>(*ptr) - kStringOffset;
+ RAW_VLOG(7, "Got poiter into %p at +%d", ptr, kStringOffset);
+ } else {
+ result = false;
}
+ return result;
+}
+
+void* HeapLeakChecker::GetAllocCaller(void* ptr) {
+ // this is used only in unittest, so the heavy checks are fine
+ HeapProfileTable::AllocInfo info;
+ heap_checker_lock.Lock();
+ CHECK(heap_profile->FindAllocDetails(ptr, &info));
+ heap_checker_lock.Unlock();
+ CHECK(info.stack_depth >= 1);
+ return info.call_stack[0];
}
diff --git a/src/heap-profile-table.cc b/src/heap-profile-table.cc
new file mode 100644
index 0000000..1da0580
--- /dev/null
+++ b/src/heap-profile-table.cc
@@ -0,0 +1,389 @@
+// Copyright (c) 2006, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// ---
+// Author: Sanjay Ghemawat
+// Maxim Lifantsev (refactoring)
+//
+
+#include <fcntl.h>
+#include <glob.h>
+#include <string>
+
+#include "heap-profile-table.h"
+
+#include "base/logging.h"
+#include <google/stacktrace.h>
+#include <google/malloc_hook.h>
+#include "base/commandlineflags.h"
+
+using std::sort;
+using std::string;
+
+//----------------------------------------------------------------------
+
+DEFINE_bool(cleanup_old_heap_profiles,
+ EnvToBool("HEAP_PROFILE_CLEANUP", true),
+ "At initialization time, delete old heap profiles.");
+
+//----------------------------------------------------------------------
+
+// header of the dumped heap profile
+static const char kProfileHeader[] = "heap profile: ";
+static const char kProcSelfMapsHeader[] = "\nMAPPED_LIBRARIES:\n";
+
+//----------------------------------------------------------------------
+
+const char HeapProfileTable::kFileExt[] = ".heap";
+
+const int HeapProfileTable::kHashTableSize;
+const int HeapProfileTable::kMaxStackTrace;
+
+//----------------------------------------------------------------------
+
+// We strip out different number of stack frames in debug mode
+// because less inlining happens in that case
+#ifdef NDEBUG
+static const int kStripFrames = 2;
+#else
+static const int kStripFrames = 3;
+#endif
+
+// Re-run fn until it doesn't cause EINTR.
+#define NO_INTR(fn) do {} while ((fn) < 0 && errno == EINTR)
+
+// Wrapper around ::write to undo it's potential partiality.
+static void FDWrite(int fd, const char* buf, size_t len) {
+ while (1) {
+ ssize_t r;
+ NO_INTR(r = write(fd, buf, len));
+ if (r <= 0) break;
+ buf += r;
+ len -= r;
+ }
+}
+
+// For sorting Stats or Buckets by in-use space
+static bool ByAllocatedSpace(HeapProfileTable::Stats* a,
+ HeapProfileTable::Stats* b) {
+ // Return true iff "a" has more allocated space than "b"
+ return (a->alloc_size - a->free_size) > (b->alloc_size - b->free_size);
+}
+
+// Helper to add the list of mapped shared libraries to a profile.
+// Fill formatted "/proc/self/maps" contents into buffer 'buf' of size 'size'
+// and return the actual size occupied in 'buf'.
+// We do not provision for 0-terminating 'buf'.
+static int FillProcSelfMaps(char buf[], int size) {
+ int buflen = snprintf(buf, size, kProcSelfMapsHeader);
+ if (buflen < 0 || buflen >= size) return 0;
+ int maps = open("/proc/self/maps", O_RDONLY);
+ if (maps >= 0) {
+ while (buflen < size) {
+ ssize_t r;
+ NO_INTR(r = read(maps, buf + buflen, size - buflen));
+ if (r <= 0) break;
+ buflen += r;
+ }
+ NO_INTR(close(maps));
+ }
+ return buflen;
+}
+
+// Dump the same data as FillProcSelfMaps reads to fd.
+// It seems easier to repeat parts of FillProcSelfMaps here than to
+// reuse it via a call.
+static void DumpProcSelfMaps(int fd) {
+ FDWrite(fd, kProcSelfMapsHeader, sizeof(kProcSelfMapsHeader)-1); // chop \0
+ int maps = open("/proc/self/maps", O_RDONLY);
+ if (maps >= 0) {
+ char buf[512];
+ while (1) {
+ ssize_t r;
+ NO_INTR(r = read(maps, buf, sizeof(buf)));
+ if (r <= 0) break;
+ FDWrite(fd, buf, r);
+ }
+ NO_INTR(close(maps));
+ }
+}
+
+//----------------------------------------------------------------------
+
+HeapProfileTable::HeapProfileTable(Allocator alloc, DeAllocator dealloc)
+ : alloc_(alloc), dealloc_(dealloc) {
+ // Make the table
+ const int table_bytes = kHashTableSize * sizeof(*table_);
+ table_ = reinterpret_cast<Bucket**>(alloc_(table_bytes));
+ memset(table_, 0, table_bytes);
+ // Make allocation map
+ allocation_ =
+ new(alloc_(sizeof(AllocationMap))) AllocationMap(alloc_, dealloc_);
+ // init the rest:
+ memset(&total_, 0, sizeof(total_));
+ num_buckets_ = 0;
+}
+
+HeapProfileTable::~HeapProfileTable() {
+ // free allocation map
+ allocation_->~AllocationMap();
+ dealloc_(allocation_);
+ allocation_ = NULL;
+ // free hash table
+ for (int b = 0; b < kHashTableSize; b++) {
+ for (Bucket* x = table_[b]; x != 0; /**/) {
+ Bucket* b = x;
+ x = x->next;
+ dealloc_(b->stack);
+ dealloc_(b);
+ }
+ }
+ dealloc_(table_);
+ table_ = NULL;
+}
+
+HeapProfileTable::Bucket* HeapProfileTable::GetBucket(int skip_count) {
+ // Get raw stack trace
+ void* key[kMaxStackTrace];
+ int depth =
+ MallocHook::GetCallerStackTrace(key, kMaxStackTrace, skip_count+1);
+ // Make hash-value
+ uintptr_t h = 0;
+ for (int i = 0; i < depth; i++) {
+ h += reinterpret_cast<uintptr_t>(key[i]);
+ h += h << 10;
+ h ^= h >> 6;
+ }
+ h += h << 3;
+ h ^= h >> 11;
+
+ // Lookup stack trace in table
+ const size_t key_size = sizeof(key[0]) * depth;
+ unsigned int buck = ((unsigned int) h) % kHashTableSize;
+ for (Bucket* b = table_[buck]; b != 0; b = b->next) {
+ if ((b->hash == h) &&
+ (b->depth == depth) &&
+ (memcmp(b->stack, key, key_size) == 0)) {
+ return b;
+ }
+ }
+
+ // Create new bucket
+ void** kcopy = reinterpret_cast<void**>(alloc_(key_size));
+ memcpy(kcopy, key, key_size);
+ Bucket* b = reinterpret_cast<Bucket*>(alloc_(sizeof(Bucket)));
+ memset(b, 0, sizeof(*b));
+ b->hash = h;
+ b->depth = depth;
+ b->stack = kcopy;
+ b->next = table_[buck];
+ table_[buck] = b;
+ num_buckets_++;
+ return b;
+}
+
+void HeapProfileTable::RecordAlloc(void* ptr, size_t bytes, int skip_count) {
+ Bucket* b = GetBucket(kStripFrames + skip_count + 1);
+ b->allocs++;
+ b->alloc_size += bytes;
+ total_.allocs++;
+ total_.alloc_size += bytes;
+
+ AllocValue v;
+ v.bucket = b;
+ v.bytes = bytes;
+ allocation_->Insert(ptr, v);
+}
+
+void HeapProfileTable::RecordFree(void* ptr) {
+ AllocValue v;
+ if (allocation_->FindAndRemove(ptr, &v)) {
+ Bucket* b = v.bucket;
+ b->frees++;
+ b->free_size += v.bytes;
+ total_.frees++;
+ total_.free_size += v.bytes;
+ }
+}
+
+bool HeapProfileTable::FindAlloc(void* ptr, size_t* object_size) const {
+ AllocValue alloc_value;
+ if (allocation_->Find(ptr, &alloc_value)) {
+ *object_size = alloc_value.bytes;
+ return true;
+ }
+ return false;
+}
+
+bool HeapProfileTable::FindAllocDetails(void* ptr, AllocInfo* info) const {
+ AllocValue alloc_value;
+ if (allocation_->Find(ptr, &alloc_value)) {
+ info->object_size = alloc_value.bytes;
+ info->call_stack = alloc_value.bucket->stack;
+ info->stack_depth = alloc_value.bucket->depth;
+ return true;
+ }
+ return false;
+}
+
+void HeapProfileTable::MapArgsAllocIterator(
+ void* ptr, AllocValue v, AllocIterator callback) {
+ AllocInfo info;
+ info.object_size = v.bytes;
+ info.call_stack = v.bucket->stack;
+ info.stack_depth = v.bucket->depth;
+ callback(ptr, info);
+}
+
+void HeapProfileTable::IterateAllocs(AllocIterator callback) const {
+ allocation_->Iterate(MapArgsAllocIterator, callback);
+}
+
+// We'd be happier using snprintfer, but we don't to reduce dependencies.
+int HeapProfileTable::UnparseBucket(const Bucket& b,
+ char* buf, int buflen, int bufsize,
+ Stats* profile_stats) {
+ profile_stats->allocs += b.allocs;
+ profile_stats->alloc_size += b.alloc_size;
+ profile_stats->frees += b.frees;
+ profile_stats->free_size += b.free_size;
+ int printed =
+ snprintf(buf + buflen, bufsize - buflen, "%6d: %8lld [%6d: %8lld] @",
+ b.allocs - b.frees,
+ b.alloc_size - b.free_size,
+ b.allocs,
+ b.alloc_size);
+ // If it looks like the snprintf failed, ignore the fact we printed anything
+ if (printed < 0 || printed >= bufsize - buflen) return buflen;
+ buflen += printed;
+ for (int d = 0; d < b.depth; d++) {
+ printed = snprintf(buf + buflen, bufsize - buflen, " 0x%08lx",
+ (unsigned long)b.stack[d]);
+ if (printed < 0 || printed >= bufsize - buflen) return buflen;
+ buflen += printed;
+ }
+ printed = snprintf(buf + buflen, bufsize - buflen, "\n");
+ if (printed < 0 || printed >= bufsize - buflen) return buflen;
+ buflen += printed;
+ return buflen;
+}
+
+int HeapProfileTable::FillOrderedProfile(char buf[], int size) const {
+ // We can't allocate list on the stack, as this would overflow on threads
+ // running with a small stack size.
+ Bucket** list =
+ reinterpret_cast<Bucket**>(alloc_(sizeof(Bucket) * num_buckets_));
+
+ int n = 0;
+ for (int b = 0; b < kHashTableSize; b++) {
+ for (Bucket* x = table_[b]; x != 0; x = x->next) {
+ list[n++] = x;
+ }
+ }
+ RAW_DCHECK(n == num_buckets_, "");
+
+ sort(list, list + num_buckets_, ByAllocatedSpace);
+
+ Stats stats;
+ memset(&stats, 0, sizeof(stats));
+ int buflen = snprintf(buf, size, kProfileHeader);
+ if (buflen < 0 || buflen >= size) return 0;
+ buflen = UnparseBucket(total_, buf, buflen, size, &stats);
+ for (int i = 0; i < n; i++) {
+ buflen = UnparseBucket(*list[i], buf, buflen, size, &stats);
+ }
+ RAW_DCHECK(buflen < size, "");
+
+ dealloc_(list);
+
+ buflen += FillProcSelfMaps(buf + buflen, size - buflen);
+
+ return buflen;
+}
+
+void HeapProfileTable::FilteredDumpIterator(void* ptr, AllocValue v,
+ const DumpArgs& args) {
+ if (args.filter(ptr, v.bytes)) return;
+ Bucket b;
+ memset(&b, 0, sizeof(b));
+ b.allocs = 1;
+ b.alloc_size = v.bytes;
+ void* stack[kMaxStackTrace + 1];
+ b.depth = v.bucket->depth + int(args.dump_alloc_addresses);
+ b.stack = stack;
+ if (args.dump_alloc_addresses) stack[0] = ptr;
+ memcpy(stack + int(args.dump_alloc_addresses),
+ v.bucket->stack, sizeof(stack[0]) * v.bucket->depth);
+ char buf[1024];
+ int len = UnparseBucket(b, buf, 0, sizeof(buf), args.profile_stats);
+ FDWrite(args.fd, buf, len);
+}
+
+bool HeapProfileTable::DumpFilteredProfile(const char* file_name,
+ DumpFilter filter,
+ bool dump_alloc_addresses,
+ Stats* profile_stats) const {
+ RAW_VLOG(1, "Dumping filtered heap profile to %s", file_name);
+ int fd = open(file_name, O_WRONLY|O_CREAT|O_TRUNC, 0644);
+ if (fd >= 0) {
+ FDWrite(fd, kProfileHeader, strlen(kProfileHeader));
+ char buf[512];
+ int len = UnparseBucket(total_, buf, 0, sizeof(buf), profile_stats);
+ FDWrite(fd, buf, len);
+ memset(profile_stats, 0, sizeof(*profile_stats));
+ const DumpArgs args(fd, dump_alloc_addresses, filter, profile_stats);
+ allocation_->Iterate<const DumpArgs&>(FilteredDumpIterator, args);
+ DumpProcSelfMaps(fd);
+ NO_INTR(close(fd));
+ return true;
+ } else {
+ RAW_LOG(ERROR, "Failed dumping filtered heap profile to %s", file_name);
+ return false;
+ }
+}
+
+void HeapProfileTable::CleanupOldProfiles(const char* prefix) {
+ if (!FLAGS_cleanup_old_heap_profiles)
+ return;
+ string pattern = string(prefix) + ".*" + kFileExt;
+ glob_t g;
+ const int r = glob(pattern.c_str(), GLOB_ERR, NULL, &g);
+ if (r == 0 || r == GLOB_NOMATCH) {
+ const int prefix_length = strlen(prefix);
+ for (int i = 0; i < g.gl_pathc; i++) {
+ const char* fname = g.gl_pathv[i];
+ if ((strlen(fname) >= prefix_length) &&
+ (memcmp(fname, prefix, prefix_length) == 0)) {
+ RAW_VLOG(0, "Removing old heap profile %s", fname);
+ unlink(fname);
+ }
+ }
+ }
+ globfree(&g);
+}
diff --git a/src/heap-profile-table.h b/src/heap-profile-table.h
new file mode 100644
index 0000000..18b4a88
--- /dev/null
+++ b/src/heap-profile-table.h
@@ -0,0 +1,216 @@
+// Copyright (c) 2006, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// ---
+// Author: Sanjay Ghemawat
+// Maxim Lifantsev (refactoring)
+//
+
+#ifndef BASE_HEAP_PROFILE_TABLE_H__
+#define BASE_HEAP_PROFILE_TABLE_H__
+
+#include "addressmap-inl.h"
+#include "base/basictypes.h"
+
+// Table to maintain a heap profile data inside,
+// i.e. the set of currently active heap memory allocations.
+// Not thread-safe and non-reentrant code:
+// each instance object must be used by one thread
+// at a time w/o self-recursion.
+//
+// TODO(maxim): add a unittest for this class.
+class HeapProfileTable {
+ public:
+
+ // Extension to be used for heap pforile files.
+ static const char kFileExt[];
+
+ // data types ----------------------------
+
+ // Profile stats.
+ struct Stats {
+ int32 allocs; // Number of allocation calls
+ int32 frees; // Number of free calls
+ int64 alloc_size; // Total size of all allocated objects so far
+ int64 free_size; // Total size of all freed objects so far
+ };
+
+ // Info we can return about an allocation.
+ struct AllocInfo {
+ size_t object_size; // size of the allocation
+ void* const* call_stack; // call stack that made the allocation call
+ int stack_depth; // depth of call_stack
+ };
+
+ // Memory (de)allocator interface we'll use.
+ typedef void* (*Allocator)(size_t);
+ typedef void (*DeAllocator)(void*);
+
+ // interface ---------------------------
+
+ HeapProfileTable(Allocator alloc, DeAllocator dealloc);
+ ~HeapProfileTable();
+
+ // Record an allocation at 'ptr' of 'bytes' bytes.
+ // skip_count gives the number of stack frames between this call
+ // and the memory allocation function that was asked to do the allocation.
+ void RecordAlloc(void* ptr, size_t bytes, int skip_count);
+
+ // Record the deallocation of memory at 'ptr'.
+ void RecordFree(void* ptr);
+
+ // Return true iff we have recorded an allocation at 'ptr'.
+ // If yes, fill *object_size with the allocation byte size.
+ bool FindAlloc(void* ptr, size_t* object_size) const;
+ // Same as FindAlloc, but fills all of *info.
+ bool FindAllocDetails(void* ptr, AllocInfo* info) const;
+
+ // Return current total (de)allocation statistics.
+ const Stats& total() const { return total_; }
+
+ // Allocation data iteration callback: gets passed object pointer and
+ // fully-filled AllocInfo.
+ typedef void (*AllocIterator)(void* ptr, const AllocInfo& info);
+
+ // Iterate over the allocation profile data calling "callback"
+ // for every allocation.
+ void IterateAllocs(AllocIterator callback) const;
+
+ // Fill profile data into buffer 'buf' of size 'size'
+ // and return the actual size occupied by the dump in 'buf'.
+ // The profile buckets are dumped in the decreasing order
+ // of currently allocated bytes.
+ // We do not provision for 0-terminating 'buf'.
+ int FillOrderedProfile(char buf[], int size) const;
+
+ // Allocation data dump filtering callback:
+ // gets passed object pointer and size
+ // needs to return true iff the object is to be filtered out of the dump.
+ typedef bool (*DumpFilter)(void* ptr, size_t size);
+
+ // Dump current heap profile for leak checking purposes to file_name
+ // while filtering the objects by "filter".
+ // Also write the sums of allocated byte and object counts in the dump
+ // to *alloc_bytes and *alloc_objects.
+ // dump_alloc_addresses controls if object addresses are dumped.
+ bool DumpFilteredProfile(const char* file_name,
+ DumpFilter filter,
+ bool dump_alloc_addresses,
+ Stats* profile_stats) const;
+
+ // Cleanup any old profile files matching prefix + ".*" + kFileExt.
+ static void CleanupOldProfiles(const char* prefix);
+
+ private:
+
+ // data types ----------------------------
+
+ // Hash table bucket to hold (de)allocation stats
+ // for a given allocation call stack trace.
+ struct Bucket : public Stats {
+ uintptr_t hash; // Hash value of the stack trace
+ int depth; // Depth of stack trace
+ void** stack; // Stack trace
+ Bucket* next; // Next entry in hash-table
+ };
+
+ // Info stored in the address map
+ struct AllocValue {
+ Bucket* bucket; // The stack-trace bucket
+ size_t bytes; // Number of bytes in this allocation
+ };
+
+ typedef AddressMap<AllocValue> AllocationMap;
+
+ // Arguments that need to be passed FilteredDumpIterator callback below.
+ struct DumpArgs {
+ int fd; // file to write to
+ bool dump_alloc_addresses; // if we are dumping allocation's addresses
+ DumpFilter filter; // dumping filter
+ Stats* profile_stats; // stats to update
+
+ DumpArgs(int a, bool b, DumpFilter c, Stats* d)
+ : fd(a), dump_alloc_addresses(b), filter(c), profile_stats(d) { }
+ };
+
+ // helpers ----------------------------
+
+ // Unparse bucket b and print its portion of profile dump into buf.
+ // We return the amount of space in buf that we use. We start printing
+ // at buf + buflen, and promise not to go beyond buf + bufsize.
+ // We do not provision for 0-terminating 'buf'.
+ // We update *profile_stats by counting bucket b.
+ static int UnparseBucket(const Bucket& b,
+ char* buf, int buflen, int bufsize,
+ Stats* profile_stats);
+
+ // Get the bucket for the current stack trace creating one if needed
+ // (skip "skip_count" most recent frames).
+ Bucket* GetBucket(int skip_count);
+
+ // Helper for IterateAllocs to do callback signature conversion
+ // from AllocationMap::Iterate to AllocIterator.
+ static void MapArgsAllocIterator(void* ptr, AllocValue v,
+ AllocIterator callback);
+
+ // Helper for DumpFilteredProfile to do object-granularity
+ // heap profile dumping. It gets passed to AllocationMap::Iterate.
+ static void FilteredDumpIterator(void* ptr, AllocValue v,
+ const DumpArgs& args);
+
+ // data ----------------------------
+
+ // Size for table_.
+ static const int kHashTableSize = 179999;
+
+ // Longest stack trace we record.
+ static const int kMaxStackTrace = 32;
+
+ // Memory (de)allocator that we use.
+ Allocator alloc_;
+ DeAllocator dealloc_;
+
+ // Overall profile stats; we use only the Stats part,
+ // but make it a Bucket to pass to UnparseBucket.
+ Bucket total_;
+
+ // Bucket hash table.
+ // We hand-craft one instead of using one of the pre-written
+ // ones because we do not want to use malloc when operating on the table.
+ // It is only few lines of code, so no big deal.
+ Bucket** table_;
+ int num_buckets_;
+
+ // Map of all currently allocated objects we know about.
+ AllocationMap* allocation_;
+
+ DISALLOW_EVIL_CONSTRUCTORS(HeapProfileTable);
+};
+
+#endif // BASE_HEAP_PROFILE_TABLE_H__
diff --git a/src/heap-profiler-inl.h b/src/heap-profiler-inl.h
deleted file mode 100644
index a731cfa..0000000
--- a/src/heap-profiler-inl.h
+++ /dev/null
@@ -1,222 +0,0 @@
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// All Rights Reserved.
-//
-// Author: Maxim Lifantsev
-//
-// Some hooks into heap-profiler.cc
-// that are needed by heap-checker.cc
-//
-
-#ifndef BASE_HEAP_PROFILER_INL_H__
-#define BASE_HEAP_PROFILER_INL_H__
-
-#include "config.h"
-
-#if defined HAVE_STDINT_H
-#include <stdint.h> // to get uint16_t (ISO naming madness)
-#elif defined HAVE_INTTYPES_H
-#include <inttypes.h> // another place uint16_t might be defined
-#else
-#include <sys/types.h> // our last best hope
-#endif
-#include <pthread.h>
-#include "base/basictypes.h"
-#include <google/heap-profiler.h>
-#include <map>
-#include <google/perftools/hash_set.h>
-
-template<class T> class AddressMap; // in addressmap-inl.h
-class HeapLeakChecker; // in heap-checker.h
-
-// namespace for heap profiler components
-class HeapProfiler {
- public: // data types
-
- // Profile entry
- struct Bucket {
- uintptr_t hash_; // Hash value
- int depth_; // Depth of stack trace
- void** stack_; // Stack trace
- int32 allocs_; // Number of allocs
- int32 frees_; // Number of frees
- int64 alloc_size_; // Total size of all allocated objects
- int64 free_size_; // Total size of all freed objects
- Bucket* next_; // Next entry in hash-table
- };
-
- // Info stored in the address map
- struct AllocValue {
- Bucket* bucket; // The stack-trace bucket
- size_t bytes; // Number of allocated bytes
- };
- typedef AddressMap<AllocValue> AllocationMap;
-
- typedef HASH_NAMESPACE::hash_set<uintptr_t> IgnoredObjectSet;
-
- private: // state variables
- // NOTE: None of these have destructors that change their state.
- // Keep it this way: heap-checker depends on it.
-
- // Is heap-profiling on as a subsytem
- static bool is_on_;
- // Is heap-profiling needed for heap leak checking.
- static bool need_for_leaks_;
- // Has Init() been called? Used by heap-profiler to avoid initting
- // more than once (since heap-checker may call Init() manually.)
- static bool init_has_been_called_;
- // If we are disabling heap-profiling recording for incoming
- // (de)allocation calls from the thread specified by self_disabled_tid_.
- // This is done for (de)allocations that are internal
- // to heap profiler or heap checker, so that we can hold the global
- // profiler's lock and pause heap activity from other threads
- // while working freely in our thread.
- static bool self_disable_;
- static pthread_t self_disabled_tid_;
- // The ignored live object addresses for profile dumping.
- static IgnoredObjectSet* ignored_objects_;
- // Flag if we are doing heap dump for leaks checking vs.
- // for general memory profiling
- static bool dump_for_leaks_;
- // Prevents recursive dumping
- static bool dumping_;
- // Overall profile stats
- static Bucket total_;
- // Last dumped profile stats
- static Bucket profile_;
- // Stats for the (de)allocs disabled with the use of self_disable_
- static Bucket self_disabled_;
- // Prefix used for profile file names (NULL if no need for dumping yet)
- static char* filename_prefix_;
- // Map of all currently allocated object we know about
- static AllocationMap* allocation_;
- // Number of frames to skip in stack traces. This is the number of functions
- // that are called between malloc() and RecordAlloc(). This can differ
- // depending on the compiler and level of optimization under which we are
- // running.
- static int strip_frames_;
- // Whether we have recorded our first allocation. This is used to
- // distinguish the magic first call of RecordAlloc that sets strip_frames_
- static bool done_first_alloc_;
- // Location of stack pointer in Init(). Also used to help determine
- // strip_frames_.
- static void* recordalloc_reference_stack_position_;
-
- // Global lock for profile structure
- static void Lock();
- static void Unlock();
-
- private: // functions
-
- // Own heap profiler's internal allocation mechanism
- static void* Malloc(size_t bytes);
- static void Free(void* p);
- // Helper for HeapProfilerDump:
- // If file_name is not NULL when it gives the name for the dumped profile,
- // else we use the standard sequential name.
- static void DumpLocked(const char *reason, const char* file_name);
-
- private: // helpers of heap-checker.cc
-
- // If "ptr" points to a heap object;
- // we also fill alloc_value for this object then.
- // If yes, we might move "ptr" to point to the very start of the object
- // (this needs to happen for C++ class array allocations
- // and for basic_string-s of C++ library that comes with gcc 3.4).
- static bool HaveOnHeap(void** ptr, AllocValue* alloc_value);
- static bool HaveOnHeapLocked(void** ptr, AllocValue* alloc_value);
-
- private: // helpers of heap-profiler.cc
-
- // Get bucket for current stack trace (skip "skip_count" most recent frames)
- static Bucket* GetBucket(int skip_count);
- // Unparse bucket b and print its portion of profile dump into buf.
- // We return the amount of space in buf that we use. We start printing
- // at buf + buflen, and promise not to go beyond buf + bufsize.
- static int UnparseBucket(char* buf, int buflen, int bufsize, const Bucket* b);
- // Add ignored_objects_ 'adjust' times (ususally -1 or 1)
- // to the profile bucket data.
- static void AdjustByIgnoredObjects(int adjust);
- static void RecordAlloc(void* ptr, size_t bytes, int skip_count);
- static void RecordFree(void* ptr);
- // Activates profile collection before profile dumping.
- // Can be called before global object constructors.
- static void EarlyStartLocked();
- // Cleanup any old profile files
- static void CleanupProfiles(const char* prefix);
- // Profiling subsystem starting and stopping.
- static void StartLocked(const char* prefix);
- static void StopLocked();
- static void StartForLeaks();
- static void StopForLeaks();
- static void NewHook(void* ptr, size_t size);
- static void DeleteHook(void* ptr);
- static void MmapHook(void* result,
- void* start, size_t size,
- int prot, int flags,
- int fd, off_t offset);
- static void MunmapHook(void* ptr, size_t size);
-
- private: // intended users
-
- friend class HeapLeakChecker;
- friend void HeapProfilerStart(const char* prefix);
- friend void HeapProfilerStop();
- friend void HeapProfilerDump(const char *reason);
- friend char* GetHeapProfile();
-
- public:
-
- // printing messages without using malloc
- // Message levels (levels <= 0 are printed by default):
- // -1 Errors
- // 0 Normal informational reports
- // 1 Stuff users won't usually care about
- static void MESSAGE(int logging_level, const char* format, ...)
-#ifdef _HAVE___ATTRIBUTE__
- __attribute__ ((__format__ (__printf__, 2, 3)))
-#endif
-;
-
- // Set this to true when you want maximal logging for
- // debugging problems in heap profiler or checker themselves.
- // We use this constant instead of logging_level in MESSAGE()
- // to completely compile-out this extra logging in all normal cases.
- static const bool kMaxLogging = false;
-
- // Module initialization
- static void Init();
-
- // Are we running?
- static bool IsOn() { return is_on_; }
-};
-
-#endif // BASE_HEAP_PROFILER_INL_H__
diff --git a/src/heap-profiler.cc b/src/heap-profiler.cc
index f0cbb69..43df3be 100644
--- a/src/heap-profiler.cc
+++ b/src/heap-profiler.cc
@@ -34,43 +34,28 @@
#include "config.h"
-#include <malloc.h>
+#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
-#include <glob.h>
-#include <stdarg.h>
#include <sys/mman.h>
-#include <stdarg.h>
#include <errno.h>
#include <assert.h>
#include <algorithm>
#include <string>
-#include <iostream>
-#include <map>
-#include <google/perftools/hash_set.h>
#include <google/heap-profiler.h>
-#include <google/stacktrace.h>
-#include <google/malloc_extension.h>
-#include <google/malloc_hook.h>
-
-#include "heap-profiler-inl.h"
-#include "internal_spinlock.h"
-#include "addressmap-inl.h"
-#include "base/basictypes.h"
#include "base/logging.h"
+#include "base/basictypes.h" // for PRId64, among other things
#include "base/googleinit.h"
#include "base/commandlineflags.h"
+#include <google/malloc_hook.h>
+#include <google/malloc_extension.h>
+#include "base/spinlock.h"
+#include "base/low_level_alloc.h"
+#include "heap-profile-table.h"
-#ifdef HAVE_INTTYPES_H
-#define __STDC_FORMAT_MACROS
-#include <inttypes.h>
-#define LLD PRId64 // how to write 64-bit numbers
-#else
-#define LLD "lld" // hope for the best
-#endif
#ifndef PATH_MAX
#ifdef MAXPATHLEN
@@ -80,9 +65,6 @@
#endif
#endif
-#define LOGF STL_NAMESPACE::cout // where we log to; LOGF is a historical name
-
-using HASH_NAMESPACE::hash_set;
using STL_NAMESPACE::string;
using STL_NAMESPACE::sort;
@@ -90,873 +72,293 @@ using STL_NAMESPACE::sort;
// Flags that control heap-profiling
//----------------------------------------------------------------------
-DEFINE_bool(cleanup_old_heap_profiles, true,
- "At initialization time, delete old heap profiles.");
-DEFINE_int64(heap_profile_allocation_interval, 1 << 30 /*1GB*/,
+DEFINE_int64(heap_profile_allocation_interval,
+ EnvToInt64("HEAP_PROFILE_ALLOCATION_INTERVAL", 1 << 30 /*1GB*/),
"Dump heap profiling information once every specified "
"number of bytes allocated by the program.");
-DEFINE_int64(heap_profile_inuse_interval, 100 << 20 /*100MB*/,
- "Dump heap profiling information whenever the high-water "
+DEFINE_int64(heap_profile_inuse_interval,
+ EnvToInt64("HEAP_PROFILE_INUSE_INTERVAL", 100 << 20 /*100MB*/),
+ "Dump heap profiling information whenever the high-water "
"memory usage mark increases by the specified number of "
"bytes.");
-DEFINE_bool(mmap_log, false, "Should mmap/munmap calls be logged?");
-DEFINE_bool(mmap_profile, false, "If heap-profiling on, also profile mmaps");
-DEFINE_int32(heap_profile_log, 0,
- "Logging level for heap profiler/checker messages");
-
-// Level of logging used by the heap profiler and heap checker (if applicable)
-// Default: 0
-void HeapProfilerSetLogLevel(int level) {
- FLAGS_heap_profile_log = level;
-}
-
-// Dump heap profiling information once every specified number of bytes
-// allocated by the program. Default: 1GB
-void HeapProfilerSetAllocationInterval(size_t interval) {
- FLAGS_heap_profile_allocation_interval = interval;
-}
-
-// Dump heap profiling information whenever the high-water
-// memory usage mark increases by the specified number of
-// bytes. Default: 100MB
-void HeapProfilerSetInuseInterval(size_t interval) {
- FLAGS_heap_profile_inuse_interval = interval;
-}
+DEFINE_bool(mmap_log,
+ EnvToBool("HEAP_PROFILE_MMAP_LOG", false),
+ "Should mmap/munmap calls be logged?");
+DEFINE_bool(mmap_profile,
+ EnvToBool("HEAP_PROFILE_MMAP", false),
+ "If heap-profiling on, also profile mmaps");
//----------------------------------------------------------------------
-// For printing messages without using malloc
+// Locking
//----------------------------------------------------------------------
-void HeapProfiler::MESSAGE(int level, const char* format, ...) {
- if (FLAGS_heap_profile_log < level) return;
-
- // We write directly to the stderr file descriptor and avoid FILE
- // buffering because that may invoke malloc()
- va_list ap;
- va_start(ap, format);
- char buf[600];
- vsnprintf(buf, sizeof(buf), format, ap);
- va_end(ap);
- write(STDERR_FILENO, buf, strlen(buf));
-}
+// A pthread_mutex has way too much lock contention to be used here.
+//
+// I would like to use Mutex, but it can call malloc(),
+// which can cause us to fall into an infinite recursion.
+//
+// So we use a simple spinlock.
+static SpinLock heap_lock(SpinLock::LINKER_INITIALIZED);
//----------------------------------------------------------------------
-// Simple allocator
+// Simple allocator for heap profiler's internal memory
//----------------------------------------------------------------------
-class HeapProfilerMemory {
- private:
- // Default unit of allocation from system
- static const int kBlockSize = 1 << 20;
-
- // Maximum number of blocks we can allocate
- static const int kMaxBlocks = 1024;
-
- // Info kept per allocated block
- struct Block {
- void* ptr;
- size_t size;
- };
-
- // Alignment
- union AlignUnion { double d; void* p; int64 i; size_t s; };
- static const int kAlignment = sizeof(AlignUnion);
-
- Block blocks_[kMaxBlocks]; // List of allocated blocks
- int nblocks_; // # of allocated blocks
- char* current_; // Current block
- int pos_; // Position in current block
-
- // Allocate a block with the specified size
- void* AllocBlock(size_t size) {
- // Round size upto a multiple of the page size
- const size_t pagesize = getpagesize();
- size = ((size + pagesize -1 ) / pagesize) * pagesize;
-
- HeapProfiler::MESSAGE(1, "HeapProfiler: allocating %"PRIuS
- " bytes for internal use\n", size);
- if (nblocks_ == kMaxBlocks) {
- HeapProfiler::MESSAGE(-1, "HeapProfilerMemory: Alloc out of memory\n");
- abort();
- }
+static LowLevelAlloc::Arena *heap_profiler_memory;
- // Disable mmap hooks while calling mmap here to avoid recursive calls
- MallocHook::MmapHook saved = MallocHook::SetMmapHook(NULL);
- void* ptr = mmap(NULL, size,
- PROT_READ|PROT_WRITE,
- MAP_PRIVATE|MAP_ANONYMOUS,
- -1, 0);
- MallocHook::SetMmapHook(saved);
-
- if (ptr == reinterpret_cast<void*>(MAP_FAILED)) {
- HeapProfiler::MESSAGE(-1, "HeapProfilerMemory: mmap %"PRIuS": %s\n",
- size, strerror(errno));
- abort();
- }
- blocks_[nblocks_].ptr = ptr;
- blocks_[nblocks_].size = size;
- return ptr;
- }
-
- public:
- void Init() {
- nblocks_ = 0;
- current_ = NULL;
- pos_ = kBlockSize;
- }
-
- void Clear() {
- // Disable munmap hooks while calling mmap here to avoid recursive calls
- MallocHook::MunmapHook saved = MallocHook::SetMunmapHook(NULL);
- for (int i = 0; i < nblocks_; ++i) {
- if (munmap(blocks_[i].ptr, blocks_[i].size) != 0) {
- HeapProfiler::MESSAGE(-1, "HeapProfilerMemory: munmap: %s\n",
- strerror(errno));
- abort();
- }
- }
- MallocHook::SetMunmapHook(saved);
-
- nblocks_ = 0;
- current_ = NULL;
- pos_ = kBlockSize;
- }
-
- void* Alloc(size_t bytes) {
- if (bytes >= kBlockSize / 8) {
- // Too big for piecemeal allocation
- return AllocBlock(bytes);
- } else {
- if (pos_ + bytes > kBlockSize) {
- current_ = reinterpret_cast<char*>(AllocBlock(kBlockSize));
- pos_ = 0;
- }
- void* result = current_ + pos_;
- pos_ = (pos_ + bytes + kAlignment - 1) & ~(kAlignment-1);
- return result;
- }
- }
-};
-static HeapProfilerMemory heap_profiler_memory;
-void* HeapProfiler::Malloc(size_t bytes) {
- return heap_profiler_memory.Alloc(bytes);
+static void* ProfilerMalloc(size_t bytes) {
+ return LowLevelAlloc::Alloc(bytes, heap_profiler_memory);
}
-void HeapProfiler::Free(void* p) {
- // Do nothing -- all memory is released in one shot
+static void ProfilerFree(void* p) {
+ LowLevelAlloc::Free(p);
}
//----------------------------------------------------------------------
-// Locking code
+// Profiling control/state data
//----------------------------------------------------------------------
-// A pthread_mutex has way too much lock contention to be used here.
-// In some applications we've run, pthread_mutex took >75% of the running
-// time.
-// I would like to roll our own mutex wrapper, but the obvious
-// solutions can call malloc(), which can lead to infinite recursion.
-//
-// So we use a simple spinlock (just like the spinlocks used in tcmalloc)
-
-static TCMalloc_SpinLock heap_lock;
-
-void HeapProfiler::Lock() {
- if (kMaxLogging) {
- // for debugging deadlocks
- HeapProfiler::MESSAGE(10, "HeapProfiler: Lock from %d\n",
- int(pthread_self()));
- }
-
- heap_lock.Lock();
-}
-
-void HeapProfiler::Unlock() {
- if (kMaxLogging) {
- HeapProfiler::MESSAGE(10, "HeapProfiler: Unlock from %d\n",
- int(pthread_self()));
- }
-
- heap_lock.Unlock();
-}
+static bool is_on = false; // If are on as a subsytem.
+static bool dumping = false; // Dumping status to prevent recursion
+static char* filename_prefix = NULL; // Prefix used for profile file names
+ // (NULL if no need for dumping yet)
+static int dump_count = 0; // How many dumps so far
+static int64 last_dump = 0; // When did we last dump
+static int64 high_water_mark = 0; // In-use-bytes at last high-water dump
+static HeapProfileTable* heap_profile = NULL; // the heap profile table
//----------------------------------------------------------------------
-// Profile-maintenance code
+// Profile generation
//----------------------------------------------------------------------
-typedef HeapProfiler::Bucket Bucket;
-
-bool HeapProfiler::is_on_ = false;
-bool HeapProfiler::init_has_been_called_ = false;
-bool HeapProfiler::need_for_leaks_ = false;
-bool HeapProfiler::self_disable_ = false;
-pthread_t HeapProfiler::self_disabled_tid_;
-HeapProfiler::IgnoredObjectSet* HeapProfiler::ignored_objects_ = NULL;
-bool HeapProfiler::dump_for_leaks_ = false;
-bool HeapProfiler::dumping_ = false;
-Bucket HeapProfiler::total_;
-Bucket HeapProfiler::self_disabled_;
-Bucket HeapProfiler::profile_;
-char* HeapProfiler::filename_prefix_ = NULL;
-
-// Hash-table: we hand-craft one instead of using one of the pre-written
-// ones because we do not want to use malloc when operating on the table.
-// It is only five lines of code, so no big deal.
-static const int kHashTableSize = 179999;
-static Bucket** table = NULL;
-HeapProfiler::AllocationMap* HeapProfiler::allocation_ = NULL;
-
-static int num_buckets = 0;
-static int total_stack_depth = 0;
-static int dump_count = 0; // How many dumps so far
-static int64 last_dump = 0; // When did we last dump
-static int64 high_water_mark = 0; // In-use-bytes at last high-water dump
-
-int HeapProfiler::strip_frames_ = 0;
-bool HeapProfiler::done_first_alloc_ = false;
-void* HeapProfiler::recordalloc_reference_stack_position_ = NULL;
-
-// For sorting buckets by in-use space
-static bool ByAllocatedSpace(Bucket* a, Bucket* b) {
- // Return true iff "a" has more allocated space than "b"
- return (a->alloc_size_ - a->free_size_) > (b->alloc_size_ - b->free_size_);
-}
-
-int HeapProfiler::UnparseBucket(char* buf, int buflen, int bufsize,
- const Bucket* b) {
- profile_.allocs_ += b->allocs_;
- profile_.alloc_size_ += b->alloc_size_;
- profile_.frees_ += b->frees_;
- profile_.free_size_ += b->free_size_;
- if (dump_for_leaks_ &&
- b->allocs_ - b->frees_ == 0 &&
- b->alloc_size_ - b->free_size_ == 0) {
- // don't waste the profile space on buckets that do not matter
- return buflen;
- }
- int printed =
- snprintf(buf + buflen, bufsize - buflen, "%6d: %8"LLD" [%6d: %8"LLD"] @",
- b->allocs_ - b->frees_,
- b->alloc_size_ - b->free_size_,
- b->allocs_,
- b->alloc_size_);
- // If it looks like the snprintf failed, ignore the fact we printed anything
- if (printed < 0 || printed >= bufsize - buflen) return buflen;
- buflen += printed;
- for (int d = 0; d < b->depth_; d++) {
- printed = snprintf(buf + buflen, bufsize - buflen, " 0x%08lx",
- (unsigned long)b->stack_[d]);
- if (printed < 0 || printed >= bufsize - buflen) return buflen;
- buflen += printed;
- }
- printed = snprintf(buf + buflen, bufsize - buflen, "\n");
- if (printed < 0 || printed >= bufsize - buflen) return buflen;
- buflen += printed;
- return buflen;
-}
-
-void HeapProfiler::AdjustByIgnoredObjects(int adjust) {
- if (ignored_objects_) {
- assert(dump_for_leaks_);
- for (IgnoredObjectSet::const_iterator i = ignored_objects_->begin();
- i != ignored_objects_->end(); ++i) {
- AllocValue v;
- if (!allocation_->Find(reinterpret_cast<void*>(*i), &v)) abort();
- // must be in
- v.bucket->allocs_ += adjust;
- v.bucket->alloc_size_ += adjust * int64(v.bytes);
- // need explicit size_t to int64 conversion before multiplication
- // in case size_t is unsigned and adjust is negative
- assert(v.bucket->allocs_ >= 0 && v.bucket->alloc_size_ >= 0);
- if (kMaxLogging && adjust < 0) {
- HeapProfiler::MESSAGE(4, "HeapChecker: "
- "Ignoring object of %"PRIuS" bytes\n", v.bytes);
- }
- }
- }
-}
-
char* GetHeapProfile() {
// We used to be smarter about estimating the required memory and
// then capping it to 1MB and generating the profile into that.
// However it should not cost us much to allocate 1MB every time.
static const int size = 1 << 20;
- int buflen = 0;
+ // This is intended to be normal malloc: we return it to the user to free it
char* buf = reinterpret_cast<char*>(malloc(size));
- if (buf == NULL) {
- return NULL;
- }
-
- Bucket **list = NULL;
-
- // We can't allocate list on the stack, as this would overflow on threads
- // running with a small stack size. We can't allocate it under the lock
- // either, as this would cause a deadlock. But num_buckets is only valid
- // while holding the lock- new buckets can be created at any time otherwise.
- // So we'll read num_buckets dirtily, allocate room for all the current
- // buckets + a few more, and check the count when we get the lock; if we
- // don't have enough, we release the lock and try again.
- while (true) {
- int nb = num_buckets + num_buckets / 16 + 8;
-
- if (list)
- delete[] list;
-
- list = new Bucket *[nb];
-
- // Grab the lock and generate the profile
- // (for leak checking the lock is acquired higher up).
- if (!HeapProfiler::dump_for_leaks_) HeapProfiler::Lock();
- if (!HeapProfiler::is_on_) {
- if (!HeapProfiler::dump_for_leaks_) HeapProfiler::Unlock();
- break;
- }
-
- // Get all buckets and sort
- assert(table != NULL);
-
- // If we have allocated some extra buckets while waiting for the lock, we
- // may have to reallocate list
- if (num_buckets > nb) {
- if (!HeapProfiler::dump_for_leaks_) HeapProfiler::Unlock();
- continue;
- }
-
- int n = 0;
- for (int b = 0; b < kHashTableSize; b++) {
- for (Bucket* x = table[b]; x != 0; x = x->next_) {
- list[n++] = x;
- }
- }
- assert(n == num_buckets);
- sort(list, list + num_buckets, ByAllocatedSpace);
-
- buflen = snprintf(buf, size-1, "heap profile: ");
- buflen = HeapProfiler::UnparseBucket(buf, buflen, size-1,
- &HeapProfiler::total_);
- memset(&HeapProfiler::profile_, 0, sizeof(HeapProfiler::profile_));
- HeapProfiler::AdjustByIgnoredObjects(-1); // drop from profile
- for (int i = 0; i < num_buckets; i++) {
- Bucket* b = list[i];
- buflen = HeapProfiler::UnparseBucket(buf, buflen, size-1, b);
- }
- HeapProfiler::AdjustByIgnoredObjects(1); // add back to profile
- assert(buflen < size);
- if (!HeapProfiler::dump_for_leaks_) HeapProfiler::Unlock();
- break;
- }
+ if (buf == NULL) return NULL;
+ // Grab the lock and generate the profile.
+ heap_lock.Lock();
+ int buflen = is_on ? heap_profile->FillOrderedProfile(buf, size - 1) : 0;
buf[buflen] = '\0';
- delete[] list;
+ RAW_DCHECK(buflen == strlen(buf), "");
+ heap_lock.Unlock();
return buf;
}
-// We keep HeapProfile() as a backwards-compatible name for GetHeapProfile(),
-// but don't export the symbol, so you probably won't be able to call this.
-extern char* HeapProfile() {
- return GetHeapProfile();
-}
+// Helper for HeapProfilerDump.
+static void DumpProfileLocked(const char* reason) {
+ RAW_DCHECK(is_on, "");
+ RAW_DCHECK(!dumping, "");
+
+ if (filename_prefix == NULL) return; // we do not yet need dumping
-void HeapProfiler::DumpLocked(const char *reason, const char* file_name) {
- assert(is_on_);
-
- if (filename_prefix_ == NULL && file_name == NULL) return;
- // we do not yet need dumping
-
- dumping_ = true;
+ dumping = true;
// Make file name
- char fname[1000];
- if (file_name == NULL) {
- dump_count++;
- snprintf(fname, sizeof(fname), "%s.%04d.heap",
- filename_prefix_, dump_count);
- file_name = fname;
- }
+ char file_name[1000];
+ dump_count++;
+ snprintf(file_name, sizeof(file_name), "%s.%04d%s",
+ filename_prefix, dump_count, HeapProfileTable::kFileExt);
// Release allocation lock around the meat of this routine
- // when not leak checking thus not blocking other threads too much,
- // but for leak checking we want to hold the lock to prevent heap activity.
- if (!dump_for_leaks_) HeapProfiler::Unlock();
+ // thus not blocking other threads too much.
+ heap_lock.Unlock();
{
// Dump the profile
- HeapProfiler::MESSAGE(dump_for_leaks_ ? 1 : 0,
- "HeapProfiler: "
- "Dumping heap profile to %s (%s)\n",
- file_name, reason);
+ RAW_VLOG(0, "Dumping heap profile to %s (%s)", file_name, reason);
FILE* f = fopen(file_name, "w");
if (f != NULL) {
- const char* profile = HeapProfile();
+ const char* profile = GetHeapProfile();
fputs(profile, f);
- free(const_cast<char*>(profile));
-
- // Dump "/proc/self/maps" so we get list of mapped shared libraries
- fputs("\nMAPPED_LIBRARIES:\n", f);
- int maps = open("/proc/self/maps", O_RDONLY);
- if (maps >= 0) {
- char buf[100];
- ssize_t r;
- while ((r = read(maps, buf, sizeof(buf))) > 0) {
- fwrite(buf, 1, r, f);
- }
- close(maps);
- }
-
+ free(const_cast<char*>(profile)); // was made with normal malloc
fclose(f);
- f = NULL;
} else {
- HeapProfiler::MESSAGE(0, "HeapProfiler: "
- "FAILED Dumping heap profile to %s (%s)\n",
- file_name, reason);
- if (dump_for_leaks_) abort(); // no sense to continue
+ RAW_LOG(ERROR, "Failed dumping heap profile to %s", file_name);
}
}
+ heap_lock.Lock();
- if (!dump_for_leaks_) HeapProfiler::Lock();
-
- dumping_ = false;
-}
-
-void HeapProfilerDump(const char *reason) {
- if (HeapProfiler::is_on_ && (num_buckets > 0)) {
-
- HeapProfiler::Lock();
- if (!HeapProfiler::dumping_) {
- HeapProfiler::DumpLocked(reason, NULL);
- }
- HeapProfiler::Unlock();
- }
+ dumping = false;
}
-// Allocation map for heap objects (de)allocated
-// while HeapProfiler::self_disable_ is true.
-// We use it to test if heap leak checking itself changed the heap state.
-// An own map seems cleaner than trying to keep everything
-// in HeapProfiler::allocation_.
-HeapProfiler::AllocationMap* self_disabled_allocation = NULL;
-
-// This is the number of bytes allocated by the first call to malloc() after
-// registering this handler. We want to sanity check that our first call is
-// actually for this number of bytes.
-static const int kFirstAllocationNumBytes = 23;
-
-void HeapProfiler::RecordAlloc(void* ptr, size_t bytes, int skip_count) {
- // Our first allocation is triggered in EarlyStartLocked and is intended
- // solely to calibrate strip_frames_, which may be greater or smaller
- // depending on the degree of optimization with which we were compiled.
- if (!done_first_alloc_) {
- done_first_alloc_ = true;
- assert(bytes == kFirstAllocationNumBytes);
- assert(strip_frames_ == 0);
-
- static const int kMaxStackTrace = 32;
- void* stack[kMaxStackTrace];
- // We skip one frame here so that it's as if we are running from NewHook,
- // which is where strip_frames_ is used.
- int depth = GetStackTrace(stack, kMaxStackTrace, 1);
-
- int i;
- for (i = 0; i < depth; i++) {
- if (stack[i] == recordalloc_reference_stack_position_) {
- MESSAGE(1, "Determined strip_frames_ to be %d\n", i - 1);
- // Subtract one to offset the fact that
- // recordalloc_reference_stack_position_ actually records the stack
- // position one frame above the spot in EarlyStartLocked where we are
- // called from.
- strip_frames_ = i - 1;
- }
- }
- // Fell through the loop without finding our parent
- if (strip_frames_ == 0) {
- MESSAGE(0, "Could not determine strip_frames_, aborting");
- abort();
- }
-
- // Return without recording the allocation. We will free the memory before
- // registering a DeleteHook.
- return;
- }
-
- // this locking before if (is_on_ ...)
- // is not an overhead because with profiling off
- // this hook is not called at all.
-
- if (kMaxLogging) {
- HeapProfiler::MESSAGE(7, "HeapProfiler: Alloc: %p of %"PRIuS" from %d\n",
- ptr, bytes, int(pthread_self()));
- }
-
- if (self_disable_ && self_disabled_tid_ == pthread_self()) {
- self_disabled_.allocs_++;
- self_disabled_.alloc_size_ += bytes;
- AllocValue v;
- v.bucket = NULL; // initialize just to make smart tools happy
- // (no one will read it)
- v.bytes = bytes;
- self_disabled_allocation->Insert(ptr, v);
- return;
- }
-
- HeapProfiler::Lock();
- if (is_on_) {
- Bucket* b = GetBucket(skip_count+1);
- b->allocs_++;
- b->alloc_size_ += bytes;
- total_.allocs_++;
- total_.alloc_size_ += bytes;
-
- AllocValue v;
- v.bucket = b;
- v.bytes = bytes;
- allocation_->Insert(ptr, v);
-
- if (kMaxLogging) {
- HeapProfiler::MESSAGE(8, "HeapProfiler: Alloc Recorded: %p of %"PRIuS"\n",
- ptr, bytes);
- }
+//----------------------------------------------------------------------
+// Profile collection
+//----------------------------------------------------------------------
- const int64 inuse_bytes = total_.alloc_size_ - total_.free_size_;
- if (!dumping_) {
- bool need_dump = false;
+// Record an allocation in the profile.
+static void RecordAlloc(void* ptr, size_t bytes, int skip_count) {
+ heap_lock.Lock();
+ if (is_on) {
+ heap_profile->RecordAlloc(ptr, bytes, skip_count + 1);
+ const HeapProfileTable::Stats& total = heap_profile->total();
+ const int64 inuse_bytes = total.alloc_size - total.free_size;
+ if (!dumping) {
+ bool need_to_dump = false;
char buf[128];
- if (total_.alloc_size_ >=
+ if (total.alloc_size >=
last_dump + FLAGS_heap_profile_allocation_interval) {
- snprintf(buf, sizeof(buf), "%"LLD" MB allocated",
- total_.alloc_size_ >> 20);
+ snprintf(buf, sizeof(buf), "%"PRId64" MB allocated",
+ total.alloc_size >> 20);
// Track that we made a "total allocation size" dump
- last_dump = total_.alloc_size_;
- need_dump = true;
- } else if(inuse_bytes >
- high_water_mark + FLAGS_heap_profile_inuse_interval) {
- sprintf(buf, "%"LLD" MB in use", inuse_bytes >> 20);
+ last_dump = total.alloc_size;
+ need_to_dump = true;
+ } else if (inuse_bytes >
+ high_water_mark + FLAGS_heap_profile_inuse_interval) {
+ sprintf(buf, "%"PRId64" MB in use", inuse_bytes >> 20);
// Track that we made a "high water mark" dump
high_water_mark = inuse_bytes;
- need_dump = true;
+ need_to_dump = true;
}
-
- if (need_dump) {
- // Dump profile
- DumpLocked(buf, NULL);
+ if (need_to_dump) {
+ DumpProfileLocked(buf);
}
}
}
- HeapProfiler::Unlock();
-}
-
-void HeapProfiler::RecordFree(void* ptr) {
- // All activity before if (is_on_)
- // is not an overhead because with profiling turned off this hook
- // is not called at all.
-
- if (kMaxLogging) {
- HeapProfiler::MESSAGE(7, "HeapProfiler: Free %p from %d\n",
- ptr, int(pthread_self()));
- }
-
- if (self_disable_ && self_disabled_tid_ == pthread_self()) {
- AllocValue v;
- if (self_disabled_allocation->FindAndRemove(ptr, &v)) {
- self_disabled_.free_size_ += v.bytes;
- self_disabled_.frees_++;
- } else {
- // Try to mess the counters up and fail later in
- // HeapLeakChecker::DumpProfileLocked instead of failing right now:
- // presently execution gets here only from within the guts
- // of pthread library and only when being in an address space
- // that is about to disappear completely.
- // I.e. failing right here is wrong, but failing later if
- // this happens in the course of normal execution is needed.
- self_disabled_.free_size_ += 100000000;
- self_disabled_.frees_ += 100000000;
- }
- return;
- }
-
- HeapProfiler::Lock();
- if (is_on_) {
- AllocValue v;
- if (allocation_->FindAndRemove(ptr, &v)) {
- Bucket* b = v.bucket;
- b->frees_++;
- b->free_size_ += v.bytes;
- total_.frees_++;
- total_.free_size_ += v.bytes;
-
- if (kMaxLogging) {
- HeapProfiler::MESSAGE(8, "HeapProfiler: Free Recorded: %p\n", ptr);
- }
- }
- }
- HeapProfiler::Unlock();
+ heap_lock.Unlock();
}
-bool HeapProfiler::HaveOnHeapLocked(void** ptr, AllocValue* alloc_value) {
- assert(is_on_);
- // Size of the C++ object array size integer
- // (potentially compiler/dependent; 4 on i386 and gcc)
- const int kArraySizeOffset = sizeof(int);
- // sizeof(basic_string<...>::_Rep) for C++ library of gcc 3.4
- // (basically three integer counters;
- // library/compiler dependent; 12 on i386 and gcc)
- const int kStringOffset = sizeof(int) * 3;
- // NOTE: One can add more similar offset cases below
- // even when they do not happen for the used compiler/library;
- // all that's impacted is
- // - HeapLeakChecker's performace during live heap walking
- // - and a slightly greater chance to mistake random memory bytes
- // for a pointer and miss a leak in a particular run of a binary.
- bool result = true;
- if (allocation_->Find(*ptr, alloc_value)) {
- // done
- } else if (allocation_->Find(reinterpret_cast<char*>(*ptr)
- - kArraySizeOffset,
- alloc_value) &&
- alloc_value->bytes > kArraySizeOffset) {
- // this case is to account for the array size stored inside of
- // the memory allocated by new FooClass[size] for classes with destructors
- *ptr = reinterpret_cast<char*>(*ptr) - kArraySizeOffset;
- if (kMaxLogging) {
- HeapProfiler::MESSAGE(7, "HeapProfiler: Got poiter into %p at +%d\n",
- ptr, kArraySizeOffset);
- }
- } else if (allocation_->Find(reinterpret_cast<char*>(*ptr)
- - kStringOffset,
- alloc_value) &&
- alloc_value->bytes > kStringOffset) {
- // this case is to account for basic_string<> representation in
- // newer C++ library versions when the kept pointer points to inside of
- // the allocated region
- *ptr = reinterpret_cast<char*>(*ptr) - kStringOffset;
- if (kMaxLogging) {
- HeapProfiler::MESSAGE(7, "HeapProfiler: Got poiter into %p at +%d\n",
- ptr, kStringOffset);
- }
- } else {
- result = false;
+// Record a deallocation in the profile.
+static void RecordFree(void* ptr) {
+ heap_lock.Lock();
+ if (is_on) {
+ heap_profile->RecordFree(ptr);
}
- return result;
+ heap_lock.Unlock();
}
-bool HeapProfiler::HaveOnHeap(void** ptr, AllocValue* alloc_value) {
- HeapProfiler::Lock();
- bool result = is_on_ && HaveOnHeapLocked(ptr, alloc_value);
- HeapProfiler::Unlock();
- return result;
-}
//----------------------------------------------------------------------
-// Allocation/deallocation hooks
+// Allocation/deallocation hooks for MallocHook
//----------------------------------------------------------------------
-void HeapProfiler::NewHook(void* ptr, size_t size) {
- if (ptr != NULL) RecordAlloc(ptr, size, strip_frames_);
+static void NewHook(void* ptr, size_t size) {
+ if (ptr != NULL) RecordAlloc(ptr, size, 0);
}
-void HeapProfiler::DeleteHook(void* ptr) {
+static void DeleteHook(void* ptr) {
if (ptr != NULL) RecordFree(ptr);
}
-void HeapProfiler::MmapHook(void* result,
- void* start, size_t size,
- int prot, int flags,
- int fd, off_t offset) {
+static void MmapHook(void* result, void* start, size_t size,
+ int prot, int flags, int fd, off_t offset) {
// Log the mmap if necessary
if (FLAGS_mmap_log) {
char buf[200];
+ // We use PRIxS not just '%p' to avoid deadlocks
+ // in pretty-printing of NULL as "nil".
+ // TODO(maxim): instead should use a safe snprintf reimplementation
snprintf(buf, sizeof(buf),
- "mmap(start=%p, len=%"PRIuS", prot=0x%x, flags=0x%x, "
- "fd=%d, offset=0x%x) = %p",
- start, size, prot, flags, fd, (unsigned int) offset,
- result);
- LOGF << buf;
+ "mmap(start=0x%"PRIxS", len=%"PRIuS", prot=0x%x, flags=0x%x, "
+ "fd=%d, offset=0x%x) = 0x%"PRIxS"",
+ (uintptr_t) start, size, prot, flags, fd, (unsigned int) offset,
+ (uintptr_t) result);
+ LOG(INFO, "%s", buf);
// TODO(jandrews): Re-enable stack tracing
//DumpStackTrace(1, DebugWriteToStream, &LOG(INFO));
}
// Record mmap in profile if appropriate
- if (result != (void*) MAP_FAILED &&
- FLAGS_mmap_profile &&
- is_on_) {
-
- RecordAlloc(result, size, strip_frames_);
+ if (FLAGS_mmap_profile && result != (void*) MAP_FAILED) {
+ RecordAlloc(result, size, 0);
}
}
-void HeapProfiler::MunmapHook(void* ptr, size_t size) {
- if (FLAGS_mmap_profile && is_on_) {
+static void MunmapHook(void* ptr, size_t size) {
+ if (FLAGS_mmap_profile) {
RecordFree(ptr);
}
if (FLAGS_mmap_log) {
char buf[200];
- snprintf(buf, sizeof(buf), "munmap(start=%p, len=%"PRIuS")", ptr, size);
- LOGF << buf;
+ // We use PRIxS not just '%p' to avoid deadlocks
+ // in pretty-printing of NULL as "nil".
+ // TODO(maxim): instead should use a safe snprintf reimplementation
+ snprintf(buf, sizeof(buf),
+ "munmap(start=0x%"PRIxS", len=%"PRIuS")", (uintptr_t) ptr, size);
+ LOG(INFO, "%s", buf);
}
}
//----------------------------------------------------------------------
-// Profiler maintenance
+// Starting/stopping/dumping
//----------------------------------------------------------------------
-Bucket* HeapProfiler::GetBucket(int skip_count) {
- // Get raw stack trace
- static const int kMaxStackTrace = 32;
- void* key[kMaxStackTrace];
- int depth = GetStackTrace(key, kMaxStackTrace, skip_count+1);
-
- // Make hash-value
- uintptr_t h = 0;
- for (int i = 0; i < depth; i++) {
- uintptr_t pc = reinterpret_cast<uintptr_t>(key[i]);
- h = (h << 8) | (h >> (8*(sizeof(h)-1)));
- h += (pc * 31) + (pc * 7) + (pc * 3);
- }
-
- // Lookup stack trace in table
- const size_t key_size = sizeof(key[0]) * depth;
- unsigned int buck = ((unsigned int) h) % kHashTableSize;
- for (Bucket* b = table[buck]; b != 0; b = b->next_) {
- if ((b->hash_ == h) &&
- (b->depth_ == depth) &&
- (memcmp(b->stack_, key, key_size) == 0)) {
- return b;
- }
- }
-
- // Create new bucket
- void** kcopy = reinterpret_cast<void**>(Malloc(key_size));
- memcpy(kcopy, key, key_size);
- Bucket* b = reinterpret_cast<Bucket*>(Malloc(sizeof(Bucket)));
- memset(b, 0, sizeof(*b));
- b->hash_ = h;
- b->depth_ = depth;
- b->stack_ = kcopy;
- b->next_ = table[buck];
- table[buck] = b;
- num_buckets++;
- total_stack_depth += depth;
- return b;
-}
+void HeapProfilerStart(const char* prefix) {
+ heap_lock.Lock();
-void HeapProfiler::EarlyStartLocked() {
- assert(!is_on_);
+ if (filename_prefix != NULL) return;
- heap_profiler_memory.Init();
+ RAW_DCHECK(!is_on, "");
- is_on_ = true;
- // we should be really turned off:
- if (need_for_leaks_) abort();
- if (self_disable_) abort();
- if (filename_prefix_ != NULL) abort();
+ heap_profiler_memory = LowLevelAlloc::NewArena(0, 0);
- // Make the table
- const int table_bytes = kHashTableSize * sizeof(Bucket*);
- table = reinterpret_cast<Bucket**>(Malloc(table_bytes));
- memset(table, 0, table_bytes);
+ heap_profile = new (ProfilerMalloc(sizeof(HeapProfileTable)))
+ HeapProfileTable(ProfilerMalloc, ProfilerFree);
- // Make allocation map
- void* aptr = Malloc(sizeof(AllocationMap));
- allocation_ = new (aptr) AllocationMap(Malloc, Free);
+ is_on = true;
- memset(&total_, 0, sizeof(total_));
- num_buckets = 0;
- total_stack_depth = 0;
last_dump = 0;
+
// We do not reset dump_count so if the user does a sequence of
// HeapProfilerStart/HeapProfileStop, we will get a continuous
// sequence of profiles.
// Now set the hooks that capture mallocs/frees
MallocHook::SetNewHook(NewHook);
-
- // Our first allocation after registering our hook is treated specially by
- // RecordAlloc(); It looks at the stack and counts how many frames up we
- // are. First we record the current stack pointer.
- // Note: The stacktrace implementations differ about how many args they
- // fill when skip is non-zero. Safest just to reserve maxdepth space.
- void* here[2];
- GetStackTrace(here, 2, 1);
- // Skip the first frame. It points to the current offset within this
- // function, which will have changed by the time we get to the malloc()
- // call which triggers. Instead, we store our parent function's offset,
- // which is shared by both us and by the malloc() call below.
- recordalloc_reference_stack_position_ = here[0];
- done_first_alloc_ = false; // Initialization has not occured yet
- void* first_alloc = malloc(kFirstAllocationNumBytes);
- free(first_alloc);
-
MallocHook::SetDeleteHook(DeleteHook);
-
- HeapProfiler::MESSAGE(1, "HeapProfiler: Starting heap tracking\n");
-}
-
-void HeapProfiler::StartLocked(const char* prefix) {
- if (filename_prefix_ != NULL) return;
-
- if (!is_on_) {
- EarlyStartLocked();
- }
+ RAW_VLOG(0, "Starting tracking the heap");
// Copy filename prefix
const int prefix_length = strlen(prefix);
- filename_prefix_ = reinterpret_cast<char*>(Malloc(prefix_length + 1));
- memcpy(filename_prefix_, prefix, prefix_length);
- filename_prefix_[prefix_length] = '\0';
-}
+ filename_prefix = reinterpret_cast<char*>(ProfilerMalloc(prefix_length + 1));
+ memcpy(filename_prefix, prefix, prefix_length);
+ filename_prefix[prefix_length] = '\0';
-void HeapProfiler::StopLocked() {
- if (!is_on_) return;
+ heap_lock.Unlock();
- filename_prefix_ = NULL;
+ // This should be done before the hooks are set up, since it should
+ // call new, and we want that to be accounted for correctly.
+ MallocExtension::Initialize();
+}
- if (need_for_leaks_) return;
+void HeapProfilerStop() {
+ heap_lock.Lock();
+
+ if (!is_on) return;
- // Turn us off completely:
+ filename_prefix = NULL;
MallocHook::SetNewHook(NULL);
MallocHook::SetDeleteHook(NULL);
- // Get rid of all memory we allocated
- heap_profiler_memory.Clear();
-
- table = NULL;
- allocation_ = NULL;
- is_on_ = false;
-}
-
-void HeapProfiler::StartForLeaks() {
- Lock();
+ // free profile
+ heap_profile->~HeapProfileTable();
+ ProfilerFree(heap_profile);
+ heap_profile = NULL;
+
+ // free prefix
+ ProfilerFree(filename_prefix);
+ filename_prefix = NULL;
- if (!is_on_) {
- EarlyStartLocked(); // fire-up HeapProfiler hooks
+ if (!LowLevelAlloc::DeleteArena(heap_profiler_memory)) {
+ RAW_LOG(FATAL, "Memory leak in HeapProfiler:");
}
- need_for_leaks_ = true;
- memset(&self_disabled_, 0, sizeof(self_disabled_)); // zero the counters
+ is_on = false;
- // Make allocation map for self-disabled allocations
- void* aptr = Malloc(sizeof(AllocationMap));
- self_disabled_allocation = new (aptr) AllocationMap(Malloc, Free);
-
- Unlock();
-}
-
-void HeapProfiler::StopForLeaks() {
- Lock();
- need_for_leaks_ = false;
- if (filename_prefix_ == NULL) StopLocked();
- Unlock();
-}
-
-void HeapProfilerStart(const char* prefix) {
- HeapProfiler::Lock();
- HeapProfiler::StartLocked(prefix);
- HeapProfiler::Unlock();
+ heap_lock.Unlock();
}
-void HeapProfilerStop() {
- HeapProfiler::Lock();
- HeapProfiler::StopLocked();
- HeapProfiler::Unlock();
+void HeapProfilerDump(const char *reason) {
+ heap_lock.Lock();
+ if (is_on && !dumping) {
+ DumpProfileLocked(reason);
+ }
+ heap_lock.Unlock();
}
//----------------------------------------------------------------------
@@ -964,19 +366,7 @@ void HeapProfilerStop() {
//----------------------------------------------------------------------
// Initialization code
-void HeapProfiler::Init() {
- // depending on the ordering of the global constructors (undefined
- // according to the C++ spec, HeapProfiler::Init() can either be
- // called from this file directly, or from heap-checker.cc's global
- // constructor if it gets run first. Either way is fine by us; we
- // just want to be sure not to run twice.
- if (init_has_been_called_) return; // we were already run, I guess
- init_has_been_called_ = true;
-
- // We want to make sure tcmalloc is set up properly, in order to
- // profile as much as we can.
- MallocExtension::Initialize();
-
+static void HeapProfilerInit() {
if (FLAGS_mmap_profile || FLAGS_mmap_log) {
MallocHook::SetMmapHook(MmapHook);
MallocHook::SetMunmapHook(MunmapHook);
@@ -990,8 +380,8 @@ void HeapProfiler::Init() {
}
// We do a uid check so we don't write out files in a setuid executable.
if (getuid() != geteuid()) {
- HeapProfiler::MESSAGE(0, ("HeapProfiler: ignoring HEAPPROFILE because "
- "program seems to be setuid\n"));
+ RAW_LOG(WARNING, ("HeapProfiler: ignoring HEAPPROFILE because "
+ "program seems to be setuid\n"));
return;
}
@@ -1019,40 +409,15 @@ void HeapProfiler::Init() {
heapprofile[0] |= 128; // set high bit for kids to see
}
- CleanupProfiles(fname);
+ HeapProfileTable::CleanupOldProfiles(fname);
HeapProfilerStart(fname);
}
-void HeapProfiler::CleanupProfiles(const char* prefix) {
- if (!FLAGS_cleanup_old_heap_profiles)
- return;
- string pattern(prefix);
- pattern += ".*.heap";
- glob_t g;
- const int r = glob(pattern.c_str(), GLOB_ERR, NULL, &g);
- if (r == 0 || r == GLOB_NOMATCH) {
- const int prefix_length = strlen(prefix);
- for (int i = 0; i < g.gl_pathc; i++) {
- const char* fname = g.gl_pathv[i];
- if ((strlen(fname) >= prefix_length) &&
- (memcmp(fname, prefix, prefix_length) == 0)) {
- HeapProfiler::MESSAGE(0, "HeapProfiler: "
- "Removing old profile %s\n", fname);
- unlink(fname);
- }
- }
- }
- globfree(&g);
-}
-
// class used for finalization -- dumps the heap-profile at program exit
-class HeapProfileEndWriter {
- public:
- ~HeapProfileEndWriter() {
- HeapProfilerDump("Exiting");
- }
+struct HeapProfileEndWriter {
+ ~HeapProfileEndWriter() { HeapProfilerDump("Exiting"); }
};
-REGISTER_MODULE_INITIALIZER(heapprofile, HeapProfiler::Init());
+REGISTER_MODULE_INITIALIZER(heapprofiler, HeapProfilerInit());
static HeapProfileEndWriter heap_profile_end_writer;
diff --git a/src/internal_logging.cc b/src/internal_logging.cc
index 8c403c5..60d6f31 100644
--- a/src/internal_logging.cc
+++ b/src/internal_logging.cc
@@ -35,8 +35,6 @@
#include <string.h>
#include "internal_logging.h"
-int TCMallocDebug::level;
-
void TCMalloc_MESSAGE(const char* format, ...) {
va_list ap;
va_start(ap, format);
diff --git a/src/internal_logging.h b/src/internal_logging.h
index 10d8502..b355ea0 100644
--- a/src/internal_logging.h
+++ b/src/internal_logging.h
@@ -44,12 +44,6 @@
// Utility routines
//-------------------------------------------------------------------
-struct TCMallocDebug {
- static int level;
-
- enum { kNone, kInfo, kVerbose };
-};
-
// Safe debugging routine: we write directly to the stderr file
// descriptor and avoid FILE buffering because that may invoke
// malloc()
diff --git a/src/internal_spinlock.h b/src/internal_spinlock.h
deleted file mode 100644
index 79c1279..0000000
--- a/src/internal_spinlock.h
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright (c) 2005, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// ---
-// Author: Sanjay Ghemawat <opensource@google.com>
-
-#ifndef TCMALLOC_INTERNAL_SPINLOCK_H__
-#define TCMALLOC_INTERNAL_SPINLOCK_H__
-
-#include "config.h"
-#include <time.h> /* For nanosleep() */
-#include <sched.h> /* For sched_yield() */
-#if defined HAVE_STDINT_H
-#include <stdint.h>
-#elif defined HAVE_INTTYPES_H
-#include <inttypes.h>
-#else
-#include <sys/types.h>
-#endif
-#include <stdlib.h> /* for abort() */
-
-#if (defined __i386__ || defined __x86_64__) && defined __GNUC__
-
-static void TCMalloc_SlowLock(volatile unsigned int* lockword);
-
-// The following is a struct so that it can be initialized at compile time
-struct TCMalloc_SpinLock {
- volatile unsigned int private_lockword_;
-
- inline void Init() { private_lockword_ = 0; }
- inline void Finalize() { }
-
- inline void Lock() {
- int r;
- __asm__ __volatile__
- ("xchgl %0, %1"
- : "=r"(r), "=m"(private_lockword_)
- : "0"(1), "m"(private_lockword_)
- : "memory");
- if (r) TCMalloc_SlowLock(&private_lockword_);
- }
-
- inline void Unlock() {
- __asm__ __volatile__
- ("movl $0, %0"
- : "=m"(private_lockword_)
- : "m" (private_lockword_)
- : "memory");
- }
-};
-
-#define SPINLOCK_INITIALIZER { 0 }
-
-static void TCMalloc_SlowLock(volatile unsigned int* lockword) {
- sched_yield(); // Yield immediately since fast path failed
- while (true) {
- int r;
- __asm__ __volatile__
- ("xchgl %0, %1"
- : "=r"(r), "=m"(*lockword)
- : "0"(1), "m"(*lockword)
- : "memory");
- if (!r) {
- return;
- }
-
- // This code was adapted from the ptmalloc2 implementation of
- // spinlocks which would sched_yield() upto 50 times before
- // sleeping once for a few milliseconds. Mike Burrows suggested
- // just doing one sched_yield() outside the loop and always
- // sleeping after that. This change helped a great deal on the
- // performance of spinlocks under high contention. A test program
- // with 10 threads on a dual Xeon (four virtual processors) went
- // from taking 30 seconds to 16 seconds.
-
- // Sleep for a few milliseconds
- struct timespec tm;
- tm.tv_sec = 0;
- tm.tv_nsec = 2000001;
- nanosleep(&tm, NULL);
- }
-}
-
-#else
-
-#include <pthread.h>
-
-// Portable version
-struct TCMalloc_SpinLock {
- pthread_mutex_t private_lock_;
-
- inline void Init() {
- if (pthread_mutex_init(&private_lock_, NULL) != 0) abort();
- }
- inline void Finalize() {
- if (pthread_mutex_destroy(&private_lock_) != 0) abort();
- }
- inline void Lock() {
- if (pthread_mutex_lock(&private_lock_) != 0) abort();
- }
- inline void Unlock() {
- if (pthread_mutex_unlock(&private_lock_) != 0) abort();
- }
-};
-
-#define SPINLOCK_INITIALIZER { PTHREAD_MUTEX_INITIALIZER }
-
-#endif
-
-// Corresponding locker object that arranges to acquire a spinlock for
-// the duration of a C++ scope.
-class TCMalloc_SpinLockHolder {
- private:
- TCMalloc_SpinLock* lock_;
- public:
- inline explicit TCMalloc_SpinLockHolder(TCMalloc_SpinLock* l)
- : lock_(l) { l->Lock(); }
- inline ~TCMalloc_SpinLockHolder() { lock_->Unlock(); }
-};
-
-// Short-hands for convenient use by tcmalloc.cc
-typedef TCMalloc_SpinLock SpinLock;
-typedef TCMalloc_SpinLockHolder SpinLockHolder;
-
-#endif // TCMALLOC_INTERNAL_SPINLOCK_H__
diff --git a/src/malloc_extension.cc b/src/malloc_extension.cc
index 686b4bc..39af35f 100644
--- a/src/malloc_extension.cc
+++ b/src/malloc_extension.cc
@@ -112,6 +112,14 @@ void** MallocExtension::ReadHeapGrowthStackTraces() {
return NULL;
}
+void MallocExtension::MarkThreadIdle() {
+ // Default implementation does nothing
+}
+
+void MallocExtension::ReleaseFreeMemory() {
+ // Default implementation does nothing
+}
+
// The current malloc extension object. We also keep a pointer to
// the default implementation so that the heap-leak checker does not
// complain about a memory leak.
@@ -159,11 +167,13 @@ void* PC(void** entry, int i) {
struct StackTraceHash {
size_t operator()(void** entry) const {
uintptr_t h = 0;
- for (unsigned int i = 0; i < Depth(entry); i++) {
- uintptr_t pc = reinterpret_cast<uintptr_t>(PC(entry, i));
- h = (h << 8) | (h >> (8*(sizeof(h)-1)));
- h += (pc * 31) + (pc * 7) + (pc * 3);
+ for (int i = 0; i < Depth(entry); i++) {
+ h += reinterpret_cast<uintptr_t>(PC(entry, i));
+ h += h << 10;
+ h ^= h >> 6;
}
+ h += h << 3;
+ h ^= h >> 11;
return h;
}
// Less operator for MSVC's hash containers.
@@ -267,11 +277,11 @@ void MallocExtension::GetHeapSample(string* result) {
delete[] entries;
}
-void MallocExtension::GetHeapGrowthStacks(std::string* result) {
+void MallocExtension::GetHeapGrowthStacks(string* result) {
void** entries = ReadHeapGrowthStackTraces();
if (entries == NULL) {
*result += "This malloc implementation does not support "
- "ReadHeapGrowhStackTraces().\n"
+ "ReadHeapGrowthStackTraces().\n"
"As of 2005/09/27, only tcmalloc supports this, and you\n"
"are probably running a binary that does not use tcmalloc.\n";
return;
diff --git a/src/malloc_hook.cc b/src/malloc_hook.cc
index 613e612..d29f15b 100644
--- a/src/malloc_hook.cc
+++ b/src/malloc_hook.cc
@@ -30,21 +30,202 @@
// ---
// Author: Sanjay Ghemawat <opensource@google.com>
+#include "config.h"
+
+// Disable the glibc prototype of mremap(), as older versions of the
+// system headers define this function with only four arguments,
+// whereas newer versions allow an optional fifth argument:
+#define mremap glibc_mremap
+#include <sys/mman.h>
+#undef mremap
+
#include <google/malloc_hook.h>
#include "base/basictypes.h"
-#include "base/linux_syscall_support.h"
+#include "base/logging.h"
+#include <google/stacktrace.h>
+
+// __THROW is defined in glibc systems. It means, counter-intuitively,
+// "This function will never throw an exception." It's an optional
+// optimization tool, but we may need to use it to match glibc prototypes.
+#ifndef __THROW // I guess we're not on a glibc system
+# define __THROW // __THROW is just an optimization, so ok to make it ""
+#endif
+
+// Declarations of three default weak hook functions, that can be overridden by
+// linking-in a strong definition (as heap-checker.cc does)
+//
+// These default hooks let some other library we link in
+// to define strong versions of InitialMallocHook_New, InitialMallocHook_MMap,
+// and InitialMallocHook_Sbrk to have a chance to hook into the very
+// first invocation of an allocation function call, mmap, or sbrk.
+//
+// These functions are declared here as weak, and defined later, rather than a
+// more straightforward simple weak definition, as a workround for an icc
+// compiler issue ((Intel reference 290819). This issue causes icc to resolve
+// weak symbols too early, at compile rather than link time. By declaring it
+// (weak) here, then defining it below after its use, we can avoid the problem.
+//
+ATTRIBUTE_WEAK
+extern void InitialMallocHook_New(void* ptr, size_t size);
+
+ATTRIBUTE_WEAK
+extern void InitialMallocHook_MMap(void* result,
+ void* start,
+ size_t size,
+ int protection,
+ int flags,
+ int fd,
+ off_t offset);
+
+ATTRIBUTE_WEAK
+extern void InitialMallocHook_Sbrk(void* result, ptrdiff_t increment);
-MallocHook::NewHook MallocHook::new_hook_ = NULL;
+MallocHook::NewHook MallocHook::new_hook_ = InitialMallocHook_New;
MallocHook::DeleteHook MallocHook::delete_hook_ = NULL;
-MallocHook::MmapHook MallocHook::mmap_hook_ = NULL;
+MallocHook::MmapHook MallocHook::mmap_hook_ = InitialMallocHook_MMap;
MallocHook::MunmapHook MallocHook::munmap_hook_ = NULL;
+MallocHook::MremapHook MallocHook::mremap_hook_ = NULL;
+MallocHook::SbrkHook MallocHook::sbrk_hook_ = InitialMallocHook_Sbrk;
-// On Linux/x86, we override mmap/munmap and provide support for
-// calling the related hooks.
+// The definitions of weak default malloc hooks (New, MMap, and Sbrk)
+// that self deinstall on their first call. This is entirely for
+// efficiency: the default version of these functions will be called a
+// maximum of one time. If these functions were a no-op instead, they'd
+// be called every time, costing an extra function call per malloc.
//
-// We define mmap() and mmap64(), which somewhat reimplements libc's mmap
-// syscall stubs. Unfortunately libc only exports the stubs via weak symbols
-// (which we're overriding with our mmap64() and mmap() wrappers) so we can't
+// However, this 'delete self' isn't safe in general -- it's possible
+// that this function will be called via a daisy chain. That is,
+// someone else might do
+// old_hook = MallocHook::SetNewHook(&myhook);
+// void myhook(void* ptr, size_t size) {
+// do_my_stuff();
+// old_hook(ptr, size); // daisy-chain the hooks
+// }
+// If old_hook is InitialMallocHook_New(), then this is broken code! --
+// after the first run it'll deregister not only InitialMallocHook_New()
+// but also myhook. To protect against that, InitialMallocHook_New()
+// makes sure it's the 'top-level' hook before doing the deregistration.
+// This means the daisy-chain case will be less efficient because the
+// hook will be called, and do an if check, for every new. Alas.
+// TODO(csilvers): add support for removing a hook from the middle of a chain.
+
+void InitialMallocHook_New(void* ptr, size_t size) {
+ if (MallocHook::GetNewHook() == &InitialMallocHook_New)
+ MallocHook::SetNewHook(NULL);
+}
+
+void InitialMallocHook_MMap(void* result,
+ void* start,
+ size_t size,
+ int protection,
+ int flags,
+ int fd,
+ off_t offset) {
+ if (MallocHook::GetMmapHook() == &InitialMallocHook_MMap)
+ MallocHook::SetMmapHook(NULL);
+}
+
+void InitialMallocHook_Sbrk(void* result, ptrdiff_t increment) {
+ if (MallocHook::GetSbrkHook() == &InitialMallocHook_Sbrk)
+ MallocHook::SetSbrkHook(NULL);
+}
+
+DECLARE_ATTRIBUTE_SECTION(google_malloc_allocators);
+ // actual functions are in debugallocation.cc or tcmalloc.cc
+DECLARE_ATTRIBUTE_SECTION(malloc_hook_callers);
+ // actual functions are in this file, malloc_hook.cc, and low_level_alloc.cc
+
+#define ADDR_IN_ATTRIBUTE_SECTION(addr, name) \
+ (reinterpret_cast<uintptr_t>(ATTRIBUTE_SECTION_START(name)) <= \
+ reinterpret_cast<uintptr_t>(addr) && \
+ reinterpret_cast<uintptr_t>(addr) < \
+ reinterpret_cast<uintptr_t>(ATTRIBUTE_SECTION_STOP(name)))
+
+// Return true iff 'caller' is a return address within a function
+// that calls one of our hooks via MallocHook:Invoke*.
+// A helper for GetCallerStackTrace.
+static inline bool InHookCaller(void* caller) {
+ return ADDR_IN_ATTRIBUTE_SECTION(caller, google_malloc_allocators) ||
+ ADDR_IN_ATTRIBUTE_SECTION(caller, malloc_hook_callers);
+ // We can use one section for everything except tcmalloc_or_debug
+ // due to its special linkage mode, which prevents merging of the sections.
+}
+
+#undef ADDR_IN_ATTRIBUTE_SECTION
+
+static bool checked_sections = false;
+
+static inline void CheckInHookCaller() {
+ if (!checked_sections) {
+ if (ATTRIBUTE_SECTION_START(google_malloc_allocators) ==
+ ATTRIBUTE_SECTION_STOP(google_malloc_allocators)) {
+ RAW_LOG(ERROR, "google_malloc_allocators section is missing, "
+ "thus InHookCaller is broken!");
+ }
+ if (ATTRIBUTE_SECTION_START(malloc_hook_callers) ==
+ ATTRIBUTE_SECTION_STOP(malloc_hook_callers)) {
+ RAW_LOG(ERROR, "malloc_hook_callers section is missing, "
+ "thus InHookCaller is broken!");
+ }
+ checked_sections = true;
+ }
+}
+
+// We can improve behavior/compactness of this function
+// if we pass a generic test function (with a generic arg)
+// into the implementations for GetStackTrace instead of the skip_count.
+int MallocHook::GetCallerStackTrace(void** result, int max_depth,
+ int skip_count) {
+#ifndef HAVE___ATTRIBUTE__
+ // Fall back to GetStackTrace and good old but fragile frame skip counts.
+ // Note: this path is inaccurate when a hook is not called directly by an
+ // allocation function but is daisy-chained through another hook,
+ // search for MallocHook::(Get|Set|Invoke)* to find such cases.
+ return GetStackTrace(result, max_depth, skip_count + int(DEBUG_MODE));
+ // due to -foptimize-sibling-calls in opt mode
+ // there's no need for extra frame skip here then
+ }
+#endif
+ CheckInHookCaller();
+ // MallocHook caller determination via InHookCaller works, use it:
+ static const int kMaxSkip = 32 + 6 + 3;
+ // Constant tuned to do just one GetStackTrace call below in practice
+ // and not get many frames that we don't actually need:
+ // currently max passsed max_depth is 32,
+ // max passed/needed skip_count is 6
+ // and 3 is to account for some hook daisy chaining.
+ static const int kStackSize = kMaxSkip + 1;
+ void* stack[kStackSize];
+ int depth = GetStackTrace(stack, kStackSize, 1); // skip this function frame
+ if (depth == 0) // silenty propagate cases when GetStackTrace does not work
+ return 0;
+ for (int i = 0; i < depth; ++i) { // stack[0] is our immediate caller
+ if (InHookCaller(stack[i])) {
+ RAW_VLOG(4, "Found hooked allocator at %d: %p <- %p",
+ i, stack[i], stack[i+1]);
+ i += 1; // skip hook caller frame
+ depth -= i; // correct depth
+ if (depth > max_depth) depth = max_depth;
+ memcpy(result, stack+i, depth * sizeof(stack[0]));
+ if (depth < max_depth && depth + i == kStackSize) {
+ // get frames for the missing depth
+ depth +=
+ GetStackTrace(result + depth, max_depth - depth, 1 + kStackSize);
+ }
+ return depth;
+ }
+ }
+ RAW_LOG(WARNING, "Hooked allocator frame not found, returning empty trace");
+ // Try increasing kMaxSkip or else something must be wrong with InHookCaller
+ return 0;
+}
+
+// On Linux/x86, we override mmap/munmap/mremap/sbrk
+// and provide support for calling the related hooks.
+//
+// We define mmap() and mmap64(), which somewhat reimplements libc's mmap
+// syscall stubs. Unfortunately libc only exports the stubs via weak symbols
+// (which we're overriding with our mmap64() and mmap() wrappers) so we can't
// just call through to them.
@@ -53,16 +234,16 @@ MallocHook::MunmapHook MallocHook::munmap_hook_ = NULL;
#include <syscall.h>
#include <sys/mman.h>
#include <errno.h>
+#include "base/linux_syscall_support.h"
// The x86-32 case and the x86-64 case differ:
// 32b has a mmap2() syscall, 64b does not.
// 64b and 32b have different calling conventions for mmap().
-# if defined(__i386__)
-
-extern "C" void* mmap64(void *start, size_t length,
- int prot, int flags,
- int fd, __off64_t offset) __THROW {
+#if defined(__i386__)
+static inline void* do_mmap64(void *start, size_t length,
+ int prot, int flags,
+ int fd, __off64_t offset) __THROW {
void *result;
// Try mmap2() unless it's not supported
@@ -101,32 +282,56 @@ extern "C" void* mmap64(void *start, size_t length,
result = (void *)syscall(SYS_mmap, args);
}
out:
- MallocHook::InvokeMmapHook(result, start, length, prot, flags, fd, offset);
return result;
+}
+# elif defined(__x86_64__)
+
+static inline void* do_mmap64(void *start, size_t length,
+ int prot, int flags,
+ int fd, __off64_t offset) __THROW {
+ return (void *)syscall(SYS_mmap, start, length, prot, flags, fd, offset);
}
-//--------------------------------------------------------------------------//
+# endif
-# elif defined(__x86_64__)
+// We use do_mmap64 abstraction to put MallocHook::InvokeMmapHook
+// calls right into mmap and mmap64, so that the stack frames in the caller's
+// stack are at the same offsets for all the calls of memory allocating
+// functions.
-extern "C" void* mmap64(void *start, size_t length,
- int prot, int flags,
- int fd, __off64_t offset) __THROW {
+// Put all callers of MallocHook::Invoke* in this module into
+// malloc_hook_callers section,
+// so that MallocHook::GetCallerStackTrace can function accurately:
+extern "C" {
+ void* mmap64(void *start, size_t length, int prot, int flags,
+ int fd, __off64_t offset ) __THROW
+ ATTRIBUTE_SECTION(malloc_hook_callers);
+ void* mmap(void *start, size_t length,int prot, int flags,
+ int fd, off_t offset) __THROW
+ ATTRIBUTE_SECTION(malloc_hook_callers);
+ int munmap(void* start, size_t length) __THROW
+ ATTRIBUTE_SECTION(malloc_hook_callers);
+ void* mremap(void* old_addr, size_t old_size, size_t new_size,
+ int flags, ...) __THROW
+ ATTRIBUTE_SECTION(malloc_hook_callers);
+ void* sbrk(ptrdiff_t increment) __THROW
+ ATTRIBUTE_SECTION(malloc_hook_callers);
+}
- void *result;
- result = (void *)syscall(SYS_mmap, start, length, prot, flags, fd, offset);
+extern "C" void* mmap64(void *start, size_t length, int prot, int flags,
+ int fd, __off64_t offset) __THROW {
+ void *result = do_mmap64(start, length, prot, flags, fd, offset);
MallocHook::InvokeMmapHook(result, start, length, prot, flags, fd, offset);
return result;
}
-# endif
-
-extern "C" void* mmap(void *start, size_t length,
- int prot, int flags,
+extern "C" void* mmap(void *start, size_t length, int prot, int flags,
int fd, off_t offset) __THROW {
- return mmap64(start, length, prot, flags, fd,
- static_cast<size_t>(offset)); // avoid sign extension
+ void *result = do_mmap64(start, length, prot, flags, fd,
+ static_cast<size_t>(offset)); // avoid sign extension
+ MallocHook::InvokeMmapHook(result, start, length, prot, flags, fd, offset);
+ return result;
}
extern "C" int munmap(void* start, size_t length) __THROW {
@@ -134,4 +339,25 @@ extern "C" int munmap(void* start, size_t length) __THROW {
return syscall(SYS_munmap, start, length);
}
+extern "C" void* mremap(void* old_addr, size_t old_size, size_t new_size,
+ int flags, ...) __THROW {
+ va_list ap;
+ va_start(ap, flags);
+ void *new_address = va_arg(ap, void *);
+ va_end(ap);
+ void* result = sys_mremap(old_addr, old_size, new_size, flags, new_address);
+ MallocHook::InvokeMremapHook(result, old_addr, old_size, new_size, flags,
+ new_address);
+ return result;
+}
+
+// libc's version:
+extern "C" void* __sbrk(ptrdiff_t increment);
+
+extern "C" void* sbrk(ptrdiff_t increment) __THROW {
+ void *result = __sbrk(increment);
+ MallocHook::InvokeSbrkHook(result, increment);
+ return result;
+}
+
#endif
diff --git a/src/maybe_threads.cc b/src/maybe_threads.cc
index 38fd25f..ebbc1e1 100644
--- a/src/maybe_threads.cc
+++ b/src/maybe_threads.cc
@@ -52,7 +52,7 @@ static pthread_key_t next_key;
// This module will behave very strangely if some pthreads functions
// exist and others don't
-int perftools_pthread_key_create(pthread_key_t *key,
+int perftools_pthread_key_create(pthread_key_t *key,
void (*destr_function) (void *)) {
if (pthread_key_create) {
return pthread_key_create(key, destr_function);
@@ -63,7 +63,7 @@ int perftools_pthread_key_create(pthread_key_t *key,
}
}
-void *perftools_pthread_getspecific(pthread_key_t key) {
+void *perftools_pthread_getspecific(pthread_key_t key) {
if (pthread_getspecific) {
return pthread_getspecific(key);
} else {
@@ -80,14 +80,15 @@ int perftools_pthread_setspecific(pthread_key_t key, void *val) {
}
}
-int perftools_pthread_once(pthread_once_t *ctl,
+static pthread_once_t pthread_once_init = PTHREAD_ONCE_INIT;
+int perftools_pthread_once(pthread_once_t *ctl,
void (*init_routine) (void)) {
if (pthread_once) {
return pthread_once(ctl, init_routine);
} else {
- if (*ctl == PTHREAD_ONCE_INIT) {
+ if (memcmp(ctl, &pthread_once_init, sizeof(*ctl)) == 0) {
init_routine();
- *ctl = 1;
+ ++*(char*)(ctl); // make it so it's no longer equal to init
}
return 0;
}
diff --git a/src/memory_region_map.cc b/src/memory_region_map.cc
new file mode 100644
index 0000000..a59283e
--- /dev/null
+++ b/src/memory_region_map.cc
@@ -0,0 +1,432 @@
+/* Copyright (c) 2006, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ---
+ * Author: Maxim Lifantsev
+ */
+
+#include <sys/mman.h>
+#include <unistd.h>
+
+#include <set>
+
+#include "memory_region_map.h"
+
+#include "base/linux_syscall_support.h"
+#include "base/logging.h"
+#include "base/low_level_alloc.h"
+
+#include <google/stacktrace.h>
+#include <google/malloc_hook.h>
+
+// ========================================================================= //
+
+bool MemoryRegionMap::have_initialized_ = false;
+MemoryRegionMap::RegionSet* MemoryRegionMap::regions_ = NULL;
+LowLevelAlloc::Arena* MemoryRegionMap::arena_ = NULL;
+SpinLock MemoryRegionMap::lock_(SpinLock::LINKER_INITIALIZED);
+int MemoryRegionMap::recursion_count_ = 0;
+pthread_t MemoryRegionMap::self_tid_;
+
+// ========================================================================= //
+
+// Simple hook into execution of global object constructors,
+// so that we do not call pthread_self() when it does not yet work.
+static bool libpthread_initialized = false;
+static bool initializer = (libpthread_initialized = true, true);
+
+static inline pthread_t safe_pthread_self() {
+ // XXX: illegal cast; pthread_t is not necessarily numeric
+ if (!libpthread_initialized) return static_cast<pthread_t>(-1);
+ // this starts working only sometime well into global constructor execution:
+ return pthread_self();
+}
+
+// ========================================================================= //
+
+union MemoryRegionMap::RegionSetRep {
+ char rep[sizeof(RegionSet)];
+ void* align_it;
+};
+
+// The bytes where MemoryRegionMap::regions_ will point to
+static MemoryRegionMap::RegionSetRep regions_rep;
+
+// ========================================================================= //
+
+void MemoryRegionMap::Init() {
+ RAW_VLOG(2, "MemoryRegionMap Init");
+ Lock();
+ if (have_initialized_) {
+ Unlock();
+ return;
+ }
+ MallocHook::SetMmapHook(MmapHook);
+ MallocHook::SetMremapHook(MremapHook);
+ MallocHook::SetSbrkHook(SbrkHook);
+ arena_ = LowLevelAlloc::NewArena(0, 0);
+ MallocHook::SetMunmapHook(MunmapHook);
+ have_initialized_ = true;
+ Unlock();
+ RAW_VLOG(2, "MemoryRegionMap Init done");
+}
+
+bool MemoryRegionMap::Shutdown() {
+ RAW_VLOG(2, "MemoryRegionMap Shutdown");
+ Lock();
+ RAW_CHECK(have_initialized_, "");
+ CheckMallocHooks();
+ MallocHook::SetMmapHook(NULL);
+ MallocHook::SetMremapHook(NULL);
+ MallocHook::SetSbrkHook(NULL);
+ MallocHook::SetMunmapHook(NULL);
+ regions_->~RegionSet();
+ regions_ = NULL;
+ bool deleted_arena = LowLevelAlloc::DeleteArena(arena_);
+ if (deleted_arena) {
+ arena_ = 0;
+ } else {
+ RAW_LOG(WARNING, "Can't delete LowLevelAlloc arena: it's being used");
+ }
+ have_initialized_ = false;
+ Unlock();
+ RAW_VLOG(2, "MemoryRegionMap Shutdown done");
+ return deleted_arena;
+}
+
+void MemoryRegionMap::CheckMallocHooks() {
+ if (MallocHook::GetMmapHook() != MmapHook ||
+ MallocHook::GetMunmapHook() != MunmapHook ||
+ MallocHook::GetMremapHook() != MremapHook ||
+ MallocHook::GetSbrkHook() != SbrkHook) {
+ RAW_LOG(FATAL, "Some malloc hooks got changed");
+ }
+}
+
+void MemoryRegionMap::Lock() {
+ if (recursion_count_ == 0 ||
+ !pthread_equal(self_tid_, safe_pthread_self())) {
+ lock_.Lock();
+ self_tid_ = safe_pthread_self();
+ }
+ recursion_count_++;
+ RAW_CHECK(recursion_count_ <= 5, "recursive lock nesting unexpectedly deep");
+}
+
+void MemoryRegionMap::Unlock() {
+ RAW_CHECK(recursion_count_ > 0, "unlock when not held");
+ RAW_CHECK(pthread_equal(self_tid_, safe_pthread_self()),
+ "unlock by non-holder");
+ recursion_count_--;
+ if (recursion_count_ == 0) {
+ lock_.Unlock();
+ }
+}
+
+bool MemoryRegionMap::LockIsHeldByThisThread() {
+ return lock_.IsHeld() && pthread_equal(self_tid_, safe_pthread_self());
+}
+
+bool MemoryRegionMap::FindStackRegion(uintptr_t stack_top, Region* result) {
+ bool found = false;
+ Lock();
+ if (regions_ != NULL) {
+ Region sample;
+ sample.end_addr = stack_top;
+ RegionSet::iterator region = regions_->lower_bound(sample);
+ if (region != regions_->end()) {
+ RAW_CHECK(stack_top <= region->end_addr, "");
+ if (region->start_addr <= stack_top && stack_top < region->end_addr) {
+ RAW_VLOG(2, "Stack at %p is inside region %p..%p",
+ reinterpret_cast<void*>(stack_top),
+ reinterpret_cast<void*>(region->start_addr),
+ reinterpret_cast<void*>(region->end_addr));
+ const_cast<Region*>(&*region)->is_stack = true; // now we know
+ *result = *region;
+ found = true;
+ }
+ }
+ }
+ Unlock();
+ return found;
+}
+
+MemoryRegionMap::RegionIterator MemoryRegionMap::BeginRegionLocked() {
+ RAW_CHECK(LockIsHeldByThisThread(), "should be held (by this thread)");
+ RAW_CHECK(regions_ != NULL, "");
+ return regions_->begin();
+}
+
+MemoryRegionMap::RegionIterator MemoryRegionMap::EndRegionLocked() {
+ RAW_CHECK(LockIsHeldByThisThread(), "should be held (by this thread)");
+ RAW_CHECK(regions_ != NULL, "");
+ return regions_->end();
+}
+
+inline void MemoryRegionMap::DoInsertRegionLocked(const Region region) {
+ if (DEBUG_MODE) {
+ RegionSet::const_iterator i = regions_->lower_bound(region);
+ RAW_CHECK(i == regions_->end() || !region.Overlaps(*i),
+ "Wow, overlapping memory regions");
+ Region sample;
+ sample.end_addr = region.start_addr;
+ i = regions_->lower_bound(sample);
+ RAW_CHECK(i == regions_->end() || !region.Overlaps(*i),
+ "Wow, overlapping memory regions");
+ }
+ RAW_VLOG(4, "Inserting region %p..%p from %p",
+ reinterpret_cast<void*>(region.start_addr),
+ reinterpret_cast<void*>(region.end_addr),
+ reinterpret_cast<void*>(region.caller));
+ regions_->insert(region);
+ RAW_VLOG(4, "Inserted region %p..%p :",
+ reinterpret_cast<void*>(region.start_addr),
+ reinterpret_cast<void*>(region.end_addr));
+ if (VLOG_IS_ON(4)) LogAllLocked();
+}
+
+// These variables are local to MemoryRegionMap::InsertRegionLocked()
+// but are outside to ensure that they are initialized at load time.
+
+// Has InsertRegionLocked been called recursively.
+static bool recursive_insert = false;
+// No. of unprocessed inserts
+static int saved_regions_count = 0;
+// Unprocessed inserts (must be big enough to hold all allocations that can
+// be caused by a InsertRegionLocked call).
+static MemoryRegionMap::Region saved_regions[10];
+
+inline void MemoryRegionMap::InsertRegionLocked(const Region& region) {
+ RAW_CHECK(LockIsHeldByThisThread(), "should be held (by this thread)");
+ // We can be called recursively, because RegionSet constructor
+ // and DoInsertRegionLocked() (called below) can call the allocator.
+ // recursive_insert tells us if that's the case. When this happens,
+ // region insertion information is recorded in saved_regions[],
+ // and taken into account when the recursion unwinds.
+ if (regions_ == NULL) { // init regions_
+ RAW_VLOG(4, "Initializing region set");
+ regions_ = reinterpret_cast<RegionSet*>(&regions_rep.rep);
+ recursive_insert = true;
+ new(regions_) RegionSet();
+ while (saved_regions_count > 0) {
+ DoInsertRegionLocked(saved_regions[--saved_regions_count]);
+ }
+ recursive_insert = false;
+ }
+ // Do the insert:
+ if (recursive_insert) { // recursion
+ RAW_VLOG(4, "Saving recursive insert of region %p..%p from %p",
+ reinterpret_cast<void*>(region.start_addr),
+ reinterpret_cast<void*>(region.end_addr),
+ reinterpret_cast<void*>(region.caller));
+ RAW_CHECK(saved_regions_count < ARRAYSIZE(saved_regions), "");
+ saved_regions[saved_regions_count++] = region;
+ } else { // not a recusrive call
+ recursive_insert = true;
+ DoInsertRegionLocked(region);
+ while (saved_regions_count > 0) {
+ DoInsertRegionLocked(saved_regions[--saved_regions_count]);
+ }
+ recursive_insert = false;
+ }
+}
+
+// We strip out different number of stack frames in debug mode
+// because less inlining happens in that case
+#ifdef NDEBUG
+static const int kStripFrames = 1;
+#else
+static const int kStripFrames = 3;
+#endif
+
+void MemoryRegionMap::RecordRegionAddition(void* start, size_t size) {
+ Region region;
+ // Record data about this memory acquisition call:
+ region.start_addr = reinterpret_cast<uintptr_t>(start);
+ region.end_addr = region.start_addr + size;
+ region.is_stack = false;
+ const int depth = MallocHook::GetCallerStackTrace(
+ reinterpret_cast<void**>(&region.caller), 1, kStripFrames + 1);
+ if (depth != 1) {
+ // If we weren't able to get the stack frame, that's ok. This
+ // usually happens in recursive calls, when the stack-unwinder
+ // calls mmap() which in turn calls the stack-unwinder.
+ region.caller = static_cast<uintptr_t>(NULL);
+ }
+ RAW_VLOG(2, "New global region %p..%p from %p",
+ reinterpret_cast<void*>(region.start_addr),
+ reinterpret_cast<void*>(region.end_addr),
+ reinterpret_cast<void*>(region.caller));
+ Lock(); // recursively lock
+ InsertRegionLocked(region);
+ Unlock();
+}
+
+void MemoryRegionMap::RecordRegionRemoval(void* start, size_t size) {
+ Lock();
+ // first handle saved regions if any
+ while (saved_regions_count > 0) {
+ DoInsertRegionLocked(saved_regions[--saved_regions_count]);
+ }
+ uintptr_t start_addr = reinterpret_cast<uintptr_t>(start);
+ uintptr_t end_addr = start_addr + size;
+ // subtract start_addr, end_addr from all the regions
+ RAW_VLOG(2, "Removing global region %p..%p; have %"PRIuS" regions",
+ reinterpret_cast<void*>(start_addr),
+ reinterpret_cast<void*>(end_addr),
+ regions_->size());
+ for (RegionSet::iterator region = regions_->begin();
+ region != regions_->end(); /*noop*/) {
+ RAW_VLOG(5, "Looking at region %p..%p",
+ reinterpret_cast<void*>(region->start_addr),
+ reinterpret_cast<void*>(region->end_addr));
+ if (start_addr <= region->start_addr &&
+ region->end_addr <= end_addr) { // full deletion
+ RAW_VLOG(4, "Deleting region %p..%p",
+ reinterpret_cast<void*>(region->start_addr),
+ reinterpret_cast<void*>(region->end_addr));
+ RegionSet::iterator d = region;
+ ++region;
+ regions_->erase(d);
+ continue;
+ } else if (region->start_addr < start_addr &&
+ end_addr < region->end_addr) { // cutting-out split
+ RAW_VLOG(4, "Splitting region %p..%p in two",
+ reinterpret_cast<void*>(region->start_addr),
+ reinterpret_cast<void*>(region->end_addr));
+ // Make another region for the start portion:
+ // The new region has to be the start portion because we can't
+ // just modify region->end_addr as it's the sorting key.
+ Region r;
+ r.start_addr = region->start_addr;
+ r.end_addr = start_addr;
+ r.caller = region->caller;
+ r.is_stack = region->is_stack;
+ InsertRegionLocked(r);
+ // cut region from start
+ const_cast<Region*>(&*region)->start_addr = end_addr;
+ } else if (end_addr > region->start_addr &&
+ start_addr <= region->start_addr) { // cut from start
+ RAW_VLOG(4, "Start-chopping region %p..%p",
+ reinterpret_cast<void*>(region->start_addr),
+ reinterpret_cast<void*>(region->end_addr));
+ const_cast<Region*>(&*region)->start_addr = end_addr;
+ } else if (start_addr > region->start_addr &&
+ start_addr < region->end_addr) { // cut from end
+ RAW_VLOG(4, "End-chopping region %p..%p",
+ reinterpret_cast<void*>(region->start_addr),
+ reinterpret_cast<void*>(region->end_addr));
+ // Can't just modify region->end_addr (it's the sorting key):
+ Region r = *region;
+ r.end_addr = start_addr;
+ RegionSet::iterator d = region;
+ ++region;
+ regions_->erase(d);
+ InsertRegionLocked(r);
+ continue;
+ }
+ ++region;
+ }
+ RAW_VLOG(4, "Removed region %p..%p; have %"PRIuS" regions",
+ reinterpret_cast<void*>(start_addr),
+ reinterpret_cast<void*>(end_addr),
+ regions_->size());
+ if (VLOG_IS_ON(4)) LogAllLocked();
+ Unlock();
+}
+
+void MemoryRegionMap::MmapHook(void* result,
+ void* start, size_t size,
+ int prot, int flags,
+ int fd, off_t offset) {
+ // TODO(maxim): replace all 0x%"PRIxS" by %p when RAW_VLOG uses a safe
+ // snprintf reimplementation that does not malloc to pretty-print NULL
+ RAW_VLOG(2, "MMap = 0x%"PRIxS" of %"PRIuS" at %llu "
+ "prot %d flags %d fd %d offs %lld",
+ reinterpret_cast<uintptr_t>(result), size,
+ reinterpret_cast<uint64>(start), prot, flags, fd,
+ static_cast<int64>(offset));
+ if (result != reinterpret_cast<void*>(MAP_FAILED) && size != 0) {
+ RecordRegionAddition(result, size);
+ }
+}
+
+void MemoryRegionMap::MunmapHook(void* ptr, size_t size) {
+ RAW_VLOG(2, "MUnmap of %p %"PRIuS"", ptr, size);
+ if (size != 0) {
+ RecordRegionRemoval(ptr, size);
+ }
+}
+
+void MemoryRegionMap::MremapHook(void* result,
+ void* old_addr, size_t old_size,
+ size_t new_size, int flags, void* new_addr) {
+ RAW_VLOG(2, "MRemap = 0x%"PRIxS" of 0x%"PRIxS" %"PRIuS" "
+ "to %"PRIuS" flags %d new_addr=0x%"PRIxS,
+ (uintptr_t)result, (uintptr_t)old_addr,
+ old_size, new_size, flags,
+ flags & MREMAP_FIXED ? (uintptr_t)new_addr : 0);
+ if (result != reinterpret_cast<void*>(-1)) {
+ RecordRegionRemoval(old_addr, old_size);
+ RecordRegionAddition(result, new_size);
+ }
+}
+
+extern "C" void* __sbrk(ptrdiff_t increment); // defined in libc
+
+void MemoryRegionMap::SbrkHook(void* result, ptrdiff_t increment) {
+ RAW_VLOG(2, "Sbrk = 0x%"PRIxS" of %"PRIdS"", (uintptr_t)result, increment);
+ if (result != reinterpret_cast<void*>(-1)) {
+ if (increment > 0) {
+ void* new_end = __sbrk(0);
+ RecordRegionAddition(result, reinterpret_cast<uintptr_t>(new_end) -
+ reinterpret_cast<uintptr_t>(result));
+ } else if (increment < 0) {
+ void* new_end = __sbrk(0);
+ RecordRegionRemoval(new_end, reinterpret_cast<uintptr_t>(result) -
+ reinterpret_cast<uintptr_t>(new_end));
+ }
+ }
+}
+
+void MemoryRegionMap::LogAllLocked() {
+ RAW_CHECK(LockIsHeldByThisThread(), "should be held (by this thread)");
+ RAW_LOG(INFO, "List of regions:");
+ uintptr_t previous = 0;
+ for (RegionSet::const_iterator r = regions_->begin();
+ r != regions_->end(); ++r) {
+ RAW_LOG(INFO, "Memory region 0x%"PRIxS"..0x%"PRIxS" "
+ "from 0x%"PRIxS" stack=%d",
+ r->start_addr, r->end_addr, r->caller, r->is_stack);
+ RAW_CHECK(previous < r->end_addr, "wow, we messed up the set order");
+ // this must be caused by uncontrolled recursive operations on regions_
+ previous = r->end_addr;
+ }
+ RAW_LOG(INFO, "End of regions list");
+}
diff --git a/src/memory_region_map.h b/src/memory_region_map.h
new file mode 100644
index 0000000..2a43b47
--- /dev/null
+++ b/src/memory_region_map.h
@@ -0,0 +1,199 @@
+/* Copyright (c) 2006, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ---
+ * Author: Maxim Lifantsev
+ */
+
+#ifndef BASE_MEMORY_REGION_MAP_H__
+#define BASE_MEMORY_REGION_MAP_H__
+
+#include <pthread.h>
+#include <set>
+#include "base/stl_allocator.h"
+#include "base/spinlock.h"
+#include "base/low_level_alloc.h"
+
+/// TODO(maxim): add a unittest
+
+// Class to collect and query the map of all memory regions
+// in a process that have been created with mmap, munmap, mremap, sbrk.
+// After initialization with Init()
+// (which can happened even before global object constructor execution)
+// we collect the map by installing and monitoring MallocHook-s
+// to mmap, munmap, mremap, sbrk.
+// At any time one can query this map via provided interface.
+class MemoryRegionMap {
+ public: // interface
+
+ // Start up this module (can be called more than once w/o harm).
+ // Will install mmap, munmap, mremap, sbrk hooks
+ // and initialize arena_ and our hook and locks, hence one can use
+ // MemoryRegionMap::Lock()/Unlock() to manage the locks.
+ // Uses Lock/Unlock inside.
+ static void Init();
+
+ // Try to shutdown this module undoing what Init() did.
+ // Returns iff could do full shutdown.
+ static bool Shutdown();
+
+ // Check that our hooks are still in place and crash if not.
+ // No need for locking.
+ static void CheckMallocHooks();
+
+ // Locks to protect our internal data structures.
+ // These also protect use of arena_
+ // if our Init() has been done.
+ // The lock is recursive.
+ static void Lock();
+ static void Unlock();
+ // Whether the lock is held by this thread.
+ static bool LockIsHeldByThisThread();
+
+ // A memory region that we know about through malloc_hook-s.
+ struct Region {
+ uintptr_t start_addr; // region start address
+ uintptr_t end_addr; // region end address
+ uintptr_t caller; // who called this region's allocation function
+ // (return address in the stack of the immediate caller)
+ // NULL if could not get it
+ bool is_stack; // does this region contain a thread's stack
+
+ bool Overlaps(const Region& x) const {
+ return start_addr < x.end_addr && end_addr > x.start_addr;
+ }
+ };
+
+ // Find the region that contains stack_top, mark that region as
+ // a stack region, and write its data into *result.
+ // Returns success. Uses Lock/Unlock inside.
+ static bool FindStackRegion(uintptr_t stack_top, Region* result);
+
+ private: // our internal types
+
+ // Region comparator for sorting with STL
+ struct RegionCmp {
+ bool operator()(const Region& x, const Region& y) const {
+ return x.end_addr < y.end_addr;
+ }
+ };
+
+ // We allocate STL objects in our own arena.
+ struct MyAllocator {
+ static void *Allocate(size_t n) {
+ return LowLevelAlloc::Alloc(n, arena_);
+ }
+ static void Free(void *p) { LowLevelAlloc::Free(p); }
+ };
+
+ // Set of the memory regions
+ typedef std::set<Region, RegionCmp,
+ STL_Allocator<Region, MyAllocator> > RegionSet;
+
+ public: // more in-depth interface
+
+ // STL iterator with values of Region
+ typedef RegionSet::const_iterator RegionIterator;
+
+ // Return the begin/end iterators to all the regions.
+ // Ideally these need Lock/Unlock protection around their whole usage (loop),
+ // but LockOther/UnlockOther is usually sufficient:
+ // in this case of single-threaded mutability (achieved by (Un)lockOther)
+ // via region additions/modifications
+ // the loop iterator will still be valid as log as its region
+ // has not been deleted and EndRegionLocked should be
+ // re-evaluated whenever the set of regions has changed.
+ static RegionIterator BeginRegionLocked();
+ static RegionIterator EndRegionLocked();
+
+ public: // effectively private type
+
+ union RegionSetRep; // in .cc
+
+ private: // representation
+
+ // If have initialized this module
+ static bool have_initialized_;
+
+ // Arena used for our allocations in regions_.
+ static LowLevelAlloc::Arena* arena_;
+
+ // Set of the mmap/sbrk/mremap-ed memory regions
+ // To be accessed *only* when Lock() is held.
+ // Hence we protect the non-recursive lock used inside of arena_
+ // with our recursive Lock(). This lets a user prevent deadlocks
+ // when threads are stopped by ListAllProcessThreads at random spots
+ // simply by acquiring our recursive Lock() before that.
+ static RegionSet* regions_;
+
+ // Lock to protect regions_ variable and the data behind.
+ static SpinLock lock_;
+
+ // Recursion count for the recursive lock.
+ static int recursion_count_;
+ // The thread id of the thread that's inside the recursive lock.
+ static pthread_t self_tid_;
+
+ private: // helpers
+
+ // Verifying wrapper around regions_->insert(region)
+ // To be called by InsertRegionLocked only!
+ // Passing "region" by value is important:
+ // for many calls the memory the argument is located-in in the caller
+ // will get written-to during this call.
+ inline static void DoInsertRegionLocked(const Region region);
+ // Wrapper around DoInsertRegionLocked
+ // that handles the case of recursive allocator calls.
+ inline static void InsertRegionLocked(const Region& region);
+
+ // Record addition of a memory region at address "start" of size "size"
+ // (called from our mmap/mremap/sbrk hooks).
+ static void RecordRegionAddition(void* start, size_t size);
+ // Record deletion of a memory region at address "start" of size "size"
+ // (called from our munmap/mremap/sbrk hooks).
+ static void RecordRegionRemoval(void* start, size_t size);
+
+ // Hooks for MallocHook
+ static void MmapHook(void* result,
+ void* start, size_t size,
+ int prot, int flags,
+ int fd, off_t offset);
+ static void MunmapHook(void* ptr, size_t size);
+ static void MremapHook(void* result, void* old_addr, size_t old_size,
+ size_t new_size, int flags, void* new_addr);
+ static void SbrkHook(void* result, ptrdiff_t increment);
+
+ // Log all memory regions; Useful for debugging only.
+ // Assumes Lock() is held
+ static void LogAllLocked();
+
+ DISALLOW_EVIL_CONSTRUCTORS(MemoryRegionMap);
+};
+
+#endif // BASE_MEMORY_REGION_MAP_H__
diff --git a/src/pprof b/src/pprof
index 24b5b74..54c907c 100755
--- a/src/pprof
+++ b/src/pprof
@@ -1,6 +1,6 @@
-#! /usr/bin/perl -w
+#! /usr/bin/env perl
-# Copyright (c) 1998-2006, Google Inc.
+# Copyright (c) 1998-2007, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -69,6 +69,7 @@
# TODO: Use color to indicate files?
use strict;
+use warnings;
use Getopt::Long;
my $PPROF_VERSION = "0.8";
@@ -88,6 +89,7 @@ my %obj_tool_map = (
);
my $DOT = "dot"; # leave non-absolute, since it may be in /usr/local
my $GV = "gv";
+my $PS2PDF = "ps2pdf";
# These are used for dynamic profiles
my $WGET = "wget";
my $CURL = "curl";
@@ -105,6 +107,9 @@ my $PROGRAM_NAME_PAGE = "/pprof/cmdline";
# nibbles) of an address, distinguishing between 32-bit and 64-bit profiles:
my $address_length = 8; # Hope for 32-bit, reset if 64-bit detected.
+# A list of paths to search for shared object files
+my @prefix_list = ();
+
##### Argument parsing #####
sub usage_string {
@@ -133,6 +138,8 @@ Options:
--base=<base> Subtract <base> from <profile> before display
--interactive Run in interactive mode (interactive "help" gives help) [default]
--seconds=<n> Length of time for dynamic profiles [default=30 secs]
+ --add_lib=<file> Read additional symbols and line info from the given library
+ --lib_prefix=<dir> Comma separated list of library path prefixes
Reporting Granularity:
--addresses Report at address level
@@ -170,6 +177,8 @@ Call-graph Options:
--focus=<regexp> Focus on nodes matching <regexp>
--ignore=<regexp> Ignore nodes matching <regexp>
--scale=<n> Set GV scaling [default=0]
+ --heapcheck Make nodes with non-0 object counts
+ (i.e. direct leak generators) more visible
Miscellaneous:
--tools=<prefix> Prefix for object tool pathnames
@@ -180,6 +189,8 @@ Miscellaneous:
Examples:
pprof /bin/ls ls.prof
+ Enters "interactive" mode
+pprof --text /bin/ls ls.prof
Outputs one line per procedure
pprof --gv /bin/ls ls.prof
Displays annotated call-graph via 'gv'
@@ -191,7 +202,7 @@ pprof --list=getdir /bin/ls ls.prof
(Per-line) annotated source listing for getdir()
pprof --disasm=getdir /bin/ls ls.prof
(Per-PC) annotated disassembly for getdir()
-pprof localhost:1234
+pprof --text localhost:1234
Outputs one line per procedure for localhost:1234
EOF
}
@@ -200,7 +211,7 @@ sub version_string {
return <<EOF
pprof (part of google-perftools $PPROF_VERSION)
-Copyright 1998-2006 Google Inc.
+Copyright 1998-2007 Google Inc.
This is BSD licensed software; see the source for copying conditions
and license information.
@@ -236,6 +247,7 @@ sub Init() {
$main::opt_lines = 0;
$main::opt_functions = 0;
$main::opt_files = 0;
+ $main::opt_lib_prefix = "";
$main::opt_text = 0;
$main::opt_list = "";
@@ -252,7 +264,9 @@ sub Init() {
$main::opt_focus = '';
$main::opt_ignore = '';
$main::opt_scale = 0;
+ $main::opt_heapcheck = 0;
$main::opt_seconds = 30;
+ $main::opt_lib = "";
$main::opt_inuse_space = 0;
$main::opt_inuse_objects = 0;
@@ -273,17 +287,21 @@ sub Init() {
# Are we using $SYMBOL_PAGE?
$main::use_symbol_page = 0;
- # Are we printing a heap profile?
- $main::heap_profile = 0;
-
- # Are we printing a lock profile?
- $main::lock_profile = 0;
+ # Type of profile we are dealing with
+ # Supported types:
+ # cpu
+ # heap
+ # growth
+ # contention
+ $main::profile_type = ''; # Empty type means "unknown"
GetOptions("help!" => \$main::opt_help,
"version!" => \$main::opt_version,
"cum!" => \$main::opt_cum,
"base=s" => \$main::opt_base,
"seconds=i" => \$main::opt_seconds,
+ "add_lib=s" => \$main::opt_lib,
+ "lib_prefix=s" => \$main::opt_lib_prefix,
"functions!" => \$main::opt_functions,
"lines!" => \$main::opt_lines,
"addresses!" => \$main::opt_addresses,
@@ -303,6 +321,7 @@ sub Init() {
"focus=s" => \$main::opt_focus,
"ignore=s" => \$main::opt_ignore,
"scale=i" => \$main::opt_scale,
+ "heapcheck" => \$main::opt_heapcheck,
"inuse_space!" => \$main::opt_inuse_space,
"inuse_objects!" => \$main::opt_inuse_objects,
"alloc_space!" => \$main::opt_alloc_space,
@@ -361,6 +380,8 @@ sub Init() {
# Check output modes
my $modes =
$main::opt_text +
+ ($main::opt_list eq '' ? 0 : 1) +
+ ($main::opt_disasm eq '' ? 0 : 1) +
$main::opt_gv +
$main::opt_dot +
$main::opt_ps +
@@ -429,6 +450,15 @@ sub Init() {
} else {
ConfigureObjTools($main::prog)
}
+
+ # Break the opt_list_prefix into the prefix_list array
+ @prefix_list = split (',', $main::opt_lib_prefix);
+
+ # Remove trailing / from the prefixes, in the list to prevent
+ # searching things like /my/path//lib/mylib.so
+ foreach (@prefix_list) {
+ s|/+$||;
+ }
}
sub Main() {
@@ -443,43 +473,15 @@ sub Main() {
# Read one profile, pick the last item on the list
my $data = ReadProfile($main::prog, pop(@main::profile_files));
my $profile = $data->{profile};
+ my $pcs = $data->{pcs};
my $libs = $data->{libs}; # Info about main program and shared libraries
- # List of function names to skip
- $main::skip = ();
- $main::skip_regexp = 'NOMATCH';
- if ($main::heap_profile) {
- foreach my $name ('calloc',
- 'cfree',
- 'malloc',
- 'free',
- 'memalign',
- 'pvalloc',
- 'valloc',
- 'realloc',
- 'do_malloc',
- 'DoSampledAllocation',
- 'simple_alloc::allocate',
- '__malloc_alloc_template::allocate',
- '__builtin_delete',
- '__builtin_new',
- '__builtin_vec_delete',
- '__builtin_vec_new') {
- $main::skip{$name} = 1;
- }
- $main::skip_regexp = "TCMalloc";
- }
- if ($main::lock_profile) {
- foreach my $vname ('Mutex::Unlock', 'Mutex::UnlockSlow') {
- $main::skip{$vname} = 1;
- }
- }
-
# Add additional profiles, if available.
if (scalar(@main::profile_files) > 0) {
foreach my $pname (@main::profile_files) {
- my $p = ReadProfile($main::prog, $pname)->{profile};
- $profile = AddProfile($profile, $p);
+ my $data2 = ReadProfile($main::prog, $pname);
+ $profile = AddProfile($profile, $data2->{profile});
+ $pcs = AddPcs($pcs, $data2->{pcs});
}
}
@@ -495,11 +497,14 @@ sub Main() {
# Collect symbols
my $symbols = undef;
if ($main::use_symbol_page) {
- $symbols = FetchSymbols($data->{pcs});
+ $symbols = FetchSymbols($pcs);
} else {
- $symbols = ExtractSymbols($libs, $profile, $data->{pcs});
+ $symbols = ExtractSymbols($libs, $profile, $pcs);
}
+ # Remove uniniteresting stack items
+ $profile = RemoveUninterestingFrames($symbols, $profile);
+
# Focus?
if ($main::opt_focus ne '') {
$profile = FocusProfile($symbols, $profile, $main::opt_focus);
@@ -574,6 +579,8 @@ sub InteractiveMode {
$| = 1; # Make output unbuffered for interactive mode
my ($orig_profile, $symbols, $libs, $total) = @_;
+ print "Welcome to pprof! For help, type 'help'.\n";
+
# Use ReadLine if it's installed.
if ( !ReadlineMightFail() &&
defined(eval {require Term::ReadLine}) ) {
@@ -780,6 +787,7 @@ parameters will be ignored.
Further pprof details are available at this location (or one similar):
/usr/doc/google-perftools-$PPROF_VERSION/cpu_profiler.html
+ /usr/doc/google-perftools-$PPROF_VERSION/heap_profiler.html
ENDOFHELP
}
@@ -1003,14 +1011,12 @@ sub PrintSource {
# Disassemble all instructions (just to get line numbers)
my @instructions = Disassemble($prog, $offset, $start_addr, $end_addr);
- # Hack 1: assume that the last source location mentioned in the
- # disassembly is the end of the source code.
+ # Hack 1: assume that the first source file encountered in the
+ # disassembly contains the routine
my $filename = undef;
- my $lastline = -1;
- for (my $i = $#instructions; $i >= 0; $i--) {
+ for (my $i = 0; $i <= $#instructions; $i++) {
if ($instructions[$i]->[2] >= 0) {
$filename = $instructions[$i]->[1];
- $lastline = $instructions[$i]->[2];
last;
}
}
@@ -1019,7 +1025,21 @@ sub PrintSource {
return;
}
- # Hack 2: assume the first source location from "filename" is the start of
+ # Hack 2: assume that the largest line number from $filename is the
+ # end of the procedure. This is typically safe since if P1 contains
+ # an inlined call to P2, then P2 usually occurs earlier in the
+ # source file. If this does not work, we might have to compute a
+ # density profile or just print all regions we find.
+ my $lastline = 0;
+ for (my $i = 0; $i <= $#instructions; $i++) {
+ my $f = $instructions[$i]->[1];
+ my $l = $instructions[$i]->[2];
+ if (($f eq $filename) && ($l > $lastline)) {
+ $lastline = $l;
+ }
+ }
+
+ # Hack 3: assume the first source location from "filename" is the start of
# the source code.
my $firstline = 1;
for (my $i = 0; $i <= $#instructions; $i++) {
@@ -1029,7 +1049,7 @@ sub PrintSource {
}
}
- # Hack 3: Extend last line forward until its indentation is less than
+ # Hack 4: Extend last line forward until its indentation is less than
# the indentation we saw on $firstline
my $oldlastline = $lastline;
{
@@ -1110,11 +1130,13 @@ sub PrintSource {
(($l <= $oldlastline + 5) || ($l <= $lastline))) {
chop;
my $text = $_;
+ if ($l == $firstline) { printf("---\n"); }
printf("%6s %6s %4d: %s\n",
UnparseAlt(GetEntry($samples1, $l)),
UnparseAlt(GetEntry($samples2, $l)),
$l,
$text);
+ if ($l == $lastline) { printf("---\n"); }
};
}
close(FILE);
@@ -1166,7 +1188,7 @@ sub PrintDot {
} elsif ($main::opt_ps) {
$output = "| $DOT -Tps";
} elsif ($main::opt_pdf) {
- $output = "| $DOT -Tps | ps2pdf - -";
+ $output = "| $DOT -Tps | $PS2PDF - -";
} elsif ($main::opt_gif) {
$output = "| $DOT -Tgif";
} else {
@@ -1222,14 +1244,27 @@ sub PrintDot {
Unparse($c),
Percent($c, $overall_total));
}
+ my $style = "";
+ if ($main::opt_heapcheck) {
+ if ($f > 0) {
+ # make leak-causing nodes more visible (add a background)
+ $style = ",style=filled,fillcolor=gray"
+ } elsif ($f < 0) {
+ # make anti-leak-causing nodes (which almost never occur)
+ # stand out as well (triple border)
+ $style = ",peripheries=3"
+ }
+ }
+
printf DOT ("N%d [label=\"%s\\n%s (%s)%s\\r" .
- "\",shape=box,fontsize=%.1f];\n",
+ "\",shape=box,fontsize=%.1f%s];\n",
$node{$a},
$sym,
Unparse($f),
Percent($f, $overall_total),
$extra,
$fs,
+ $style,
);
}
@@ -1304,11 +1339,6 @@ sub OutputKey {
$fileline = $symbols->{$a}->[1];
}
- # We drop a few well-known names
- if ($main::skip{$func} || ($func =~ m/$main::skip_regexp/)) {
- return '';
- }
-
if ($main::opt_disasm || $main::opt_list) {
return $a; # We want just the address for the key
} elsif ($main::opt_addresses) {
@@ -1340,7 +1370,7 @@ sub Percent {
# Generate pretty-printed form of number
sub Unparse {
my $num = shift;
- if ($main::heap_profile) {
+ if ($main::profile_type eq 'heap' || $main::profile_type eq 'growth') {
if ($main::opt_inuse_objects || $main::opt_alloc_objects) {
return sprintf("%d", $num);
} else {
@@ -1350,7 +1380,7 @@ sub Unparse {
return sprintf("%.1f", $num / 1048576.0);
}
}
- } elsif ($main::lock_profile && !$main::opt_contentions) {
+ } elsif ($main::profile_type eq 'contention' && !$main::opt_contentions) {
return sprintf("%.3f", $num / 1e9); # Convert nanoseconds to seconds
} else {
return sprintf("%d", $num);
@@ -1369,7 +1399,7 @@ sub UnparseAlt {
# Return output units
sub Units {
- if ($main::heap_profile) {
+ if ($main::profile_type eq 'heap' || $main::profile_type eq 'growth') {
if ($main::opt_inuse_objects || $main::opt_alloc_objects) {
return "objects";
} else {
@@ -1379,7 +1409,7 @@ sub Units {
return "MB";
}
}
- } elsif ($main::lock_profile && !$main::opt_contentions) {
+ } elsif ($main::profile_type eq 'contention' && !$main::opt_contentions) {
return "seconds";
} else {
return "samples";
@@ -1420,6 +1450,120 @@ sub CumulativeProfile {
return $result;
}
+# If the second-youngest PC on the stack is always the same, returns
+# that pc. Otherwise, returns undef.
+sub IsSecondPcAlwaysTheSame {
+ my $profile = shift;
+
+ my $second_pc = undef;
+ foreach my $k (keys(%{$profile})) {
+ my @addrs = split(/\n/, $k);
+ if ($#addrs < 1) {
+ return undef;
+ }
+ if (not defined $second_pc) {
+ $second_pc = $addrs[1];
+ } else {
+ if ($second_pc ne $addrs[1]) {
+ return undef;
+ }
+ }
+ }
+ return $second_pc;
+}
+
+sub RemoveUninterestingFrames {
+ my $symbols = shift;
+ my $profile = shift;
+
+ # List of function names to skip
+ my %skip = ();
+ my $skip_regexp = 'NOMATCH';
+ if ($main::profile_type eq 'heap' || $main::profile_type eq 'growth') {
+ foreach my $name ('calloc',
+ 'cfree',
+ 'malloc',
+ 'free',
+ 'memalign',
+ 'pvalloc',
+ 'valloc',
+ 'realloc',
+ 'do_malloc',
+ 'DoSampledAllocation',
+ 'simple_alloc::allocate',
+ '__malloc_alloc_template::allocate',
+ '__builtin_delete',
+ '__builtin_new',
+ '__builtin_vec_delete',
+ '__builtin_vec_new',
+ 'operator new',
+ 'operator new[]') {
+ $skip{$name} = 1;
+ }
+ $skip_regexp = "TCMalloc";
+ } elsif ($main::profile_type eq 'contention') {
+ foreach my $vname ('Mutex::Unlock', 'Mutex::UnlockSlow') {
+ $skip{$vname} = 1;
+ }
+ } elsif ($main::profile_type eq 'cpu') {
+ # Drop signal handlers used for CPU profile collection
+ # TODO(dpeng): this should not be necessary; it's taken
+ # care of by the general 2nd-pc mechanism below.
+ foreach my $name ('ProfileData::Add',
+ 'ProfileData::prof_handler',
+ '__pthread_sighandler',
+ '__restore') {
+ $skip{$name} = 1;
+ }
+ } else {
+ # Nothing skipped for unknown types
+ }
+
+ if ($main::profile_type eq 'cpu') {
+ # If all the second-youngest program counters are the same,
+ # this STRONGLY suggests that it is an artifact of measurement,
+ # i.e., stack frames pushed by the CPU profiler signal handler.
+ # Hence, we delete them.
+ # (The topmost PC is read from the signal structure, not from
+ # the stack, so it does not get involved.)
+ while (my $second_pc = IsSecondPcAlwaysTheSame($profile)) {
+ my $result = {};
+ my $func = '';
+ if (exists($symbols->{$second_pc})) {
+ $second_pc = $symbols->{$second_pc}->[0];
+ }
+ print STDERR "Removing $second_pc from all stack traces.\n";
+ foreach my $k (keys(%{$profile})) {
+ my $count = $profile->{$k};
+ my @addrs = split(/\n/, $k);
+ splice @addrs, 1, 1;
+ my $reduced_path = join("\n", @addrs);
+ AddEntry($result, $reduced_path, $count);
+ }
+ $profile = $result;
+ }
+ }
+
+ my $result = {};
+ foreach my $k (keys(%{$profile})) {
+ my $count = $profile->{$k};
+ my @addrs = split(/\n/, $k);
+ my @path = ();
+ foreach my $a (@addrs) {
+ if (exists($symbols->{$a})) {
+ my $func = $symbols->{$a}->[0];
+ if ($skip{$func} || ($func =~ m/$skip_regexp/)) {
+ next;
+ }
+ }
+ push(@path, $a);
+ }
+ my $reduced_path = join("\n", @path);
+ AddEntry($result, $reduced_path, $count);
+ }
+ return $result;
+}
+
# Reduce profile to granularity given by user
sub ReduceProfile {
my $symbols = shift;
@@ -1436,8 +1580,8 @@ sub ReduceProfile {
# entry if it has already been seen
my $key = OutputKey($symbols, $a);
if (!$seen{$key}) {
- $seen{$key} = 1;
- push(@path, $key);
+ $seen{$key} = 1;
+ push(@path, $key);
}
}
my $reduced_path = join("\n", @path);
@@ -1525,6 +1669,23 @@ sub AddProfile {
return $R;
}
+# Add A to B
+sub AddPcs {
+ my $A = shift;
+ my $B = shift;
+
+ my $R = {};
+ # add all keys in A
+ foreach my $k (keys(%{$A})) {
+ $R->{$k} = 1
+ }
+ # add all keys in B
+ foreach my $k (keys(%{$B})) {
+ $R->{$k} = 1
+ }
+ return $R;
+}
+
# Subtract B from A
sub SubtractProfile {
my $A = shift;
@@ -1671,7 +1832,7 @@ sub FetchSymbols {
my $url = SymbolPageURL();
# Here we use curl for sending data via POST since old
- # wgets don't't have --post-file option.
+ # wget doesn't have --post-file option.
$url = ResolveRedirectionForCurl($url);
my $command_line = "$CURL -sd '\@$main::tmpfile_sym' '$url'";
# We use c++filt in case $SYMBOL_PAGE gives us mangled symbols.
@@ -1680,7 +1841,8 @@ sub FetchSymbols {
my %map;
while (<SYMBOL>) {
- if (m/^0x([0-9a-f]+)\s+(.+)/) {
+ # Removes all the leading zeroes from the symbols, see comment below.
+ if (m/^0x0*([0-9a-f]+)\s+(.+)/) {
$map{$1} = $2;
}
}
@@ -1689,8 +1851,15 @@ sub FetchSymbols {
my $symbols = {};
for my $pc (@pcs) {
my $fullname;
- if (defined($map{$pc})) {
- $fullname = $map{$pc};
+ # For 64 bits binaries, symbols are extracted with 8 leading zeroes.
+ # Then /symbolz reads the long symbols in as uint64, and outputs
+ # the result with a "0x%08llx" format which get rid of the zeroes.
+ # By removing all the leading zeroes in both $pc and the symbols from
+ # /symbolz, the symbols match and are retrievable from the map.
+ my $shortpc = $pc;
+ $shortpc =~ s/^0*//;
+ if (defined($map{$shortpc})) {
+ $fullname = $map{$shortpc};
} else {
$fullname = "0x" . $pc; # Just use addresses
}
@@ -1720,11 +1889,6 @@ sub FetchDynamicProfile {
my $fetch_name_only = shift;
my $encourage_patience = shift;
- my $user_dir = $ENV{HOME};
- my $profile_dir = $user_dir . "/pprof";
- if (!(-d $profile_dir)) {
- mkdir($profile_dir) || die("Unable to create profile directory $profile_dir\n");
- }
if (!IsProfileURL($profile_name)) {
return $profile_name;
} else {
@@ -1752,6 +1916,12 @@ sub FetchDynamicProfile {
$url = "http://$host:$port$type";
$wget_timeout = "";
}
+
+ my $profile_dir = $ENV{"PPROF_TMPDIR"} || ($ENV{HOME} . "/pprof");
+ if (!(-d $profile_dir)) {
+ mkdir($profile_dir)
+ || die("Unable to create profile directory $profile_dir: $!\n");
+ }
my $tmp_profile = "$profile_dir/.tmp.$profile_file";
my $real_profile = "$profile_dir/$profile_file";
@@ -1845,28 +2015,31 @@ sub ReadProfile {
my $prog = shift;
my $fname = shift;
- $main::heap_profile = 0;
- $main::lock_profile = 0;
+ $main::profile_type = '';
# Look at first line to see if it is a heap or a CPU profile
open(PROFILE, "<$fname") || error("$fname: $!\n");
binmode PROFILE; # New perls do UTF-8 processing
my $header = <PROFILE>;
my $contention_marker = substr($CONTENTION_PAGE, 1); # remove leading /
- if ($header =~ m/^heap profile:/) {
- $main::heap_profile = 1;
+ if ($header =~ m/^heap profile:.*growthz/) {
+ $main::profile_type = 'growth';
+ return ReadHeapProfile($prog, $fname, $header);
+ } elsif ($header =~ m/^heap profile:/) {
+ $main::profile_type = 'heap';
return ReadHeapProfile($prog, $fname, $header);
} elsif ($header =~ m/^--- *$contention_marker/o ) {
- $main::lock_profile = 1;
+ $main::profile_type = 'contention';
return ReadSynchProfile($prog, $fname);
} elsif ($header =~ m/^--- *Stacks:/ ) {
print STDERR
"Old format contention profile: mistakenly reports " .
"condition variable signals as lock contentions.\n";
- $main::lock_profile = 1;
+ $main::profile_type = 'contention';
return ReadSynchProfile($prog, $fname);
} else {
# Need to unread the line we just read
+ $main::profile_type = 'cpu';
close(PROFILE);
open(PROFILE, "<$fname") || error("$fname: $!\n");
binmode PROFILE; # New perls do UTF-8 processing
@@ -2159,6 +2332,10 @@ sub ReadSynchProfile {
# Convert cycles to nanoseconds
$cycles /= $cyclespernanosec;
+ # Adjust for sampling done by application
+ $cycles *= $sampling_period;
+ $count *= $sampling_period;
+
my @values = ($cycles, $count, $cycles / $count);
AddEntries($profile, $pcs, $stack, $values[$index]);
@@ -2171,14 +2348,33 @@ sub ReadSynchProfile {
# Convert cycles to nanoseconds
$cycles /= $cyclespernanosec;
- AddEntries($profile, $pcs, $stack, $cycles);
- } elsif ( $line =~ m|cycles/second = (\d+)|) {
- $cyclespernanosec = $1 / 1e9;
- $seen_clockrate = 1;
- } elsif ( $line =~ /sampling period = (\d+)/ ) {
- $sampling_period = $1;
+ # Adjust for sampling done by application
+ $cycles *= $sampling_period;
+
+ AddEntries($profile, $pcs, $stack, $cycles);
+ } elsif ( $line =~ m/^([^=]*)=(.*)$/ ) {
+ my ($variable, $value) = ($1,$2);
+ for ($variable, $value) {
+ s/^\s+//;
+ s/\s+$//;
+ }
+ if($variable eq "cycles/second") {
+ $cyclespernanosec = $value / 1e9;
+ $seen_clockrate = 1;
+ } elsif ($variable eq "sampling period") {
+ $sampling_period = $value;
+ } elsif ($variable eq "ms since reset") {
+ # Currently nothing is done with this value in pprof
+ # So we just silently ignore it for now
+ } elsif ($variable eq "discarded samples") {
+ # Currently nothing is done with this value in pprof
+ # So we just silently ignore it for now
+ } else {
+ printf STDERR ("Ignoring unnknown variable in /contentionz output: " .
+ "'%s' = '%s'\n",$variable,$value);
+ }
} else {
# Memory map entry
$map .= $line;
@@ -2212,6 +2408,72 @@ sub HexExtend {
##### Symbol extraction #####
+# Aggressively search the lib_prefix values for the given library
+# If all else fails, just return the name of the library unmodified.
+# If the lib_prefix is "/my/path,/other/path" and $file is "/lib/dir/mylib.so"
+# it will search the following locations in this order, until it finds a file:
+# /my/path/lib/dir/mylib.so
+# /other/path/lib/dir/mylib.so
+# /my/path/dir/mylib.so
+# /other/path/dir/mylib.so
+# /my/path/mylib.so
+# /other/path/mylib.so
+# /lib/dir/mylib.so (returned as last resort)
+sub FindLibrary {
+ my $file = shift;
+ my $suffix = $file;
+
+ # Search for the library as described above
+ do {
+ foreach my $prefix (@prefix_list) {
+ my $fullpath = $prefix . $suffix;
+ if (-e $fullpath) {
+ return $fullpath;
+ }
+ }
+ } while ($suffix =~ s|^/[^/]+/|/|);
+ return $file;
+}
+
+# Parse text section header of a library using objdump
+sub ParseTextSectionHeader {
+ my $lib = shift;
+
+ my $size = undef;
+ my $vma;
+ my $file_offset;
+ # Get objdump output from the library file to figure out how to
+ # map between mapped addresses and addresses in the library.
+ my $objdump = $obj_tool_map{"objdump"};
+ open(OBJDUMP, "$objdump -h $lib |")
+ || error("$objdump $lib: $!\n");
+ while (<OBJDUMP>) {
+ # Idx Name Size VMA LMA File off Algn
+ # 10 .text 00104b2c 420156f0 420156f0 000156f0 2**4
+ # For 64-bit objects, VMA and LMA will be 16 hex digits, size and file
+ # offset may still be 8. But AddressSub below will still handle that.
+ my @x = split;
+ if (($#x >= 6) && ($x[1] eq '.text')) {
+ $size = $x[2];
+ $vma = $x[3];
+ $file_offset = $x[5];
+ last;
+ }
+ }
+ close(OBJDUMP);
+
+ if (!defined($size)) {
+ return undef;
+ }
+
+ my $r = {};
+ $r->{size} = $size;
+ $r->{vma} = $vma;
+ $r->{file_offset} = $file_offset;
+
+ return $r;
+}
+
# Split /proc/pid/maps dump into a list of libraries
sub ParseLibraries {
return if $main::use_symbol_page; # We don't need libraries info.
@@ -2254,30 +2516,28 @@ sub ParseLibraries {
# Expand "$build" variable if available
$lib =~ s/\$build\b/$buildvar/g;
- # Get objdump output from the library file to figure out how to
- # map between mapped addresses and addresses in the library.
- my $objdump = $obj_tool_map{"objdump"};
- open(OBJDUMP, "$objdump -h $lib |")
- || error("$objdump $lib: $!\n");
- while (<OBJDUMP>) {
- # Idx Name Size VMA LMA File off Algn
- # 10 .text 00104b2c 420156f0 420156f0 000156f0 2**4
- # For 64-bit objects, VMA and LMA will be 16 hex digits, size and file
- # offset may still be 8. But AddressSub below will still handle that.
- my @x = split;
- if (($#x >= 6) && ($x[1] eq '.text')) {
- my $vma = $x[3];
- my $file_offset = $x[5];
- my $vma_offset = AddressSub($vma, $file_offset);
- $offset = AddressAdd($offset, $vma_offset);
- last;
- }
+ $lib = FindLibrary($lib);
+
+ my $text = ParseTextSectionHeader($lib);
+ if (defined($text)) {
+ my $vma_offset = AddressSub($text->{vma}, $text->{file_offset});
+ $offset = AddressAdd($offset, $vma_offset);
}
- close(OBJDUMP);
push(@{$result}, [$lib, $start, $finish, $offset]);
}
+ # Append special entry for additional library (not relocated)
+ if ($main::opt_lib ne "") {
+ my $text = ParseTextSectionHeader($main::opt_lib);
+ if (defined($text)) {
+ my $start = $text->{vma};
+ my $finish = AddressAdd($start, $text->{size});
+
+ push(@{$result}, [$main::opt_lib, $start, $finish, $start]);
+ }
+ }
+
# Append special entry for the main program
my $max_pc = "0";
foreach my $pc (keys(%{$pcs})) {
@@ -2489,6 +2749,7 @@ sub MapToSymbols {
MapSymbolsWithNM($image, $offset, $pclist, $symbols);
if ($main::opt_interactive ||
+ $main::opt_addresses ||
$main::opt_lines ||
$main::opt_files ||
$main::opt_list) {
@@ -2574,7 +2835,12 @@ sub MapSymbolsWithNM {
$fullname = $names[$index];
$name = ShortFunctionName($fullname);
}
- $symbols->{$pc} = [$name, "?", $fullname];
+ if ($mpc lt $symbol_table->{$fullname}->[1]) {
+ $symbols->{$pc} = [$name, "?", $fullname];
+ } else {
+ my $pcstr = "0x" . $pc;
+ $symbols->{$pc} = [$pcstr, "?", $pcstr];
+ }
}
}
@@ -2599,7 +2865,8 @@ sub ConfigureObjTools {
# Figure out the right default pathname prefix based on the program file
# type:
my $default_prefix = "/usr/bin/";
- my $file_type = `/usr/bin/file $prog_file`;
+ # Follow symlinks (at least for systems where "file" supports that)
+ my $file_type = `/usr/bin/file -L $prog_file || /usr/bin/file $prog_file`;
if ($file_type =~ /ELF 32-bit/) {
$default_prefix = "/usr/bin/";
} elsif ($file_type =~ /ELF 64-bit/) {
@@ -2686,16 +2953,15 @@ sub error {
}
-# Gets the procedure boundaries for all routines in "$image" whose names
-# match "$regexp" and returns them in a hashtable mapping from procedure
-# name to a two-element vector of [start address, end address]
-sub GetProcedureBoundaries {
- my $image = shift;
+# Run $nm_command and get all the resulting procedure boundaries whose
+# names match "$regexp" and returns them in a hashtable mapping from
+# procedure name to a two-element vector of [start address, end address]
+sub GetProcedureBoundariesViaNm {
+ my $nm_command = shift;
my $regexp = shift;
my $symbol_table = {};
- my $nm = $obj_tool_map{"nm"};
- open(NM, "$nm -C -n $image |") || error("$nm: $!\n");
+ open(NM, "$nm_command |") || error("$nm_command: $!\n");
my $last_start = "0";
my $routine = "";
while (<NM>) {
@@ -2714,6 +2980,29 @@ sub GetProcedureBoundaries {
return $symbol_table;
}
+# Gets the procedure boundaries for all routines in "$image" whose names
+# match "$regexp" and returns them in a hashtable mapping from procedure
+# name to a two-element vector of [start address, end address]
+sub GetProcedureBoundaries {
+ my $image = shift;
+ my $regexp = shift;
+
+ # For libc libraries, the copy in /usr/lib/debug contains debugging symbols
+ if ($image =~ m|^/| && -f "/usr/lib/debug$image") {
+ $image = "/usr/lib/debug$image";
+ }
+ my $nm = $obj_tool_map{"nm"};
+ my $nm_command = "$nm -C -n $image";
+ my $symbol_table = GetProcedureBoundariesViaNm($nm_command, $regexp);
+ if (!(%{$symbol_table})) {
+ # Coulnd't get any symbols: probably $image isn't a debug library.
+ # In that case, we can at least get the *exported* symbols via -D
+ $nm_command = "$nm -C -D -n $image";
+ $symbol_table = GetProcedureBoundariesViaNm($nm_command, $regexp);
+ }
+ return $symbol_table;
+}
+
# The test vectors for AddressAdd/Sub/Inc are 8-16-nibble hex strings.
# To make them more readable, we add underscores at interesting places.
diff --git a/src/profiler.cc b/src/profiler.cc
index 8ddcc41..2fe75e4 100644
--- a/src/profiler.cc
+++ b/src/profiler.cc
@@ -38,10 +38,19 @@
// do nothing in the per-thread registration code.
#include "config.h"
+
+// On __x86_64__ systems, we may need _XOPEN_SOURCE defined to get access
+// to the struct ucontext, via signal.h. We need _GNU_SOURCE to get access
+// to REG_RIP. (We can use some trickery to get around that need, though.)
+// Note this #define must come first!
+#define _GNU_SOURCE 1
+// If #define _GNU_SOURCE causes problems, this might work instead:
+//#define _XOPEN_SOURCE 500
+#include <signal.h>
+
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
-#include <unistd.h> // for getuid() and geteuid()
#if defined HAVE_STDINT_H
#include <stdint.h>
#elif defined HAVE_INTTYPES_H
@@ -50,84 +59,151 @@
#include <sys/types.h>
#endif
#include <errno.h>
-#include <signal.h>
#include <unistd.h>
#include <sys/time.h>
#include <string.h>
#include <fcntl.h>
-#include "google/profiler.h"
-#include "google/stacktrace.h"
+#include <google/profiler.h>
+#include <google/stacktrace.h>
#include "base/commandlineflags.h"
#include "base/googleinit.h"
+#include "base/mutex.h"
+#include "base/spinlock.h"
#ifdef HAVE_CONFLICT_SIGNAL_H
#include "conflict-signal.h" /* used on msvc machines */
#endif
#include "base/logging.h"
-#ifndef PATH_MAX
-#ifdef MAXPATHLEN
-#define PATH_MAX MAXPATHLEN
-#else
-#define PATH_MAX 4096 // seems conservative for max filename len!
-#endif
-#endif
-
-#if HAVE_PTHREAD
-# include <pthread.h>
-# define LOCK(m) pthread_mutex_lock(m)
-# define UNLOCK(m) pthread_mutex_unlock(m)
-// Macro for easily checking return values from pthread routines
-# define PCALL(f) do { int __r = f; if (__r != 0) { fprintf(stderr, "%s: %s\n", #f, strerror(__r)); abort(); } } while (0)
-#else
-# define LOCK(m)
-# define UNLOCK(m)
-# define PCALL(f)
-#endif
-
-// For now, keep logging as a noop. TODO: do something better?
-#undef LOG
-#define LOG(msg)
+using std::string;
DEFINE_string(cpu_profile, "",
"Profile file name (used if CPUPROFILE env var not specified)");
-// Figure out how to get the PC for our architecture
-#if defined HAVE_STRUCT_SIGINFO_SI_FADDR
-typedef struct siginfo SigStructure;
-inline void* GetPC(const SigStructure& sig_structure ) {
- return (void*)sig_structure.si_faddr; // maybe not correct
-}
-#elif defined HAVE_STRUCT_SIGCONTEXT_SC_EIP
-typedef struct sigcontext SigStructure;
-inline void* GetPC(const SigStructure& sig_structure ) {
- return (void*)sig_structure.sc_eip;
-}
+// This might be used by GetPC, below.
+// If the profiler interrupt happened just when the current function was
+// entering the stack frame, or after leaving it but just before
+// returning, then the stack trace cannot see the caller function
+// anymore.
+// GetPC tries to unwind the current function call in this case to avoid
+// false edges in the profile graph skipping over a function.
+// A static array of this struct helps GetPC detect these situations.
+//
+// This is a best effort patch -- if we fail to detect such a situation, or
+// mess up the PC, nothing happens; the returned PC is not used for any
+// further processing.
+struct CallUnrollInfo {
+ // Offset from (e)ip register where this instruction sequence should be
+ // matched. Interpreted as bytes. Offset 0 is the next instruction to
+ // execute. Be extra careful with negative offsets in architectures of
+ // variable instruction length (like x86) - it is not that easy as taking
+ // an offset to step one instruction back!
+ int pc_offset;
+ // The actual instruction bytes. Feel free to make it larger if you need
+ // a longer sequence.
+ char ins[16];
+ // How many byutes to match from ins array?
+ size_t ins_size;
+ // The offset from the stack pointer (e)sp where to look for the call
+ // return address. Interpreted as bytes.
+ int return_sp_offset;
+};
+
+
+// TODO: gather the necessary instruction bytes for other architectures.
+#if defined __i386
+static CallUnrollInfo callunrollinfo[] = {
+ // Entry to a function: push %ebp; mov %esp,%ebp
+ // Top-of-stack contains the caller IP.
+ { 0,
+ {0x55, 0x89, 0xe5}, 3,
+ 0
+ },
+ // Entry to a function, second instruction: push %ebp; mov %esp,%ebp
+ // Top-of-stack contains the old frame, caller IP is +4.
+ { -1,
+ {0x55, 0x89, 0xe5}, 3,
+ 4
+ },
+ // Return from a function: RET.
+ // Top-of-stack contains the caller IP.
+ { 0,
+ {0xc3}, 1,
+ 0
+ }
+};
+
+#endif
+
+// Figure out how to get the PC for our architecture.
-#elif defined HAVE_STRUCT_SIGCONTEXT_EIP
+// __i386
+#if defined HAVE_STRUCT_SIGCONTEXT_EIP
typedef struct sigcontext SigStructure;
inline void* GetPC(const SigStructure& sig_structure ) {
+#if defined __i386
+ // See comment above struct CallUnrollInfo.
+ // Only try instruction flow matching if both eip and esp looks
+ // reasonable.
+ if ((sig_structure.eip & 0xffff0000) != 0 &&
+ (~sig_structure.eip & 0xffff0000) != 0 &&
+ (sig_structure.esp & 0xffff0000) != 0) {
+ char* eip = (char*)sig_structure.eip;
+ for (int i = 0; i < ARRAYSIZE(callunrollinfo); ++i) {
+ if (!memcmp(eip + callunrollinfo[i].pc_offset, callunrollinfo[i].ins,
+ callunrollinfo[i].ins_size)) {
+ // We have a match.
+ void **retaddr = (void**)(sig_structure.esp +
+ callunrollinfo[i].return_sp_offset);
+ return *retaddr;
+ }
+ }
+ }
+#endif
return (void*)sig_structure.eip;
}
-#elif defined HAVE_STRUCT_SIGCONTEXT_RIP
+// freebsd (__x386, I assume)
+#elif defined HAVE_STRUCT_SIGCONTEXT_SC_EIP
typedef struct sigcontext SigStructure;
inline void* GetPC(const SigStructure& sig_structure ) {
- return (void*)sig_structure.rip;
+ return (void*)sig_structure.sc_eip;
}
+// __ia64
#elif defined HAVE_STRUCT_SIGCONTEXT_SC_IP
typedef struct sigcontext SigStructure;
inline void* GetPC(const SigStructure& sig_structure ) {
return (void*)sig_structure.sc_ip;
}
+// __x86_64__
+// This may require _XOPEN_SOURCE to have access to ucontext
#elif defined HAVE_STRUCT_UCONTEXT_UC_MCONTEXT
typedef struct ucontext SigStructure;
inline void* GetPC(const SigStructure& sig_structure ) {
- return (void*)sig_structure.uc_mcontext.gregs[REG_RIP];
+ // For this architecture, the regs are stored in a data structure that can
+ // be accessed either as a flat array or (via some trickery) as a struct.
+ // Alas, the index we need into the array, is only defined for _GNU_SOURCE.
+ // Lacking that, we can interpret the register array as a struct sigcontext.
+ // This works in practice, but is probably not guaranteed by anything.
+# ifdef REG_RIP // only defined if _GNU_SOURCE is 1, probably
+ return (void*)(sig_structure.uc_mcontext.gregs[REG_RIP]);
+# else
+ const struct sigcontext* const sc =
+ reinterpret_cast<const struct sigcontext*>(&sig_structure.uc_mcontext.gregs);
+ return (void*)(sc->rip);
+# endif
+}
+
+// solaris (probably solaris-x86, but I'm not sure)
+#elif defined HAVE_STRUCT_SIGINFO_SI_FADDR
+typedef struct siginfo SigStructure;
+inline void* GetPC(const SigStructure& sig_structure ) {
+ return (void*)sig_structure.si_faddr; // maybe not correct
}
+// ibook powerpc
#elif defined HAVE_STRUCT_SIGCONTEXT_REGS__NIP
typedef struct sigcontext SigStructure;
inline void* GetPC(const SigStructure& sig_structure ) {
@@ -139,6 +215,46 @@ inline void* GetPC(const SigStructure& sig_structure ) {
#endif
+// This takes as an argument an environment-variable name (like
+// CPUPROFILE) whose value is supposed to be a file-path, and sets
+// path to that path, and returns true. If the env var doesn't exist,
+// or is the empty string, leave path unchanged and returns false.
+// The reason this is non-trivial is that this function handles munged
+// pathnames. Here's why:
+//
+// If we're a child process of the 'main' process, we can't just use
+// getenv("CPUPROFILE") -- the parent process will be using that path.
+// Instead we append our pid to the pathname. How do we tell if we're a
+// child process? Ideally we'd set an environment variable that all
+// our children would inherit. But -- and this is seemingly a bug in
+// gcc -- if you do a setenv() in a shared libarary in a global
+// constructor, the environment setting is lost by the time main() is
+// called. The only safe thing we can do in such a situation is to
+// modify the existing envvar. So we do a hack: in the parent, we set
+// the high bit of the 1st char of CPUPROFILE. In the child, we
+// notice the high bit is set and append the pid(). This works
+// assuming cpuprofile filenames don't normally have the high bit set
+// in their first character! If that assumption is violated, we'll
+// still get a profile, but one with an unexpected name.
+// TODO(csilvers): set an envvar instead when we can do it reliably.
+static bool GetUniquePathFromEnv(const char* env_name, string* path) {
+ char* envval = getenv(env_name);
+ if (envval == NULL || *envval == '\0')
+ return false;
+ if (envval[0] & 128) { // high bit is set
+ char pid[64]; // pids are smaller than this!
+ snprintf(pid, sizeof(pid), "%u", (unsigned int)(getpid()));
+ *path = envval;
+ *path += "_";
+ *path += pid;
+ (*path)[0] &= 127;
+ } else {
+ *path = string(envval);
+ envval[0] |= 128; // set high bit for kids to see
+ }
+ return true;
+}
+
// Collects up all profile data
class ProfileData {
@@ -148,7 +264,7 @@ class ProfileData {
// Is profiling turned on at all
inline bool enabled() { return out_ >= 0; }
-
+
// What is the frequency of interrupts (ticks per second)
inline int frequency() { return frequency_; }
@@ -163,7 +279,7 @@ class ProfileData {
void Stop();
void GetCurrentState(ProfilerState* state);
-
+
private:
static const int kMaxStackDepth = 64; // Max stack depth profiled
static const int kMaxFrequency = 4000; // Largest allowed frequency
@@ -187,16 +303,14 @@ class ProfileData {
Entry entry[kAssociativity];
};
-#ifdef HAVE_PTHREAD
// Invariant: table_lock_ is only grabbed by handler, or by other code
// when the signal is being ignored (via SIG_IGN).
//
// Locking order is "state_lock_" first, and then "table_lock_"
- pthread_mutex_t state_lock_; // Protects filename, etc.(not used in handler)
- pthread_mutex_t table_lock_; // Cannot use "Mutex" in signal handlers
-#endif
+ Mutex state_lock_; // Protects filename, etc.(not used in handler)
+ SpinLock table_lock_; // SpinLock is safer in signal handlers
Bucket* hash_; // hash table
-
+
Slot* evict_; // evicted entries
int num_evicted_; // how many evicted entries?
int out_; // fd for output file
@@ -248,12 +362,9 @@ ProfileData::ProfileData() :
frequency_(0),
start_time_(0) {
- PCALL(pthread_mutex_init(&state_lock_, NULL));
- PCALL(pthread_mutex_init(&table_lock_, NULL));
-
// Get frequency of interrupts (if specified)
char junk;
- const char* fr = getenv("PROFILEFREQUENCY");
+ const char* fr = getenv("CPUPROFILE_FREQUENCY");
if (fr != NULL && (sscanf(fr, "%d%c", &frequency_, &junk) == 1) &&
(frequency_ > 0)) {
// Limit to kMaxFrequency
@@ -268,52 +379,25 @@ ProfileData::ProfileData() :
ProfilerRegisterThread();
// Should profiling be enabled automatically at start?
- char* cpuprofile = getenv("CPUPROFILE");
- if (!cpuprofile || cpuprofile[0] == '\0') {
+ string fname;
+ if (!GetUniquePathFromEnv("CPUPROFILE", &fname)) {
return;
}
// We don't enable profiling if setuid -- it's a security risk
if (getuid() != geteuid())
return;
- // If we're a child process of the 'main' process, we can't just use
- // the name CPUPROFILE -- the parent process will be using that.
- // Instead we append our pid to the name. How do we tell if we're a
- // child process? Ideally we'd set an environment variable that all
- // our children would inherit. But -- and perhaps this is a bug in
- // gcc -- if you do a setenv() in a shared libarary in a global
- // constructor, the environment setting is lost by the time main()
- // is called. The only safe thing we can do in such a situation is
- // to modify the existing envvar. So we do a hack: in the parent,
- // we set the high bit of the 1st char of CPUPROFILE. In the child,
- // we notice the high bit is set and append the pid(). This works
- // assuming cpuprofile filenames don't normally have the high bit
- // set in their first character! If that assumption is violated,
- // we'll still get a profile, but one with an unexpected name.
- // TODO(csilvers): set an envvar instead when we can do it reliably.
- char fname[PATH_MAX];
- if (cpuprofile[0] & 128) { // high bit is set
- snprintf(fname, sizeof(fname), "%c%s_%u", // add pid and clear high bit
- cpuprofile[0] & 127, cpuprofile+1, (unsigned int)(getpid()));
- } else {
- snprintf(fname, sizeof(fname), "%s", cpuprofile);
- cpuprofile[0] |= 128; // set high bit for kids to see
- }
-
- // process being profiled. CPU profiles are messed up in that case.
-
- if (!Start(fname)) {
+ if (!Start(fname.c_str())) {
fprintf(stderr, "Can't turn on cpu profiling: ");
- perror(fname);
+ perror(fname.c_str());
exit(1);
}
}
bool ProfileData::Start(const char* fname) {
- LOCK(&state_lock_);
+ MutexLock l(&state_lock_);
if (enabled()) {
// profiling is already enabled
- UNLOCK(&state_lock_);
return false;
}
@@ -321,42 +405,43 @@ bool ProfileData::Start(const char* fname) {
int fd = open(fname, O_CREAT | O_WRONLY | O_TRUNC, 0666);
if (fd < 0) {
// Can't open outfile for write
- UNLOCK(&state_lock_);
return false;
}
start_time_ = time(NULL);
fname_ = strdup(fname);
- LOCK(&table_lock_);
-
- // Reset counters
- num_evicted_ = 0;
- count_ = 0;
- evictions_ = 0;
- total_bytes_ = 0;
- // But leave frequency_ alone (i.e., ProfilerStart() doesn't affect
- // their values originally set in the constructor)
-
- out_ = fd;
-
- hash_ = new Bucket[kBuckets];
- evict_ = new Slot[kBufferLength];
- memset(hash_, 0, sizeof(hash_[0]) * kBuckets);
-
- // Record special entries
- evict_[num_evicted_++] = 0; // count for header
- evict_[num_evicted_++] = 3; // depth for header
- evict_[num_evicted_++] = 0; // Version number
- evict_[num_evicted_++] = 1000000 / frequency_; // Period (microseconds)
- evict_[num_evicted_++] = 0; // Padding
-
- UNLOCK(&table_lock_);
+ {
+ SpinLockHolder l2(&table_lock_);
+
+ // Reset counters
+ num_evicted_ = 0;
+ count_ = 0;
+ evictions_ = 0;
+ total_bytes_ = 0;
+ // But leave frequency_ alone (i.e., ProfilerStart() doesn't affect
+ // their values originally set in the constructor)
+
+ out_ = fd;
+
+ hash_ = new Bucket[kBuckets];
+ evict_ = new Slot[kBufferLength];
+ memset(hash_, 0, sizeof(hash_[0]) * kBuckets);
+
+ // Record special entries
+ evict_[num_evicted_++] = 0; // count for header
+ evict_[num_evicted_++] = 3; // depth for header
+ evict_[num_evicted_++] = 0; // Version number
+ evict_[num_evicted_++] = 1000000 / frequency_; // Period (microseconds)
+ evict_[num_evicted_++] = 0; // Padding
+
+ // Must unlock before setting prof_handler to avoid deadlock
+ // with signal delivered to this thread.
+ }
// Setup handler for SIGPROF interrupts
SetHandler((void (*)(int)) prof_handler);
- UNLOCK(&state_lock_);
return true;
}
@@ -367,18 +452,16 @@ ProfileData::~ProfileData() {
// Stop profiling and write out any collected profile data
void ProfileData::Stop() {
- LOCK(&state_lock_);
+ MutexLock l(&state_lock_);
// Prevent handler from running anymore
SetHandler(SIG_IGN);
// This lock prevents interference with signal handlers in other threads
- LOCK(&table_lock_);
+ SpinLockHolder l2(&table_lock_);
if (out_ < 0) {
// Profiling is not enabled
- UNLOCK(&table_lock_);
- UNLOCK(&state_lock_);
return;
}
@@ -426,12 +509,10 @@ void ProfileData::Stop() {
start_time_ = 0;
out_ = -1;
- UNLOCK(&table_lock_);
- UNLOCK(&state_lock_);
}
void ProfileData::GetCurrentState(ProfilerState* state) {
- LOCK(&state_lock_);
+ MutexLock l(&state_lock_);
if (enabled()) {
state->enabled = true;
state->start_time = start_time_;
@@ -445,7 +526,6 @@ void ProfileData::GetCurrentState(ProfilerState* state) {
state->samples_gathered = 0;
state->profile_name[0] = '\0';
}
- UNLOCK(&state_lock_);
}
void ProfileData::SetHandler(void (*handler)(int)) {
@@ -460,39 +540,47 @@ void ProfileData::SetHandler(void (*handler)(int)) {
}
void ProfileData::FlushTable() {
- LOCK(&state_lock_); {
- if (out_ < 0) {
- // Profiling is not enabled
- UNLOCK(&state_lock_);
- return;
- }
- SetHandler(SIG_IGN); // Disable timer interrupts while we're flushing
- LOCK(&table_lock_); {
- // Move data from hash table to eviction buffer
- for (int b = 0; b < kBuckets; b++) {
- Bucket* bucket = &hash_[b];
- for (int a = 0; a < kAssociativity; a++) {
- if (bucket->entry[a].count > 0) {
- Evict(bucket->entry[a]);
- bucket->entry[a].depth = 0;
- bucket->entry[a].count = 0;
- }
+ MutexLock l(&state_lock_);
+ if (out_ < 0) {
+ // Profiling is not enabled
+ return;
+ }
+ SetHandler(SIG_IGN); // Disable timer interrupts while we're flushing
+ {
+ // Move data from hash table to eviction buffer
+ SpinLockHolder l(&table_lock_);
+ for (int b = 0; b < kBuckets; b++) {
+ Bucket* bucket = &hash_[b];
+ for (int a = 0; a < kAssociativity; a++) {
+ if (bucket->entry[a].count > 0) {
+ Evict(bucket->entry[a]);
+ bucket->entry[a].depth = 0;
+ bucket->entry[a].count = 0;
}
}
+ }
- // Write out all pending data
- FlushEvicted();
- } UNLOCK(&table_lock_);
- SetHandler((void (*)(int)) prof_handler);
- } UNLOCK(&state_lock_);
+ // Write out all pending data
+ FlushEvicted();
+ }
+ SetHandler((void (*)(int)) prof_handler);
}
// Record the specified "pc" in the profile data
void ProfileData::Add(unsigned long pc) {
void* stack[kMaxStackDepth];
+
+ // The top-most active routine doesn't show up as a normal
+ // frame, but as the "pc" value in the signal handler context.
stack[0] = (void*)pc;
- int depth = GetStackTrace(stack+1, kMaxStackDepth-1,
- 4/*Removes Add,prof_handler,sighandlers*/);
+
+ // We remove the top three entries (typically Add, prof_handler, and
+ // a signal handler setup routine) since they are artifacts of
+ // profiling and should not be measured. Other profiling related
+ // frames (signal handler setup) will be removed by "pprof" at
+ // analysis time. Instead of skipping the top frames, we could skip
+ // nothing, but that would increase the profile size unnecessarily.
+ int depth = GetStackTrace(stack+1, kMaxStackDepth-1, 3);
depth++; // To account for pc value
// Make hash-value
@@ -503,7 +591,7 @@ void ProfileData::Add(unsigned long pc) {
h += (slot * 31) + (slot * 7) + (slot * 3);
}
- LOCK(&table_lock_);
+ SpinLockHolder l(&table_lock_);
count_++;
// See if table already has an entry for this stack trace
@@ -526,7 +614,7 @@ void ProfileData::Add(unsigned long pc) {
}
}
}
-
+
if (!done) {
// Evict entry with smallest count
Entry* e = &bucket->entry[0];
@@ -539,7 +627,7 @@ void ProfileData::Add(unsigned long pc) {
evictions_++;
Evict(*e);
}
-
+
// Use the newly evicted entry
e->depth = depth;
e->count = 1;
@@ -547,7 +635,6 @@ void ProfileData::Add(unsigned long pc) {
e->stack[i] = reinterpret_cast<Slot>(stack[i]);
}
}
- UNLOCK(&table_lock_);
}
// Write all evicted data to the profile file
@@ -601,7 +688,7 @@ void ProfilerFlush() {
pdata.FlushTable();
}
-bool ProfilingIsEnabledForAllThreads() {
+bool ProfilingIsEnabledForAllThreads() {
return pdata.enabled();
}
diff --git a/src/solaris/libstdc++.la b/src/solaris/libstdc++.la
new file mode 100644
index 0000000..e3aa5a0
--- /dev/null
+++ b/src/solaris/libstdc++.la
@@ -0,0 +1,51 @@
+# ---
+# NOTE: This file lives in /usr/sfw/lib on Solaris 10. Unfortunately,
+# due to an apparent bug in the Solaris 10 6/06 release,
+# /usr/sfw/lib/libstdc++.la is empty. Below is the correct content,
+# according to
+# http://forum.java.sun.com/thread.jspa?threadID=5073150
+# By passing LDFLAGS='-Lsrc/solaris' to configure, make will pick up
+# this copy of the file rather than the empty copy in /usr/sfw/lib.
+#
+# Also see
+# http://www.technicalarticles.org/index.php/Compiling_MySQL_5.0_on_Solaris_10
+#
+# Note: this is for 32-bit systems. If you have a 64-bit system,
+# uncomment the appropriate dependency_libs line below.
+# ----
+
+# libstdc++.la - a libtool library file
+# Generated by ltmain.sh - GNU libtool 1.4a-GCC3.0 (1.641.2.256 2001/05/28 20:09:07 with GCC-local changes)
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname='libstdc++.so.6'
+
+# Names of this library.
+library_names='libstdc++.so.6.0.3 libstdc++.so.6 libstdc++.so'
+
+# The name of the static archive.
+old_library='libstdc++.a'
+
+# Libraries that this one depends upon.
+# 32-bit version:
+dependency_libs='-lc -lm -L/usr/sfw/lib -lgcc_s'
+# 64-bit version:
+#dependency_libs='-L/lib/64 -lc -lm -L/usr/sfw/lib/64 -lgcc_s'
+
+# Version information for libstdc++.
+current=6
+age=0
+revision=3
+
+# Is this an already installed library?
+installed=yes
+
+# Files to dlopen/dlpreopen
+dlopen=''
+dlpreopen=''
+
+# Directory that this library needs to be installed in:
+libdir='/usr/sfw/lib'
diff --git a/src/stacktrace.cc b/src/stacktrace.cc
index da20659..f236798 100644
--- a/src/stacktrace.cc
+++ b/src/stacktrace.cc
@@ -30,38 +30,58 @@
// ---
// Author: Sanjay Ghemawat
//
-// Produce stack trace
+// Produce stack trace.
+//
+// There are three different ways we can try to get the stack trace:
+//
+// 1) Our hand-coded stack-unwinder. This depends on a certain stack
+// layout, which is used by gcc (and those systems using a
+// gcc-compatible ABI) on x86 systems, at least since gcc 2.95.
+// It uses the frame pointer to do its work.
+//
+// 2) The libunwind library. This is still in development, and as a
+// separate library adds a new dependency, abut doesn't need a frame
+// pointer. It also doesn't call malloc.
+//
+// 3) The gdb unwinder -- also the one used by the c++ exception code.
+// It's obviously well-tested, but has a fatal flaw: it can call
+// malloc() from the unwinder. This is a problem because we're
+// trying to use the unwinder to instrument malloc().
+//
+// Note: if you add a new implementation here, make sure it works
+// correctly when GetStackTrace() is called with max_depth == 0.
+// Some code may do that.
#include "config.h"
-#include <stdlib.h>
-#include "google/stacktrace.h"
-
-#undef IMPLEMENTED_STACK_TRACE
-// Linux/x86 implementation (requires the binary to be compiled with
-// frame pointers)
-#if defined(__i386__) && defined(__linux) && !defined(NO_FRAME_POINTER)
-#define IMPLEMENTED_STACK_TRACE
-#include "stacktrace_x86-inl.h"
-#endif
-
-#if !defined(IMPLEMENTED_STACK_TRACE) && defined(__x86_64__) && HAVE_LIBUNWIND_H
-#define IMPLEMENTED_STACK_TRACE
-#define UNW_LOCAL_ONLY
-#include "stacktrace_libunwind-inl.h"
-#endif
+// First, the i386 case.
+#if defined(__i386__) && __GNUC__ >= 2
+# if !defined(NO_FRAME_POINTER)
+# include "stacktrace_x86-inl.h"
+# else
+# include "stacktrace_generic-inl.h"
+# endif
-#if !defined(IMPLEMENTED_STACK_TRACE) && defined(__x86_64__) && HAVE_UNWIND_H
-// This implementation suffers from deadlocks. Don't enable it.
-#define IMPLEMENTED_STACK_TRACE
-#include "stacktrace_x86_64-inl.h"
-#endif
-
-#if !defined(IMPLEMENTED_STACK_TRACE) && !defined(__x86_64__) && HAVE_EXECINFO_H
-#define IMPLEMENTED_STACK_TRACE
-#include "stacktrace_generic-inl.h"
-#endif
+// Now, the x86_64 case.
+#elif defined(__x86_64__) && __GNUC__ >= 2
+# if !defined(NO_FRAME_POINTER)
+# include "stacktrace_x86-inl.h"
+# elif defined(HAVE_LIBUNWIND_H) // a proxy for having libunwind installed
+# define UNW_LOCAL_ONLY
+# include "stacktrace_libunwind-inl.h"
+# elif 0
+ // This is the unwinder used by gdb, which can call malloc (see above).
+ // We keep this code around, so we can test cases where libunwind
+ // doesn't work, but there's no way to enable it except for manually
+ // editing this file (by replacing this "elif 0" with "elif 1", e.g.).
+# include "stacktrace_x86_64-inl.h"
+# elif defined(__linux)
+# error Cannnot calculate stack trace: need either libunwind or frame-pointers (see INSTALL file)
+# else
+# error Cannnot calculate stack trace: need libunwind (see INSTALL file)
+# endif
-#ifndef IMPLEMENTED_STACK_TRACE
-#error Cannot calculate stack trace: will need to write for your environment
+// OK, those are all the processors we know how to deal with.
+#else
+# error Cannot calculate stack trace: will need to write for your environment
#endif
diff --git a/src/stacktrace_generic-inl.h b/src/stacktrace_generic-inl.h
index 28a539a..3375ada 100644
--- a/src/stacktrace_generic-inl.h
+++ b/src/stacktrace_generic-inl.h
@@ -55,7 +55,3 @@ int GetStackTrace(void** result, int max_depth, int skip_count) {
return result_count;
}
-
-bool GetStackExtent(void* sp, void** stack_top, void** stack_bottom) {
- return false; // can't climb up
-}
diff --git a/src/stacktrace_libunwind-inl.h b/src/stacktrace_libunwind-inl.h
index bf39633..4b0e102 100644
--- a/src/stacktrace_libunwind-inl.h
+++ b/src/stacktrace_libunwind-inl.h
@@ -37,20 +37,40 @@ extern "C" {
#include <libunwind.h>
}
#include "google/stacktrace.h"
+#include "base/spinlock.h"
+
+// Sometimes, we can try to get a stack trace from within a stack
+// trace, because libunwind can call mmap/sbrk (maybe indirectly via
+// malloc), and that mmap gets trapped and causes a stack-trace
+// request. If were to try to honor that recursive request, we'd end
+// up with infinite recursion or deadlock. Luckily, it's safe to
+// ignore those subsequent traces. In such cases, we return 0 to
+// indicate the situation.
+static SpinLock libunwind_lock(SpinLock::LINKER_INITIALIZED);
+static bool in_get_stack_trace = false;
int GetStackTrace(void** result, int max_depth, int skip_count) {
void *ip;
- int ret, n = 0;
+ int n = 0;
unw_cursor_t cursor;
unw_context_t uc;
+ {
+ SpinLockHolder sh(&libunwind_lock);
+ if (in_get_stack_trace) {
+ return 0;
+ } else {
+ in_get_stack_trace = true;
+ }
+ }
+
unw_getcontext(&uc);
ret = unw_init_local(&cursor, &uc);
assert(ret >= 0);
skip_count++; // Do not include the "GetStackTrace" frame
- do {
- ret = unw_get_reg(&cursor, UNW_REG_IP, (unw_word_t *) &ip);
+ while (n < max_depth) {
+ int ret = unw_get_reg(&cursor, UNW_REG_IP, (unw_word_t *) &ip);
if (ret < 0)
break;
if (skip_count > 0) {
@@ -59,11 +79,12 @@ int GetStackTrace(void** result, int max_depth, int skip_count) {
result[n++] = ip;
}
ret = unw_step(&cursor);
- } while ((n < max_depth) && (ret > 0));
+ if (ret <= 0)
+ break;
+ }
- return n;
-}
+ SpinLockHolder sh(&libunwind_lock);
+ in_get_stack_trace = false;
-bool GetStackExtent(void* sp, void** stack_top, void** stack_bottom) {
- return false; // Not implemented yet
+ return n;
}
diff --git a/src/stacktrace_x86-inl.h b/src/stacktrace_x86-inl.h
index cdab19b..299cdf8 100644
--- a/src/stacktrace_x86-inl.h
+++ b/src/stacktrace_x86-inl.h
@@ -56,16 +56,32 @@ static void **NextStackFrame(void **old_sp) {
return new_sp;
}
-// Note: the code for GetStackExtent below is pretty similar to this one;
-// change both if chaning one.
int GetStackTrace(void** result, int max_depth, int skip_count) {
void **sp;
+#ifdef __i386__
// Stack frame format:
// sp[0] pointer to previous frame
// sp[1] caller address
// sp[2] first argument
// ...
sp = (void **)&result - 2;
+#endif
+
+#ifdef __x86_64__
+ // __builtin_frame_address(0) can return the wrong address on gcc-4.1.0-k8
+ unsigned long rbp;
+ // Move the value of the register %rbp into the local variable rbp.
+ // We need 'volatile' to prevent this instruction from getting moved
+ // around during optimization to before function prologue is done.
+ // An alternative way to achieve this
+ // would be (before this __asm__ instruction) to call Noop() defined as
+ // static void Noop() __attribute__ ((noinline)); // prevent inlining
+ // static void Noop() { asm(""); } // prevent optimizing-away
+ __asm__ volatile ("mov %%rbp, %0" : "=r" (rbp));
+ // Arguments are passed in registers on x86-64, so we can't just
+ // offset from &result
+ sp = (void **) rbp;
+#endif
int n = 0;
while (sp && n < max_depth) {
@@ -85,35 +101,3 @@ int GetStackTrace(void** result, int max_depth, int skip_count) {
}
return n;
}
-
-// Note: the code is pretty similar to GetStackTrace above;
-// change both if changing one.
-bool GetStackExtent(void* sp, void** stack_top, void** stack_bottom) {
- void** cur_sp;
-
- if (sp != NULL) {
- cur_sp = (void**)sp;
- *stack_top = sp;
- } else {
- // Stack frame format:
- // sp[0] pointer to previous frame
- // sp[1] caller address
- // sp[2] first argument
- // ...
- cur_sp = (void**)&sp - 2;
-
- *stack_top = NULL;
- }
-
- while (cur_sp) {
- void** new_sp = NextStackFrame(cur_sp);
- if (!new_sp) {
- *stack_bottom = (void*)cur_sp;
- return true;
- }
- cur_sp = new_sp;
- if (*stack_top == NULL) *stack_top = (void*)cur_sp;
- // get out of the stack frame for this call
- }
- return false;
-}
diff --git a/src/stacktrace_x86_64-inl.h b/src/stacktrace_x86_64-inl.h
index 3cdfe13..578b50a 100644
--- a/src/stacktrace_x86_64-inl.h
+++ b/src/stacktrace_x86_64-inl.h
@@ -43,8 +43,6 @@ typedef struct {
int max_depth;
int skip_count;
int count;
- void *top;
- void *bottom;
} trace_arg_t;
@@ -101,34 +99,3 @@ int GetStackTrace(void** result, int max_depth, int skip_count) {
return targ.count;
}
-
-static _Unwind_Reason_Code SearchExtents(struct _Unwind_Context *uc, void *opq) {
- trace_arg_t *targ = (trace_arg_t *) opq;
-
- targ->bottom = (void *) _Unwind_GetCFA(uc);
-
- if (targ->top == NULL)
- targ->top = targ->bottom;
-
- return _URC_NO_REASON;
-}
-
-bool GetStackExtent(void* sp, void** stack_top, void** stack_bottom) {
- if (!ready_to_run)
- return false;
-
- trace_arg_t targ;
-
- targ.top = NULL;
- targ.bottom = NULL;
-
- _Unwind_Backtrace(SearchExtents, &targ);
-
- if ((targ.top != NULL) && (targ.bottom != NULL)) {
- *stack_bottom = targ.bottom;
- *stack_top = targ.top;
- return true;
- }
-
- return false;
-}
diff --git a/src/system-alloc.cc b/src/system-alloc.cc
index dee2490..5e69817 100644
--- a/src/system-alloc.cc
+++ b/src/system-alloc.cc
@@ -40,11 +40,25 @@
#endif
#include <unistd.h>
#include <fcntl.h>
+#include <errno.h>
#include <sys/mman.h>
#include "system-alloc.h"
-#include "internal_spinlock.h"
#include "internal_logging.h"
#include "base/commandlineflags.h"
+#include "base/spinlock.h"
+
+// On systems (like freebsd) that don't define MAP_ANONYMOUS, use the old
+// form of the name instead.
+#ifndef MAP_ANONYMOUS
+# define MAP_ANONYMOUS MAP_ANON
+#endif
+
+// Solaris has a bug where it doesn't declare madvise() for C++.
+// http://www.opensolaris.org/jive/thread.jspa?threadID=21035&tstart=0
+#if defined(__sun) && defined(__SVR4)
+# include <sys/types.h> // for caddr_t
+ extern "C" { extern int madvise(caddr_t, size_t, int); }
+#endif
// Structure for discovering alignment
union MemoryAligner {
@@ -53,8 +67,8 @@ union MemoryAligner {
size_t s;
};
-static SpinLock spinlock = SPINLOCK_INITIALIZER;
-
+static SpinLock spinlock(SpinLock::LINKER_INITIALIZED);
+
// Page size is initialized on demand
static size_t pagesize = 0;
@@ -175,7 +189,7 @@ static void* TryDevMem(size_t size, size_t alignment) {
static off_t physmem_base; // next physical memory address to allocate
static off_t physmem_limit; // maximum physical address allowed
static int physmem_fd; // file descriptor for /dev/mem
-
+
// Check if we should use /dev/mem allocation. Note that it may take
// a while to get this flag initialized, so meanwhile we fall back to
// the next allocator. (It looks like 7MB gets allocated before
@@ -185,7 +199,7 @@ static void* TryDevMem(size_t size, size_t alignment) {
// try us again next time.
return NULL;
}
-
+
if (!initialized) {
physmem_fd = open("/dev/mem", O_RDWR);
if (physmem_fd < 0) {
@@ -196,7 +210,7 @@ static void* TryDevMem(size_t size, size_t alignment) {
physmem_limit = FLAGS_malloc_devmem_limit*1024LL*1024LL;
initialized = true;
}
-
+
// Enforce page alignment
if (pagesize == 0) pagesize = getpagesize();
if (alignment < pagesize) alignment = pagesize;
@@ -207,7 +221,7 @@ static void* TryDevMem(size_t size, size_t alignment) {
if (alignment > pagesize) {
extra = alignment - pagesize;
}
-
+
// check to see if we have any memory left
if (physmem_limit != 0 &&
((size + extra) > (physmem_limit - physmem_base))) {
@@ -226,13 +240,13 @@ static void* TryDevMem(size_t size, size_t alignment) {
return NULL;
}
uintptr_t ptr = reinterpret_cast<uintptr_t>(result);
-
+
// Adjust the return memory so it is aligned
size_t adjust = 0;
if ((ptr & (alignment - 1)) != 0) {
adjust = alignment - (ptr & (alignment - 1));
}
-
+
// Return the unused virtual memory to the system
if (adjust > 0) {
munmap(reinterpret_cast<void*>(ptr), adjust);
@@ -240,10 +254,10 @@ static void* TryDevMem(size_t size, size_t alignment) {
if (adjust < extra) {
munmap(reinterpret_cast<void*>(ptr + adjust + size), extra - adjust);
}
-
+
ptr += adjust;
physmem_base += adjust + size;
-
+
return reinterpret_cast<void*>(ptr);
}
@@ -251,10 +265,6 @@ void* TCMalloc_SystemAlloc(size_t size, size_t alignment) {
// Discard requests that overflow
if (size + alignment < size) return NULL;
- if (TCMallocDebug::level >= TCMallocDebug::kVerbose) {
- MESSAGE("TCMalloc_SystemAlloc(%" PRIuS ", %" PRIuS")\n",
- size, alignment);
- }
SpinLockHolder lock_holder(&spinlock);
// Enforce minimum alignment
@@ -289,3 +299,39 @@ void* TCMalloc_SystemAlloc(size_t size, size_t alignment) {
}
return NULL;
}
+
+void TCMalloc_SystemRelease(void* start, size_t length) {
+#ifdef MADV_DONTNEED
+ if (FLAGS_malloc_devmem_start) {
+ // It's not safe to use MADV_DONTNEED if we've been mapping
+ // /dev/mem for heap memory
+ return;
+ }
+ if (pagesize == 0) pagesize = getpagesize();
+ const size_t pagemask = pagesize - 1;
+
+ size_t new_start = reinterpret_cast<size_t>(start);
+ size_t end = new_start + length;
+ size_t new_end = end;
+
+ // Round up the starting address and round down the ending address
+ // to be page aligned:
+ new_start = (new_start + pagesize - 1) & ~pagemask;
+ new_end = new_end & ~pagemask;
+
+ ASSERT((new_start & pagemask) == 0);
+ ASSERT((new_end & pagemask) == 0);
+ ASSERT(new_start >= reinterpret_cast<size_t>(start));
+ ASSERT(new_end <= end);
+
+ if (new_end > new_start) {
+ // Note -- ignoring most return codes, because if this fails it
+ // doesn't matter...
+ while (madvise(reinterpret_cast<void*>(new_start), new_end - new_start,
+ MADV_DONTNEED) == -1 &&
+ errno == EAGAIN) {
+ // NOP
+ }
+ }
+#endif
+}
diff --git a/src/system-alloc.h b/src/system-alloc.h
index 7cb4bd4..511db7c 100644
--- a/src/system-alloc.h
+++ b/src/system-alloc.h
@@ -43,4 +43,15 @@
// when out of memory.
extern void* TCMalloc_SystemAlloc(size_t bytes, size_t alignment = 0);
+// This call is a hint to the operating system that the pages
+// contained in the specified range of memory will not be used for a
+// while, and can be released for use by other processes or the OS.
+// Pages which are released in this way may be destroyed (zeroed) by
+// the OS. The benefit of this function is that it frees memory for
+// use by the system, the cost is that the pages are faulted back into
+// the address space next time they are touched, which can impact
+// performance. (Only pages fully covered by the memory region will
+// be released, partial pages will not.)
+extern void TCMalloc_SystemRelease(void* start, size_t length);
+
#endif /* TCMALLOC_SYSTEM_ALLOC_H__ */
diff --git a/src/tcmalloc.cc b/src/tcmalloc.cc
index bf45dfb..a23449b 100644
--- a/src/tcmalloc.cc
+++ b/src/tcmalloc.cc
@@ -55,7 +55,6 @@
// TODO: Bias reclamation to larger addresses
// TODO: implement mallinfo/mallopt
// TODO: Better testing
-// TODO: Return memory to system
//
// 9/28/2003 (new page-level allocator replaces ptmalloc2):
// * malloc/free of small objects goes from ~300 ns to ~50 ns.
@@ -73,28 +72,68 @@
#else
#include <sys/types.h>
#endif
-#include <malloc.h>
+#ifdef HAVE_STRUCT_MALLINFO
+#include <malloc.h> // for struct mallinfo
+#endif
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#include <errno.h>
#include <stdarg.h>
#include "base/commandlineflags.h"
-#include "google/malloc_hook.h"
-#include "google/malloc_extension.h"
-#include "google/stacktrace.h"
+#include "base/basictypes.h" // gets us PRIu64
+#include "base/sysinfo.h"
+#include "base/spinlock.h"
+#include <google/malloc_hook.h>
+#include <google/malloc_extension.h>
+#include <google/stacktrace.h>
#include "internal_logging.h"
-#include "internal_spinlock.h"
#include "pagemap.h"
#include "system-alloc.h"
#include "maybe_threads.h"
-#if defined HAVE_INTTYPES_H
-#define __STDC_FORMAT_MACROS
-#include <inttypes.h>
-#define LLU PRIu64
-#else
-#define LLU "llu" // hope for the best
+// Even if we have support for thread-local storage in the compiler
+// and linker, the OS may not support it. We need to check that at
+// runtime. Right now, we have to keep a manual set of "bad" OSes.
+#if defined(HAVE_TLS)
+ static bool kernel_supports_tls = false; // be conservative
+ static inline bool KernelSupportsTLS() {
+ return kernel_supports_tls;
+ }
+# if !HAVE_DECL_UNAME // if too old for uname, probably too old for TLS
+ static void CheckIfKernelSupportsTLS() {
+ kernel_supports_tls = false;
+ }
+# else
+# include <sys/utsname.h> // DECL_UNAME checked for <sys/utsname.h> too
+ static void CheckIfKernelSupportsTLS() {
+ struct utsname buf;
+ if (uname(&buf) != 0) { // should be impossible
+ MESSAGE("uname failed assuming no TLS support (errno=%d)\n", errno);
+ kernel_supports_tls = false;
+ } else if (strcasecmp(buf.sysname, "linux") == 0) {
+ // The linux case: the first kernel to support TLS was 2.6.0
+ if (buf.release[0] < '2' && buf.release[1] == '.') // 0.x or 1.x
+ kernel_supports_tls = false;
+ else if (buf.release[0] == '2' && buf.release[1] == '.' &&
+ buf.release[2] >= '0' && buf.release[2] < '6' &&
+ buf.release[3] == '.') // 2.0 - 2.5
+ kernel_supports_tls = false;
+ else
+ kernel_supports_tls = true;
+ } else { // some other kernel, we'll be optimisitic
+ kernel_supports_tls = true;
+ }
+ // TODO(csilvers): VLOG(1) the tls status once we support RAW_VLOG
+ }
+# endif // HAVE_DECL_UNAME
+#endif // HAVE_TLS
+
+// __THROW is defined in glibc systems. It means, counter-intuitively,
+// "This function will never throw an exception." It's an optional
+// optimization tool, but we may need to use it to match glibc prototypes.
+#ifndef __THROW // I guess we're not on a glibc system
+# define __THROW // __THROW is just an optimization, so ok to make it ""
#endif
//-------------------------------------------------------------------
@@ -109,7 +148,7 @@ static const size_t kPageSize = 1 << kPageShift;
static const size_t kMaxSize = 8u * kPageSize;
static const size_t kAlignShift = 3;
static const size_t kAlignment = 1 << kAlignShift;
-static const size_t kNumClasses = 170;
+static const size_t kNumClasses = 68;
// Allocates a big block of memory for the pagemap once we reach more than
// 128MB
@@ -168,26 +207,63 @@ DEFINE_int64(tcmalloc_sample_parameter, 262147,
" larger prime number");
static size_t sample_period = 262147;
// Protects sample_period above
-static SpinLock sample_period_lock = SPINLOCK_INITIALIZER;
+static SpinLock sample_period_lock(SpinLock::LINKER_INITIALIZED);
+
+// Parameters for controlling how fast memory is returned to the OS.
+
+DEFINE_double(tcmalloc_release_rate, 1,
+ "Rate at which we release unused memory to the system. "
+ "Zero means we never release memory back to the system. "
+ "Increase this flag to return memory faster; decrease it "
+ "to return memory slower. Reasonable rates are in the "
+ "range [0,10]");
//-------------------------------------------------------------------
// Mapping from size to size_class and vice versa
//-------------------------------------------------------------------
-// A pair of arrays we use for implementing the mapping from a size to
-// its size class. Indexed by "floor(lg(size))".
-static const int kSizeBits = 8 * sizeof(size_t);
-static unsigned char size_base[kSizeBits];
-static unsigned char size_shift[kSizeBits];
-
-// Mapping from size class to size
+// Sizes <= 1024 have an alignment >= 8. So for such sizes we have an
+// array indexed by ceil(size/8). Sizes > 1024 have an alignment >= 128.
+// So for these larger sizes we have an array indexed by ceil(size/128).
+//
+// We flatten both logical arrays into one physical array and use
+// arithmetic to compute an appropriate index. The "base_index[]"
+// array contains the bases of the two logical arrays.
+//
+// base_index[] contains non-obvious values. We always add 127 to the
+// size before dividing it by either 8 or 128 to implement ceil()
+// efficiently. Therefore base_index[0] is -15 to compensate for the
+// extra 127/8 we added to small sizes. Similarly base_index[1] is
+// 120, so that the first index used by the second logical array is
+// just past the last index used by the first logical array.
+//
+// Examples:
+// Size Expression Index
+// -------------------------------------------------------
+// 0 -15 + ((0+127) / 8) 0
+// 1 -15 + ((1+127) / 8) 1
+// ...
+// 1024 -15 + ((1024+127) / 8) 128
+// 1025 120 + ((1025+127) / 128) 129
+// ...
+// 32768 120 + ((32768+127) / 128) 376
+static const int kMaxSmallSize = 1024;
+static const int shift_amount[2] = { 3, 7 }; // For divides by 8 or 128
+static const int base_index[2] = { -15, 120 }; // For finding array bases
+static unsigned char class_array[377];
+
+// Compute index of the class_array[] entry for a given size
+static inline int ClassIndex(size_t s) {
+ const int i = (s > kMaxSmallSize);
+ return base_index[i] + ((s+127) >> shift_amount[i]);
+}
+
+// Mapping from size class to max size storable in that class
static size_t class_to_size[kNumClasses];
// Mapping from size class to number of pages to allocate at a time
static size_t class_to_pages[kNumClasses];
-
-
// TransferCache is used to cache transfers of num_objects_to_move[size_class]
// back and forth between thread caches and the central cache for a given size
// class.
@@ -202,20 +278,6 @@ struct TCEntry {
// one class can have is kNumClasses.
static const int kNumTransferEntries = kNumClasses;
-// Return floor(log2(n)) for n > 0.
-#if (defined __i386__ || defined __x86_64__) && defined __GNUC__
-static inline int LgFloor(size_t n) {
- // "ro" for the input spec means the input can come from either a
- // register ("r") or offsetable memory ("o").
- size_t result;
- __asm__("bsr %1, %0"
- : "=r" (result) // Output spec
- : "ro" (n) // Input spec
- : "cc" // Clobbers condition-codes
- );
- return result;
-}
-#else
// Note: the following only works for "n"s that fit in 32-bits, but
// that is fine since we only use it for small sizes.
static inline int LgFloor(size_t n) {
@@ -231,8 +293,6 @@ static inline int LgFloor(size_t n) {
ASSERT(n == 1);
return log;
}
-#endif
-
// Some very basic linked list functions for dealing with using void * as
// storage.
@@ -298,10 +358,7 @@ static inline size_t SLL_Size(void *head) {
// Setup helper functions.
static inline int SizeClass(size_t size) {
- if (size == 0) size = 1;
- const int lg = LgFloor(size);
- const int align = size_shift[lg];
- return static_cast<int>(size_base[lg]) + ((size-1) >> align);
+ return class_array[ClassIndex(size)];
}
// Get the byte-size for a specified class
@@ -335,13 +392,18 @@ static int NumMoveSize(size_t size) {
// Initialize the mapping arrays
static void InitSizeClasses() {
- // Special initialization for small sizes
- for (int lg = 0; lg < kAlignShift; lg++) {
- size_base[lg] = 1;
- size_shift[lg] = kAlignShift;
+ // Do some sanity checking on base_index[]/shift_amount[]/class_array[]
+ if (ClassIndex(0) < 0) {
+ MESSAGE("Invalid class index %d for size 0\n", ClassIndex(0));
+ abort();
+ }
+ if (ClassIndex(kMaxSize) >= sizeof(class_array)) {
+ MESSAGE("Invalid class index %d for kMaxSize\n", ClassIndex(kMaxSize));
+ abort();
}
- int next_class = 1;
+ // Compute the size classes we want to use
+ int sc = 1; // Next size class to assign
int alignshift = kAlignShift;
int last_lg = -1;
for (size_t size = kAlignment; size <= kMaxSize; size += (1 << alignshift)) {
@@ -357,31 +419,49 @@ static void InitSizeClasses() {
if ((lg >= 7) && (alignshift < 8)) {
alignshift++;
}
- size_base[lg] = next_class - ((size-1) >> alignshift);
- size_shift[lg] = alignshift;
+ last_lg = lg;
}
- class_to_size[next_class] = size;
- last_lg = lg;
+ // Allocate enough pages so leftover is less than 1/8 of total.
+ // This bounds wasted space to at most 12.5%.
+ size_t psize = kPageSize;
+ while ((psize % size) > (psize >> 3)) {
+ psize += kPageSize;
+ }
+ const size_t my_pages = psize >> kPageShift;
+
+ if (sc > 1 && my_pages == class_to_pages[sc-1]) {
+ // See if we can merge this into the previous class without
+ // increasing the fragmentation of the previous class.
+ const size_t my_objects = (my_pages << kPageShift) / size;
+ const size_t prev_objects = (class_to_pages[sc-1] << kPageShift)
+ / class_to_size[sc-1];
+ if (my_objects == prev_objects) {
+ // Adjust last class to include this size
+ class_to_size[sc-1] = size;
+ continue;
+ }
+ }
- next_class++;
+ // Add new class
+ class_to_pages[sc] = my_pages;
+ class_to_size[sc] = size;
+ sc++;
}
- if (next_class >= kNumClasses) {
- MESSAGE("used up too many size classes: %d\n", next_class);
+ if (sc != kNumClasses) {
+ MESSAGE("wrong number of size classes: found %d instead of %d\n",
+ sc, int(kNumClasses));
abort();
}
- // Initialize the number of pages we should allocate to split into
- // small objects for a given class.
- for (size_t cl = 1; cl < next_class; cl++) {
- // Allocate enough pages so leftover is less than 1/8 of total.
- // This bounds wasted space to at most 12.5%.
- size_t psize = kPageSize;
- const size_t s = class_to_size[cl];
- while ((psize % s) > (psize >> 3)) {
- psize += kPageSize;
+ // Initialize the mapping arrays
+ int next_size = 0;
+ for (int c = 1; c < kNumClasses; c++) {
+ const int max_size_in_class = class_to_size[c];
+ for (int s = next_size; s <= max_size_in_class; s += kAlignment) {
+ class_array[ClassIndex(s)] = c;
}
- class_to_pages[cl] = psize >> kPageShift;
+ next_size = max_size_in_class + kAlignment;
}
// Double-check sizes just to be safe
@@ -415,6 +495,23 @@ static void InitSizeClasses() {
for (size_t cl = 1; cl < kNumClasses; ++cl) {
num_objects_to_move[cl] = NumMoveSize(ByteSizeForClass(cl));
}
+
+ if (false) {
+ // Dump class sizes and maximum external wastage per size class
+ for (size_t cl = 1; cl < kNumClasses; ++cl) {
+ const int alloc_size = class_to_pages[cl] << kPageShift;
+ const int alloc_objs = alloc_size / class_to_size[cl];
+ const int min_used = (class_to_size[cl-1] + 1) * alloc_objs;
+ const int max_waste = alloc_size - min_used;
+ MESSAGE("SC %3d [ %8d .. %8d ] from %8d ; %2.0f%% maxwaste\n",
+ int(cl),
+ int(class_to_size[cl-1] + 1),
+ int(class_to_size[cl]),
+ int(class_to_pages[cl] << kPageShift),
+ max_waste * 100.0 / alloc_size
+ );
+ }
+ }
}
// -------------------------------------------------------------------------
@@ -620,20 +717,6 @@ static void DLL_Prepend(Span* list, Span* span) {
list->next = span;
}
-static void DLL_InsertOrdered(Span* list, Span* span) {
- ASSERT(span->next == NULL);
- ASSERT(span->prev == NULL);
- // Look for appropriate place to insert
- Span* x = list;
- while ((x->next != list) && (x->next->start < span->start)) {
- x = x->next;
- }
- span->next = x->next;
- span->prev = x;
- x->next->prev = span;
- x->next = span;
-}
-
// -------------------------------------------------------------------------
// Stack traces kept for sampled allocations
// The following state is protected by pageheap_lock_.
@@ -729,16 +812,27 @@ class TCMalloc_PageHeap {
bool Check();
bool CheckList(Span* list, Length min_pages, Length max_pages);
+ // Release all pages on the free list for reuse by the OS:
+ void ReleaseFreePages();
+
private:
// Pick the appropriate map type based on pointer size
typedef MapSelector<8*sizeof(uintptr_t)>::Type PageMap;
PageMap pagemap_;
+ // We segregate spans of a given size into two circular linked
+ // lists: one for normal spans, and one for spans whose memory
+ // has been returned to the system.
+ struct SpanList {
+ Span normal;
+ Span returned;
+ };
+
// List of free spans of length >= kMaxPages
- Span large_;
+ SpanList large_;
// Array mapping from span length to a doubly linked list of free spans
- Span free_[kMaxPages];
+ SpanList free_[kMaxPages];
// Number of pages kept in free lists
uintptr_t free_pages_;
@@ -753,7 +847,9 @@ class TCMalloc_PageHeap {
// span into appropriate free lists. Also update "span" to have
// length exactly "n" and mark it as non-free so it can be returned
// to the client.
- void Carve(Span* span, Length n);
+ //
+ // "released" is true iff "span" was found on a "returned" list.
+ void Carve(Span* span, Length n, bool released);
void RecordSpan(Span* span) {
pagemap_.set(span->start, span);
@@ -761,14 +857,34 @@ class TCMalloc_PageHeap {
pagemap_.set(span->start + span->length - 1, span);
}
}
+
+ // Allocate a large span of length == n. If successful, returns a
+ // span of exactly the specified length. Else, returns NULL.
+ Span* AllocLarge(Length n);
+
+ // Incrementally release some memory to the system.
+ // IncrementalScavenge(n) is called whenever n pages are freed.
+ void IncrementalScavenge(Length n);
+
+ // Number of pages to deallocate before doing more scavenging
+ int64_t scavenge_counter_;
+
+ // Index of last free list we scavenged
+ int scavenge_index_;
};
-TCMalloc_PageHeap::TCMalloc_PageHeap() : pagemap_(MetaDataAlloc),
- free_pages_(0),
- system_bytes_(0) {
- DLL_Init(&large_);
+TCMalloc_PageHeap::TCMalloc_PageHeap()
+ : pagemap_(MetaDataAlloc),
+ free_pages_(0),
+ system_bytes_(0),
+ scavenge_counter_(0),
+ // Start scavenging at kMaxPages list
+ scavenge_index_(kMaxPages-1) {
+ DLL_Init(&large_.normal);
+ DLL_Init(&large_.returned);
for (int i = 0; i < kMaxPages; i++) {
- DLL_Init(&free_[i]);
+ DLL_Init(&free_[i].normal);
+ DLL_Init(&free_[i].returned);
}
}
@@ -780,40 +896,79 @@ Span* TCMalloc_PageHeap::New(Length n) {
// Find first size >= n that has a non-empty list
for (Length s = n; s < kMaxPages; s++) {
- if (!DLL_IsEmpty(&free_[s])) {
- Span* result = free_[s].next;
- Carve(result, n);
- ASSERT(Check());
- free_pages_ -= n;
- return result;
+ Span* ll = NULL;
+ bool released = false;
+ if (!DLL_IsEmpty(&free_[s].normal)) {
+ // Found normal span
+ ll = &free_[s].normal;
+ } else if (!DLL_IsEmpty(&free_[s].returned)) {
+ // Found returned span; reallocate it
+ ll = &free_[s].returned;
+ released = true;
+ } else {
+ // Keep looking in larger classes
+ continue;
}
+
+ Span* result = ll->next;
+ Carve(result, n, released);
+ ASSERT(Check());
+ free_pages_ -= n;
+ return result;
}
- // Look in large list. If we first do not find something, we try to
- // grow the heap and try again.
- for (int i = 0; i < 2; i++) {
- // find the best span (closest to n in size)
- Span *best = NULL;
- for (Span* span = large_.next; span != &large_; span = span->next) {
- if (span->length >= n &&
- (best == NULL || span->length < best->length)) {
+ Span* result = AllocLarge(n);
+ if (result != NULL) return result;
+
+ // Grow the heap and try again
+ if (!GrowHeap(n)) {
+ ASSERT(Check());
+ return NULL;
+ }
+
+ return AllocLarge(n);
+}
+
+Span* TCMalloc_PageHeap::AllocLarge(Length n) {
+ // find the best span (closest to n in size).
+ // The following loops implements address-ordered best-fit.
+ bool from_released = false;
+ Span *best = NULL;
+
+ // Search through normal list
+ for (Span* span = large_.normal.next;
+ span != &large_.normal;
+ span = span->next) {
+ if (span->length >= n) {
+ if ((best == NULL)
+ || (span->length < best->length)
+ || ((span->length == best->length) && (span->start < best->start))) {
best = span;
+ from_released = false;
}
}
- if (best != NULL) {
- Carve(best, n);
- ASSERT(Check());
- free_pages_ -= n;
- return best;
- }
- if (i == 0) {
- // Nothing suitable in large list. Grow the heap and look again.
- if (!GrowHeap(n)) {
- ASSERT(Check());
- return NULL;
+ }
+
+ // Search through released list in case it has a better fit
+ for (Span* span = large_.returned.next;
+ span != &large_.returned;
+ span = span->next) {
+ if (span->length >= n) {
+ if ((best == NULL)
+ || (span->length < best->length)
+ || ((span->length == best->length) && (span->start < best->start))) {
+ best = span;
+ from_released = true;
}
}
}
+
+ if (best != NULL) {
+ Carve(best, n, from_released);
+ ASSERT(Check());
+ free_pages_ -= n;
+ return best;
+ }
return NULL;
}
@@ -834,7 +989,7 @@ Span* TCMalloc_PageHeap::Split(Span* span, Length n) {
return leftover;
}
-void TCMalloc_PageHeap::Carve(Span* span, Length n) {
+void TCMalloc_PageHeap::Carve(Span* span, Length n, bool released) {
ASSERT(n > 0);
DLL_Remove(span);
span->free = 0;
@@ -847,11 +1002,12 @@ void TCMalloc_PageHeap::Carve(Span* span, Length n) {
leftover->free = 1;
Event(leftover, 'S', extra);
RecordSpan(leftover);
- if (extra < kMaxPages) {
- DLL_Prepend(&free_[extra], leftover);
- } else {
- DLL_InsertOrdered(&large_, leftover);
- }
+
+ // Place leftover span on appropriate free list
+ SpanList* listpair = (extra < kMaxPages) ? &free_[extra] : &large_;
+ Span* dst = released ? &listpair->returned : &listpair->normal;
+ DLL_Prepend(dst, leftover);
+
span->length = n;
pagemap_.set(span->start + n - 1, span);
}
@@ -870,6 +1026,10 @@ void TCMalloc_PageHeap::Delete(Span* span) {
// necessary. We do not bother resetting the stale pagemap
// entries for the pieces we are merging together because we only
// care about the pagemap entries for the boundaries.
+ //
+ // Note that the spans we merge into "span" may come out of
+ // a "returned" list. For simplicity, we move these into the
+ // "normal" list of the appropriate size class.
const PageID p = span->start;
const Length n = span->length;
Span* prev = GetDescriptor(p-1);
@@ -899,15 +1059,71 @@ void TCMalloc_PageHeap::Delete(Span* span) {
Event(span, 'D', span->length);
span->free = 1;
if (span->length < kMaxPages) {
- DLL_Prepend(&free_[span->length], span);
+ DLL_Prepend(&free_[span->length].normal, span);
} else {
- DLL_InsertOrdered(&large_, span);
+ DLL_Prepend(&large_.normal, span);
}
free_pages_ += n;
+ IncrementalScavenge(n);
ASSERT(Check());
}
+void TCMalloc_PageHeap::IncrementalScavenge(Length n) {
+ // Fast path; not yet time to release memory
+ scavenge_counter_ -= n;
+ if (scavenge_counter_ >= 0) return; // Not yet time to scavenge
+
+ // Never delay scavenging for more than the following number of
+ // deallocated pages. With 4K pages, this comes to 4GB of
+ // deallocation.
+ static const int kMaxReleaseDelay = 1 << 20;
+
+ // If there is nothing to release, wait for so many pages before
+ // scavenging again. With 4K pages, this comes to 1GB of memory.
+ static const int kDefaultReleaseDelay = 1 << 18;
+
+ const double rate = FLAGS_tcmalloc_release_rate;
+ if (rate <= 1e-6) {
+ // Tiny release rate means that releasing is disabled.
+ scavenge_counter_ = kDefaultReleaseDelay;
+ return;
+ }
+
+ // Find index of free list to scavenge
+ int index = scavenge_index_ + 1;
+ for (int i = 0; i < kMaxPages+1; i++) {
+ if (index > kMaxPages) index = 0;
+ SpanList* slist = (index == kMaxPages) ? &large_ : &free_[index];
+ if (!DLL_IsEmpty(&slist->normal)) {
+ // Release the last span on the normal portion of this list
+ Span* s = slist->normal.prev;
+ DLL_Remove(s);
+ TCMalloc_SystemRelease(reinterpret_cast<void*>(s->start << kPageShift),
+ static_cast<size_t>(s->length << kPageShift));
+ DLL_Prepend(&slist->returned, s);
+
+ // Compute how long to wait until we return memory.
+ // FLAGS_tcmalloc_release_rate==1 means wait for 1000 pages
+ // after releasing one page.
+ const double mult = 1000.0 / rate;
+ double wait = mult * static_cast<double>(s->length);
+ if (wait > kMaxReleaseDelay) {
+ // Avoid overflow and bound to reasonable range
+ wait = kMaxReleaseDelay;
+ }
+ scavenge_counter_ = static_cast<int64_t>(wait);
+
+ scavenge_index_ = index; // Scavenge at index+1 next time
+ return;
+ }
+ index++;
+ }
+
+ // Nothing to scavenge, delay for a while
+ scavenge_counter_ = kDefaultReleaseDelay;
+}
+
void TCMalloc_PageHeap::RegisterSizeClass(Span* span, size_t sc) {
// Associate span object with all interior pages as well
ASSERT(!span->free);
@@ -920,40 +1136,69 @@ void TCMalloc_PageHeap::RegisterSizeClass(Span* span, size_t sc) {
}
}
+static double PagesToMB(uint64_t pages) {
+ return (pages << kPageShift) / 1048576.0;
+}
+
void TCMalloc_PageHeap::Dump(TCMalloc_Printer* out) {
int nonempty_sizes = 0;
for (int s = 0; s < kMaxPages; s++) {
- if (!DLL_IsEmpty(&free_[s])) nonempty_sizes++;
+ if (!DLL_IsEmpty(&free_[s].normal) || !DLL_IsEmpty(&free_[s].returned)) {
+ nonempty_sizes++;
+ }
}
out->printf("------------------------------------------------\n");
- out->printf("PageHeap: %d sizes; %6.1f MB free\n", nonempty_sizes,
- (static_cast<double>(free_pages_) * kPageSize) / 1048576.0);
+ out->printf("PageHeap: %d sizes; %6.1f MB free\n",
+ nonempty_sizes, PagesToMB(free_pages_));
out->printf("------------------------------------------------\n");
- uint64_t cumulative = 0;
+ uint64_t total_normal = 0;
+ uint64_t total_returned = 0;
for (int s = 0; s < kMaxPages; s++) {
- if (!DLL_IsEmpty(&free_[s])) {
- const int list_length = DLL_Length(&free_[s]);
- uint64_t s_pages = s * list_length;
- cumulative += s_pages;
- out->printf("%6u pages * %6u spans ~ %6.1f MB; %6.1f MB cum\n",
- s, list_length,
- (s_pages << kPageShift) / 1048576.0,
- (cumulative << kPageShift) / 1048576.0);
+ const int n_length = DLL_Length(&free_[s].normal);
+ const int r_length = DLL_Length(&free_[s].returned);
+ if (n_length + r_length > 0) {
+ uint64_t n_pages = s * n_length;
+ uint64_t r_pages = s * r_length;
+ total_normal += n_pages;
+ total_returned += r_pages;
+ out->printf("%6u pages * %6u spans ~ %6.1f MB; %6.1f MB cum"
+ "; unmapped: %6.1f MB; %6.1f MB cum\n",
+ s,
+ (n_length + r_length),
+ PagesToMB(n_pages + r_pages),
+ PagesToMB(total_normal + total_returned),
+ PagesToMB(r_pages),
+ PagesToMB(total_returned));
}
}
- uint64_t large_pages = 0;
- int large_spans = 0;
- for (Span* s = large_.next; s != &large_; s = s->next) {
- out->printf(" [ %6" PRIuS " pages ]\n", s->length);
- large_pages += s->length;
- large_spans++;
- }
- cumulative += large_pages;
- out->printf(">255 large * %6u spans ~ %6.1f MB; %6.1f MB cum\n",
- large_spans,
- (large_pages << kPageShift) / 1048576.0,
- (cumulative << kPageShift) / 1048576.0);
+ uint64_t n_pages = 0;
+ uint64_t r_pages = 0;
+ int n_spans = 0;
+ int r_spans = 0;
+ out->printf("Normal large spans:\n");
+ for (Span* s = large_.normal.next; s != &large_.normal; s = s->next) {
+ out->printf(" [ %6" PRIuS " pages ] %6.1f MB\n",
+ s->length, PagesToMB(s->length));
+ n_pages += s->length;
+ n_spans++;
+ }
+ out->printf("Unmapped large spans:\n");
+ for (Span* s = large_.returned.next; s != &large_.returned; s = s->next) {
+ out->printf(" [ %6" PRIuS " pages ] %6.1f MB\n",
+ s->length, PagesToMB(s->length));
+ r_pages += s->length;
+ r_spans++;
+ }
+ total_normal += n_pages;
+ total_returned += r_pages;
+ out->printf(">255 large * %6u spans ~ %6.1f MB; %6.1f MB cum"
+ "; unmapped: %6.1f MB; %6.1f MB cum\n",
+ (n_spans + r_spans),
+ PagesToMB(n_pages + r_pages),
+ PagesToMB(total_normal + total_returned),
+ PagesToMB(r_pages),
+ PagesToMB(total_returned));
}
static void RecordGrowth(size_t growth) {
@@ -1013,10 +1258,13 @@ bool TCMalloc_PageHeap::GrowHeap(Length n) {
}
bool TCMalloc_PageHeap::Check() {
- ASSERT(free_[0].next == &free_[0]);
- CheckList(&large_, kMaxPages, 1000000000);
+ ASSERT(free_[0].normal.next == &free_[0].normal);
+ ASSERT(free_[0].returned.next == &free_[0].returned);
+ CheckList(&large_.normal, kMaxPages, 1000000000);
+ CheckList(&large_.returned, kMaxPages, 1000000000);
for (Length s = 1; s < kMaxPages; s++) {
- CheckList(&free_[s], s, s);
+ CheckList(&free_[s].normal, s, s);
+ CheckList(&free_[s].returned, s, s);
}
return true;
}
@@ -1032,6 +1280,26 @@ bool TCMalloc_PageHeap::CheckList(Span* list, Length min_pages, Length max_pages
return true;
}
+static void ReleaseFreeList(Span* list, Span* returned) {
+ // Walk backwards through list so that when we push these
+ // spans on the "returned" list, we preserve the order.
+ while (!DLL_IsEmpty(list)) {
+ Span* s = list->prev;
+ DLL_Remove(s);
+ DLL_Prepend(returned, s);
+ TCMalloc_SystemRelease(reinterpret_cast<void*>(s->start << kPageShift),
+ static_cast<size_t>(s->length << kPageShift));
+ }
+}
+
+void TCMalloc_PageHeap::ReleaseFreePages() {
+ for (Length s = 0; s < kMaxPages; s++) {
+ ReleaseFreeList(&free_[s].normal, &free_[s].returned);
+ }
+ ReleaseFreeList(&large_.normal, &large_.returned);
+ ASSERT(Check());
+}
+
//-------------------------------------------------------------------
// Free list
//-------------------------------------------------------------------
@@ -1105,6 +1373,11 @@ class TCMalloc_ThreadCache {
uint32_t rnd_; // Cheap random number generator
size_t bytes_until_sample_; // Bytes until we sample next
+ // Allocate a new heap. REQUIRES: pageheap_lock is held.
+ static inline TCMalloc_ThreadCache* NewHeap(pthread_t tid);
+
+ // Use only as pthread thread-specific destructor function.
+ static void DestroyThreadCache(void* ptr);
public:
// All ThreadCache objects are kept in a linked list (for stats collection)
TCMalloc_ThreadCache* next_;
@@ -1132,14 +1405,16 @@ class TCMalloc_ThreadCache {
bool SampleAllocation(size_t k);
// Pick next sampling point
- void PickNextSample();
+ void PickNextSample(size_t k);
static void InitModule();
static void InitTSD();
+ static TCMalloc_ThreadCache* GetThreadHeap();
static TCMalloc_ThreadCache* GetCache();
static TCMalloc_ThreadCache* GetCacheIfPresent();
- static void* CreateCacheIfNecessary();
- static void DeleteCache(void* ptr);
+ static TCMalloc_ThreadCache* CreateCacheIfNecessary();
+ static void DeleteCache(TCMalloc_ThreadCache* heap);
+ static void BecomeIdle();
static void RecomputeThreadCacheSize();
};
@@ -1260,7 +1535,7 @@ class TCMalloc_Central_FreeListPadded : public TCMalloc_Central_FreeList {
static TCMalloc_Central_FreeListPadded central_cache[kNumClasses];
// Page-level allocator
-static SpinLock pageheap_lock = SPINLOCK_INITIALIZER;
+static SpinLock pageheap_lock(SpinLock::LINKER_INITIALIZED);
static char pageheap_memory[sizeof(TCMalloc_PageHeap)];
static bool phinited = false;
@@ -1268,6 +1543,16 @@ static bool phinited = false;
// of pageheap_memory.
#define pageheap ((TCMalloc_PageHeap*) pageheap_memory)
+// If TLS is available, we also store a copy
+// of the per-thread object in a __thread variable
+// since __thread variables are faster to read
+// than pthread_getspecific(). We still need
+// pthread_setspecific() because __thread
+// variables provide no way to run cleanup
+// code when a thread is destroyed.
+#ifdef HAVE_TLS
+static __thread TCMalloc_ThreadCache *threadlocal_heap;
+#endif
// Thread-specific key. Initialization here is somewhat tricky
// because some Linux startup code invokes malloc() before it
// is in a good enough state to handle pthread_keycreate().
@@ -1297,7 +1582,6 @@ static volatile size_t per_thread_cache_size = kMaxThreadCacheSize;
//-------------------------------------------------------------------
void TCMalloc_Central_FreeList::Init(size_t cl) {
- lock_.Init();
size_class_ = cl;
DLL_Init(&empty_);
DLL_Init(&nonempty_);
@@ -1396,9 +1680,9 @@ bool TCMalloc_Central_FreeList::MakeCacheSpace() {
namespace {
class LockInverter {
private:
- TCMalloc_SpinLock *held_, *temp_;
+ SpinLock *held_, *temp_;
public:
- inline explicit LockInverter(TCMalloc_SpinLock* held, TCMalloc_SpinLock *temp)
+ inline explicit LockInverter(SpinLock* held, SpinLock *temp)
: held_(held), temp_(temp) { held_->Unlock(); temp_->Lock(); }
inline ~LockInverter() { temp_->Unlock(); held_->Lock(); }
};
@@ -1558,7 +1842,7 @@ void TCMalloc_Central_FreeList::Populate() {
inline bool TCMalloc_ThreadCache::SampleAllocation(size_t k) {
if (bytes_until_sample_ < k) {
- PickNextSample();
+ PickNextSample(k);
return true;
} else {
bytes_until_sample_ -= k;
@@ -1577,9 +1861,10 @@ void TCMalloc_ThreadCache::Init(pthread_t tid) {
}
// Initialize RNG -- run it for a bit to get to good values
+ bytes_until_sample_ = 0;
rnd_ = static_cast<uint32_t>(reinterpret_cast<uintptr_t>(this));
for (int i = 0; i < 100; i++) {
- PickNextSample();
+ PickNextSample(FLAGS_tcmalloc_sample_parameter * 2);
}
}
@@ -1670,27 +1955,7 @@ void TCMalloc_ThreadCache::Scavenge() {
//MESSAGE("GC: %.0f ns\n", ct.CyclesToUsec(finish-start)*1000.0);
}
-inline TCMalloc_ThreadCache* TCMalloc_ThreadCache::GetCache() {
- void* ptr = NULL;
- if (!tsd_inited) {
- InitModule();
- } else {
- ptr = perftools_pthread_getspecific(heap_key);
- }
- if (ptr == NULL) ptr = CreateCacheIfNecessary();
- return reinterpret_cast<TCMalloc_ThreadCache*>(ptr);
-}
-
-// In deletion paths, we do not try to create a thread-cache. This is
-// because we may be in the thread destruction code and may have
-// already cleaned up the cache for this thread.
-inline TCMalloc_ThreadCache* TCMalloc_ThreadCache::GetCacheIfPresent() {
- if (!tsd_inited) return NULL;
- return reinterpret_cast<TCMalloc_ThreadCache*>
- (perftools_pthread_getspecific(heap_key));
-}
-
-void TCMalloc_ThreadCache::PickNextSample() {
+void TCMalloc_ThreadCache::PickNextSample(size_t k) {
// Make next "random" number
// x^32+x^22+x^2+x^1+1 is a primitive polynomial for random numbers
static const uint32_t kPoly = (1 << 22) | (1 << 2) | (1 << 1) | (1 << 0);
@@ -1713,7 +1978,27 @@ void TCMalloc_ThreadCache::PickNextSample() {
sample_period = primes_list[i];
last_flag_value = flag_value;
}
- bytes_until_sample_ = rnd_ % sample_period;
+
+ bytes_until_sample_ += rnd_ % sample_period;
+
+ if (k > (static_cast<size_t>(-1) >> 2)) {
+ // If the user has asked for a huge allocation then it is possible
+ // for the code below to loop infinitely. Just return (note that
+ // this throws off the sampling accuracy somewhat, but a user who
+ // is allocating more than 1G of memory at a time can live with a
+ // minor inaccuracy in profiling of small allocations, and also
+ // would rather not wait for the loop below to terminate).
+ return;
+ }
+
+ while (bytes_until_sample_ < k) {
+ // Increase bytes_until_sample_ by enough average sampling periods
+ // (sample_period >> 1) to allow us to sample past the current
+ // allocation.
+ bytes_until_sample_ += (sample_period >> 1);
+ }
+
+ bytes_until_sample_ -= k;
}
void TCMalloc_ThreadCache::InitModule() {
@@ -1740,9 +2025,52 @@ void TCMalloc_ThreadCache::InitModule() {
}
}
+inline TCMalloc_ThreadCache* TCMalloc_ThreadCache::NewHeap(pthread_t tid) {
+ // Create the heap and add it to the linked list
+ TCMalloc_ThreadCache *heap = threadheap_allocator.New();
+ heap->Init(tid);
+ heap->next_ = thread_heaps;
+ heap->prev_ = NULL;
+ if (thread_heaps != NULL) thread_heaps->prev_ = heap;
+ thread_heaps = heap;
+ thread_heap_count++;
+ RecomputeThreadCacheSize();
+ return heap;
+}
+
+inline TCMalloc_ThreadCache* TCMalloc_ThreadCache::GetThreadHeap() {
+#ifdef HAVE_TLS
+ // __thread is faster, but only when the kernel supports it
+ if (KernelSupportsTLS())
+ return threadlocal_heap;
+#endif
+ return
+ reinterpret_cast<TCMalloc_ThreadCache *>(perftools_pthread_getspecific(heap_key));
+}
+
+inline TCMalloc_ThreadCache* TCMalloc_ThreadCache::GetCache() {
+ TCMalloc_ThreadCache* ptr = NULL;
+ if (!tsd_inited) {
+ InitModule();
+ } else {
+ ptr = GetThreadHeap();
+ }
+ if (ptr == NULL) ptr = CreateCacheIfNecessary();
+ return ptr;
+}
+
+// In deletion paths, we do not try to create a thread-cache. This is
+// because we may be in the thread destruction code and may have
+// already cleaned up the cache for this thread.
+inline TCMalloc_ThreadCache* TCMalloc_ThreadCache::GetCacheIfPresent() {
+ if (!tsd_inited) return NULL;
+ void* const p = GetThreadHeap();
+ return reinterpret_cast<TCMalloc_ThreadCache*>(p);
+}
+
void TCMalloc_ThreadCache::InitTSD() {
ASSERT(!tsd_inited);
- perftools_pthread_key_create(&heap_key, DeleteCache);
+ perftools_pthread_key_create(&heap_key, DestroyThreadCache);
tsd_inited = true;
// We may have used a fake pthread_t for the main thread. Fix it.
@@ -1756,7 +2084,7 @@ void TCMalloc_ThreadCache::InitTSD() {
}
}
-void* TCMalloc_ThreadCache::CreateCacheIfNecessary() {
+TCMalloc_ThreadCache* TCMalloc_ThreadCache::CreateCacheIfNecessary() {
// Initialize per-thread data if necessary
TCMalloc_ThreadCache* heap = NULL;
{
@@ -1780,17 +2108,7 @@ void* TCMalloc_ThreadCache::CreateCacheIfNecessary() {
}
}
- if (heap == NULL) {
- // Create the heap and add it to the linked list
- heap = threadheap_allocator.New();
- heap->Init(me);
- heap->next_ = thread_heaps;
- heap->prev_ = NULL;
- if (thread_heaps != NULL) thread_heaps->prev_ = heap;
- thread_heaps = heap;
- thread_heap_count++;
- RecomputeThreadCacheSize();
- }
+ if (heap == NULL) heap = NewHeap(me);
}
// We call pthread_setspecific() outside the lock because it may
@@ -1800,15 +2118,52 @@ void* TCMalloc_ThreadCache::CreateCacheIfNecessary() {
if (!heap->in_setspecific_ && tsd_inited) {
heap->in_setspecific_ = true;
perftools_pthread_setspecific(heap_key, heap);
+#ifdef HAVE_TLS
+ // Also keep a copy in __thread for faster retrieval
+ threadlocal_heap = heap;
+#endif
heap->in_setspecific_ = false;
}
return heap;
}
-void TCMalloc_ThreadCache::DeleteCache(void* ptr) {
+void TCMalloc_ThreadCache::BecomeIdle() {
+ if (!tsd_inited) return; // No caches yet
+ TCMalloc_ThreadCache* heap = GetThreadHeap();
+ if (heap == NULL) return; // No thread cache to remove
+ if (heap->in_setspecific_) return; // Do not disturb the active caller
+
+ heap->in_setspecific_ = true;
+ perftools_pthread_setspecific(heap_key, NULL);
+#ifdef HAVE_TLS
+ // Also update the copy in __thread
+ threadlocal_heap = NULL;
+#endif
+ heap->in_setspecific_ = false;
+ if (GetThreadHeap() == heap) {
+ // Somehow heap got reinstated by a recursive call to malloc
+ // from pthread_setspecific. We give up in this case.
+ return;
+ }
+
+ // We can now get rid of the heap
+ DeleteCache(heap);
+}
+
+void TCMalloc_ThreadCache::DestroyThreadCache(void* ptr) {
+ // Note that "ptr" cannot be NULL since pthread promises not
+ // to invoke the destructor on NULL values, but for safety,
+ // we check anyway.
+ if (ptr == NULL) return;
+#ifdef HAVE_TLS
+ // Prevent fast path of GetThreadHeap() from returning heap.
+ threadlocal_heap = NULL;
+#endif
+ DeleteCache(reinterpret_cast<TCMalloc_ThreadCache*>(ptr));
+}
+
+void TCMalloc_ThreadCache::DeleteCache(TCMalloc_ThreadCache* heap) {
// Remove all memory from heap
- TCMalloc_ThreadCache* heap;
- heap = reinterpret_cast<TCMalloc_ThreadCache*>(ptr);
heap->Cleanup();
// Remove from linked list
@@ -1832,6 +2187,7 @@ void TCMalloc_ThreadCache::RecomputeThreadCacheSize() {
if (space > kMaxThreadCacheSize) space = kMaxThreadCacheSize;
per_thread_cache_size = space;
+ //MESSAGE("Threads %d => cache size %8d\n", n, int(space));
}
void TCMalloc_ThreadCache::Print() const {
@@ -1902,7 +2258,7 @@ static void DumpStats(TCMalloc_Printer* out, int level) {
uint64_t class_bytes = class_count[cl] * ByteSizeForClass(cl);
cumulative += class_bytes;
out->printf("class %3d [ %8" PRIuS " bytes ] : "
- "%8" LLU " objs; %5.1f MB; %5.1f cum MB\n",
+ "%8" PRIu64 " objs; %5.1f MB; %5.1f cum MB\n",
cl, ByteSizeForClass(cl),
class_count[cl],
class_bytes / 1048576.0,
@@ -1921,15 +2277,15 @@ static void DumpStats(TCMalloc_Printer* out, int level) {
- stats.thread_bytes;
out->printf("------------------------------------------------\n"
- "MALLOC: %12" LLU " Heap size\n"
- "MALLOC: %12" LLU " Bytes in use by application\n"
- "MALLOC: %12" LLU " Bytes free in page heap\n"
- "MALLOC: %12" LLU " Bytes free in central cache\n"
- "MALLOC: %12" LLU " Bytes free in transfer cache\n"
- "MALLOC: %12" LLU " Bytes free in thread caches\n"
- "MALLOC: %12" LLU " Spans in use\n"
- "MALLOC: %12" LLU " Thread heaps in use\n"
- "MALLOC: %12" LLU " Metadata allocated\n"
+ "MALLOC: %12" PRIu64 " Heap size\n"
+ "MALLOC: %12" PRIu64 " Bytes in use by application\n"
+ "MALLOC: %12" PRIu64 " Bytes free in page heap\n"
+ "MALLOC: %12" PRIu64 " Bytes free in central cache\n"
+ "MALLOC: %12" PRIu64 " Bytes free in transfer cache\n"
+ "MALLOC: %12" PRIu64 " Bytes free in thread caches\n"
+ "MALLOC: %12" PRIu64 " Spans in use\n"
+ "MALLOC: %12" PRIu64 " Thread heaps in use\n"
+ "MALLOC: %12" PRIu64 " Metadata allocated\n"
"------------------------------------------------\n",
stats.system_bytes,
bytes_in_use,
@@ -2120,31 +2476,80 @@ class TCMallocImplementation : public MallocExtension {
return false;
}
+
+ virtual void MarkThreadIdle() {
+ TCMalloc_ThreadCache::BecomeIdle();
+ }
+
+ virtual void ReleaseFreeMemory() {
+ SpinLockHolder h(&pageheap_lock);
+ pageheap->ReleaseFreePages();
+ }
+};
+
+// The constructor allocates an object to ensure that initialization
+// runs before main(), and therefore we do not have a chance to become
+// multi-threaded before initialization. We also create the TSD key
+// here. Presumably by the time this constructor runs, glibc is in
+// good enough shape to handle pthread_key_create().
+//
+// The constructor also takes the opportunity to tell STL to use
+// tcmalloc. We want to do this early, before construct time, so
+// all user STL allocations go through tcmalloc (which works really
+// well for STL).
+//
+// The destructor prints stats when the program exits.
+class TCMallocGuard {
+ public:
+
+ TCMallocGuard() {
+#ifdef HAVE_TLS // this is true if the cc/ld/libc combo support TLS
+ // Check whether the kernel also supports TLS (needs to happen at runtime)
+ CheckIfKernelSupportsTLS();
+#endif
+ free(malloc(1));
+ TCMalloc_ThreadCache::InitTSD();
+ free(malloc(1));
+ MallocExtension::Register(new TCMallocImplementation);
+ }
+
+ ~TCMallocGuard() {
+ const char* env = getenv("MALLOCSTATS");
+ if (env != NULL) {
+ int level = atoi(env);
+ if (level < 1) level = 1;
+ PrintStats(level);
+ }
+ }
};
+static TCMallocGuard module_enter_exit_hook;
//-------------------------------------------------------------------
// Helpers for the exported routines below
//-------------------------------------------------------------------
static Span* DoSampledAllocation(size_t size) {
- SpinLockHolder h(&pageheap_lock);
+ // Grab the stack trace outside the heap lock
+ StackTrace tmp;
+ tmp.depth = GetStackTrace(tmp.stack, kMaxStackDepth, 1);
+ tmp.size = size;
+
+ SpinLockHolder h(&pageheap_lock);
// Allocate span
- Span* span = pageheap->New(pages(size == 0 ? 1 : size));
+ Span *span = pageheap->New(pages(size == 0 ? 1 : size));
if (span == NULL) {
return NULL;
}
-
+
// Allocate stack trace
- StackTrace* stack = stacktrace_allocator.New();
+ StackTrace *stack = stacktrace_allocator.New();
if (stack == NULL) {
// Sampling failed because of lack of memory
return span;
}
- // Fill stack trace and record properly
- stack->depth = GetStackTrace(stack->stack, kMaxStackDepth, 1);
- stack->size = size;
+ *stack = tmp;
span->sample = 1;
span->objects = stack;
DLL_Prepend(&sampled_objects, span);
@@ -2155,9 +2560,6 @@ static Span* DoSampledAllocation(size_t size) {
static inline void* do_malloc(size_t size) {
void* ret = NULL;
- if (TCMallocDebug::level >= TCMallocDebug::kVerbose) {
- MESSAGE("In tcmalloc do_malloc(%" PRIuS")\n", size);
- }
// The following call forces module initialization
TCMalloc_ThreadCache* heap = TCMalloc_ThreadCache::GetCache();
if ((FLAGS_tcmalloc_sample_parameter > 0) && heap->SampleAllocation(size)) {
@@ -2180,8 +2582,6 @@ static inline void* do_malloc(size_t size) {
}
static inline void do_free(void* ptr) {
- if (TCMallocDebug::level >= TCMallocDebug::kVerbose)
- MESSAGE("In tcmalloc do_free(%p)\n", ptr);
if (ptr == NULL) return;
ASSERT(pageheap != NULL); // Should not call free() before malloc()
const PageID p = reinterpret_cast<uintptr_t>(ptr) >> kPageShift;
@@ -2286,47 +2686,41 @@ static void* do_memalign(size_t align, size_t size) {
return reinterpret_cast<void*>(span->start << kPageShift);
}
+// Helpers for use by exported routines below:
+static inline void do_malloc_stats() {
+ PrintStats(1);
+}
-// The constructor allocates an object to ensure that initialization
-// runs before main(), and therefore we do not have a chance to become
-// multi-threaded before initialization. We also create the TSD key
-// here. Presumably by the time this constructor runs, glibc is in
-// good enough shape to handle pthread_key_create().
-//
-// The constructor also takes the opportunity to tell STL to use
-// tcmalloc. We want to do this early, before construct time, so
-// all user STL allocations go through tcmalloc (which works really
-// well for STL).
-//
-// The destructor prints stats when the program exits.
+static inline int do_mallopt(int cmd, int value) {
+ return 1; // Indicates error
+}
-class TCMallocGuard {
- public:
- TCMallocGuard() {
- char *envval;
- if ((envval = getenv("TCMALLOC_DEBUG"))) {
- TCMallocDebug::level = atoi(envval);
- MESSAGE("Set tcmalloc debugging level to %d\n", TCMallocDebug::level);
- }
- do_free(do_malloc(1));
- TCMalloc_ThreadCache::InitTSD();
- do_free(do_malloc(1));
- MallocExtension::Register(new TCMallocImplementation);
- }
+#ifdef HAVE_STRUCT_MALLINFO // mallinfo isn't defined on freebsd, for instance
+static inline struct mallinfo do_mallinfo() {
+ TCMallocStats stats;
+ ExtractStats(&stats, NULL);
- ~TCMallocGuard() {
- const char* env = getenv("MALLOCSTATS");
- if (env != NULL) {
- int level = atoi(env);
- if (level < 1) level = 1;
- PrintStats(level);
- }
- }
-};
+ // Just some of the fields are filled in.
+ struct mallinfo info;
+ memset(&info, 0, sizeof(info));
-static TCMallocGuard module_enter_exit_hook;
+ // Unfortunately, the struct contains "int" field, so some of the
+ // size values will be truncated.
+ info.arena = static_cast<int>(stats.system_bytes);
+ info.fsmblks = static_cast<int>(stats.thread_bytes
+ + stats.central_bytes
+ + stats.transfer_bytes);
+ info.fordblks = static_cast<int>(stats.pageheap_bytes);
+ info.uordblks = static_cast<int>(stats.system_bytes
+ - stats.thread_bytes
+ - stats.central_bytes
+ - stats.transfer_bytes
+ - stats.pageheap_bytes);
+ return info;
+}
+#endif
//-------------------------------------------------------------------
// Exported routines
@@ -2337,18 +2731,67 @@ static TCMallocGuard module_enter_exit_hook;
// heap-checker.cc depends on this to start a stack trace from
// the call to the (de)allocation function.
-extern "C" void* malloc(size_t size) {
+// Put all callers of MallocHook::Invoke* in this module into
+// ATTRIBUTE_SECTION(google_malloc_allocators) section,
+// so that MallocHook::GetCallerStackTrace can function accurately:
+
+// NOTE: __THROW expands to 'throw()', which means 'never throws.' Urgh.
+extern "C" {
+ void* malloc(size_t size)
+ __THROW ATTRIBUTE_SECTION(google_malloc_allocators);
+ void free(void* ptr)
+ __THROW ATTRIBUTE_SECTION(google_malloc_allocators);
+ void* realloc(void* ptr, size_t size)
+ __THROW ATTRIBUTE_SECTION(google_malloc_allocators);
+ void* calloc(size_t nmemb, size_t size)
+ __THROW ATTRIBUTE_SECTION(google_malloc_allocators);
+ void cfree(void* ptr)
+ __THROW ATTRIBUTE_SECTION(google_malloc_allocators);
+
+ void* memalign(size_t __alignment, size_t __size)
+ __THROW ATTRIBUTE_SECTION(google_malloc_allocators);
+ int posix_memalign(void** ptr, size_t align, size_t size)
+ __THROW ATTRIBUTE_SECTION(google_malloc_allocators);
+ void* valloc(size_t __size)
+ __THROW ATTRIBUTE_SECTION(google_malloc_allocators);
+ void* pvalloc(size_t __size)
+ __THROW ATTRIBUTE_SECTION(google_malloc_allocators);
+}
+
+static void *MemalignOverride(size_t align, size_t size, const void *caller)
+ __THROW ATTRIBUTE_SECTION(google_malloc_allocators);
+
+void* operator new(size_t size)
+ ATTRIBUTE_SECTION(google_malloc_allocators);
+void operator delete(void* p)
+ __THROW ATTRIBUTE_SECTION(google_malloc_allocators);
+void* operator new[](size_t size)
+ ATTRIBUTE_SECTION(google_malloc_allocators);
+void operator delete[](void* p)
+ __THROW ATTRIBUTE_SECTION(google_malloc_allocators);
+
+// And the nothrow variants of these:
+void* operator new(size_t size, const std::nothrow_t&)
+ __THROW ATTRIBUTE_SECTION(google_malloc_allocators);
+void operator delete(void* p, const std::nothrow_t&)
+ __THROW ATTRIBUTE_SECTION(google_malloc_allocators);
+void* operator new[](size_t size, const std::nothrow_t&)
+ __THROW ATTRIBUTE_SECTION(google_malloc_allocators);
+void operator delete[](void* p, const std::nothrow_t&)
+ __THROW ATTRIBUTE_SECTION(google_malloc_allocators);
+
+extern "C" void* malloc(size_t size) __THROW {
void* result = do_malloc(size);
MallocHook::InvokeNewHook(result, size);
return result;
}
-extern "C" void free(void* ptr) {
+extern "C" void free(void* ptr) __THROW {
MallocHook::InvokeDeleteHook(ptr);
do_free(ptr);
}
-extern "C" void* calloc(size_t n, size_t elem_size) {
+extern "C" void* calloc(size_t n, size_t elem_size) __THROW {
// Overflow check
const size_t size = n * elem_size;
if (elem_size != 0 && size / elem_size != n) return NULL;
@@ -2361,12 +2804,12 @@ extern "C" void* calloc(size_t n, size_t elem_size) {
return result;
}
-extern "C" void cfree(void* ptr) {
+extern "C" void cfree(void* ptr) __THROW {
MallocHook::InvokeDeleteHook(ptr);
do_free(ptr);
}
-extern "C" void* realloc(void* old_ptr, size_t new_size) {
+extern "C" void* realloc(void* old_ptr, size_t new_size) __THROW {
if (old_ptr == NULL) {
void* result = do_malloc(new_size);
MallocHook::InvokeNewHook(result, new_size);
@@ -2406,21 +2849,12 @@ extern "C" void* realloc(void* old_ptr, size_t new_size) {
}
}
-#ifndef COMPILER_INTEL
-#define OP_THROWNOTHING
-#define OP_THROWBADALLOC
-#else
-#define OP_THROWNOTHING throw()
-#define OP_THROWBADALLOC throw(std::bad_alloc)
-#endif
-
-static SpinLock set_new_handler_lock = SPINLOCK_INITIALIZER;
+static SpinLock set_new_handler_lock(SpinLock::LINKER_INITIALIZED);
static inline void* cpp_alloc(size_t size, bool nothrow) {
for (;;) {
void* p = do_malloc(size);
#ifdef PREANSINEW
- MallocHook::InvokeNewHook(p, size);
return p;
#else
if (p == NULL) { // allocation failed
@@ -2446,60 +2880,77 @@ static inline void* cpp_alloc(size_t size, bool nothrow) {
(*nh)();
} catch (const std::bad_alloc&) {
if (!nothrow) throw;
- MallocHook::InvokeNewHook(p, size);
return p;
}
} else { // allocation success
- MallocHook::InvokeNewHook(p, size);
return p;
}
#endif
}
}
-void* operator new(size_t size) OP_THROWBADALLOC {
- return cpp_alloc(size, false);
+void* operator new(size_t size) {
+ void* p = cpp_alloc(size, false);
+ // We keep this next instruction out of cpp_alloc for a reason: when
+ // it's in, and new just calls cpp_alloc, the optimizer may fold the
+ // new call into cpp_alloc, which messes up our whole section-based
+ // stacktracing (see ATTRIBUTE_SECTION, above). This ensures cpp_alloc
+ // isn't the last thing this fn calls, and prevents the folding.
+ MallocHook::InvokeNewHook(p, size);
+ return p;
}
-void* operator new(size_t size, const std::nothrow_t&) OP_THROWNOTHING {
- return cpp_alloc(size, true);
+void* operator new(size_t size, const std::nothrow_t&) __THROW {
+ void* p = cpp_alloc(size, true);
+ MallocHook::InvokeNewHook(p, size);
+ return p;
}
-void operator delete(void* p) OP_THROWNOTHING {
+void operator delete(void* p) __THROW {
MallocHook::InvokeDeleteHook(p);
do_free(p);
}
-void operator delete(void* p, const std::nothrow_t&) OP_THROWNOTHING {
+void operator delete(void* p, const std::nothrow_t&) __THROW {
MallocHook::InvokeDeleteHook(p);
do_free(p);
}
-void* operator new[](size_t size) OP_THROWBADALLOC {
- return cpp_alloc(size, false);
+void* operator new[](size_t size) {
+ void* p = cpp_alloc(size, false);
+ // We keep this next instruction out of cpp_alloc for a reason: when
+ // it's in, and new just calls cpp_alloc, the optimizer may fold the
+ // new call into cpp_alloc, which messes up our whole section-based
+ // stacktracing (see ATTRIBUTE_SECTION, above). This ensures cpp_alloc
+ // isn't the last thing this fn calls, and prevents the folding.
+ MallocHook::InvokeNewHook(p, size);
+ return p;
}
-void* operator new[](size_t size, const std::nothrow_t&) OP_THROWNOTHING {
- return cpp_alloc(size, true);
+void* operator new[](size_t size, const std::nothrow_t&) __THROW {
+ void* p = cpp_alloc(size, true);
+ MallocHook::InvokeNewHook(p, size);
+ return p;
}
-void operator delete[](void* p) OP_THROWNOTHING {
+void operator delete[](void* p) __THROW {
MallocHook::InvokeDeleteHook(p);
do_free(p);
}
-void operator delete[](void* p, const std::nothrow_t&) OP_THROWNOTHING {
+void operator delete[](void* p, const std::nothrow_t&) __THROW {
MallocHook::InvokeDeleteHook(p);
do_free(p);
}
-extern "C" void* memalign(size_t align, size_t size) {
+extern "C" void* memalign(size_t align, size_t size) __THROW {
void* result = do_memalign(align, size);
MallocHook::InvokeNewHook(result, size);
return result;
}
-extern "C" int posix_memalign(void** result_ptr, size_t align, size_t size) {
+extern "C" int posix_memalign(void** result_ptr, size_t align, size_t size)
+ __THROW {
if (((align % sizeof(void*)) != 0) ||
((align & (align - 1)) != 0) ||
(align == 0)) {
@@ -2518,7 +2969,7 @@ extern "C" int posix_memalign(void** result_ptr, size_t align, size_t size) {
static size_t pagesize = 0;
-extern "C" void* valloc(size_t size) {
+extern "C" void* valloc(size_t size) __THROW {
// Allocate page-aligned object of length >= size bytes
if (pagesize == 0) pagesize = getpagesize();
void* result = do_memalign(pagesize, size);
@@ -2526,7 +2977,7 @@ extern "C" void* valloc(size_t size) {
return result;
}
-extern "C" void* pvalloc(size_t size) {
+extern "C" void* pvalloc(size_t size) __THROW {
// Round up size to a multiple of pagesize
if (pagesize == 0) pagesize = getpagesize();
size = (size + pagesize - 1) & ~(pagesize - 1);
@@ -2536,36 +2987,18 @@ extern "C" void* pvalloc(size_t size) {
}
extern "C" void malloc_stats(void) {
- PrintStats(1);
+ do_malloc_stats();
}
extern "C" int mallopt(int cmd, int value) {
- return 1; // Indicates error
+ return do_mallopt(cmd, value);
}
+#ifdef HAVE_STRUCT_MALLINFO
extern "C" struct mallinfo mallinfo(void) {
- TCMallocStats stats;
- ExtractStats(&stats, NULL);
-
- // Just some of the fields are filled in.
- struct mallinfo info;
- memset(&info, 0, sizeof(info));
-
- // Unfortunately, the struct contains "int" field, so some of the
- // size values will be truncated.
- info.arena = static_cast<int>(stats.system_bytes);
- info.fsmblks = static_cast<int>(stats.thread_bytes
- + stats.central_bytes
- + stats.transfer_bytes);
- info.fordblks = static_cast<int>(stats.pageheap_bytes);
- info.uordblks = static_cast<int>(stats.system_bytes
- - stats.thread_bytes
- - stats.central_bytes
- - stats.transfer_bytes
- - stats.pageheap_bytes);
-
- return info;
+ return do_mallinfo();
}
+#endif
//-------------------------------------------------------------------
// Some library routines on RedHat 9 allocate memory using malloc()
@@ -2611,7 +3044,8 @@ extern "C" {
// This function is an exception to the rule of calling MallocHook method
// from the stack frame of the allocation function;
// heap-checker handles this special case explicitly.
-static void *MemalignOverride(size_t align, size_t size, const void *caller) {
+static void *MemalignOverride(size_t align, size_t size, const void *caller)
+ __THROW {
void* result = do_memalign(align, size);
MallocHook::InvokeNewHook(result, size);
return result;
diff --git a/src/tests/addressmap_unittest.cc b/src/tests/addressmap_unittest.cc
index 0636dc3..868235d 100644
--- a/src/tests/addressmap_unittest.cc
+++ b/src/tests/addressmap_unittest.cc
@@ -43,12 +43,12 @@ DEFINE_int32(N, 100000, "Number of elements to test per iteration");
using std::pair;
using std::make_pair;
using std::vector;
+using std::set;
using std::random_shuffle;
-static std::set<pair<void*, int> > check_set;
-
-static void SetCheckCallback(void* ptr, int val) {
- check_set.insert(make_pair(ptr, val));
+static void SetCheckCallback(void* ptr, int val,
+ set<pair<void*, int> >* check_set) {
+ check_set->insert(make_pair(ptr, val));
}
int main(int argc, char** argv) {
@@ -105,7 +105,8 @@ int main(int argc, char** argv) {
}
// Check all entries
- map.Iterate(SetCheckCallback);
+ set<pair<void*, int> > check_set;
+ map.Iterate(SetCheckCallback, &check_set);
CHECK_EQ(check_set.size(), N);
for (int i = 0; i < N; ++i) {
void* p = ptrs[i];
diff --git a/src/tests/atomicops_unittest.cc b/src/tests/atomicops_unittest.cc
new file mode 100644
index 0000000..26fd896
--- /dev/null
+++ b/src/tests/atomicops_unittest.cc
@@ -0,0 +1,111 @@
+/* Copyright (c) 2006, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ---
+ * Author: Sanjay Ghemawat
+ */
+
+#include "base/logging.h"
+#include "base/atomicops.h"
+
+template <class AtomicType>
+static void TestAtomicIncrement() {
+ // For now, we just test single threaded execution
+
+ // use a guard value to make sure the AtomicIncrement doesn't go
+ // outside the expected address bounds. This is in particular to
+ // test that some future change to the asm code doesn't cause the
+ // 32-bit AtomicIncrement doesn't do the wrong thing on 64-bit
+ // machines.
+ struct {
+ AtomicType prev_word;
+ AtomicType count;
+ AtomicType next_word;
+ } s;
+
+ AtomicType prev_word_value, next_word_value;
+ memset(&prev_word_value, 0xFF, sizeof(AtomicType));
+ memset(&next_word_value, 0xEE, sizeof(AtomicType));
+
+ s.prev_word = prev_word_value;
+ s.count = 0;
+ s.next_word = next_word_value;
+
+ CHECK_EQ(AtomicIncrement(&s.count, 1), 1);
+ CHECK_EQ(s.count, 1);
+ CHECK_EQ(s.prev_word, prev_word_value);
+ CHECK_EQ(s.next_word, next_word_value);
+
+ CHECK_EQ(AtomicIncrement(&s.count, 2), 3);
+ CHECK_EQ(s.count, 3);
+ CHECK_EQ(s.prev_word, prev_word_value);
+ CHECK_EQ(s.next_word, next_word_value);
+
+ CHECK_EQ(AtomicIncrement(&s.count, 3), 6);
+ CHECK_EQ(s.count, 6);
+ CHECK_EQ(s.prev_word, prev_word_value);
+ CHECK_EQ(s.next_word, next_word_value);
+
+ CHECK_EQ(AtomicIncrement(&s.count, -3), 3);
+ CHECK_EQ(s.count, 3);
+ CHECK_EQ(s.prev_word, prev_word_value);
+ CHECK_EQ(s.next_word, next_word_value);
+
+ CHECK_EQ(AtomicIncrement(&s.count, -2), 1);
+ CHECK_EQ(s.count, 1);
+ CHECK_EQ(s.prev_word, prev_word_value);
+ CHECK_EQ(s.next_word, next_word_value);
+
+ CHECK_EQ(AtomicIncrement(&s.count, -1), 0);
+ CHECK_EQ(s.count, 0);
+ CHECK_EQ(s.prev_word, prev_word_value);
+ CHECK_EQ(s.next_word, next_word_value);
+
+ CHECK_EQ(AtomicIncrement(&s.count, -1), -1);
+ CHECK_EQ(s.count, -1);
+ CHECK_EQ(s.prev_word, prev_word_value);
+ CHECK_EQ(s.next_word, next_word_value);
+
+ CHECK_EQ(AtomicIncrement(&s.count, -4), -5);
+ CHECK_EQ(s.count, -5);
+ CHECK_EQ(s.prev_word, prev_word_value);
+ CHECK_EQ(s.next_word, next_word_value);
+
+ CHECK_EQ(AtomicIncrement(&s.count, 5), 0);
+ CHECK_EQ(s.count, 0);
+ CHECK_EQ(s.prev_word, prev_word_value);
+ CHECK_EQ(s.next_word, next_word_value);
+}
+
+int main(int argc, char** argv) {
+ TestAtomicIncrement<AtomicWord>();
+ TestAtomicIncrement<Atomic32>();
+ printf("PASS\n");
+ return 0;
+}
diff --git a/src/tests/frag_unittest.cc b/src/tests/frag_unittest.cc
new file mode 100644
index 0000000..cc25e31
--- /dev/null
+++ b/src/tests/frag_unittest.cc
@@ -0,0 +1,101 @@
+// Copyright (c) 2003, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// ---
+// Author: Sanjay Ghemawat
+//
+// Test speed of handling fragmented heap
+
+#include "config.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/time.h> // for struct timeval
+#include <sys/resource.h> // for getrusage
+#include <vector>
+#include "base/logging.h"
+#include <google/malloc_extension.h>
+
+using std::vector;
+
+int main(int argc, char** argv) {
+ static const int kAllocSize = 36<<10; // Bigger than tcmalloc page size
+ static const int kTotalAlloc = 400 << 20; // Allocate 400MB in total
+ static const int kAllocIterations = kTotalAlloc / kAllocSize;
+
+ // Allocate lots of objects
+ vector<char*> saved(kAllocIterations);
+ for (int i = 0; i < kAllocIterations; i++) {
+ saved[i] = new char[kAllocSize];
+ }
+
+ // Free alternating ones to fragment heap
+ size_t free_bytes = 0;
+ for (int i = 0; i < saved.size(); i += 2) {
+ delete[] saved[i];
+ free_bytes += kAllocSize;
+ }
+
+ // Check that slack is within 10% of expected
+ size_t slack;
+ MallocExtension::instance()->GetNumericProperty("tcmalloc.slack_bytes",
+ &slack);
+ CHECK_GT(double(slack), 0.9*free_bytes);
+ CHECK_LT(double(slack), 1.1*free_bytes);
+
+ // Dump malloc stats
+ static const int kBufSize = 1<<20;
+ char* buffer = new char[kBufSize];
+ MallocExtension::instance()->GetStats(buffer, kBufSize);
+ VLOG(1, "%s", buffer);
+ delete[] buffer;
+
+ // Now do timing tests
+ for (int i = 0; i < 5; i++) {
+ static const int kIterations = 100000;
+ struct rusage r;
+ getrusage(RUSAGE_SELF, &r); // figure out user-time spent on this
+ struct timeval tv_start = r.ru_utime;
+
+ for (int i = 0; i < kIterations; i++) {
+ size_t s;
+ MallocExtension::instance()->GetNumericProperty("tcmalloc.slack_bytes",
+ &s);
+ }
+
+ getrusage(RUSAGE_SELF, &r);
+ struct timeval tv_end = r.ru_utime;
+ int64 sumsec = static_cast<int64>(tv_end.tv_sec) - tv_start.tv_sec;
+ int64 sumusec = static_cast<int64>(tv_end.tv_usec) - tv_start.tv_usec;
+ fprintf(stderr, "getproperty: %6.1f ns/call\n",
+ (sumsec * 1e9 + sumusec * 1e3) / kIterations);
+ }
+
+ printf("PASS\n");
+ return 0;
+}
diff --git a/src/tests/heap-checker-death_unittest.sh b/src/tests/heap-checker-death_unittest.sh
index 45b4077..6ba628b 100755
--- a/src/tests/heap-checker-death_unittest.sh
+++ b/src/tests/heap-checker-death_unittest.sh
@@ -1,5 +1,4 @@
-#!/bin/sh
-
+#!/bin/bash
# Copyright (c) 2005, Google Inc.
# All rights reserved.
#
@@ -30,30 +29,134 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# ---
+# Author: Maxim Lifantsev
+#
# Run the heap checker unittest in a mode where it is supposed to crash and
-# return an error if it doesn't
-
-export HEAPCHECK=strict
+# return an error if it doesn't.
-# When the environment variable HEAP_CHECKER_TEST_LEAK is set,
-# heap-checker_unittest should leak some memory and then crash on exit.
-HEAPCHECK_TEST_LEAK=1 ./heap-checker_unittest
+# We expect BINDIR to be set in the environment.
+# If not, we set it to some reasonable value.
+BINDIR="${BINDIR:-.}"
-if [ "$?" == 0 ] ; then
- echo >&2 "Heap checker unittest did not crash when it was supposed to"
- echo >&2 "for test HEAPCHECK_TEST_LEAK=1"
+if [ "x$1" = "x-h" -o "x$1" = "x--help" ]; then
+ echo "USAGE: $0 [unittest dir]"
+ echo " By default, unittest_dir=$BINDIR"
exit 1
fi
-# When the environment variable HEAP_CHECKER_TEST_LOOP_LEAK is set,
-# heap-checker_unittest should allocate two pointers that form a loop, leak
-# them, and crash on exit.
-HEAPCHECK_TEST_LOOP_LEAK=1 ./heap-checker_unittest
+EXE="${1:-$BINDIR}/heap-checker_unittest"
+TMPDIR="/tmp/heap_check_death_info"
-if [ "$?" == 0 ] ; then
- echo >&2 "Heap checker unittest did not crash when it was supposed to"
- echo >&2 "for test HEAPCHECK_TEST_LOOP_LEAK=1"
- exit 1
-fi
+function ALARM() {
+ # You need perl to run pprof, so I assume it's installed
+ perl -e '
+ $timeout=$ARGV[0]; shift;
+ $retval = 255; # the default retval, for the case where we timed out
+ eval { # need to run in an eval-block to trigger during system()
+ local $SIG{ALRM} = sub { die "alarm\n" }; # \n is required!
+ alarm $timeout;
+ $retval = system(@ARGV);
+ # Make retval bash-style: exit status, or 128+n if terminated by signal n
+ $retval = ($retval & 127) ? (128 + $retval) : ($retval >> 8);
+ alarm 0;
+ };
+ exit $retval; # return system()-retval, or 255 if system() never returned
+' "$@"
+}
+
+# $1: timeout for alarm;
+# $2: regexp of expected exit code(s);
+# $3: regexp to match a line in the output;
+# $4: regexp to not match a line in the output;
+# $5+ args to pass to $EXE
+function Test() {
+ local timeout="$1"
+ shift
+ local expected_ec="$1"
+ shift
+ local expected_regexp="$1"
+ shift
+ local unexpected_regexp="$1"
+ shift
+
+ echo -n "Testing $EXE with $@ ... "
+ local output="$TMPDIR/output"
+ ALARM $timeout env "$@" $EXE > "$output" 2>&1
+ local actual_ec=$?
+ local ec_ok=$(expr "$actual_ec" : "$expected_ec$" >/dev/null || echo false)
+ local matches_ok=$(test -z "$expected_regexp" || \
+ grep -q "$expected_regexp" "$output" || echo false)
+ local negmatches_ok=$(test -z "$unexpected_regexp" || \
+ ! grep -q "$unexpected_regexp" "$output" || echo false)
+ if $ec_ok && $matches_ok && $negmatches_ok; then
+ echo "PASS"
+ return 0 # 0: success
+ fi
+ # If we get here, we failed. Now we just need to report why
+ echo "FAIL"
+ if [ $actual_ec == 255 ]; then # 255 == SIGTERM due to $ALARM
+ echo "Test was taking unexpectedly long time to run and so we aborted it."
+ echo "Try the test case manually or raise the timeout from $timeout"
+ echo "to distinguish test slowness from a real problem."
+ else
+ $ec_ok || \
+ echo "Wrong exit code: expected: '$expected_ec'; actual: $actual_ec"
+ $matches_ok || \
+ echo "Output did not match '$expected_regexp'"
+ $negmatches_ok || \
+ echo "Output unexpectedly matched '$unexpected_regexp'"
+ fi
+ echo "Output from failed run:"
+ echo "---"
+ cat "$output"
+ echo "---"
+ return 1 # 1: failure
+}
+
+TMPDIR=/tmp/heap_check_death_info
+rm -rf $TMPDIR || exit 1
+mkdir $TMPDIR || exit 2
+
+export HEAPCHECK=strict # default mode
+
+# These invocations should pass (0 == PASS):
+
+# This tests that turning leak-checker off dynamically works fine
+Test 120 0 "^PASS$" "" HEAPCHECK="" || exit 1
+
+# This disables threads so we can cause leaks reliably and test finding them
+Test 120 0 "^PASS$" "" HEAP_CHECKER_TEST_NO_THREADS=1 || exit 2
+
+# Test that --test_cancel_global_check works
+Test 20 0 "Canceling .* whole-program .* leak check$" "" \
+ HEAP_CHECKER_TEST_TEST_LEAK=1 HEAP_CHECKER_TEST_TEST_CANCEL_GLOBAL_CHECK=1 || exit 3
+Test 20 0 "Canceling .* whole-program .* leak check$" "" \
+ HEAP_CHECKER_TEST_TEST_LOOP_LEAK=1 HEAP_CHECKER_TEST_TEST_CANCEL_GLOBAL_CHECK=1 || exit 4
+
+# Test that very early log messages are present and controllable:
+EARLY_MSG="Starting tracking the heap$"
+
+Test 60 0 "$EARLY_MSG" "" \
+ HEAPCHECK="" HEAP_CHECKER_TEST_TEST_LEAK=1 HEAP_CHECKER_TEST_NO_THREADS=1 \
+ || exit 5
+Test 60 0 "MemoryRegionMap Init$" "" \
+ HEAPCHECK="" HEAP_CHECKER_TEST_TEST_LEAK=1 HEAP_CHECKER_TEST_NO_THREADS=1 \
+ PERFTOOLS_VERBOSE=2 || exit 6
+Test 60 0 "" "$EARLY_MSG" \
+ HEAPCHECK="" HEAP_CHECKER_TEST_TEST_LEAK=1 HEAP_CHECKER_TEST_NO_THREADS=1 \
+ PERFTOOLS_VERBOSE=-2 || exit 7
+
+# These invocations should fail with very high probability,
+# rather than return 0 or hang (1 == exit(1), 134 == abort(), 139 = SIGSEGV):
+
+Test 20 1 "Exiting .* because of .* leaks$" "" \
+ HEAP_CHECKER_TEST_TEST_LEAK=1 HEAP_CHECKER_TEST_NO_THREADS=1 || exit 8
+Test 20 1 "Exiting .* because of .* leaks$" "" \
+ HEAP_CHECKER_TEST_TEST_LOOP_LEAK=1 HEAP_CHECKER_TEST_NO_THREADS=1 || exit 9
+
+cd / # so we're not in TMPDIR when we delete it
+rm -rf $TMPDIR
+
+echo "PASS"
-echo PASS
+exit 0
diff --git a/src/tests/heap-checker_unittest.cc b/src/tests/heap-checker_unittest.cc
index 3e85e7a..4510050 100644
--- a/src/tests/heap-checker_unittest.cc
+++ b/src/tests/heap-checker_unittest.cc
@@ -42,7 +42,7 @@
//
// Note: Both of the above commands *should* abort with an error message.
-// CAVEAT: Do not use vector<>s and string-s in this test,
+// CAVEAT: Do not use vector<> and string on-heap objects in this test,
// otherwise the test can sometimes fail for tricky leak checks
// when we want some allocated object not to be found live by the heap checker.
// This can happen with memory allocators like tcmalloc that can allocate
@@ -58,28 +58,20 @@
// (see the comment in our .h file).
#include "config.h"
-#include "base/logging.h"
-#include "base/googleinit.h"
-#include <google/malloc_extension.h>
-#include <google/heap-profiler.h>
-#include <google/heap-checker.h>
-
-#include <stdlib.h>
#include <sys/poll.h>
#if defined HAVE_STDINT_H
#include <stdint.h> // to get uint16_t (ISO naming madness)
#elif defined HAVE_INTTYPES_H
#include <inttypes.h> // another place uint16_t might be defined
-#else
-#include <sys/types.h> // our last best hope
#endif
-#include <unistd.h> // for sleep()
-#include <iostream> // for cout
-#include <vector>
-#include <set>
-#include <string>
-
+#include <sys/types.h>
+#include <stdlib.h>
#include <errno.h> // errno
+#include <unistd.h> // for sleep(), geteuid()
+#include <fcntl.h> // for open(), close()
+#include <malloc.h>
+#include <sys/mman.h>
+
#include <netinet/in.h> // inet_ntoa
#include <arpa/inet.h> // inet_ntoa
#ifdef HAVE_EXECINFO_H
@@ -88,6 +80,75 @@
#ifdef HAVE_GRP_H
#include <grp.h> // getgrent, getgrnam
#endif
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
+
+#include <iostream> // for cout
+#include <iomanip> // for hex
+#include <set>
+#include <map>
+#include <vector>
+#include <string>
+
+#include "base/googleinit.h"
+#include "base/logging.h"
+#include "base/commandlineflags.h"
+#include <google/heap-checker.h>
+#include "memory_region_map.h"
+#include <google/malloc_extension.h>
+
+using namespace std;
+
+
+// TODO(maxim): write a shell script to test that these indeed crash us
+// (i.e. we do detect leaks)
+// Maybe add more such crash tests.
+
+DEFINE_bool(test_leak,
+ EnvToBool("HEAP_CHECKER_TEST_TEST_LEAK", false),
+ "If should cause a leak crash");
+DEFINE_bool(test_loop_leak,
+ EnvToBool("HEAP_CHECKER_TEST_TEST_LOOP_LEAK", false),
+ "If should cause a looped leak crash");
+DEFINE_bool(test_register_leak,
+ EnvToBool("HEAP_CHECKER_TEST_TEST_REGISTER_LEAK", false),
+ "If should cause a leak crash by hiding a pointer "
+ "that is only in a register");
+DEFINE_bool(test_cancel_global_check,
+ EnvToBool("HEAP_CHECKER_TEST_TEST_CANCEL_GLOBAL_CHECK", false),
+ "If should test HeapLeakChecker::CancelGlobalCheck "
+ "when --test_leak or --test_loop_leak are given; "
+ "the test should not fail then");
+DEFINE_bool(maybe_stripped,
+ EnvToBool("HEAP_CHECKER_TEST_MAYBE_STRIPPED", true),
+ "If we think we can be a stripped binary");
+DEFINE_bool(interfering_threads,
+ EnvToBool("HEAP_CHECKER_TEST_INTERFERING_THREADS", true),
+ "If we should use threads trying "
+ "to interfere with leak checking");
+DEFINE_bool(hoarding_threads,
+ EnvToBool("HEAP_CHECKER_TEST_HOARDING_THREADS", true),
+ "If threads (usually the manager thread) are known "
+ "to retain some old state in their global buffers, "
+ "so that it's hard to force leaks when threads are around");
+ // TODO(maxim): Chage the default to false
+ // when the standard environment used NTPL threads:
+ // they do not seem to have this problem.
+DEFINE_bool(no_threads,
+ EnvToBool("HEAP_CHECKER_TEST_NO_THREADS", false),
+ "If we should not use any threads");
+ // This is used so we can make can_create_leaks_reliably true
+ // for any pthread implementation and test with that.
+
+#define WARN_IF(cond, msg) LOG_IF(WARNING, cond, msg)
+
+// This is an evil macro! Be very careful using it...
+#undef VLOG // and we start by evilling overriding logging.h VLOG
+#define VLOG(lvl) if (FLAGS_verbose >= (lvl)) cout << "\n"
+// This is, likewise, evil
+#define LOGF VLOG(INFO)
+
class Closure {
public:
@@ -146,21 +207,13 @@ inline Callback2<P1,P2>* NewCallback(void (*function)(P1,P2), P1 p1, P2 p2) {
}
-using namespace std;
-
-static bool FLAGS_maybe_stripped = false; // TODO(csilvers): use this?
-static bool FLAGS_interfering_threads = true;
-static bool FLAGS_test_register_leak = false; // TODO(csilvers): this as well?
-
// Set to true at end of main, so threads know. Not entirely thread-safe!,
// but probably good enough.
static bool g_have_exited_main = false;
-// If our allocator guarantees that heap object addresses are never reused.
-// We need this property so that stale uncleared pointer data
-// does not accidentaly lead to heap-checker wrongly believing that
-// some data is live.
-static bool unique_heap_addresses = false;
+// If we can reliably create leaks (i.e. make leaked object
+// really unreachable from any global data).
+static bool can_create_leaks_reliably = false;
// We use a simple allocation wrapper
// to make sure we wipe out the newly allocated objects
@@ -169,8 +222,8 @@ static bool unique_heap_addresses = false;
struct Initialized { };
static Initialized initialized;
void* operator new(size_t size, const Initialized&) {
- // Below we use "p = new (initialized) Foo[1];" and "delete[] p;"
- // instead of "p = new (initialized) Foo;"
+ // Below we use "p = new(initialized) Foo[1];" and "delete[] p;"
+ // instead of "p = new(initialized) Foo;"
// when we need to delete an allocated object.
void* p = malloc(size);
memset(p, 0, size);
@@ -182,60 +235,30 @@ void* operator new[](size_t size, const Initialized&) {
return p;
}
-static void CheckLeak(HeapLeakChecker* check,
- size_t bytes_leaked, size_t objects_leaked) {
- if (unique_heap_addresses) {
- if (getenv("HEAPCHECK")) {
- // these might still fail occasionally, but it should be very rare
- CHECK_EQ(check->BriefNoLeaks(), false);
- CHECK_EQ(check->BytesLeaked(), bytes_leaked);
- CHECK_EQ(check->ObjectsLeaked(), objects_leaked);
- }
- } else if (check->BriefNoLeaks() != false) {
- cout << "Some liveness flood must be too optimistic\n";
- }
-}
-
static void Pause() {
poll(NULL, 0, 77); // time for thread activity in HeapBusyThreadBody
- // Indirectly test debugallocation.* and malloc_interface.*:
-
+ // Indirectly test malloc_extension.*:
CHECK(MallocExtension::instance()->VerifyAllMemory());
- // Comment the printing of malloc-stats out for now. It seems a bit broken
-#if 0
int blocks;
size_t total;
int histogram[kMallocHistogramSize];
if (MallocExtension::instance()
->MallocMemoryStats(&blocks, &total, histogram) && total != 0) {
- cout << "Malloc stats: " << blocks << " blocks of "
- << total << " bytes\n";
+ VLOG(3) << "Malloc stats: " << blocks << " blocks of "
+ << total << " bytes";
for (int i = 0; i < kMallocHistogramSize; ++i) {
if (histogram[i]) {
- cout << " Malloc histogram at " << i << " : " << histogram[i] << "\n";
+ VLOG(3) << " Malloc histogram at " << i << " : " << histogram[i];
}
}
}
-#endif
-}
-
-static bool noleak() { // compare to this if you expect no leak
- return true;
-}
-
-static bool leak() { // compare to this if you expect a leak
- // When we're not doing heap-checking, we can't tell if there's a leak
- if ( !getenv("HEAPCHECK") ) {
- return true;
- } else {
- return false;
- }
}
// Make gcc think a pointer is "used"
template <class T>
static void Use(T** foo) {
+ VLOG(2) << "Dummy-using " << static_cast<void*>(*foo) << " at " << foo;
}
// Arbitrary value, but not such that xor'ing with it is likely
@@ -253,14 +276,27 @@ static const uintptr_t kHideMask = 0xF03A5F7B;
// can be allocated at the same heap address.)
template <class T>
static void Hide(T** ptr) {
- reinterpret_cast<uintptr_t&>(*ptr) =
- (reinterpret_cast<uintptr_t&>(*ptr) ^ kHideMask);
+ // We have to do memcpy rather than just casting here, because a cast
+ // is illegal (and can cause aliasing issues).
+ uintptr_t hidden = reinterpret_cast<uintptr_t>(*ptr) ^ kHideMask;
+ assert(sizeof(*ptr) == sizeof(hidden));
+ memcpy(ptr, &hidden, sizeof(*ptr));
+ VLOG(2) << "hid: " << static_cast<void*>(*ptr);
}
template <class T>
static void UnHide(T** ptr) {
- reinterpret_cast<uintptr_t&>(*ptr) =
- (reinterpret_cast<uintptr_t&>(*ptr) ^ kHideMask);
+ VLOG(2) << "unhiding: " << static_cast<void*>(*ptr);
+ // We have to do memcpy rather than just casting here, because a cast
+ // is illegal (and can cause aliasing issues).
+ uintptr_t unhidden = reinterpret_cast<uintptr_t>(*ptr) ^ kHideMask;
+ assert(sizeof(*ptr) == sizeof(unhidden));
+ memcpy(ptr, &unhidden, sizeof(*ptr));
+}
+
+static void LogHidden(const char* message, const void* ptr) {
+ LOGF << message << " : "
+ << ptr << " ^ " << reinterpret_cast<void*>(kHideMask) << endl;
}
// non-static to fool the compiler against inlining
@@ -271,6 +307,7 @@ void (*wipe_stack_ptr)(int n);
static void DoRunHidden(Closure* c, int n) {
if (n) {
+ VLOG(10) << "Level " << n << " at " << &n;
run_hidden_ptr(c, n-1);
wipe_stack_ptr(n);
sleep(0); // undo -foptimize-sibling-calls
@@ -280,6 +317,7 @@ static void DoRunHidden(Closure* c, int n) {
}
static void DoWipeStack(int n) {
+ VLOG(10) << "Wipe level " << n << " at " << &n;
if (n) {
const int sz = 30;
volatile int arr[sz];
@@ -301,9 +339,10 @@ static void RunHidden(Closure* c) {
}
static void DoAllocHidden(size_t size, void** ptr) {
- void* p = new (initialized) char[size];
+ void* p = new(initialized) char[size];
Hide(&p);
Use(&p); // use only hidden versions
+ VLOG(2) << "Allocated hidden " << p << " at " << &p;
*ptr = p; // assign the hidden versions
}
@@ -316,6 +355,7 @@ static void* AllocHidden(size_t size) {
static void DoDeAllocHidden(void** ptr) {
Use(ptr); // use only hidden versions
void* p = *ptr;
+ VLOG(2) << "Deallocating hidden " << p;
UnHide(&p);
delete [] (char*)p;
}
@@ -326,6 +366,41 @@ static void DeAllocHidden(void** ptr) {
Use(ptr);
}
+static bool RunSilent(HeapLeakChecker* check,
+ bool (HeapLeakChecker::* func)()) {
+ // By default, don't print the 'we detected a leak' message in the
+ // cases we're expecting a leak (we still print when --v is >= 1).
+ // This way, the logging output is less confusing: we only print
+ // "we detected a leak", and how to diagnose it, for *unexpected* leaks.
+ int32 old_FLAGS_verbose = FLAGS_verbose;
+ if (!VLOG_IS_ON(1)) // not on a verbose setting
+ FLAGS_verbose = FATAL; // only log fatal errors
+ const bool retval = (check->*func)();
+ FLAGS_verbose = old_FLAGS_verbose;
+ return retval;
+}
+
+#define RUN_SILENT(check, func) RunSilent(&(check), &HeapLeakChecker::func)
+
+enum CheckType { SAME_HEAP, NO_LEAKS };
+
+static void VerifyLeaks(HeapLeakChecker* check, CheckType type,
+ int leaked_bytes, int leaked_objects) {
+ const bool no_leaks =
+ type == NO_LEAKS ? RUN_SILENT(*check, BriefNoLeaks)
+ : RUN_SILENT(*check, BriefSameHeap);
+ if (can_create_leaks_reliably) {
+ // these might still fail occasionally, but it should be very rare
+ CHECK_EQ(no_leaks, false);
+ CHECK_EQ(check->BytesLeaked(), leaked_bytes);
+ CHECK_EQ(check->ObjectsLeaked(), leaked_objects);
+ } else {
+ WARN_IF(no_leaks != false,
+ "Expected leaks not found: "
+ "Some liveness flood must be too optimistic");
+ }
+}
+
// not deallocates
static void TestHeapLeakCheckerDeathSimple() {
HeapLeakChecker check("death_simple");
@@ -333,20 +408,24 @@ static void TestHeapLeakCheckerDeathSimple() {
Use(&foo);
void* bar = AllocHidden(300);
Use(&bar);
- CheckLeak(&check, 300 + 100 * sizeof(int), 2);
+ LogHidden("Leaking", foo);
+ LogHidden("Leaking", bar);
+ Pause();
+ VerifyLeaks(&check, NO_LEAKS, 300 + 100 * sizeof(int), 2);
DeAllocHidden(&foo);
DeAllocHidden(&bar);
}
static void MakeDeathLoop(void** arr1, void** arr2) {
- void** a1 = new (initialized) void*[2];
- void** a2 = new (initialized) void*[2];
+ void** a1 = new(initialized) void*[2];
+ void** a2 = new(initialized) void*[2];
a1[1] = (void*)a2;
a2[1] = (void*)a1;
Hide(&a1);
Hide(&a2);
Use(&a1);
Use(&a2);
+ VLOG(2) << "Made hidden loop at " << &a1 << " to " << arr1;
*arr1 = a1;
*arr2 = a2;
}
@@ -359,7 +438,10 @@ static void TestHeapLeakCheckerDeathLoop() {
RunHidden(NewCallback(MakeDeathLoop, &arr1, &arr2));
Use(&arr1);
Use(&arr2);
- CheckLeak(&check, 4 * sizeof(void*), 2);
+ LogHidden("Leaking", arr1);
+ LogHidden("Leaking", arr2);
+ Pause();
+ VerifyLeaks(&check, NO_LEAKS, 4 * sizeof(void*), 2);
DeAllocHidden(&arr1);
DeAllocHidden(&arr2);
}
@@ -368,11 +450,15 @@ static void TestHeapLeakCheckerDeathLoop() {
static void TestHeapLeakCheckerDeathInverse() {
void* bar = AllocHidden(250 * sizeof(int));
Use(&bar);
+ LogHidden("Pre leaking", bar);
+ Pause();
HeapLeakChecker check("death_inverse");
void* foo = AllocHidden(100 * sizeof(int));
Use(&foo);
+ LogHidden("Leaking", foo);
DeAllocHidden(&bar);
- CheckLeak(&check, (size_t)(-150 * size_t(sizeof(int))), 0);
+ Pause();
+ VerifyLeaks(&check, SAME_HEAP, -150 * int64(sizeof(int)), 0);
DeAllocHidden(&foo);
}
@@ -384,7 +470,7 @@ static void TestHeapLeakCheckerDeathNoLeaks() {
Use(&bar);
HeapLeakChecker check("death_noleaks");
DeAllocHidden(&bar);
- CHECK_EQ(check.BriefNoLeaks(), noleak());
+ CHECK_EQ(check.BriefNoLeaks(), true);
DeAllocHidden(&foo);
}
@@ -394,12 +480,17 @@ static void TestHeapLeakCheckerDeathCountLess() {
Use(&bar1);
void* bar2 = AllocHidden(50 * sizeof(int));
Use(&bar2);
+ LogHidden("Pre leaking", bar1);
+ LogHidden("Pre leaking", bar2);
+ Pause();
HeapLeakChecker check("death_count_less");
void* foo = AllocHidden(100 * sizeof(int));
Use(&foo);
+ LogHidden("Leaking", foo);
DeAllocHidden(&bar1);
DeAllocHidden(&bar2);
- CheckLeak(&check, 0, (size_t)-1);
+ Pause();
+ VerifyLeaks(&check, SAME_HEAP, 0, -1);
DeAllocHidden(&foo);
}
@@ -407,13 +498,18 @@ static void TestHeapLeakCheckerDeathCountLess() {
static void TestHeapLeakCheckerDeathCountMore() {
void* foo = AllocHidden(100 * sizeof(int));
Use(&foo);
+ LogHidden("Pre leaking", foo);
+ Pause();
HeapLeakChecker check("death_count_more");
void* bar1 = AllocHidden(50 * sizeof(int));
Use(&bar1);
void* bar2 = AllocHidden(50 * sizeof(int));
Use(&bar2);
+ LogHidden("Leaking", bar1);
+ LogHidden("Leaking", bar2);
DeAllocHidden(&foo);
- CheckLeak(&check, 0, 1);
+ Pause();
+ VerifyLeaks(&check, SAME_HEAP, 0, 1);
DeAllocHidden(&bar1);
DeAllocHidden(&bar2);
}
@@ -469,15 +565,28 @@ static void TestHeapLeakCheckerTrick() {
Use(&bar1);
void* bar2 = AllocHidden(160 * sizeof(int));
Use(&bar2);
+ LogHidden("Pre leaking", bar1);
+ LogHidden("Pre leaking", bar2);
+ Pause();
HeapLeakChecker check("trick");
void* foo1 = AllocHidden(280 * sizeof(int));
Use(&foo1);
void* foo2 = AllocHidden(120 * sizeof(int));
Use(&foo2);
+ LogHidden("Leaking", foo1);
+ LogHidden("Leaking", foo2);
DeAllocHidden(&bar1);
DeAllocHidden(&bar2);
Pause();
- CHECK(check.BriefSameHeap());
+ if (can_create_leaks_reliably) {
+ // this might still fail occasionally, but it should be very rare:
+ CHECK(check.BriefSameHeap());
+ } else {
+ // we expect it to usually misbehave, so we silence it:
+ WARN_IF(RUN_SILENT(check, BriefSameHeap) != true,
+ "Tricky leaks unexpectedly found: "
+ "Some liveness flood must be too optimistic");
+ }
DeAllocHidden(&foo1);
DeAllocHidden(&foo2);
}
@@ -497,9 +606,12 @@ static void TestHeapLeakCheckerDeathTrick() {
Use(&foo2);
// TODO(maxim): use the above if we make pprof work in automated test runs
if (!FLAGS_maybe_stripped) {
- CHECK_EQ(check.SameHeap(), leak()); // pprof checking should catch it
- } else if (check.SameHeap()) {
- cout << "death_trick leak is not caught; we must be using stripped binary\n";
+ CHECK_EQ(RUN_SILENT(check, SameHeap), false);
+ // pprof checking should catch the leak
+ } else {
+ WARN_IF(RUN_SILENT(check, SameHeap) != false,
+ "death_trick leak is not caught; "
+ "we must be using a stripped binary");
}
DeAllocHidden(&foo1);
DeAllocHidden(&foo2);
@@ -541,6 +653,7 @@ static void* RunDisabledLeaks(void* a) {
// have different disabled leaks inside of a thread
static void ThreadDisabledLeaks() {
+ if (FLAGS_no_threads) return;
pthread_t tid;
pthread_attr_t attr;
CHECK(pthread_attr_init(&attr) == 0);
@@ -560,9 +673,9 @@ static void TestHeapLeakCheckerDisabling() {
ThreadDisabledLeaks();
ThreadDisabledLeaks();
- // if this fails, some code with DisableChecksUp() got inlined into here;
- // need to add more tricks to prevent this inlining.
- CHECK(!HeapLeakChecker::HaveDisabledChecksUp(1));
+ LOG_IF(FATAL, HeapLeakChecker::HaveDisabledChecksUp(1),
+ "Some code with DisableChecksUp() got inlined into here; "
+ "need to add more tricks to prevent this inlining.");
Pause();
@@ -574,8 +687,8 @@ typedef set<int> IntSet;
static int some_ints[] = { 1, 2, 3, 21, 22, 23, 24, 25 };
static void DoTestSTLAlloc() {
- IntSet* x = new (initialized) IntSet[1];
- *x = IntSet(some_ints, some_ints + 6);
+ IntSet* x = new(initialized) IntSet[1];
+ *x = IntSet(some_ints, some_ints + 6);
for (int i = 0; i < 1000; i++) {
x->insert(i*3);
}
@@ -593,7 +706,7 @@ static void TestSTLAlloc() {
}
static void DoTestSTLAllocInverse(IntSet** setx) {
- IntSet* x = new (initialized) IntSet[1];
+ IntSet* x = new(initialized) IntSet[1];
*x = IntSet(some_ints, some_ints + 3);
for (int i = 0; i < 100; i++) {
x->insert(i*2);
@@ -613,20 +726,21 @@ static void FreeTestSTLAllocInverse(IntSet** setx) {
// running on top of our allocator with hooks to heap profiler
// that can result in false absence of leak report in this case.)
static void TestSTLAllocInverse() {
- HeapLeakChecker check("inverse_stl");
+ HeapLeakChecker check("death_inverse_stl");
IntSet* x;
RunHidden(NewCallback(DoTestSTLAllocInverse, &x));
- if (unique_heap_addresses) {
- if (getenv("HEAPCHECK")) {
- // these might still fail occasionally, but it should be very rare
- CHECK_EQ(check.BriefNoLeaks(), false);
- CHECK_GE(check.BytesLeaked(), 100 * sizeof(int));
- CHECK_GE(check.ObjectsLeaked(), 100);
+ LogHidden("Leaking", x);
+ if (can_create_leaks_reliably) {
+ // these might still fail occasionally, but it should be very rare
+ CHECK_EQ(RUN_SILENT(check, BriefNoLeaks), false);
+ CHECK_GE(check.BytesLeaked(), 100 * sizeof(int));
+ CHECK_GE(check.ObjectsLeaked(), 100);
// assumes set<>s are represented by some kind of binary tree
// or something else allocating >=1 heap object per set object
- }
- } else if (check.BriefNoLeaks() != false) {
- cout << "Some liveness flood must be too optimistic";
+ } else {
+ WARN_IF(RUN_SILENT(check, BriefNoLeaks) != false,
+ "Expected leaks not found: "
+ "Some liveness flood must be too optimistic");
}
RunHidden(NewCallback(FreeTestSTLAllocInverse, &x));
}
@@ -635,9 +749,9 @@ template<class Alloc>
static void DirectTestSTLAlloc(Alloc allocator, const char* name) {
HeapLeakChecker check((string("direct_stl-") + name).c_str());
const int size = 1000;
- char* ptrs[size];
+ typename Alloc::pointer ptrs[size];
for (int i = 0; i < size; ++i) {
- char* p = allocator.allocate(i*3+1);
+ typename Alloc::pointer p = allocator.allocate(i*3+1);
HeapLeakChecker::IgnoreObject(p);
// This will crash if p is not known to heap profiler:
// (i.e. STL's "allocator" does not have a direct hook to heap profiler)
@@ -663,6 +777,7 @@ static void KeyFree(void* ptr) {
static void KeyInit() {
for (int i = 0; i < kKeys; ++i) {
CHECK_EQ(pthread_key_create(&key[i], KeyFree), 0);
+ VLOG(2) << "pthread key " << i << " : " << key[i];
}
}
@@ -672,7 +787,14 @@ static void TestLibCAllocate() {
for (int i = 0; i < kKeys; ++i) {
void* p = pthread_getspecific(key[i]);
if (NULL == p) {
- p = new (initialized) char[77 + i];
+ if (i == 0) {
+ // Test-logging inside threads which (potentially) creates and uses
+ // thread-local data inside standard C++ library:
+ VLOG(0) << "Adding pthread-specifics for thread " << pthread_self()
+ << " pid " << getpid();
+ }
+ p = new(initialized) char[77 + i];
+ VLOG(2) << "pthread specific " << i << " : " << p;
pthread_setspecific(key[i], p);
}
}
@@ -683,14 +805,19 @@ static void TestLibCAllocate() {
inet_ntoa(addr);
const time_t now = time(NULL);
ctime(&now);
-#ifdef HAVE_EXECINFO_H
void *stack[1];
+#ifdef HAVE_EXECINFO_H
backtrace(stack, 1);
#endif
#ifdef HAVE_GRP_H
+ gid_t gid = getgid();
+ getgrgid(gid);
if (grp == NULL) grp = getgrent(); // a race condition here is okay
getgrnam(grp->gr_name);
#endif
+#ifdef HAVE_PWD_H
+ getpwuid(geteuid());
+#endif
}
// Continuous random heap memory activity to try to disrupt heap checking.
@@ -702,10 +829,10 @@ static void* HeapBusyThreadBody(void* a) {
// Here we are just making a best effort to put the only pointer
// to a heap object into a thread register to test
// the thread-register finding machinery in the heap checker.
-#if defined(__i386__) && \
- (__GNUC__ == 2 || __GNUC__ == 3 || __GNUC__ == 4 || \
- defined(__INTEL_COMPILER))
+#if defined(__i386__) && defined(__GNUC__)
register int** ptr asm("esi");
+#elif defined(__x86_64__) && defined(__GNUC__)
+ register int** ptr asm("r15");
#else
register int** ptr;
#endif
@@ -719,10 +846,10 @@ static void* HeapBusyThreadBody(void* a) {
TestLibCAllocate();
if (ptr == NULL) {
- ptr = new (initialized) int*[1];
- *ptr = new (initialized) int[1];
+ ptr = new(initialized) int*[1];
+ *ptr = new(initialized) int[1];
}
- set<int>* s2 = new (initialized) set<int>[1];
+ set<int>* s2 = new(initialized) set<int>[1];
s1.insert(random());
s2->insert(*s1.begin());
user += *s2->begin();
@@ -731,16 +858,22 @@ static void* HeapBusyThreadBody(void* a) {
s1.clear();
if (random() % 2 == 0) {
s1.~Set();
- new (&s1) Set;
+ new(&s1) Set;
}
}
+ VLOG(3) << pthread_self() << " (" << getpid() << "): in wait: "
+ << ptr << ", " << *ptr << "; " << s1.size();
+ VLOG(2) << pthread_self() << " (" << getpid() << "): in wait, ptr = "
+ << reinterpret_cast<void*>(
+ reinterpret_cast<uintptr_t>(ptr) ^ kHideMask)
+ << "^" << reinterpret_cast<void*>(kHideMask);
if (FLAGS_test_register_leak) {
// Hide the register "ptr" value with an xor mask.
// If one provides --test_register_leak flag, the test should
// (with very high probability) crash on some leak check
// with a leak report (of some x * sizeof(int) + y * sizeof(int*) bytes)
// pointing at the two lines above in this function
- // with "new (initialized) int" in them as the allocators
+ // with "new(initialized) int" in them as the allocators
// of the leaked objects.
// CAVEAT: We can't really prevent a compiler to save some
// temporary values of "ptr" on the stack and thus let us find
@@ -757,6 +890,7 @@ static void* HeapBusyThreadBody(void* a) {
} else {
poll(NULL, 0, random() % 100);
}
+ VLOG(2) << pthread_self() << ": continuing";
if (random() % 3 == 0) {
delete [] *ptr;
delete [] ptr;
@@ -768,6 +902,8 @@ static void* HeapBusyThreadBody(void* a) {
}
static void RunHeapBusyThreads() {
+ if (FLAGS_no_threads) return;
+
const int n = 17; // make many threads
pthread_t tid;
@@ -775,6 +911,7 @@ static void RunHeapBusyThreads() {
CHECK(pthread_attr_init(&attr) == 0);
// make them and let them run
for (int i = 0; i < n; ++i) {
+ VLOG(0) << "Creating extra thread " << i + 1;
CHECK(pthread_create(&tid, &attr, HeapBusyThreadBody, NULL) == 0);
}
@@ -784,6 +921,8 @@ static void RunHeapBusyThreads() {
// tests disabling via function name
REGISTER_MODULE_INITIALIZER(heap_checker_unittest, {
+ // TODO(csilvers): figure out when this might be true
+ can_create_leaks_reliably = false;
HeapLeakChecker::DisableChecksIn("NamedDisabledLeaks");
});
@@ -799,6 +938,7 @@ REGISTER_MODULE_INITIALIZER(heap_checker_unittest, {
// have leaks that we disable via our function name in MODULE_INITIALIZER
static void NamedDisabledLeaks() {
AllocHidden(5 * sizeof(float));
+ TransLeaks();
sleep(0); // undo -foptimize-sibling-calls
}
@@ -813,6 +953,7 @@ static void NamedTwoDisabledLeaks() {
first = false;
}
AllocHidden(5 * sizeof(double));
+ TransLeaks();
sleep(0); // undo -foptimize-sibling-calls
}
@@ -822,6 +963,7 @@ static void (*named_two_disabled_leaks)() = &NamedTwoDisabledLeaks;
// have leaks that we disable via our function name in our caller
static void NamedThreeDisabledLeaks() {
AllocHidden(5 * sizeof(float));
+ TransLeaks();
sleep(0); // undo -foptimize-sibling-calls
}
@@ -851,6 +993,7 @@ static void* RunNamedDisabledLeaks(void* a) {
// have leaks inside of threads that we disable via function names
static void ThreadNamedDisabledLeaks() {
+ if (FLAGS_no_threads) return;
pthread_t tid;
pthread_attr_t attr;
CHECK(pthread_attr_init(&attr) == 0);
@@ -877,8 +1020,10 @@ static void TestHeapLeakCheckerNamedDisabling() {
if (!FLAGS_maybe_stripped) {
CHECK_EQ(check.SameHeap(), true);
// pprof checking should allow it
- } else if (!check.SameHeap()) {
- cout << "named_disabling leaks are caught; we must be using stripped binary\n";
+ } else {
+ WARN_IF(check.SameHeap() != true,
+ "named_disabling leaks are caught; "
+ "we must be using a stripped binary");
}
}
@@ -892,12 +1037,12 @@ template<class T>
struct Array {
Array() {
size = 3 + random() % 30;
- ptr = new (initialized) T[size];
+ ptr = new(initialized) T[size];
}
~Array() { delete [] ptr; }
Array(const Array& x) {
size = x.size;
- ptr = new (initialized) T[size];
+ ptr = new(initialized) T[size];
for (size_t i = 0; i < size; ++i) {
ptr[i] = x.ptr[i];
}
@@ -905,13 +1050,13 @@ struct Array {
void operator=(const Array& x) {
delete [] ptr;
size = x.size;
- ptr = new (initialized) T[size];
+ ptr = new(initialized) T[size];
for (size_t i = 0; i < size; ++i) {
ptr[i] = x.ptr[i];
}
}
void append(const Array& x) {
- T* p = new (initialized) T[size + x.size];
+ T* p = new(initialized) T[size + x.size];
for (size_t i = 0; i < size; ++i) {
p[i] = ptr[i];
}
@@ -928,13 +1073,13 @@ struct Array {
};
static Array<char>* live_leak = NULL;
-static Array<char>* live_leak2 = new (initialized) Array<char>();
-static int* live_leak3 = new (initialized) int[10];
-static const char* live_leak4 = new (initialized) char[5];
+static Array<char>* live_leak2 = new(initialized) Array<char>();
+static int* live_leak3 = new(initialized) int[10];
+static const char* live_leak4 = new(initialized) char[5];
static int data[] = { 1, 2, 3, 4, 5, 6, 7, 21, 22, 23, 24, 25, 26, 27 };
static set<int> live_leak5(data, data+7);
static const set<int> live_leak6(data, data+14);
-static const Array<char>* live_leak_arr1 = new (initialized) Array<char>[5];
+static const Array<char>* live_leak_arr1 = new(initialized) Array<char>[5];
class ClassA {
public:
@@ -1001,29 +1146,29 @@ static ClassD2* live_leak_d2_d;
// have leaks but ignore the leaked objects
static void IgnoredLeaks() {
- int* p = new (initialized) int[1];
+ int* p = new(initialized) int[1];
HeapLeakChecker::IgnoreObject(p);
- int** leak = new (initialized) int*;
+ int** leak = new(initialized) int*;
HeapLeakChecker::IgnoreObject(leak);
- *leak = new (initialized) int;
+ *leak = new(initialized) int;
HeapLeakChecker::UnIgnoreObject(p);
delete [] p;
}
// allocate many objects reachable from global data
static void TestHeapLeakCheckerLiveness() {
- live_leak_b = new (initialized) ClassB;
- live_leak_d1 = new (initialized) ClassD1;
- live_leak_d2 = new (initialized) ClassD2;
- live_leak_d = new (initialized) ClassD;
+ live_leak_b = new(initialized) ClassB;
+ live_leak_d1 = new(initialized) ClassD1;
+ live_leak_d2 = new(initialized) ClassD2;
+ live_leak_d = new(initialized) ClassD;
- live_leak_b_d1 = new (initialized) ClassD1;
- live_leak_b2_d2 = new (initialized) ClassD2;
- live_leak_b_d = new (initialized) ClassD;
- live_leak_b2_d = new (initialized) ClassD;
+ live_leak_b_d1 = new(initialized) ClassD1;
+ live_leak_b2_d2 = new(initialized) ClassD2;
+ live_leak_b_d = new(initialized) ClassD;
+ live_leak_b2_d = new(initialized) ClassD;
- live_leak_d1_d = new (initialized) ClassD;
- live_leak_d2_d = new (initialized) ClassD;
+ live_leak_d1_d = new(initialized) ClassD;
+ live_leak_d2_d = new(initialized) ClassD;
HeapLeakChecker::IgnoreObject((ClassD*)live_leak_b2_d);
HeapLeakChecker::IgnoreObject((ClassD*)live_leak_d2_d);
@@ -1032,12 +1177,12 @@ static void TestHeapLeakCheckerLiveness() {
// in such cases of multiple inheritance.
// Luckily google code does not use multiple inheritance almost at all.
- live_leak = new (initialized) Array<char>();
+ live_leak = new(initialized) Array<char>();
delete [] live_leak3;
- live_leak3 = new (initialized) int[33];
+ live_leak3 = new(initialized) int[33];
live_leak2->append(*live_leak);
- live_leak7.ptr = new (initialized) char[77];
- live_leak8.ptr = new (initialized) Array<char>();
+ live_leak7.ptr = new(initialized) char[77];
+ live_leak8.ptr = new(initialized) Array<char>();
live_leak8.val = Array<char>();
IgnoredLeaks();
@@ -1045,40 +1190,137 @@ static void TestHeapLeakCheckerLiveness() {
IgnoredLeaks();
}
-int main(int argc, char** argv) {
- // This needs to be set before InternalInitStart(), which makes a local copy
- if (getenv("PPROF_PATH"))
- HeapLeakChecker::set_pprof_path(getenv("PPROF_PATH"));
+DECLARE_string(heap_check);
+
+static void* Mmapper() {
+ void* r = mmap(NULL, 100, PROT_READ|PROT_WRITE,
+ MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
+ sleep(0); // undo -foptimize-sibling-calls
+ return r;
+}
+
+// to trick complier into preventing inlining
+static void* (*mmapper_addr)() = &Mmapper;
+
+// TODO(maxim): copy/move this to memory_region_map_unittest
+// TODO(maxim): expand this test to include mmap64, mremap and sbrk calls.
+static void VerifyMemoryRegionMapStackGet() {
+ void* addr = (*mmapper_addr)();
+ uintptr_t caller = 0;
+ MemoryRegionMap::Lock();
+ for (MemoryRegionMap::RegionIterator
+ i = MemoryRegionMap::BeginRegionLocked();
+ i != MemoryRegionMap::EndRegionLocked(); ++i) {
+ if (i->start_addr == reinterpret_cast<uintptr_t>(addr)) {
+ CHECK(caller == 0);
+ caller = i->caller;
+ }
+ }
+ MemoryRegionMap::Unlock();
+ // caller must point into Mmapper function:
+ if (!(reinterpret_cast<uintptr_t>(mmapper_addr) <= caller &&
+ caller <= reinterpret_cast<uintptr_t>(mmapper_addr) + 0x40)) {
+ LOGF << std::hex << "0x" << caller
+ << " does not seem to point into code of function Mmapper at "
+ << "0x" << reinterpret_cast<uintptr_t>(mmapper_addr)
+ << "! Stack frame collection must be off in MemoryRegionMap!";
+ LOG(FATAL, "\n");
+ }
+ munmap(addr, 100);
+}
+static void* Mallocer() {
+ void* r = malloc(100);
+ sleep(0); // undo -foptimize-sibling-calls
+ return r;
+}
+
+// to trick complier into preventing inlining
+static void* (*mallocer_addr)() = &Mallocer;
+
+// non-static for friendship with HeapProfiler
+// TODO(maxim): expand this test to include
+// realloc, calloc, memalign, valloc, pvalloc, new, and new[].
+extern void VerifyHeapProfileTableStackGet() {
+ void* addr = (*mallocer_addr)();
+ uintptr_t caller =
+ reinterpret_cast<uintptr_t>(HeapLeakChecker::GetAllocCaller(addr));
+ // caller must point into Mallocer function:
+ if (!(reinterpret_cast<uintptr_t>(mallocer_addr) <= caller &&
+ caller <= reinterpret_cast<uintptr_t>(mallocer_addr) + 0x40)) {
+ LOGF << std::hex << "0x" << caller
+ << " does not seem to point into code of function Mallocer at "
+ << "0x" << reinterpret_cast<uintptr_t>(mallocer_addr)
+ << "! Stack frame collection must be off in heap profiler!";
+ LOG(FATAL, "\n");
+ }
+ free(addr);
+}
+
+// Helper to do 'return 0;' inside main(): insted we do 'return Pass();'
+static int Pass() {
+ fprintf(stdout, "PASS\n");
+ g_have_exited_main = true;
+ return 0;
+}
+
+int main(int argc, char** argv) {
run_hidden_ptr = DoRunHidden;
wipe_stack_ptr = DoWipeStack;
+
+ if (!HeapLeakChecker::IsActive()) {
+ CHECK_EQ(FLAGS_heap_check, "");
+ LOG(WARNING, "HeapLeakChecker got turned off; we won't test much...");
+ } else {
+ VerifyMemoryRegionMapStackGet();
+ VerifyHeapProfileTableStackGet();
+ }
+
+ // glibc 2.4, on x86_64 at least, has a lock-ordering bug, which
+ // means deadlock is possible when one thread calls dl_open at the
+ // same time another thread is calling dl_iterate_phdr. libunwind
+ // calls dl_iterate_phdr, and TestLibCAllocate calls dl_open (or the
+ // various syscalls in it do), at least the first time it's run.
+ // To avoid the deadlock, we run TestLibCAllocate once before getting
+ // multi-threaded.
+ // TODO(csilvers): once libc is fixed, or libunwind can work around it,
+ // get rid of this early call. We *want* our test to
+ // find potential problems like this one!
+ TestLibCAllocate();
if (FLAGS_interfering_threads) {
RunHeapBusyThreads(); // add interference early
}
TestLibCAllocate();
- LogPrintf(INFO, "In main()");
+ LOGF << "In main(): heap_check=" << FLAGS_heap_check << endl;
+
+ CHECK(HeapLeakChecker::NoGlobalLeaks()); // so far, so good
- // The following two modes test whether the whole-program leak checker
- // appropriately detects leaks on exit.
- if (getenv("HEAPCHECK_TEST_LEAK")) {
+ if (FLAGS_test_leak) {
void* arr = AllocHidden(10 * sizeof(int));
Use(&arr);
- LogPrintf(INFO, "Leaking %p", arr);
- return 0; // whole-program leak-check should (with very high probability)
- // catch the leak of arr (10 * sizeof(int) bytes)
+ LogHidden("Leaking", arr);
+ if (FLAGS_test_cancel_global_check) HeapLeakChecker::CancelGlobalCheck();
+ return Pass();
+ // whole-program leak-check should (with very high probability)
+ // catch the leak of arr (10 * sizeof(int) bytes)
+ // (when !FLAGS_test_cancel_global_check)
}
- if (getenv("HEAPCHECK_TEST_LOOP_LEAK")) {
+ if (FLAGS_test_loop_leak) {
void* arr1;
void* arr2;
RunHidden(NewCallback(MakeDeathLoop, &arr1, &arr2));
Use(&arr1);
Use(&arr2);
- LogPrintf(INFO, "Loop leaking %p and %p", arr1, arr2);
- return 0; // whole-program leak-check should (with very high probability)
- // catch the leak of arr1 and arr2 (4 * sizeof(void*) bytes)
+ LogHidden("Loop leaking", arr1);
+ LogHidden("Loop leaking", arr2);
+ if (FLAGS_test_cancel_global_check) HeapLeakChecker::CancelGlobalCheck();
+ return Pass();
+ // whole-program leak-check should (with very high probability)
+ // catch the leak of arr1 and arr2 (4 * sizeof(void*) bytes)
+ // (when !FLAGS_test_cancel_global_check)
}
TestHeapLeakCheckerLiveness();
@@ -1106,6 +1348,8 @@ int main(int argc, char** argv) {
TestHeapLeakCheckerDeathTrick();
Pause();
+ CHECK(HeapLeakChecker::NoGlobalLeaks()); // so far, so good
+
TestHeapLeakCheckerPProf();
Pause();
@@ -1116,17 +1360,29 @@ int main(int argc, char** argv) {
Pause();
TestSTLAllocInverse();
Pause();
- DirectTestSTLAlloc(set<char>().get_allocator(), "alloc");
- // default STL allocator
- Pause();
- // TODO: re-enable this test once we've change configure.ac to include
- // the right header file that defines pthread_allocator.
- //DirectTestSTLAlloc(pthread_allocator<char>(), "pthread_alloc");
- Pause();
+
+ // Test that various STL allocators work. Some of these are redundant, but
+ // we don't know how STL might change in the future. For example,
+ // http://wiki/Main/StringNeStdString.
+#define DTSL(a) { DirectTestSTLAlloc(a, #a); Pause(); }
+ DTSL(std::allocator<char>());
+ DTSL(std::allocator<int>());
+ DTSL(std::string().get_allocator());
+ DTSL(string().get_allocator());
+ DTSL(vector<int>().get_allocator());
+ DTSL(vector<double>().get_allocator());
+ DTSL(vector<vector<int> >().get_allocator());
+ DTSL(vector<string>().get_allocator());
+ DTSL((map<string, string>().get_allocator()));
+ DTSL((map<string, int>().get_allocator()));
+ DTSL(set<char>().get_allocator());
+#undef DTSL
TestLibCAllocate();
Pause();
+ CHECK(HeapLeakChecker::NoGlobalLeaks()); // so far, so good
+
void* start_address = HeapLeakChecker::GetDisableChecksStart();
TestHeapLeakCheckerNamedDisabling();
@@ -1134,21 +1390,23 @@ int main(int argc, char** argv) {
if (!FLAGS_maybe_stripped) {
CHECK(heap_check.SameHeap());
- } else if (!heap_check.SameHeap()) {
- cout << "overall leaks are caught; we must be using stripped binary\n";
+ } else {
+ WARN_IF(heap_check.SameHeap() != true,
+ "overall leaks are caught; we must be using a stripped binary");
}
+ // TODO(maxim): do not need these if we make pprof work in automated test runs
+ HeapLeakChecker::DisableChecksToHereFrom(start_address);
// This will also disable (w/o relying on pprof anymore)
// all leaks that earlier occured inside of ThreadNamedDisabledLeaks:
range_disable_named = true;
ThreadNamedDisabledLeaks();
- HeapLeakChecker::IgnoreObject(new (initialized) set<int>(data, data + 13));
+ HeapLeakChecker::IgnoreObject(new(initialized) set<int>(data, data + 13));
// This checks both that IgnoreObject works, and
// and the fact that we don't drop such leaks as live for some reason.
- fprintf(stdout, "PASS\n");
+ CHECK(HeapLeakChecker::NoGlobalLeaks()); // so far, so good
- g_have_exited_main = true;
- return 0;
+ return Pass();
}
diff --git a/src/tests/heap-checker_unittest.sh b/src/tests/heap-checker_unittest.sh
index 22bde9e..765e6c7 100755
--- a/src/tests/heap-checker_unittest.sh
+++ b/src/tests/heap-checker_unittest.sh
@@ -1,4 +1,4 @@
-#!/bin/sh -e
+#!/bin/sh
# Copyright (c) 2005, Google Inc.
# All rights reserved.
@@ -36,52 +36,54 @@
# This is necessary because we turn on features like the heap profiler
# and heap checker via environment variables. This test makes sure
# they all play well together.
-#
-# Notice that we run this script with -e, so *any* error is fatal.
-if [ -z "$2" ]
-then
- echo "USAGE: $0 <unittest dir> <pprof dir>"
- exit 1
-fi
+# We expect BINDIR and PPROF_PATH to be set in the environment.
+# If not, we set them to some reasonable values
+BINDIR="${BINDIR:-.}"
+PPROF_PATH="${PPROF_PATH:-$BINDIR/src/pprof}"
-UNITTEST_DIR=$1
-PPROF=$2/pprof
+if [ "x$1" = "x-h" -o "$1" = "x--help" ]; then
+ echo "USAGE: $0 [unittest dir] [path to pprof]"
+ echo " By default, unittest_dir=$BINDIR, pprof_path=$PPROF_PATH"
+ exit 1
+fi
-HEAP_CHECKER="$1/heap-checker_unittest"
+HEAP_CHECKER="${1:-$BINDIR}/heap-checker_unittest"
+PPROF_PATH="${2:-$PPROF_PATH}"
TMPDIR=/tmp/heap_check_info
+rm -rf $TMPDIR || exit 2
+mkdir $TMPDIR || exit 3
-rm -rf $TMPDIR
-mkdir $TMPDIR
-
-# $1: value of heap-profile env. var. $2: value of heap-check env. var.
+# $1: value of heap-check env. var.
run_check() {
- export PPROF_PATH="$PPROF"
- [ -n "$1" ] && export HEAPPROFILE="$1" || unset HEAPPROFILE
- [ -n "$2" ] && export HEAPCHECK="$2" || unset HEAPCHECK
+ export PPROF_PATH="$PPROF_PATH"
+ [ -n "$1" ] && export HEAPCHECK="$1" || unset HEAPPROFILE
- echo ""
- echo ">>> TESTING $HEAP_CHECKER with HEAPPROFILE=$1 and HEAPCHECK=$2"
- $HEAP_CHECKER
- echo ">>> DONE testing $HEAP_CHECKER with HEAPPROFILE=$1 and HEAPCHECK=$2"
+ echo -n "Testing $HEAP_CHECKER with HEAPCHECK=$1 ... "
+ if $HEAP_CHECKER > $TMPDIR/output 2>&1; then
+ echo "OK"
+ else
+ echo "FAILED"
+ echo "Output from the failed run:"
+ echo "----"
+ cat $TMPDIR/output
+ echo "----"
+ exit 4
+ fi
# If we set HEAPPROFILE, then we expect it to actually have emitted
# a profile. Check that it did.
if [ -n "$HEAPPROFILE" ]; then
- [ -e "$HEAPPROFILE.0001.heap" ] || exit 1
+ [ -e "$HEAPPROFILE.0001.heap" ] || exit 5
fi
}
-run_check "" ""
-run_check "" "local"
-run_check "" "normal"
-run_check "" "strict"
-run_check "$TMPDIR/profile" ""
-run_check "$TMPDIR/profile" "local"
-run_check "$TMPDIR/profile" "normal"
-run_check "$TMPDIR/profile" "strict"
+run_check ""
+run_check "local"
+run_check "normal"
+run_check "strict"
rm -rf $TMPDIR # clean up
-echo "ALL TESTS PASSED"
+echo "PASS"
diff --git a/src/tests/heap-profiler_unittest.cc b/src/tests/heap-profiler_unittest.cc
index 332dbbc..32428b9 100644
--- a/src/tests/heap-profiler_unittest.cc
+++ b/src/tests/heap-profiler_unittest.cc
@@ -46,23 +46,23 @@
const static int kMaxCount = 100000;
int* g_array[kMaxCount]; // an array of int-vectors
-int Allocate(int start, int end, int size) {
+static void Allocate(int start, int end, int size) {
for (int i = start; i < end; ++i) {
if (i < kMaxCount)
g_array[i] = new int[size];
}
}
-int Allocate2(int start, int end, int size) {
+static void Allocate2(int start, int end, int size) {
for (int i = start; i < end; ++i) {
if (i < kMaxCount)
g_array[i] = new int[size];
}
}
-int Deallocate(int start, int end) {
+static void Deallocate(int start, int end) {
for (int i = start; i < end; ++i) {
- delete g_array[i];
+ delete[] g_array[i];
g_array[i] = 0;
}
}
@@ -77,8 +77,6 @@ int main(int argc, char** argv) {
num_forks = atoi(argv[1]);
}
- HeapProfilerSetInuseInterval(10 << 10); // set inuse interval at 10MB
-
Allocate(0, 40, 100);
Deallocate(0, 40);
@@ -96,8 +94,8 @@ int main(int argc, char** argv) {
while (num_forks-- > 0) {
switch (fork()) {
- case -1:
- printf("FORK failed!\n");
+ case -1:
+ printf("FORK failed!\n");
return 1;
case 0: // child
return execl(argv[0], argv[0], NULL); // run child with no args
diff --git a/src/tests/heap-profiler_unittest.sh b/src/tests/heap-profiler_unittest.sh
index dd7e247..824814e 100755
--- a/src/tests/heap-profiler_unittest.sh
+++ b/src/tests/heap-profiler_unittest.sh
@@ -41,24 +41,26 @@
# This is because libtool sometimes turns the 'executable' into a
# shell script which runs an actual binary somewhere else.
-if [ -z "$2" ]
-then
- echo "USAGE: $0 <unittest dir> <pprof dir>"
- exit 1
+# We expect BINDIR and PPROF_PATH to be set in the environment.
+# If not, we set them to some reasonable values
+BINDIR="${BINDIR:-.}"
+PPROF_PATH="${PPROF_PATH:-$BINDIR/src/pprof}"
+
+if [ "x$1" = "x-h" -o "x$1" = "x--help" ]; then
+ echo "USAGE: $0 [unittest dir] [path to pprof]"
+ echo " By default, unittest_dir=$BINDIR, pprof_path=$PPROF_PATH"
+ exit 1
fi
-UNITTEST_DIR=$1
-PPROF=$2/pprof
-
-HEAP_PROFILER=$UNITTEST_DIR/heap-profiler_unittest
-
-TMPDIR=/tmp/heap_profile_info
+HEAP_PROFILER="${1:-$BINDIR}/heap-profiler_unittest"
+PPROF="${2:-$PPROF_PATH}"
+TEST_TMPDIR=/tmp/heap_profile_info
# It's meaningful to the profiler, so make sure we know its state
unset HEAPPROFILE
-rm -rf $TMPDIR
-mkdir $TMPDIR || exit 2
+rm -rf $TEST_TMPDIR
+mkdir $TEST_TMPDIR || exit 2
num_failures=0
@@ -67,43 +69,56 @@ num_failures=0
# name, verify that the function name takes up at least 90% of the
# allocated memory. The function name is actually specified first.
VerifyMemFunction() {
- function=$1
- shift
-
- # Getting the 'real' name is annoying, since running HEAP_PROFILER
- # at all tends to destroy the old profiles if we're not careful
- HEAPPROFILE_SAVED="$HEAPPROFILE"
- unset HEAPPROFILE
- exec=`$HEAP_PROFILER --help | awk '{print $2; exit;}'` # get program name
- export HEAPPROFILE="$HEAPPROFILE_SAVED"
-
- if [ $# = 2 ]; then
- [ -e "$1" -a -e "$2" ] || { echo "Profile not found: $1 or $2"; exit 1; }
- $PPROF --base="$1" $exec "$2"
- else
- [ -e "$1" ] || { echo "Profile not found: $1"; exit 1; }
- $PPROF $exec "$1"
- fi | tr -d % | awk '$6 ~ /^'$function'$/ && $2 > 90 {exit 1;}'
-
- if [ $? != 1 ]; then
- echo
- echo ">>> Test failed for $function: didn't use 90% of cpu"
- echo
- num_failures=`expr $num_failures + 1`
- fi
+ function=$1
+ shift
+
+ # get program name. Note we have to unset HEAPPROFILE so running
+ # help doesn't overwrite existing profiles.
+ exec=`env -u HEAPPROFILE $HEAP_PROFILER --help | awk '{print $2; exit;}'`
+
+ if [ $# = 2 ]; then
+ [ -e "$1" ] || { echo "Profile not found: $1"; exit 1; }
+ [ -e "$2" ] || { echo "Profile not found: $2"; exit 1; }
+ $PPROF --base="$1" $exec "$2" >$TEST_TMPDIR/output.pprof 2>&1
+ else
+ [ -e "$1" ] || { echo "Profile not found: $1"; exit 1; }
+ $PPROF $exec "$1" >$TEST_TMPDIR/output.pprof 2>&1
+ fi
+
+ cat $TEST_TMPDIR/output.pprof \
+ | tr -d % | awk '$6 ~ /^'$function'$/ && $2 > 90 {exit 1;}'
+ if [ $? != 1 ]; then
+ echo
+ echo "--- Test failed for $function: didn't account for 90% of executable memory"
+ echo "--- Program output:"
+ cat $TEST_TMPDIR/output
+ echo "--- pprof output:"
+ cat $TEST_TMPDIR/output.pprof
+ echo "---"
+ num_failures=`expr $num_failures + 1`
+ fi
}
-export HEAPPROFILE=$TMPDIR/test
-$HEAP_PROFILER 1 # actually run the program, with a child process
+export HEAPPROFILE="$TEST_TMPDIR/test"
+export HEAP_PROFILE_INUSE_INTERVAL="10240" # need this to be 10Kb
+
+# We make the unittest run a child process, to test that the child
+# process doesn't try to write a heap profile as well and step on the
+# parent's toes. If it does, we expect the parent-test to fail.
+$HEAP_PROFILER 1 >$TEST_TMPDIR/output 2>&1 # run program, with 1 child proc
VerifyMemFunction Allocate2 $HEAPPROFILE.0723.heap
VerifyMemFunction Allocate $HEAPPROFILE.0700.heap $HEAPPROFILE.0760.heap
-# Check the child process too
+# Check the child process got to emit its own profile as well.
VerifyMemFunction Allocate2 ${HEAPPROFILE}_*.0723.heap
VerifyMemFunction Allocate ${HEAPPROFILE}_*.0700.heap ${HEAPPROFILE}_*.0760.heap
rm -rf $TMPDIR # clean up
-echo "Tests finished with $num_failures failures"
+if [ $num_failures = 0 ]; then
+ echo "PASS"
+else
+ echo "Tests finished with $num_failures failures"
+fi
exit $num_failures
diff --git a/src/tests/low_level_alloc_unittest.cc b/src/tests/low_level_alloc_unittest.cc
new file mode 100644
index 0000000..8f55554
--- /dev/null
+++ b/src/tests/low_level_alloc_unittest.cc
@@ -0,0 +1,191 @@
+/* Copyright (c) 2006, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ---
+ * Author: Mike Burrows
+ */
+
+// A test for low_level_alloc.cc
+
+#include <map>
+#include "base/low_level_alloc.h"
+#include "base/logging.h"
+#include <google/malloc_hook.h>
+
+using std::map;
+
+// a block of memory obtained from the allocator
+struct BlockDesc {
+ char *ptr; // pointer to memory
+ int len; // number of bytes
+ int fill; // filled with data starting with this
+};
+
+// Check that the pattern placed in the block d
+// by RandomizeBlockDesc is still there.
+static void CheckBlockDesc(const BlockDesc &d) {
+ for (int i = 0; i != d.len; i++) {
+ CHECK((d.ptr[i] & 0xff) == ((d.fill + i) & 0xff));
+ }
+}
+
+// Fill the block "*d" with a pattern
+// starting with a random byte.
+static void RandomizeBlockDesc(BlockDesc *d) {
+ d->fill = rand() & 0xff;
+ for (int i = 0; i != d->len; i++) {
+ d->ptr[i] = (d->fill + i) & 0xff;
+ }
+}
+
+// Use to indicate to the malloc hooks that
+// this calls is from LowLevelAlloc.
+static bool using_low_level_alloc = false;
+
+// n times, toss a coin, and based on the outcome
+// either allocate a new block or deallocate an old block.
+// New blocks are placed in a map with a random key
+// and initialized with RandomizeBlockDesc().
+// If keys conflict, the older block is freed.
+// Old blocks are always checked with CheckBlockDesc()
+// before being freed. At the end of the run,
+// all remaining allocated blocks are freed.
+// If use_new_arena is true, use a fresh arena, and then delete it.
+// If call_malloc_hook is true and user_arena is true,
+// allocations and deallocations are reported via the MallocHook
+// interface.
+static void Test(bool use_new_arena, bool call_malloc_hook, int n) {
+ typedef map<int, BlockDesc> AllocMap;
+ AllocMap allocated;
+ AllocMap::iterator it;
+ BlockDesc block_desc;
+ int rnd;
+ LowLevelAlloc::Arena *arena = 0;
+ if (use_new_arena) {
+ int32 flags = call_malloc_hook? LowLevelAlloc::kCallMallocHook : 0;
+ arena = LowLevelAlloc::NewArena(flags, 0);
+ }
+ for (int i = 0; i != n; i++) {
+ switch(rand() & 1) { // toss a coin
+ case 0: // coin came up heads: add a block
+ using_low_level_alloc = true;
+ block_desc.len = rand() & 0x3fff;
+ block_desc.ptr = reinterpret_cast<char *>(
+ LowLevelAlloc::Alloc(block_desc.len, arena));
+ using_low_level_alloc = false;
+ RandomizeBlockDesc(&block_desc);
+ rnd = rand();
+ it = allocated.find(rnd);
+ if (it != allocated.end()) {
+ CheckBlockDesc(it->second);
+ using_low_level_alloc = true;
+ LowLevelAlloc::Free(it->second.ptr);
+ using_low_level_alloc = false;
+ it->second = block_desc;
+ } else {
+ allocated[rnd] = block_desc;
+ }
+ break;
+ case 1: // coin came up tails: remove a block
+ it = allocated.begin();
+ if (it != allocated.end()) {
+ CheckBlockDesc(it->second);
+ using_low_level_alloc = true;
+ LowLevelAlloc::Free(it->second.ptr);
+ using_low_level_alloc = false;
+ allocated.erase(it);
+ }
+ break;
+ }
+ }
+ // remove all remaniing blocks
+ while ((it = allocated.begin()) != allocated.end()) {
+ CheckBlockDesc(it->second);
+ using_low_level_alloc = true;
+ LowLevelAlloc::Free(it->second.ptr);
+ using_low_level_alloc = false;
+ allocated.erase(it);
+ }
+ if (use_new_arena) {
+ CHECK(LowLevelAlloc::DeleteArena(arena));
+ }
+}
+
+// used for counting allocates and frees
+static int32 allocates;
+static int32 frees;
+static MallocHook::NewHook old_alloc_hook;
+static MallocHook::DeleteHook old_free_hook;
+
+// called on each alloc if kCallMallocHook specified
+static void AllocHook(void *p, size_t size) {
+ if (using_low_level_alloc) {
+ allocates++;
+ }
+ if (old_alloc_hook != 0) {
+ (*old_alloc_hook)(p, size);
+ }
+}
+
+// called on each free if kCallMallocHook specified
+static void FreeHook(void *p) {
+ if (using_low_level_alloc) {
+ frees++;
+ }
+ if (old_free_hook != 0) {
+ (*old_free_hook)(p);
+ }
+}
+
+int main(int argc, char *argv[]) {
+ old_alloc_hook = MallocHook::SetNewHook(AllocHook);
+ old_free_hook = MallocHook::SetDeleteHook(FreeHook);
+ CHECK_EQ(allocates, 0);
+ CHECK_EQ(frees, 0);
+ Test(false, false, 50000);
+ CHECK_EQ(allocates, 0); // default arena doesn't call hooks
+ CHECK_EQ(frees, 0);
+ for (int i = 0; i != 16; i++) {
+ bool call_hooks = ((i & 1) == 1);
+ allocates = 0;
+ frees = 0;
+ Test(true, call_hooks, 15000);
+ if (call_hooks) {
+ CHECK_GT(allocates, 5000); // arena calls hooks
+ CHECK_GT(frees, 5000);
+ } else {
+ CHECK_EQ(allocates, 0); // arena doesn't call hooks
+ CHECK_EQ(frees, 0);
+ }
+ }
+ printf("PASS\n");
+ MallocHook::SetNewHook(old_alloc_hook);
+ MallocHook::SetDeleteHook(old_free_hook);
+ return 0;
+}
diff --git a/src/tests/markidle_unittest.cc b/src/tests/markidle_unittest.cc
new file mode 100644
index 0000000..753cf62
--- /dev/null
+++ b/src/tests/markidle_unittest.cc
@@ -0,0 +1,105 @@
+// Copyright (c) 2003, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// ---
+// Author: Sanjay Ghemawat
+//
+// MallocExtension::MarkThreadIdle() testing
+
+#include "config.h"
+#include "base/logging.h"
+#include <google/malloc_extension.h>
+#include "tests/testutil.h" // for RunInThread()
+
+// Helper routine to do lots of allocations
+static void TestAllocation() {
+ static const int kNum = 100;
+ void* ptr[kNum];
+ for (int size = 8; size <= 65536; size*=2) {
+ for (int i = 0; i < kNum; i++) {
+ ptr[i] = malloc(size);
+ }
+ for (int i = 0; i < kNum; i++) {
+ free(ptr[i]);
+ }
+ }
+}
+
+// Routine that does a bunch of MarkThreadIdle() calls in sequence
+// without any intervening allocations
+static void MultipleIdleCalls() {
+ for (int i = 0; i < 4; i++) {
+ MallocExtension::instance()->MarkThreadIdle();
+ }
+}
+
+// Routine that does a bunch of MarkThreadIdle() calls in sequence
+// with intervening allocations
+static void MultipleIdleNonIdlePhases() {
+ for (int i = 0; i < 4; i++) {
+ TestAllocation();
+ MallocExtension::instance()->MarkThreadIdle();
+ }
+}
+
+// Get current thread cache usage
+static size_t GetTotalThreadCacheSize() {
+ size_t result;
+ CHECK(MallocExtension::instance()->GetNumericProperty(
+ "tcmalloc.current_total_thread_cache_bytes",
+ &result));
+ return result;
+}
+
+// Check that MarkThreadIdle() actually reduces the amount
+// of per-thread memory.
+static void TestIdleUsage() {
+ const size_t original = GetTotalThreadCacheSize();
+ VLOG(0, "Original usage: %"PRIuS"\n", original);
+
+ TestAllocation();
+ const size_t post_allocation = GetTotalThreadCacheSize();
+ VLOG(0, "Post allocation: %"PRIuS"\n", post_allocation);
+ CHECK_GT(post_allocation, original);
+
+ MallocExtension::instance()->MarkThreadIdle();
+ const size_t post_idle = GetTotalThreadCacheSize();
+ VLOG(0, "Post idle: %"PRIuS"\n", post_idle);
+ CHECK_LE(post_idle, original);
+}
+
+int main(int argc, char** argv) {
+ RunInThread(&TestIdleUsage);
+ RunInThread(&TestAllocation);
+ RunInThread(&MultipleIdleCalls);
+ RunInThread(&MultipleIdleNonIdlePhases);
+
+ printf("PASS\n");
+ return 0;
+}
diff --git a/src/tests/memalign_unittest.cc b/src/tests/memalign_unittest.cc
new file mode 100644
index 0000000..27c3d8b
--- /dev/null
+++ b/src/tests/memalign_unittest.cc
@@ -0,0 +1,193 @@
+// Copyright (c) 2004, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// ---
+// Author: Sanjay Ghemawat
+//
+// Check memalign related routines.
+//
+// We can't really do a huge amount of checking, but at the very
+// least, the following code checks that return values are properly
+// aligned, and that writing into the objects works.
+
+#include "config.h"
+#define _XOPEN_SOURCE 600 // to get posix_memalign
+#include <stdlib.h> // defines posix_memalign
+#include <stdio.h> // for the printf at the end
+#include <stdint.h>
+#include <unistd.h> // for sysconf()
+#include <malloc.h>
+#include "base/basictypes.h"
+#include "base/logging.h"
+
+// Return the next interesting size/delta to check. Returns -1 if no more.
+static int NextSize(int size) {
+ if (size < 100) {
+ return size+1;
+ } else if (size < 1048576) {
+ // Find next power of two
+ int power = 1;
+ while (power < size) {
+ power <<= 1;
+ }
+
+ // Yield (power-1, power, power+1)
+ if (size < power-1) {
+ return power-1;
+ } else if (size == power-1) {
+ return power;
+ } else {
+ assert(size == power);
+ return power+1;
+ }
+ } else {
+ return -1;
+ }
+}
+
+// Shortform for cast
+static uintptr_t Number(void* p) {
+ return reinterpret_cast<uintptr_t>(p);
+}
+
+// Check alignment
+static void CheckAlignment(void* p, int align) {
+ if ((Number(p) & (align-1)) != 0)
+ LOG(FATAL, "wrong alignment; wanted 0x%x; got %p\n", align, p);
+}
+
+// Fill a buffer of the specified size with a predetermined pattern
+static void Fill(void* p, int n, char seed) {
+ unsigned char* buffer = reinterpret_cast<unsigned char*>(p);
+ for (int i = 0; i < n; i++) {
+ buffer[i] = ((seed + i) & 0xff);
+ }
+}
+
+// Check that the specified buffer has the predetermined pattern
+// generated by Fill()
+static bool Valid(const void* p, int n, char seed) {
+ const unsigned char* buffer = reinterpret_cast<const unsigned char*>(p);
+ for (int i = 0; i < n; i++) {
+ if (buffer[i] != ((seed + i) & 0xff)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+int main(int argc, char** argv) {
+ // Try allocating data with a bunch of alignments and sizes
+ for (int a = 1; a < 1048576; a *= 2) {
+ for (int s = 0; s != -1; s = NextSize(s)) {
+ void* ptr = memalign(a, s);
+ CheckAlignment(ptr, a);
+ Fill(ptr, s, 'x');
+ CHECK(Valid(ptr, s, 'x'));
+ free(ptr);
+
+ if ((a >= sizeof(void*)) && ((a & (a-1)) == 0)) {
+ CHECK(posix_memalign(&ptr, a, s) == 0);
+ CheckAlignment(ptr, a);
+ Fill(ptr, s, 'y');
+ CHECK(Valid(ptr, s, 'y'));
+ free(ptr);
+ }
+ }
+ }
+
+ {
+ // Check various corner cases
+ void* p1 = memalign(1<<20, 1<<19);
+ void* p2 = memalign(1<<19, 1<<19);
+ void* p3 = memalign(1<<21, 1<<19);
+ CheckAlignment(p1, 1<<20);
+ CheckAlignment(p2, 1<<19);
+ CheckAlignment(p3, 1<<21);
+ Fill(p1, 1<<19, 'a');
+ Fill(p2, 1<<19, 'b');
+ Fill(p3, 1<<19, 'c');
+ CHECK(Valid(p1, 1<<19, 'a'));
+ CHECK(Valid(p2, 1<<19, 'b'));
+ CHECK(Valid(p3, 1<<19, 'c'));
+ free(p1);
+ free(p2);
+ free(p3);
+ }
+
+ {
+ // posix_memalign
+ void* ptr;
+ CHECK(posix_memalign(&ptr, 0, 1) == EINVAL);
+ CHECK(posix_memalign(&ptr, sizeof(void*)/2, 1) == EINVAL);
+ CHECK(posix_memalign(&ptr, sizeof(void*)+1, 1) == EINVAL);
+ CHECK(posix_memalign(&ptr, 4097, 1) == EINVAL);
+
+ // Make sure overflow is returned as ENOMEM
+ for (size_t s = 0; ; s += (10 << 20)) {
+ int r = posix_memalign(&ptr, 1024, s);
+ if (r == ENOMEM) break;
+ CHECK(r == 0);
+ free(ptr);
+ }
+ }
+
+ const int pagesize = sysconf(_SC_PAGESIZE);
+ {
+ // valloc
+ for (int s = 0; s != -1; s = NextSize(s)) {
+ void* p = valloc(s);
+ CheckAlignment(p, pagesize);
+ Fill(p, pagesize, 'v');
+ CHECK(Valid(p, pagesize, 'v'));
+ free(p);
+ }
+ }
+
+ {
+ // pvalloc
+ for (int s = 0; s != -1; s = NextSize(s)) {
+ void* p = pvalloc(s);
+ CheckAlignment(p, pagesize);
+ int alloc_needed = ((s + pagesize - 1) / pagesize) * pagesize;
+ Fill(p, alloc_needed, 'x');
+ CHECK(Valid(p, alloc_needed, 'x'));
+ free(p);
+ }
+
+ // should be safe to write upto a page in pvalloc(0) region
+ void* p = pvalloc(0);
+ Fill(p, pagesize, 'y');
+ CHECK(Valid(p, pagesize, 'y'));
+ free(p);
+ }
+
+ printf("PASS\n");
+ return 0;
+}
diff --git a/src/tests/profiler_unittest.sh b/src/tests/profiler_unittest.sh
index cc6c52f..72d1c15 100755
--- a/src/tests/profiler_unittest.sh
+++ b/src/tests/profiler_unittest.sh
@@ -42,14 +42,19 @@
# This is because libtool sometimes turns the 'executable' into a
# shell script which runs an actual binary somewhere else.
-if [ -z "$2" ]
-then
- echo "USAGE: $0 <unittest dir> <pprof dir>"
- exit 1
+# We expect BINDIR and PPROF_PATH to be set in the environment.
+# If not, we set them to some reasonable values
+BINDIR="${BINDIR:-.}"
+PPROF_PATH="${PPROF_PATH:-$BINDIR/src/pprof}"
+
+if [ "x$1" = "x-h" -o "x$1" = "x--help" ]; then
+ echo "USAGE: $0 [unittest dir] [path to pprof]"
+ echo " By default, unittest_dir=$BINDIR, pprof_path=$PPROF_PATH"
+ exit 1
fi
-UNITTEST_DIR=$1
-PPROF=$2/pprof
+UNITTEST_DIR=${1:-$BINDIR}
+PPROF=${2:-$PPROF_PATH}
PROFILER1=$UNITTEST_DIR/profiler1_unittest
PROFILER2=$UNITTEST_DIR/profiler2_unittest
@@ -66,6 +71,10 @@ mkdir $TMPDIR || exit 2
num_failures=0
+RegisterFailure() {
+ num_failures=`expr $num_failures + 1`
+}
+
# Takes two filenames representing profiles, with their executable scripts,
# and a multiplier, and verifies that the 'contentful' functions in
# each profile take the same time (possibly scaled by the given
@@ -73,28 +82,28 @@ num_failures=0
# noise-reducing X units to each value. But even that would often
# spuriously fail, so now it's "both non-zero". We're pretty forgiving.
VerifySimilar() {
- prof1=$TMPDIR/$1
- # We need to run the script with no args to get the actual exe name
- exec1=`$2 2>&1 | awk '{print $2; exit;}'`
- prof2=$TMPDIR/$3
- exec2=`$4 2>&1 | awk '{print $2; exit;}'`
- mult=$5
-
- mthread1=`$PPROF $exec1 $prof1 | grep test_main_thread | awk '{print $1}'`
- mthread2=`$PPROF $exec2 $prof2 | grep test_main_thread | awk '{print $1}'`
- mthread1_plus=`expr $mthread1 + 5`
- mthread2_plus=`expr $mthread2 + 5`
- if [ -z "$mthread1" ] || [ -z "$mthread2" ] || \
- [ "$mthread1" -le 0 -o "$mthread2" -le 0 ]
+ prof1=$TMPDIR/$1
+ # We need to run the script with no args to get the actual exe name
+ exec1=`$2 2>&1 | awk '{print $2; exit;}'`
+ prof2=$TMPDIR/$3
+ exec2=`$4 2>&1 | awk '{print $2; exit;}'`
+ mult=$5
+
+ mthread1=`$PPROF $exec1 $prof1 | grep test_main_thread | awk '{print $1}'`
+ mthread2=`$PPROF $exec2 $prof2 | grep test_main_thread | awk '{print $1}'`
+ mthread1_plus=`expr $mthread1 + 5`
+ mthread2_plus=`expr $mthread2 + 5`
+ if [ -z "$mthread1" ] || [ -z "$mthread2" ] || \
+ [ "$mthread1" -le 0 -o "$mthread2" -le 0 ]
# || [ `expr $mthread1_plus \* $mult` -gt `expr $mthread2_plus \* 2` -o \
# `expr $mthread1_plus \* $mult \* 2` -lt `expr $mthread2_plus` ]
- then
- echo
- echo ">>> profile on $exec1 vs $exec2 with multiplier $mult failed:"
- echo "Actual times (in profiling units) were '$mthread1' vs. '$mthread2'"
- echo
- num_failures=`expr $num_failures + 1`
- fi
+ then
+ echo
+ echo ">>> profile on $exec1 vs $exec2 with multiplier $mult failed:"
+ echo "Actual times (in profiling units) were '$mthread1' vs. '$mthread2'"
+ echo
+ RegisterFailure
+ fi
}
# Takes a filenames representing a profile, with its executables,
@@ -106,24 +115,24 @@ VerifySimilar() {
# noise-reducing X units to each value. But even that would often
# spuriously fail, so now it's "both non-zero". We're pretty forgiving.
VerifyAcrossThreads() {
- prof1=$TMPDIR/$1
- # We need to run the script with no args to get the actual exe name
- exec1=`$2 2>&1 | awk '{print $2; exit;}'`
- mult=$3
-
- mthread=`$PPROF $exec1 $prof1 | grep test_main_thread | awk '{print $1}'`
- othread=`$PPROF $exec2 $prof2 | grep test_other_thread | awk '{print $1}'`
- if [ -z "$mthread" ] || [ -z "$othread" ] || \
- [ "$mthread" -le 0 -o "$othread" -le 0 ]
+ prof1=$TMPDIR/$1
+ # We need to run the script with no args to get the actual exe name
+ exec1=`$2 2>&1 | awk '{print $2; exit;}'`
+ mult=$3
+
+ mthread=`$PPROF $exec1 $prof1 | grep test_main_thread | awk '{print $1}'`
+ othread=`$PPROF $exec2 $prof2 | grep test_other_thread | awk '{print $1}'`
+ if [ -z "$mthread" ] || [ -z "$othread" ] || \
+ [ "$mthread" -le 0 -o "$othread" -le 0 ]
# || [ `expr $mthread \* $mult \* 3` -gt `expr $othread \* 10` -o \
# `expr $mthread \* $mult \* 10` -lt `expr $othread \* 3` ]
- then
- echo
- echo ">>> profile on $exec1 vs $exec2 with multiplier $mult failed:"
- echo "Actual times (in profiling units) were '$mthread1' vs. '$mthread2'"
- echo
- num_failures=`expr $num_failures + 1`
- fi
+ then
+ echo
+ echo ">>> profile on $exec1 vs $exec2 with multiplier $mult failed:"
+ echo "Actual times (in profiling units) were '$mthread1' vs. '$mthread2'"
+ echo
+ RegisterFailure
+ fi
}
echo
@@ -134,47 +143,47 @@ echo "If the test does fail with an 'Actual times' error, try running again."
echo
# profiler1 is a non-threaded version
-$PROFILER1 50 1 $TMPDIR/p1
-$PROFILER1 100 1 $TMPDIR/p2
+$PROFILER1 50 1 $TMPDIR/p1 || RegisterFailure
+$PROFILER1 100 1 $TMPDIR/p2 || RegisterFailure
VerifySimilar p1 $PROFILER1 p2 $PROFILER1 2
# Verify the same thing works if we statically link
-$PROFILER2 50 1 $TMPDIR/p3
-$PROFILER2 100 1 $TMPDIR/p4
+$PROFILER2 50 1 $TMPDIR/p3 || RegisterFailure
+$PROFILER2 100 1 $TMPDIR/p4 || RegisterFailure
VerifySimilar p3 $PROFILER2 p4 $PROFILER2 2
# Verify the same thing works if we specify via CPUPROFILE
-CPUPROFILE=$TMPDIR/p5 $PROFILER2 50
-CPUPROFILE=$TMPDIR/p6 $PROFILER2 100
+CPUPROFILE=$TMPDIR/p5 $PROFILER2 50 || RegisterFailure
+CPUPROFILE=$TMPDIR/p6 $PROFILER2 100 || RegisterFailure
VerifySimilar p5 $PROFILER2 p6 $PROFILER2 2
# When we compile with threads, things take a lot longer even when we only use 1
-CPUPROFILE=$TMPDIR/p5b $PROFILER3 10
-CPUPROFILE=$TMPDIR/p5c $PROFILER3 20
+CPUPROFILE=$TMPDIR/p5b $PROFILER3 10 || RegisterFailure
+CPUPROFILE=$TMPDIR/p5c $PROFILER3 20 || RegisterFailure
VerifySimilar p5b $PROFILER3 p5c $PROFILER3 2
# Now try what happens when we use threads
-$PROFILER3 5 2 $TMPDIR/p7
-$PROFILER3 10 2 $TMPDIR/p8
+$PROFILER3 5 2 $TMPDIR/p7 || RegisterFailure
+$PROFILER3 10 2 $TMPDIR/p8 || RegisterFailure
VerifySimilar p7 $PROFILER3 p8 $PROFILER3 2
-$PROFILER4 5 2 $TMPDIR/p9
-$PROFILER4 10 2 $TMPDIR/p10
+$PROFILER4 5 2 $TMPDIR/p9 || RegisterFailure
+$PROFILER4 10 2 $TMPDIR/p10 || RegisterFailure
VerifySimilar p9 $PROFILER4 p10 $PROFILER4 2
# More threads!
-$PROFILER4 2 3 $TMPDIR/p9
-$PROFILER4 4 3 $TMPDIR/p10
+$PROFILER4 2 3 $TMPDIR/p9 || RegisterFailure
+$PROFILER4 4 3 $TMPDIR/p10 || RegisterFailure
VerifySimilar p9 $PROFILER4 p10 $PROFILER4 2
# Compare how much time the main thread takes compared to the other threads
# Recall the main thread runs twice as long as the other threads, by design.
-$PROFILER4 2 4 $TMPDIR/p11
+$PROFILER4 2 4 $TMPDIR/p11 || RegisterFailure
VerifyAcrossThreads p11 $PROFILER4 2
# Make sure that when we have a process with a fork, the profiles don't
# clobber each other
-CPUPROFILE=$TMPDIR/p6 $PROFILER1 1 -2
+CPUPROFILE=$TMPDIR/p6 $PROFILER1 1 -2 || RegisterFailure
n=`ls $TMPDIR/p6* | wc -l`
if [ $n != 3 ]; then
echo "FORK test FAILED: expected 3 profiles (for main + 2 children), found $n"
diff --git a/src/tests/ptmalloc/malloc-machine.h b/src/tests/ptmalloc/malloc-machine.h
index f32ca35..44c7802 100644
--- a/src/tests/ptmalloc/malloc-machine.h
+++ b/src/tests/ptmalloc/malloc-machine.h
@@ -31,7 +31,7 @@ PERFORMANCE OF THIS SOFTWARE.
/* Use fast inline spinlocks with gcc. */
#if (defined __i386__ || defined __x86_64__) && defined __GNUC__ && \
- !defined USE_NO_SPINLOCKS
+ !defined USE_NO_SPINLOCKS && 0 /*!!*/
#include <time.h>
#include <sched.h>
diff --git a/src/tests/stacktrace_unittest.cc b/src/tests/stacktrace_unittest.cc
index b73cf4b..5a4b654 100644
--- a/src/tests/stacktrace_unittest.cc
+++ b/src/tests/stacktrace_unittest.cc
@@ -28,15 +28,15 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "config.h"
+#ifdef HAVE_EXECINFO_H
+#include <execinfo.h>
+#endif
#include <stdio.h>
#include <stdlib.h>
#include "base/commandlineflags.h"
#include "base/logging.h"
-#include "google/stacktrace.h"
+#include <google/stacktrace.h>
-#ifdef HAVE_EXECINFO_H
-#include <execinfo.h>
-#endif
// Obtain a backtrace, verify that the expected callers are present in the
// backtrace, and maybe print the backtrace to stdout.
@@ -94,35 +94,25 @@ void CheckStackTraceLeaf(void) {
const int STACK_LEN = 10;
void *stack[STACK_LEN];
int size;
- void *top, *bottom;
size = GetStackTrace(stack, STACK_LEN, 0);
printf("Obtained %d stack frames.\n", size);
CHECK_LE(size, STACK_LEN);
- // GetStackExtent() may not be implemented
- if (GetStackExtent(NULL, &top, &bottom)) {
- printf("%p %p\n", top, bottom);
- }
-
- for (int i = 0; i < BACKTRACE_STEPS; i++)
- {
- CheckRetAddrIsInFunction(stack[i], expected_stack[i]);
- }
-
-
#ifdef HAVE_EXECINFO_H
{
char **strings = backtrace_symbols(stack, size);
-
printf("Obtained %d stack frames.\n", size);
for (int i = 0; i < size; i++)
- printf("%s\n", strings[i]);
+ printf("%s %p\n", strings[i], stack[i]);
printf("CheckStackTrace() addr: %p\n", &CheckStackTrace);
free(strings);
}
#endif
+ for (int i = 0; i < BACKTRACE_STEPS; i++) {
+ CheckRetAddrIsInFunction(stack[i], expected_stack[i]);
+ }
}
//-----------------------------------------------------------------------//
diff --git a/src/tests/tcmalloc_large_unittest.cc b/src/tests/tcmalloc_large_unittest.cc
index fd9f885..260ac29 100644
--- a/src/tests/tcmalloc_large_unittest.cc
+++ b/src/tests/tcmalloc_large_unittest.cc
@@ -40,9 +40,9 @@
#include <stdio.h>
#include <set>
-#define CHECK(b) do { \
- if (b) {} else { fprintf(stderr, "TEST FAILED: " #b); exit(1); } \
-} while (0)
+#include "base/logging.h"
+
+using std::set;
// Alloc a size that should always fail.
@@ -90,7 +90,7 @@ int main (int argc, char** argv) {
{
static const int kZeroTimes = 1024;
printf("Test malloc(0) x %d\n", kZeroTimes);
- std::set<char*> p_set;
+ set<char*> p_set;
for ( int i = 0; i < kZeroTimes; ++i ) {
char* p = new char;
CHECK(p != NULL);
diff --git a/src/tests/tcmalloc_unittest.cc b/src/tests/tcmalloc_unittest.cc
index 9f2df59..2d07481 100644
--- a/src/tests/tcmalloc_unittest.cc
+++ b/src/tests/tcmalloc_unittest.cc
@@ -57,6 +57,7 @@
#include <string>
#include <new>
#include "base/logging.h"
+#include "google/malloc_extension.h"
#define LOGSTREAM stdout
@@ -64,7 +65,7 @@ using std::vector;
using std::string;
static const int FLAGS_numtests = 50000;
-static const int FLAGS_log_every_n_tests = 10000;
+static const int FLAGS_log_every_n_tests = 50000; // log exactly once
// Testing parameters
static const int FLAGS_lgmaxsize = 16; // lg() of the max size object to alloc
@@ -156,6 +157,7 @@ void TestHarness::AddType(int type, int weight, const char* name) {
int TestHarness::PickType() {
if (num_tests_ >= FLAGS_numtests) return -1;
+ num_tests_++;
assert(total_weight_ > 0);
// This is a little skewed if total_weight_ doesn't divide 2^31, but it's close
@@ -170,10 +172,9 @@ int TestHarness::PickType() {
assert(i < types_->size());
if ((num_tests_ % FLAGS_log_every_n_tests) == 0) {
- fprintf(LOGSTREAM, "Test %d out of %d: %s\n",
+ fprintf(LOGSTREAM, " Test %d out of %d: %s\n",
num_tests_, FLAGS_numtests, (*types_)[i].name.c_str());
}
- num_tests_++;
return (*types_)[i].type;
}
@@ -211,8 +212,9 @@ class TesterThread {
}
virtual ~TesterThread() {
- fprintf(LOGSTREAM, "Thread %2d: locks %6d ok; %6d trylocks failed\n",
- id_, locks_ok_, locks_failed_);
+ if (FLAGS_verbose)
+ fprintf(LOGSTREAM, "Thread %2d: locks %6d ok; %6d trylocks failed\n",
+ id_, locks_ok_, locks_failed_);
if (locks_ok_ + locks_failed_ >= 1000) {
CHECK_LE(locks_failed_, locks_ok_ / 2);
}
@@ -408,15 +410,22 @@ static void TestHugeAllocations() {
p = malloc(kMaxSignedSize - i);
if (p) free(p);
}
+
+ // Check that ReleaseFreeMemory has no visible effect (aka, does not
+ // crash the test):
+ MallocExtension* inst = MallocExtension::instance();
+ CHECK(inst);
+ inst->ReleaseFreeMemory();
}
static void TestCalloc(size_t n, size_t s, bool ok) {
char* p = reinterpret_cast<char*>(calloc(n, s));
- fprintf(LOGSTREAM, "calloc(%x, %x): %p\n", n, s, p);
+ if (FLAGS_verbose)
+ fprintf(LOGSTREAM, "calloc(%x, %x): %p\n", n, s, p);
if (!ok) {
- CHECK(p == NULL); // calloc(n, s) should succeed
+ CHECK(p == NULL); // calloc(n, s) should not succeed
} else {
- CHECK(p != NULL); // calloc(n, s) should not succeed
+ CHECK(p != NULL); // calloc(n, s) should succeed
for (int i = 0; i < n*s; i++) {
CHECK(p[i] == '\0');
}
@@ -525,7 +534,7 @@ int main(int argc, char** argv) {
// before this test, it may break).
{
size_t memory_usage = MemoryUsage(getpid());
- fprintf(LOGSTREAM, "==== Testing fragmentation\n");
+ fprintf(LOGSTREAM, "Testing fragmentation\n");
for ( int i = 200; i < 240; ++i ) {
int size = i << 20;
void *test1 = malloc(size);
@@ -543,7 +552,7 @@ int main(int argc, char** argv) {
#endif
// Check that empty allocation works
- fprintf(LOGSTREAM, "==== Testing empty allocation\n");
+ fprintf(LOGSTREAM, "Testing empty allocation\n");
{
void* p1 = malloc(0);
CHECK(p1 != NULL);
@@ -555,7 +564,7 @@ int main(int argc, char** argv) {
}
// Check that "lots" of memory can be allocated
- fprintf(LOGSTREAM, "==== Testing large allocation\n");
+ fprintf(LOGSTREAM, "Testing large allocation\n");
{
const int mb_to_allocate = 100;
void* p = malloc(mb_to_allocate << 20);
@@ -564,7 +573,7 @@ int main(int argc, char** argv) {
}
// Check calloc() with various arguments
- fprintf(LOGSTREAM, "==== Testing calloc\n");
+ fprintf(LOGSTREAM, "Testing calloc\n");
TestCalloc(0, 0, true);
TestCalloc(0, 1, true);
TestCalloc(1, 1, true);
@@ -592,10 +601,10 @@ int main(int argc, char** argv) {
TestNew(&::operator new);
fprintf(LOGSTREAM, "Testing operator new[].\n");
TestNew(&::operator new[]);
- fprintf(LOGSTREAM, "Done testing C++ operators.\n");
// Create threads
- fprintf(LOGSTREAM, "==== Testing threaded allocation/deallocation\n");
+ fprintf(LOGSTREAM, "Testing threaded allocation/deallocation (%d threads)\n",
+ FLAGS_numthreads);
threads = new TesterThread*[FLAGS_numthreads];
pthread_t* thread_ids = new pthread_t[FLAGS_numthreads];
for (int i = 0; i < FLAGS_numthreads; ++i) {
@@ -625,11 +634,11 @@ int main(int argc, char** argv) {
// the available address space can make pthread_create to fail.
// Check that huge allocations fail with NULL instead of crashing
- fprintf(LOGSTREAM, "==== Testing huge allocations\n");
+ fprintf(LOGSTREAM, "Testing huge allocations\n");
TestHugeAllocations();
// Check that large allocations fail with NULL instead of crashing
- fprintf(LOGSTREAM, "==== Testing out of memory\n");
+ fprintf(LOGSTREAM, "Testing out of memory\n");
for (int s = 0; ; s += (10<<20)) {
void* large_object = malloc(s);
if (large_object == NULL) break;
diff --git a/src/tests/testutil.cc b/src/tests/testutil.cc
new file mode 100644
index 0000000..9c9f4c0
--- /dev/null
+++ b/src/tests/testutil.cc
@@ -0,0 +1,72 @@
+// Copyright (c) 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// ---
+// Author: Craig Silverstein
+//
+// A few routines that are useful for multiple tests in this directory.
+
+#include "config.h"
+#include <stdlib.h> // for NULL, abort()
+#include "tests/testutil.h"
+
+#ifdef HAVE_PTHREAD
+
+#include <pthread.h>
+
+#define SAFE_PTHREAD(fncall) do { if ((fncall) != 0) abort(); } while (0)
+
+// Run a function in a thread of its own and wait for it to finish.
+// This is useful for tcmalloc testing, because each thread is handled
+// separately in tcmalloc, so there's interesting stuff to test even if
+// the threads are not running concurrently.
+
+// This helper function has the signature that pthread_create wants.
+extern "C" {
+ static void* RunFunctionInThread(void *ptr_to_ptr_to_fn) {
+ (**static_cast<void (**)()>(ptr_to_ptr_to_fn))(); // runs fn
+ return NULL;
+ }
+}
+
+void RunInThread(void (*fn)()) {
+ pthread_t thr;
+ // Even though fn is on the stack, it's safe to pass a pointer to it,
+ // because we pthread_join immediately (ie, before RunInThread exits).
+ SAFE_PTHREAD(pthread_create(&thr, NULL, RunFunctionInThread, &fn));
+ SAFE_PTHREAD(pthread_join(thr, NULL));
+}
+
+#else // !HAVE_PTHREAD
+
+void RunInThread(void (*fn)()) {
+ fn(); // best we can do: just run it
+}
+
+#endif
diff --git a/src/tests/testutil.h b/src/tests/testutil.h
new file mode 100644
index 0000000..aed7bd7
--- /dev/null
+++ b/src/tests/testutil.h
@@ -0,0 +1,41 @@
+// Copyright (c) 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// ---
+// Author: Craig Silverstein
+
+#ifndef TCMALLOC_TOOLS_TESTUTIL_H__
+#define TCMALLOC_TOOLS_TESTUTIL_H__
+
+// Run a function in a thread of its own and wait for it to finish.
+// The function you pass in must have the signature
+// void MyFunction();
+extern void RunInThread(void (*fn)());
+
+#endif // TCMALLOC_TOOLS_TESTUTIL_H__
diff --git a/src/tests/thread_dealloc_unittest.cc b/src/tests/thread_dealloc_unittest.cc
new file mode 100644
index 0000000..4c36e2e
--- /dev/null
+++ b/src/tests/thread_dealloc_unittest.cc
@@ -0,0 +1,78 @@
+// Copyright (c) 2004, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// ---
+// Author: Sanjay Ghemawat
+//
+// Check that we do not leak memory when cycling through lots of threads.
+
+#include "config.h"
+#include <unistd.h>
+#include "base/logging.h"
+#include <google/malloc_extension.h>
+#include "tests/testutil.h" // for RunInThread()
+
+// Size/number of objects to allocate per thread (1 MB per thread)
+static const int kObjectSize = 1024;
+static const int kNumObjects = 1024;
+
+// Number of threads to create and destroy
+static const int kNumThreads = 1000;
+
+// Allocate lots of stuff
+static void AllocStuff() {
+ void** objects = new void*[kNumObjects];
+ for (int i = 0; i < kNumObjects; i++) {
+ objects[i] = malloc(kObjectSize);
+ }
+ for (int i = 0; i < kNumObjects; i++) {
+ free(objects[i]);
+ }
+ delete[] objects;
+}
+
+int main(int argc, char** argv) {
+ static const int kDisplaySize = 1048576;
+ char* display = new char[kDisplaySize];
+
+ for (int i = 0; i < kNumThreads; i++) {
+ RunInThread(&AllocStuff);
+
+ if (((i+1) % 200) == 0) {
+ fprintf(stderr, "Iteration: %d of %d\n", (i+1), kNumThreads);
+ MallocExtension::instance()->GetStats(display, kDisplaySize);
+ fprintf(stderr, "%s\n", display);
+ }
+ }
+ delete[] display;
+
+ printf("PASS\n");
+ sleep(1); // Prevent exit race problem with glibc
+ return 0;
+}