Skip to content

Commit

Permalink
support out-of-tree build
Browse files Browse the repository at this point in the history
this change adds support for building musl outside of the source
tree. the implementation is similar to autotools where running
configure in a different directory creates config.mak in the current
working directory and symlinks the makefile, which contains the
logic for creating all necessary directories and resolving paths
relative to the source directory.

to support both in-tree and out-of-tree builds with implicit make
rules, all object files are now placed into a separate directory.
  • Loading branch information
petrhosek authored and richfelker committed Jan 17, 2016
1 parent d5f8394 commit 2f853dd
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 60 deletions.
5 changes: 1 addition & 4 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@
*.so.1
arch/*/bits/alltypes.h
config.mak
include/bits
tools/musl-gcc
tools/musl-clang
tools/ld.musl-clang
lib/musl-gcc.specs
src/internal/version.h
/obj/
126 changes: 75 additions & 51 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
# Do not make changes here.
#

srcdir = .
exec_prefix = /usr/local
bindir = $(exec_prefix)/bin

Expand All @@ -16,12 +17,16 @@ includedir = $(prefix)/include
libdir = $(prefix)/lib
syslibdir = /lib

SRCS = $(sort $(wildcard src/*/*.c arch/$(ARCH)/src/*.c))
OBJS = $(SRCS:.c=.o)
BASE_SRCS = $(sort $(wildcard $(srcdir)/src/*/*.c $(srcdir)/arch/$(ARCH)/src/*.c))
BASE_OBJS = $(patsubst $(srcdir)/%.c,%.o,$(BASE_SRCS))
ARCH_SRCS = $(wildcard $(srcdir)/src/*/$(ARCH)/*.s $(srcdir)/src/*/$(ARCH)$(ASMSUBARCH)/*.sub)
ARCH_OBJS = $(patsubst $(srcdir)/%.sub,%.o,$(patsubst $(srcdir)/%.s,%.o,$(ARCH_SRCS)))
REPLACED_OBJS = $(sort $(subst /$(ARCH)$(ASMSUBARCH)/,/,$(subst /$(ARCH)/,/,$(ARCH_OBJS))) $(subst /$(ARCH)$(ASMSUBARCH)/,/$(ARCH)/,$(subst /$(ARCH)/,/,$(ARCH_OBJS))))
OBJS = $(addprefix obj/, $(filter-out $(REPLACED_OBJS), $(sort $(BASE_OBJS) $(ARCH_OBJS))))
LOBJS = $(OBJS:.o=.lo)
GENH = include/bits/alltypes.h
GENH_INT = src/internal/version.h
IMPH = src/internal/stdio_impl.h src/internal/pthread_impl.h src/internal/libc.h
GENH = obj/include/bits/alltypes.h
GENH_INT = obj/src/internal/version.h
IMPH = $(addprefix $(srcdir)/, src/internal/stdio_impl.h src/internal/pthread_impl.h src/internal/libc.h)

LDFLAGS =
LDFLAGS_AUTO =
Expand All @@ -32,7 +37,7 @@ CFLAGS_AUTO = -Os -pipe
CFLAGS_C99FSE = -std=c99 -ffreestanding -nostdinc

CFLAGS_ALL = $(CFLAGS_C99FSE)
CFLAGS_ALL += -D_XOPEN_SOURCE=700 -I./arch/$(ARCH) -I./src/internal -I./include
CFLAGS_ALL += -D_XOPEN_SOURCE=700 -I$(srcdir)/arch/$(ARCH) -Iobj/src/internal -I$(srcdir)/src/internal -Iobj/include -I$(srcdir)/include
CFLAGS_ALL += $(CPPFLAGS) $(CFLAGS_AUTO) $(CFLAGS)
CFLAGS_ALL_STATIC = $(CFLAGS_ALL)
CFLAGS_ALL_SHARED = $(CFLAGS_ALL) -fPIC -DSHARED
Expand All @@ -41,10 +46,11 @@ LDFLAGS_ALL = $(LDFLAGS_AUTO) $(LDFLAGS)

AR = $(CROSS_COMPILE)ar
RANLIB = $(CROSS_COMPILE)ranlib
INSTALL = ./tools/install.sh
INSTALL = $(srcdir)/tools/install.sh

ARCH_INCLUDES = $(wildcard arch/$(ARCH)/bits/*.h)
ALL_INCLUDES = $(sort $(wildcard include/*.h include/*/*.h) $(GENH) $(ARCH_INCLUDES:arch/$(ARCH)/%=include/%))
ARCH_INCLUDES = $(wildcard $(srcdir)/arch/$(ARCH)/bits/*.h)
INCLUDES = $(wildcard $(srcdir)/include/*.h $(srcdir)/include/*/*.h)
ALL_INCLUDES = $(sort $(INCLUDES:$(srcdir)/%=%) $(GENH:obj/%=%) $(ARCH_INCLUDES:$(srcdir)/arch/$(ARCH)/%=include/%))

