bug 323188: Link order is important when building executables

It also seems to be important in certain cases when using g++
to build shared libraries.
I was having weird errors building the CLUs on linux x86_64.  These turned out to be due to the incorrect ordering of objects on the link line.

The LINK_EXE macro already has everything needed - it is not necessary to
supply extra libs in the form of the LDTOOLS_LIBS.  Just specify them in the
correct order in EXTRA_LIBS.  You don't need to set EXTRA_LIBS for every
platform - on *nix platforms, they are all the same, so just define them in a
common place in the correct order.  Use PLATFORMLIBS to specify platform
dependent libs.

The one tricky thing is that LINK_EXE expects OBJS to have all of the objects.
This works if you only build one executable per makefile, but this makefile
builds several, so you need to get the executable specific .obj file in the
link line as well.  I suppose I could have used target specific variable
assignment to OBJS, but that seemed messy to me, so I just added a $(filter ..)
to the LINK_EXE command which will add all of the .obj files specified in the
executable link target dependency list to the link line.  The filter is to
filter out libraries and other dependencies, which are usually specified
elsewhere.  This seems to work on linux x86_64 and HP IPF 64 just fine.
This commit is contained in:
richm%stanfordalumni.org 2006-01-13 15:35:45 +00:00
parent 51272beaf9
commit 75853eee2e
4 changed files with 1670 additions and 2413 deletions

View File

