#
# C library Makefile
# 
#
# Copyright 2001-2004, Broadcom Corporation
# All Rights Reserved.
#
# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
#


include $(TOP)/.config

# Extra libraries
lib-$(CONFIG_LIBCRYPT) += libcrypt
lib-$(CONFIG_LIBDL) += libdl
lib-$(CONFIG_LIBM) += libm
lib-$(CONFIG_LIBNSL) += libnsl
lib-$(CONFIG_LIBPTHREAD) += libpthread
lib-$(CONFIG_LIBUTIL) += libutil
lib-$(CONFIG_LIBRESOLV) += libresolv
lib-$(CONFIG_LIBDNS) += libnss_dns
lib-$(CONFIG_LIBNSS_FILES) += libnss_files

ifeq ($(CONFIG_UCLIBC),y)

# uClibc names
LINKER := ld-uClibc.so.0
LIBC := libc.so.0
MAP := uClibc.map

else

# GNU libc names
LINKER := $(foreach lib,ld.so.* ld-linux.so.*,$(notdir $(wildcard $(LIBDIR)/$(lib))))
LIBC := libc.so.6
MAP := libc.map

endif

LIBGCC_S = $(notdir $(wildcard $(TOOLCHAIN)/lib/libgcc_s.so.?))

# it looks like some versions of gcc (3.2.3 and up for sure) have split
# gcc into 2 parts - libgcc.a and libgcc_eh.a. Since some things reference
# __register_frame_info, we need to link with -libgcc_eh if it is present - BBB 07/27/04
LIBGCC_DIR = $(dir $(shell mipsel-linux-gcc --print-libgcc-file))
EXTRA_LIBS = -lgcc
ifneq ($(wildcard $(LIBGCC_DIR)/libgcc_eh.a),)
EXTRA_LIBS += -lgcc_eh
endif



# Nothing to do until installation
all:

ifeq ($(CONFIG_LIBOPT),y)

# Find all ELF binaries (including extra libraries)
BINARIES := $(shell find $(TARGETDIR) -path $(TARGETDIR)/lib -prune -o -type f -print | file -f - | grep ELF | cut -d':' -f1)
BINARIES += $(wildcard $(foreach lib,$(LINKER) $(lib-y),$(LIBDIR)/$(lib) $(LIBDIR)/$(lib).so.?))
BINARIES += $(TARGETDIR)/lib/libbigballofmud.so
BINARIES += $(TOOLCHAIN)/lib/$(LIBGCC_S)

ifneq ($(wildcard .custom_binaries),)
BINARIES += $(shell cat .custom_binaries)
endif

ifneq ($(wildcard $(LIBDIR)/optinfo),)
# Try the toolchain directory first for precursors
OPTINFO := $(LIBDIR)/optinfo
else
# Fall back on platform directory
OPTINFO := $(PLATFORM)
endif

ifeq ($(CONFIG_UCLIBC),y)

# uClibc precursors
OBJS := $(wildcard $(foreach file,libgcc-need.a libc.a interp.o,$(OPTINFO)/$(file)))

# uClibc link parameters
ENTRY := __uClibc_init
LDFLAGS := -s -shared --warn-common --warn-once -z combreloc  -soname=$(LIBC) -init $(ENTRY)
LIBGCC := $(shell $(CC) -print-libgcc-file-name)

$(MAP): $(OPTINFO)/libc.a
	$(NM) -o --defined-only --no-sort $< | cut -d' ' -f3 > $@

# Find all unresolved symbols that uClibc could resolve
.symbols: $(MAP) $(BINARIES)
	rm -f $@
	for symbol in `$(NM) --dynamic -u --no-sort $(BINARIES) | sort -u` ; do \
	    grep -q "^$${symbol}$$" $(MAP) && echo "EXTERN($${symbol})" >> $@ ; \
	done ; \
	true
	echo "INCLUDE \"ldscripts/elf32ltsmip.xs\"" >> $@

# Re-link uClibc
$(LIBC): .symbols $(OBJS)
	$(LD) $(LDFLAGS) -o $@ $(OBJS) $(LIBGCC) -T .symbols

else

# GNU libc precursors
OBJS := $(wildcard $(foreach file,soinit.os libc_pic.a sofini.os,$(OPTINFO)/$(file)))

# GNU libc link parameters
ENTRY := __libc_main
CFLAGS := -shared -Wl,-O1 -Wl,-dynamic-linker=$(LINKER) -Wl,--version-script=$(MAP) -Wl,-soname=$(LIBC) -nostdlib -nostartfiles -e $(ENTRY)

$(MAP): $(OPTINFO)/libc.map
	cp $< $@

# Find all unresolved symbols that GNU libc could resolve
.symbols: $(MAP) $(BINARIES)
	./find_syms.pl --map $(MAP) $(addprefix --bin ,$(BINARIES)) > $@
	echo "INCLUDE \"ldscripts/elf32ltsmip.xs\"" >> $@

# Re-link GNU libc
$(LIBC): .symbols $(OBJS) $(LIBDIR)/$(LINKER)
	$(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBDIR)/$(LINKER) $(EXTRA_LIBS) -T .symbols

endif

# @@@ We want a very limited version of libgcc_s, with only the symbols listed
# @@@ below.  That's so we don't accidentally pull in a bunch of floating-point
# @@@ stuff.  If any code starts using floating point, we want to modify it to
# @@@ stop using floating point since that is very slow.
./$(LIBGCC_S):
	cp $(TOOLCHAIN)/lib/$(LIBGCC_S) $@
#	$(CC) $(CFLAGS) -o $@ -Wl,-soname=$(LIBGCC_S) $(LIBDIR)/$(LINKER) -lgcc_s -u __udivdi3 -u __floatdidf

# Install optimized C library
install: $(LIBC)
install: $(LIBGCC_S)

else

# Install default C library
install: $(LIBDIR)/$(LIBC)

endif

# Also install extra libraries
install: $(wildcard $(foreach lib,$(LINKER) $(lib-y),$(LIBDIR)/$(lib) $(LIBDIR)/$(lib).so.?))
	install -d $(TARGETDIR)/lib
	install $^ $(TARGETDIR)/lib/
	$(STRIP) $(TARGETDIR)/lib/*.so.*

clean:
	rm -f $(LIBC) $(MAP) .symbols