EMPTY_LIB_NAMES = m rt pthread crypt util xnet resolv dl
EMPTY_LIBS = $(EMPTY_LIB_NAMES:%=lib/lib%.a)
Expand All @@ -53,7 +59,7 @@ STATIC_LIBS = lib/libc.a
SHARED_LIBS = lib/libc.so
TOOL_LIBS = lib/musl-gcc.specs
ALL_LIBS = $(CRT_LIBS) $(STATIC_LIBS) $(SHARED_LIBS) $(EMPTY_LIBS) $(TOOL_LIBS)
ALL_TOOLS = tools/musl-gcc
ALL_TOOLS = obj/musl-gcc

WRAPCC_GCC = gcc
WRAPCC_CLANG = clang
Expand All @@ -62,91 +68,100 @@ LDSO_PATHNAME = $(syslibdir)/ld-musl-$(ARCH)$(SUBARCH).so.1

-include config.mak

ifeq ($(ARCH),)
$(error Please set ARCH in config.mak before running make.)
endif

all: $(ALL_LIBS) $(ALL_TOOLS)

OBJ_DIRS = $(sort $(patsubst %/,%,$(dir $(ALL_LIBS) $(ALL_TOOLS) $(OBJS) $(GENH) $(GENH_INT))) $(addprefix obj/, crt crt/$(ARCH) include))

$(ALL_LIBS) $(ALL_TOOLS) $(CRT_LIBS:lib/%=obj/crt/%) $(OBJS) $(LOBJS) $(GENH) $(GENH_INT): | $(OBJ_DIRS)

$(OBJ_DIRS):
mkdir -p $@

install: install-libs install-headers install-tools