@ -425,7 +425,8 @@ endif
ifeq ($(OS_ARCH), WINNT)
ifdef NS_USE_GCC
LINK_EXE = $(CC_FOR_LINK) -o $@ $(LDFLAGS) $(LCFLAGS) $(DEPLIBS) $(OBJS) $(EXTRA_LIBS) $(PLATFORMLIBS)
LINK_EXE = $(CC_FOR_LINK) -o $@ $(LDFLAGS) $(LCFLAGS) $(DEPLIBS) \
$(filter %.$(OBJ_SUFFIX),$^) $(OBJS) $(EXTRA_LIBS) $(PLATFORMLIBS)
LINK_LIB = $(AR) cr $@ $(OBJS)
LINK_DLL = $(CC_FOR_LINK) -shared -Wl,--export-all-symbols -Wl,--out-implib -Wl,$(@:.$(DLL_SUFFIX)=.$(LIB_SUFFIX)) $(LLFLAGS) $(DLL_LDFLAGS) -o $@ $(OBJS) $(EXTRA_LIBS) $(EXTRA_DLL_LIBS)
else
@ -445,7 +446,7 @@ endif
LINK_EXE = $(CYGWIN_WRAPPER) link $(DEBUG_LINK_OPT) -OUT:"$@" -MAP $(ALDFLAGS) $(LDFLAGS) $(ML_DEBUG) \
$(LCFLAGS) -NOLOGO $(DEBUG_FLAGS) -INCREMENTAL:NO \
-NODEFAULTLIB:MSVCRTD -SUBSYSTEM:$(SUBSYSTEM) $(DEPLIBS) \
$(EXTRA_LIBS) $(PLATFORMLIBS) $(OBJS)
$(filter %.$(OBJ_SUFFIX),$^) $(OBJS) $(EXTRA_LIBS) $(PLATFORMLIBS)
LINK_LIB = $(CYGWIN_WRAPPER) lib -OUT:"$@" $(OBJS)
LINK_DLL = $(CYGWIN_WRAPPER) link $(DEBUG_LINK_OPT) -nologo -MAP -DLL $(DEBUG_FLAGS) \
$(ML_DEBUG) -SUBSYSTEM:$(SUBSYSTEM) $(LLFLAGS) $(DLL_LDFLAGS) \
@ -496,13 +497,13 @@ ifeq ($(OS_ARCH), HP-UX)
# needs this).
# 2) Add a "-Wl,-E" option so the linker gets a "-E" flag. This makes symbols
# in an executable visible to shared libraries loaded at runtime.
LINK_EXE = $(CC_FOR_LINK) -Wl,-E $(ALDFLAGS) $(LDFLAGS) $(RPATHFLAG_PREFIX)$(RPATHFLAG) -o $@ $(OBJS) $(EXTRA_LIBS) $(PLATFORMLIBS)
LINK_EXE = $(CC_FOR_LINK) -Wl,-E $(ALDFLAGS) $(LDFLAGS) $(RPATHFLAG_PREFIX)$(RPATHFLAG) -o $@ $(filter %.$(OBJ_SUFFIX),$^) $(OBJS) $(EXTRA_LIBS) $(PLATFORMLIBS)
ifeq ($(USE_64), 1)
ifeq ($(OS_RELEASE), B.11.23)
LINK_EXE = $(CC_FOR_LINK) -DHPUX_ACC -D__STDC_EXT__ -D_POSIX_C_SOURCE=199506L +DD64 +DSblended -Wl,-E $(ALDFLAGS) $(LDFLAGS) $(RPATHFLAG_PREFIX)$(RPATHFLAG) -o $@ $(OBJS) $(EXTRA_LIBS) $(PLATFORMLIBS)
LINK_EXE = $(CC_FOR_LINK) -DHPUX_ACC -D__STDC_EXT__ -D_POSIX_C_SOURCE=199506L +DD64 +DSblended -Wl,-E $(ALDFLAGS) $(LDFLAGS) $(RPATHFLAG_PREFIX)$(RPATHFLAG) -o $@ $(filter %.$(OBJ_SUFFIX),$^) $(OBJS) $(EXTRA_LIBS) $(PLATFORMLIBS)
else
LINK_EXE = $(CC_FOR_LINK) -DHPUX_ACC -D__STDC_EXT__ -D_POSIX_C_SOURCE=199506L +DA2.0W +DS2.0 -Wl,-E $(ALDFLAGS) $(LDFLAGS) $(RPATHFLAG_PREFIX)$(RPATHFLAG) -o $@ $(OBJS) $(EXTRA_LIBS) $(PLATFORMLIBS)
LINK_EXE = $(CC_FOR_LINK) -DHPUX_ACC -D__STDC_EXT__ -D_POSIX_C_SOURCE=199506L +DA2.0W +DS2.0 -Wl,-E $(ALDFLAGS) $(LDFLAGS) $(RPATHFLAG_PREFIX)$(RPATHFLAG) -o $@ $(filter %.$(OBJ_SUFFIX),$^) $(OBJS) $(EXTRA_LIBS) $(PLATFORMLIBS)
endif
endif
@ -514,12 +515,12 @@ ifdef USE_LD_RUN_PATH
#see ns/netsite/ldap/clients/tools/Makefile for an example
export LD_RUN_PATH=$(RPATHFLAG)
LINK_EXE = $(CC_FOR_LINK) $(ALDFLAGS) $(LDFLAGS) \
-o $@ $(OBJS) $(EXTRA_LIBS) $(PLATFORMLIBS)
-o $@ $(filter %.$(OBJ_SUFFIX),$^) $(OBJS) $(EXTRA_LIBS) $(PLATFORMLIBS)
LINK_EXE_NOLIBSOBJS = $(CC_FOR_LINK) $(ALDFLAGS) $(LDFLAGS) -o $@
else # USE_LD_RUN_PATH
LINK_EXE = $(CC_FOR_LINK) $(ALDFLAGS) $(LDFLAGS) \
$(RPATHFLAG_PREFIX)$(RPATHFLAG)$(RPATHFLAG_EXTRAS) \
-o $@ $(OBJS) $(EXTRA_LIBS) $(PLATFORMLIBS)
-o $@ $(filter %.$(OBJ_SUFFIX),$^) $(OBJS) $(EXTRA_LIBS) $(PLATFORMLIBS)
LINK_EXE_NOLIBSOBJS = $(CC_FOR_LINK) $(ALDFLAGS) $(LDFLAGS) \
$(RPATHFLAG_PREFIX)$(RPATHFLAG)$(RPATHFLAG_EXTRAS) -o $@
endif # USE_LD_RUN_PATH