clean:
rm -f crt/*.o
rm -f obj/crt/*.o obj/crt/$(ARCH)/*.o
rm -f $(OBJS)
rm -f $(LOBJS)
rm -f $(ALL_LIBS) lib/*.[ao] lib/*.so
rm -f $(ALL_TOOLS)
rm -f $(GENH) $(GENH_INT)
rm -f include/bits
rm -f obj/include/bits/alltypes.h

distclean: clean
rm -f config.mak

include/bits:
@test "$(ARCH)" || { echo "Please set ARCH in config.mak before running make." ; exit 1 ; }
ln -sf ../arch/$(ARCH)/bits $@
obj/include/bits/alltypes.h: $(srcdir)/arch/$(ARCH)/bits/alltypes.h.in $(srcdir)/include/alltypes.h.in $(srcdir)/tools/mkalltypes.sed
sed -f $(srcdir)/tools/mkalltypes.sed $(srcdir)/arch/$(ARCH)/bits/alltypes.h.in $(srcdir)/include/alltypes.h.in > $@

include/bits/alltypes.h.in: include/bits
obj/src/internal/version.h: $(wildcard $(srcdir)/VERSION $(srcdir)/.git)
printf '#define VERSION "%s"\n' "$$(cd $(srcdir); sh tools/version.sh)" > $@

include/bits/alltypes.h: include/bits/alltypes.h.in include/alltypes.h.in tools/mkalltypes.sed
sed -f tools/mkalltypes.sed include/bits/alltypes.h.in include/alltypes.h.in > $@
obj/src/internal/version.o obj/src/internal/version.lo: obj/src/internal/version.h

src/internal/version.h: $(wildcard VERSION .git)
printf '#define VERSION "%s"\n' "$$(sh tools/version.sh)" > $@
obj/crt/rcrt1.o obj/src/ldso/dlstart.lo obj/src/ldso/dynlink.lo: $(srcdir)/src/internal/dynlink.h $(srcdir)/arch/$(ARCH)/reloc.h

src/internal/version.o src/internal/version.lo: src/internal/version.h
obj/crt/crt1.o obj/crt/scrt1.o obj/crt/rcrt1.o obj/src/ldso/dlstart.lo: $(srcdir)/arch/$(ARCH)/crt_arch.h

crt/rcrt1.o src/ldso/dlstart.lo src/ldso/dynlink.lo: src/internal/dynlink.h arch/$(ARCH)/reloc.h
obj/crt/rcrt1.o: $(srcdir)/src/ldso/dlstart.c

crt/crt1.o crt/Scrt1.o crt/rcrt1.o src/ldso/dlstart.lo: $(wildcard arch/$(ARCH)/crt_arch.h)
obj/crt/Scrt1.o obj/crt/rcrt1.o: CFLAGS_ALL += -fPIC

crt/rcrt1.o: src/ldso/dlstart.c
obj/crt/$(ARCH)/crti.o: $(srcdir)/crt/$(ARCH)/crti.s

crt/Scrt1.o crt/rcrt1.o: CFLAGS_ALL += -fPIC
obj/crt/$(ARCH)/crtn.o: $(srcdir)/crt/$(ARCH)/crtn.s

OPTIMIZE_SRCS = $(wildcard $(OPTIMIZE_GLOBS:%=src/%))
$(OPTIMIZE_SRCS:%.c=%.o) $(OPTIMIZE_SRCS:%.c=%.lo): CFLAGS += -O3
OPTIMIZE_SRCS = $(wildcard $(OPTIMIZE_GLOBS:%=$(srcdir)/src/%))
$(OPTIMIZE_SRCS:$(srcdir)/%.c=obj/%.o) $(OPTIMIZE_SRCS:$(srcdir)/%.c=obj/%.lo): CFLAGS += -O3

MEMOPS_SRCS = src/string/memcpy.c src/string/memmove.c src/string/memcmp.c src/string/memset.c
$(MEMOPS_SRCS:%.c=%.o) $(MEMOPS_SRCS:%.c=%.lo): CFLAGS_ALL += $(CFLAGS_MEMOPS)
$(MEMOPS_SRCS:%.c=obj/%.o) $(MEMOPS_SRCS:%.c=obj/%.lo): CFLAGS_ALL += $(CFLAGS_MEMOPS)

NOSSP_SRCS = $(wildcard crt/*.c) \
src/env/__libc_start_main.c src/env/__init_tls.c \
src/thread/__set_thread_area.c src/env/__stack_chk_fail.c \
src/string/memset.c src/string/memcpy.c \
src/ldso/dlstart.c src/ldso/dynlink.c
$(NOSSP_SRCS:%.c=%.o) $(NOSSP_SRCS:%.c=%.lo): CFLAGS_ALL += $(CFLAGS_NOSSP)
$(NOSSP_SRCS:%.c=obj/%.o) $(NOSSP_SRCS:%.c=obj/%.lo): CFLAGS_ALL += $(CFLAGS_NOSSP)

$(CRT_LIBS:lib/%=crt/%): CFLAGS_ALL += -DCRT
$(CRT_LIBS:lib/%=obj/crt/%): CFLAGS_ALL += -DCRT

# This incantation ensures that changes to any subarch asm files will
# force the corresponding object file to be rebuilt, even if the implicit
# rule below goes indirectly through a .sub file.
define mkasmdep
$(dir $(patsubst %/,%,$(dir $(1))))$(notdir $(1:.s=.o)): $(1)
$(patsubst $(srcdir)/%,obj/%,$(dir $(patsubst %/,%,$(dir $(1))))$(ARCH)$(ASMSUBARCH)/$(notdir $(1:.s=.o))): $(1)
endef
$(foreach s,$(wildcard src/*/$(ARCH)*/*.s),$(eval $(call mkasmdep,$(s))))
$(foreach s,$(wildcard $(srcdir)/src/*/$(ARCH)*/*.s),$(eval $(call mkasmdep,$(s))))

# Choose invocation of assembler to be used
# $(1) is input file, $(2) is output file, $(3) is assembler flags
ifeq ($(ADD_CFI),yes)
AS_CMD = LC_ALL=C awk -f tools/add-cfi.common.awk -f tools/add-cfi.$(ARCH).awk $< | $(CC) -x assembler -c -o $@ -
AS_CMD = LC_ALL=C awk -f $(srcdir)/tools/add-cfi.common.awk -f $(srcdir)/tools/add-cfi.$(ARCH).awk $< | $(CC) -x assembler -c -o $@ -
else
AS_CMD = $(CC) -c -o $@ $<
endif

%.o: $(ARCH)$(ASMSUBARCH)/%.sub
$(CC) $(CFLAGS_ALL_STATIC) -c -o $@ $(dir $<)$(shell cat $<)
obj/%.o: $(srcdir)/%.sub
$(CC) $(CFLAGS_ALL_STATIC) -c -o $@ $(dir $<)$$(cat $<)

%.o: $(ARCH)/%.s
obj/%.o: $(srcdir)/%.s
$(AS_CMD) $(CFLAGS_ALL_STATIC)

%.o: %.c $(GENH) $(IMPH)
obj/%.o: $(srcdir)/%.c $(GENH) $(IMPH)
$(CC) $(CFLAGS_ALL_STATIC) -c -o $@ $<

%.lo: $(ARCH)$(ASMSUBARCH)/%.sub
$(CC) $(CFLAGS_ALL_SHARED) -c -o $@ $(dir $<)$(shell cat $<)
obj/%.lo: $(srcdir)/%.sub
$(CC) $(CFLAGS_ALL_SHARED) -c -o $@ $(dir $<)$$(cat $<)

%.lo: $(ARCH)/%.s
obj/%.lo: $(srcdir)/%.s
$(AS_CMD) $(CFLAGS_ALL_SHARED)

%.lo: %.c $(GENH) $(IMPH)
obj/%.lo: $(srcdir)/%.c $(GENH) $(IMPH)
$(CC) $(CFLAGS_ALL_SHARED) -c -o $@ $<

lib/libc.so: $(LOBJS)
Expand All @@ -163,21 +178,27 @@ $(EMPTY_LIBS):
rm -f $@
$(AR) rc $@

lib/%.o: crt/%.o
lib/%.o: obj/crt/%.o
cp $< $@

lib/musl-gcc.specs: tools/musl-gcc.specs.sh config.mak
lib/crti.o: obj/crt/$(ARCH)/crti.o
cp $< $@

lib/crtn.o: obj/crt/$(ARCH)/crtn.o
cp $< $@

lib/musl-gcc.specs: $(srcdir)/tools/musl-gcc.specs.sh config.mak
sh $< "$(includedir)" "$(libdir)" "$(LDSO_PATHNAME)" > $@

tools/musl-gcc: config.mak
obj/musl-gcc: config.mak
printf '#!/bin/sh\nexec "$${REALGCC:-$(WRAPCC_GCC)}" "$$@" -specs "%s/musl-gcc.specs"\n' "$(libdir)" > $@
chmod +x $@

tools/%-clang: tools/%-clang.in config.mak
obj/%-clang: $(srcdir)/tools/%-clang.in config.mak
sed -e 's!@CC@!$(WRAPCC_CLANG)!g' -e 's!@PREFIX@!$(prefix)!g' -e 's!@INCDIR@!$(includedir)!g' -e 's!@LIBDIR@!$(libdir)!g' -e 's!@LDSO@!$(LDSO_PATHNAME)!g' $< > $@
chmod +x $@

$(DESTDIR)$(bindir)/%: tools/%
$(DESTDIR)$(bindir)/%: obj/%
$(INSTALL) -D $< $@

$(DESTDIR)$(libdir)/%.so: lib/%.so
Expand All @@ -186,10 +207,13 @@ $(DESTDIR)$(libdir)/%.so: lib/%.so
$(DESTDIR)$(libdir)/%: lib/%
$(INSTALL) -D -m 644 $< $@

$(DESTDIR)$(includedir)/bits/%: arch/$(ARCH)/bits/%
$(DESTDIR)$(includedir)/bits/%: $(srcdir)/arch/$(ARCH)/bits/%
$(INSTALL) -D -m 644 $< $@

$(DESTDIR)$(includedir)/bits/%: obj/include/bits/%
$(INSTALL) -D -m 644 $< $@

$(DESTDIR)$(includedir)/%: include/%
$(DESTDIR)$(includedir)/%: $(srcdir)/include/%
$(INSTALL) -D -m 644 $< $@

$(DESTDIR)$(LDSO_PATHNAME): $(DESTDIR)$(libdir)/libc.so
Expand All @@ -199,12 +223,12 @@ install-libs: $(ALL_LIBS:lib/%=$(DESTDIR)$(libdir)/%) $(if $(SHARED_LIBS),$(DEST

install-headers: $(ALL_INCLUDES:include/%=$(DESTDIR)$(includedir)/%)

install-tools: $(ALL_TOOLS:tools/%=$(DESTDIR)$(bindir)/%)
install-tools: $(ALL_TOOLS:obj/%=$(DESTDIR)$(bindir)/%)

musl-git-%.tar.gz: .git
git archive --format=tar.gz --prefix=$(patsubst %.tar.gz,%,$@)/ -o $@ $(patsubst musl-git-%.tar.gz,%,$@)
git --git-dir=$(srcdir)/.git archive --format=tar.gz --prefix=$(patsubst %.tar.gz,%,$@)/ -o $@ $(patsubst musl-git-%.tar.gz,%,$@)

musl-%.tar.gz: .git
git archive --format=tar.gz --prefix=$(patsubst %.tar.gz,%,$@)/ -o $@ v$(patsubst musl-%.tar.gz,%,$@)
git --git-dir=$(srcdir)/.git archive --format=tar.gz --prefix=$(patsubst %.tar.gz,%,$@)/ -o $@ v$(patsubst musl-%.tar.gz,%,$@)

.PHONY: all clean install install-libs install-headers install-tools
30 changes: 25 additions & 5 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ VAR=VALUE. See below for descriptions of some of the useful variables.
Defaults for the options are specified in brackets.
Configuration:
--srcdir=DIR source directory [detected]
Installation directories:
--prefix=PREFIX main installation prefix [/usr/local/musl]
--exec-prefix=EPREFIX installation prefix for executable files [PREFIX]
Expand Down Expand Up @@ -117,6 +120,7 @@ CFLAGS_TRY=
LDFLAGS_AUTO=
LDFLAGS_TRY=
OPTIMIZE_GLOBS=
srcdir=
prefix=/usr/local/musl
exec_prefix='$(prefix)'
bindir='$(exec_prefix)/bin'
Expand All @@ -139,6 +143,7 @@ clang_wrapper=no
for arg ; do
case "$arg" in
--help) usage ;;
--srcdir=*) srcdir=${arg#*=} ;;
--prefix=*) prefix=${arg#*=} ;;
--exec-prefix=*) exec_prefix=${arg#*=} ;;
--bindir=*) bindir=${arg#*=} ;;
Expand Down Expand Up @@ -179,10 +184,22 @@ LIBCC=*) LIBCC=${arg#*=} ;;
esac
done

for i in prefix exec_prefix bindir libdir includedir syslibdir ; do
for i in srcdir prefix exec_prefix bindir libdir includedir syslibdir ; do
stripdir $i
done

#
# Get the source dir for out-of-tree builds
#
if test -z "$srcdir" ; then
srcdir="${0%/configure}"
stripdir srcdir
fi
abs_builddir="$(pwd)" || fail "$0: cannot determine working directory"
abs_srcdir="$(cd $srcdir && pwd)" || fail "$0: invalid source directory $srcdir"
test "$abs_srcdir" = "$abs_builddir" && srcdir=.
test "$srcdir" != "." -a -f Makefile -a ! -h Makefile && fail "$0: Makefile already exists in the working directory"

#
# Get a temp filename we can use
#
Expand Down Expand Up @@ -263,11 +280,11 @@ fi
fi

if test "$gcc_wrapper" = yes ; then
tools="$tools tools/musl-gcc"
tools="$tools obj/musl-gcc"
tool_libs="$tool_libs lib/musl-gcc.specs"
fi
if test "$clang_wrapper" = yes ; then
tools="$tools tools/musl-clang tools/ld.musl-clang"
tools="$tools obj/musl-clang obj/ld.musl-clang"
fi

#
Expand Down Expand Up @@ -321,7 +338,7 @@ __attribute__((__may_alias__))
#endif
x;
EOF
if $CC $CFLAGS_C99FSE -I./arch/$ARCH -I./include $CPPFLAGS $CFLAGS \
if $CC $CFLAGS_C99FSE -I$srcdir/arch/$ARCH -I$srcdir/include $CPPFLAGS $CFLAGS \
-c -o /dev/null "$tmpc" >/dev/null 2>&1 ; then
printf "no\n"
else
Expand Down Expand Up @@ -625,7 +642,7 @@ echo '#include <float.h>' > "$tmpc"
echo '#if LDBL_MANT_DIG == 53' >> "$tmpc"
echo 'typedef char ldcheck[9-(int)sizeof(long double)];' >> "$tmpc"
echo '#endif' >> "$tmpc"
if $CC $CFLAGS_C99FSE -I./arch/$ARCH -I./include $CPPFLAGS $CFLAGS \
if $CC $CFLAGS_C99FSE -I$srcdir/arch/$ARCH -I$srcdir/include $CPPFLAGS $CFLAGS \
-c -o /dev/null "$tmpc" >/dev/null 2>&1 ; then
printf "yes\n"
else
Expand All @@ -648,6 +665,7 @@ cat << EOF
ARCH = $ARCH
SUBARCH = $SUBARCH
ASMSUBARCH = $ASMSUBARCH
srcdir = $srcdir
prefix = $prefix
exec_prefix = $exec_prefix
bindir = $bindir
Expand Down Expand Up @@ -676,4 +694,6 @@ test "x$cc_family" = xgcc && echo 'WRAPCC_GCC = $(CC)'
test "x$cc_family" = xclang && echo 'WRAPCC_CLANG = $(CC)'
exec 1>&3 3>&-

test "$srcdir" = "." || ln -sf $srcdir/Makefile .

printf "done\n"

0 comments on commit 2f853dd

Please sign in to comment.