File diff suppressed because it is too large Load Diff

View File

@ -459,7 +459,27 @@ if test -z "$SKIP_COMPILER_CHECKS"; then
dnl ========================================================
dnl Checks for compilers.
dnl ========================================================
if test "$target" != "$host"; then
if test "$target" = "$host"; then
AC_PROG_CXX
if test "$CXX" = "cl" -a -z "$CC"; then
CC=$CXX
else
AC_PROG_CC
fi
AC_PROG_CPP
AC_PROG_RANLIB
AC_PATH_PROGS(AS, as, $CC)
AC_PATH_PROGS(AR, ar, echo not_ar)
AC_PATH_PROGS(LD, ld link, echo not_ld)
AC_PATH_PROGS(STRIP, strip, echo not_strip)
AC_PATH_PROGS(WINDRES, windres, echo not_windres)
if test -z "$HOST_CC"; then
HOST_CC="$CC"
fi
if test -z "$HOST_CFLAGS"; then
HOST_CFLAGS="$CFLAGS"
fi
else
echo "cross compiling from $host to $target"
cross_compiling=yes
@ -505,27 +525,6 @@ if test "$target" != "$host"; then
AC_CHECK_PROGS(LD, $LD "${target_alias}-ld" "${target}-ld", echo)
AC_CHECK_PROGS(STRIP, $STRIP "${target_alias}-strip" "${target}-strip", echo)
AC_CHECK_PROGS(WINDRES, $WINDRES "${target_alias}-windres" "${target}-windres", echo)
else
AC_PROG_CXX
if test "$CXX" = "cl" -a -z "$CC"; then
CC=$CXX
else
AC_PROG_CC
fi
AC_PROG_CPP
AC_PROG_RANLIB
AC_PATH_PROGS(AS, as, $CC)
AC_PATH_PROGS(AR, ar, echo not_ar)
AC_PATH_PROGS(LD, ld link, echo not_ld)
AC_PATH_PROGS(STRIP, strip, echo not_strip)
AC_PATH_PROGS(WINDRES, windres, echo not_windres)
if test -z "$HOST_CC"; then
HOST_CC="$CC"
fi
if test -z "$HOST_CFLAGS"; then
HOST_CFLAGS="$CFLAGS"
fi
fi
if test "$GCC" = "yes"; then

View File

@ -125,7 +125,7 @@ ifeq ($(OS_ARCH), HP-UX)
LDAPTOOLCPPCOMMON_OBJ = $(addprefix $(OBJDEST)/, convutf8.o)
endif
CLIENT_OBJS = $(LDAPDELETE_OBJ) $(LDAPMODIFY_OBJ) \
CLIENT_OBJS= $(LDAPDELETE_OBJ) $(LDAPMODIFY_OBJ) \
$(LDAPSEARCH_OBJ) $(LDAPCOMPARE_OBJ) $(LDAPCMP_OBJ) $(LDAPTOOLCOMMON_OBJ)
# For 'clean' target:
@ -141,61 +141,51 @@ BINS= $(LDAPDELETE) $(LDAPMODIFY) $(LDAPSEARCH) $(LDAPCOMPARE) $(LDAPCMP)
LDAPTOOLS_NSS_LINK=$(NSSLINK)
ifeq ($(OS_ARCH), SunOS)
EXTRA_LIBS = -L$(DIST)/$(OBJDIR_NAME)/lib -l$(LDAP_LIBNAME) \
-l$(LDIF_LIBNAME) -l$(SSLDAP_LIBNAME) -l$(PRLDAP_LIBNAME) \
-L$(DIST)/lib -L$(DIST_LIB_PATH) $(SVRCORE_LINK) \
$(LDAPTOOLS_NSS_LINK) $(NSPRLINK) \
-lthread -lposix4 -lsocket -lnls \
-ldl -lresolv -lgen
endif
# set common libs for all platforms
ifeq ($(OS_ARCH), WINNT)
EXTRA_LIBS =wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib \
comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib \
rpcrt4.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib
EXTRA_LIBS += $(DIST)/$(OBJDIR_NAME)/lib/$(LBER_LIBNAME).lib
EXTRA_LIBS = $(DIST)/$(OBJDIR_NAME)/lib/$(SSLDAP_LIBNAME).lib
EXTRA_LIBS += $(DIST)/$(OBJDIR_NAME)/lib/$(PRLDAP_LIBNAME).lib
EXTRA_LIBS += $(DIST)/$(OBJDIR_NAME)/lib/$(LDAP_LIBNAME).lib
EXTRA_LIBS += $(DIST)/$(OBJDIR_NAME)/lib/$(LBER_LIBNAME).lib
EXTRA_LIBS += $(DIST)/$(OBJDIR_NAME)/lib/$(LDIF_LIBNAME).lib
EXTRA_LIBS += $(DIST)/$(OBJDIR_NAME)/lib/$(UTIL_LIBNAME).lib
EXTRA_LIBS += $(SVRCORE_LINK)
EXTRA_LIBS += $(NSSLINK)
EXTRA_LIBS += $(NSPRLINK)
EXTRA_LIBS += $(DIST)/$(OBJDIR_NAME)/lib/$(SSLDAP_LIBNAME).lib
EXTRA_LIBS += $(DIST)/$(OBJDIR_NAME)/lib/$(PRLDAP_LIBNAME).lib
else
# ordering appears to be important, at least on some platforms with some
# linkers
EXTRA_LIBS = -L$(DIST)/$(OBJDIR_NAME)/lib -l$(SSLDAP_LIBNAME) \
-l$(PRLDAP_LIBNAME) -l$(LDAP_LIBNAME) -l$(LDIF_LIBNAME) \
-L$(DIST)/lib $(SVRCORE_LINK) $(LDAPTOOLS_NSS_LINK) $(NSPRLINK)
endif
# set platform specific libs
ifeq ($(OS_ARCH), SunOS)
PLATFORMLIBS=-lthread -lposix4 -lsocket -lnls \
-ldl -lresolv -lgen
endif
ifeq ($(OS_ARCH), WINNT)
PLATFORMLIBS =wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib \
comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib \
rpcrt4.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib
endif
ifeq ($(OS_ARCH), OSF1)
EXTRA_LIBS = -L$(DIST)/$(OBJDIR_NAME)/lib -l$(LDAP_LIBNAME) \
-l$(LDIF_LIBNAME) -l$(SSLDAP_LIBNAME) -l$(PRLDAP_LIBNAME) \
-L$(DIST)/lib -L$(DIST_LIB_PATH) $(SVRCORE_LINK) \
$(LDAPTOOLS_NSS_LINK) $(NSPRLINK) \
-lcxx -lpthread -lrt -lmach -lexc
PLATFORMLIBS = -lcxx -lpthread -lrt -lmach -lexc
endif
ifeq ($(OS_ARCH), Linux)
EXTRA_LIBS = -L$(DIST)/$(OBJDIR_NAME)/lib -l$(LDAP_LIBNAME) \
-l$(LDIF_LIBNAME) -l$(SSLDAP_LIBNAME) -l$(PRLDAP_LIBNAME) \
-L$(DIST)/lib -L$(DIST_LIB_PATH) $(SVRCORE_LINK) \
$(LDAPTOOLS_NSS_LINK) $(NSPRLINK) \
-l$(LBER_LIBNAME) \
-ldl -lresolv -lpthread
PLATFORMLIBS=-ldl -lresolv -lpthread
endif
ifeq ($(OS_ARCH), HP-UX)
EXTRA_LIBS = -ldld -lm -lpthread -lrt \
-L$(DIST)/$(OBJDIR_NAME)/lib -l$(LDAP_LIBNAME) \
-l$(LDIF_LIBNAME) -l$(SSLDAP_LIBNAME) -l$(PRLDAP_LIBNAME) \
-L$(DIST)/lib -L$(DIST_LIB_PATH) $(SVRCORE_LINK) \
-l$(LBER_LIBNAME) $(LDAPTOOLS_NSS_LINK) $(NSPRLINK)
PLATFORMLIBS = -ldld -lm -lpthread -lrt
endif
ifeq ($(OS_ARCH), AIX)
EXTRA_LIBS = -L$(DIST)/$(OBJDIR_NAME)/lib -l$(LDAP_LIBNAME) \
-l$(LDIF_LIBNAME) -l$(SSLDAP_LIBNAME) -l$(PRLDAP_LIBNAME) \
-L$(DIST)/lib -L$(DIST_LIB_PATH) $(SVRCORE_LINK) \
$(LDAPTOOLS_NSS_LINK) $(NSPRLINK) \
-ldl -brtl -lpthreads -lc_r -lm
PLATFORMLIBS=-ldl -brtl -lpthreads -lc_r -lm
endif
ifdef HAVE_LIBNLS
@ -228,9 +218,6 @@ EXTRA_LIBS += $(LIBNLS_LIBDIR)/$(NSCNV_LIBNAME) \
endif
endif
LDTOOLS_LIBS += $(EXTRA_LIBS)
LIBLOCATION = $(DIST)/$(OBJDIR_NAME)/lib
include $(topsrcdir)/config/rules.mk
###########################################################################
@ -272,23 +259,23 @@ endif
$(LDAPCOMPARE): $(LDAPCOMPARE_OBJ) $(LDAPTOOLCOMMON_OBJ) \
$(LDAPTOOLCPPCOMMON_OBJ) $(LDTOOLS_LIBS_DEP)
$(LINK_EXE) $(LDAPCOMPARE_OBJ) $(LDAPTOOLCOMMON_OBJ) $(LDAPTOOLCPPCOMMON_OBJ) $(LDTOOLS_LIBS)
$(LINK_EXE)
$(LDAPDELETE): $(LDAPDELETE_OBJ) $(LDAPTOOLCOMMON_OBJ) \
$(LDAPTOOLCPPCOMMON_OBJ) $(LDTOOLS_LIBS_DEP)
$(LINK_EXE) $(LDAPDELETE_OBJ) $(LDAPTOOLCOMMON_OBJ) $(LDAPTOOLCPPCOMMON_OBJ) $(LDTOOLS_LIBS)
$(LINK_EXE)
$(LDAPMODIFY): $(LDAPMODIFY_OBJ) $(LDAPTOOLCOMMON_OBJ) \
$(LDAPTOOLCPPCOMMON_OBJ) $(LDTOOLS_LIBS_DEP)
$(LINK_EXE) $(LDAPMODIFY_OBJ) $(LDAPTOOLCOMMON_OBJ) $(LDAPTOOLCPPCOMMON_OBJ) $(LDTOOLS_LIBS)
$(LINK_EXE)
$(LDAPSEARCH): $(LDAPSEARCH_OBJ) $(LDAPTOOLCOMMON_OBJ) \
$(LDAPTOOLCPPCOMMON_OBJ) $(LDTOOLS_LIBS_DEP)
$(LINK_EXE) $(LDAPSEARCH_OBJ) $(LDAPTOOLCOMMON_OBJ) $(LDAPTOOLCPPCOMMON_OBJ) $(LDTOOLS_LIBS)
$(LINK_EXE)
$(LDAPCMP): $(LDAPCMP_OBJ) $(LDAPTOOLCOMMON_OBJ) \
$(LDAPTOOLCPPCOMMON_OBJ) $(LDTOOLS_LIBS_DEP)
$(LINK_EXE) $(LDAPCMP_OBJ) $(LDAPTOOLCOMMON_OBJ) $(LDAPTOOLCPPCOMMON_OBJ) $(LDTOOLS_LIBS)
$(LINK_EXE)
$(OBJDEST): FORCE
$(NSINSTALL) -D $(OBJDEST)