From cd980b3bee5bd48e8a6cd4c0d7c8e0fb0fdb64dd Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 21 Apr 2015 15:42:05 -0700 Subject: [PATCH] mk: Add support for musl-based builds This commit adds support to the makefiles, configuration script, and build system to understand MUSL. This is broken up into a few parts: * Any target of the form `*-musl` requires the `--musl-root` option to `./configure` which will indicate the root of the MUSL installation. It is also expected that there is a libunwind build inside of that installation built against that MUSL. * Objects from MUSL are copied into the build tree for Rust to be statically linked into the appropriate Rust library. * Objects for binary startup and shutdown are included in each Rust installation by default for MUSL. This requires MUSL to only be installed on the machine compiling rust. Only a linker will be necessary for compiling against MUSL on a target machine. Eventually a MUSL and/or libunwind build may be integrated by default into the build but for now they are just always assumed to exist externally. --- configure | 8 ++++++++ mk/cfg/x86_64-unknown-linux-musl.mk | 27 +++++++++++++++++++++++++++ mk/crates.mk | 3 +++ mk/main.mk | 6 ++++-- mk/prepare.mk | 4 ++-- mk/rt.mk | 21 ++++++++++++++++++++- mk/target.mk | 13 ++++--------- 7 files changed, 68 insertions(+), 14 deletions(-) create mode 100644 mk/cfg/x86_64-unknown-linux-musl.mk diff --git a/configure b/configure index 6d629bf9807..71d608fbdaa 100755 --- a/configure +++ b/configure @@ -583,6 +583,7 @@ valopt jemalloc-root "" "set directory where libjemalloc_pic.a is located" valopt build "${DEFAULT_BUILD}" "GNUs ./configure syntax LLVM build triple" valopt android-cross-path "/opt/ndk_standalone" "Android NDK standalone path" valopt release-channel "dev" "the name of the release channel to build" +valopt musl-root "/usr/local" "MUSL root installation directory" # Many of these are saved below during the "writing configuration" step # (others are conditionally saved). @@ -1058,6 +1059,13 @@ do fi ;; + + *-musl) + if [ ! -f $CFG_MUSL_ROOT/lib/libc.a ] + then + err "musl libc $CFG_MUSL_ROOT/lib/libc.a not found" + fi + ;; *) ;; esac diff --git a/mk/cfg/x86_64-unknown-linux-musl.mk b/mk/cfg/x86_64-unknown-linux-musl.mk new file mode 100644 index 00000000000..b3dea6f97cb --- /dev/null +++ b/mk/cfg/x86_64-unknown-linux-musl.mk @@ -0,0 +1,27 @@ +# x86_64-unknown-linux-musl configuration +CC_x86_64-unknown-linux-musl=$(CFG_MUSL_ROOT)/bin/musl-gcc +CXX_x86_64-unknown-linux-musl=notaprogram +CPP_x86_64-unknown-linux-musl=$(CFG_MUSL_ROOT)/bin/musl-gcc -E +AR_x86_64-unknown-linux-musl=$(AR) +CFG_LIB_NAME_x86_64-unknown-linux-musl=lib$(1).so +CFG_STATIC_LIB_NAME_x86_64-unknown-linux-musl=lib$(1).a +CFG_LIB_GLOB_x86_64-unknown-linux-musl=lib$(1)-*.so +CFG_JEMALLOC_CFLAGS_x86_64-unknown-linux-musl := -m64 +CFG_GCCISH_CFLAGS_x86_64-unknown-linux-musl := -Wall -Werror -g -fPIC -m64 +CFG_GCCISH_CXXFLAGS_x86_64-unknown-linux-musl := +CFG_GCCISH_LINK_FLAGS_x86_64-unknown-linux-musl := +CFG_GCCISH_DEF_FLAG_x86_64-unknown-linux-musl := +CFG_LLC_FLAGS_x86_64-unknown-linux-musl := +CFG_INSTALL_NAME_x86_64-unknown-linux-musl = +CFG_EXE_SUFFIX_x86_64-unknown-linux-musl = +CFG_WINDOWSY_x86_64-unknown-linux-musl := +CFG_UNIXY_x86_64-unknown-linux-musl := 1 +CFG_LDPATH_x86_64-unknown-linux-musl := +CFG_RUN_x86_64-unknown-linux-musl=$(2) +CFG_RUN_TARG_x86_64-unknown-linux-musl=$(call CFG_RUN_x86_64-unknown-linux-musl,,$(2)) +CFG_GNU_TRIPLE_x86_64-unknown-linux-musl := x86_64-unknown-linux-musl + +NATIVE_DEPS_libc_T_x86_64-unknown-linux-musl += libc.a +NATIVE_DEPS_std_T_x86_64-unknown-linux-musl += libunwind.a \ + crt1.o crti.o crtn.o +INSTALLED_OBJECTS_x86_64-unknown-linux-musl += crt1.o crti.o crtn.o diff --git a/mk/crates.mk b/mk/crates.mk index e7c6a716f4c..367c25a8a6d 100644 --- a/mk/crates.mk +++ b/mk/crates.mk @@ -123,6 +123,9 @@ ONLY_RLIB_rustc_bitflags := 1 # Documented-by-default crates DOC_CRATES := std alloc collections core libc rustc_unicode +# Installed objects/libraries by default +INSTALLED_OBJECTS := libmorestack.a libcompiler-rt.a + ################################################################################ # You should not need to edit below this line ################################################################################ diff --git a/mk/main.mk b/mk/main.mk index c1ce1051d0a..9ac96aa90f6 100644 --- a/mk/main.mk +++ b/mk/main.mk @@ -399,8 +399,10 @@ endif # Prerequisites for using the stageN compiler to build target artifacts TSREQ$(1)_T_$(2)_H_$(3) = \ $$(HSREQ$(1)_H_$(3)) \ - $$(TLIB$(1)_T_$(2)_H_$(3))/libmorestack.a \ - $$(TLIB$(1)_T_$(2)_H_$(3))/libcompiler-rt.a + $$(foreach obj,$$(INSTALLED_OBJECTS),\ + $$(TLIB$(1)_T_$(2)_H_$(3))/$$(obj)) \ + $$(foreach obj,$$(INSTALLED_OBJECTS_$(2)),\ + $$(TLIB$(1)_T_$(2)_H_$(3))/$$(obj)) # Prerequisites for a working stageN compiler and libraries, for a specific # target diff --git a/mk/prepare.mk b/mk/prepare.mk index 4ded8a7916b..1382d160e13 100644 --- a/mk/prepare.mk +++ b/mk/prepare.mk @@ -140,8 +140,8 @@ prepare-target-$(2)-host-$(3)-$(1)-$(4): prepare-maybe-clean-$(4) \ $$(if $$(findstring $(2),$$(CFG_HOST)), \ $$(foreach crate,$$(HOST_CRATES), \ $$(call PREPARE_LIB,$$(call CFG_LIB_GLOB_$(2),$$(crate)))),) \ - $$(call PREPARE_LIB,libmorestack.a) \ - $$(call PREPARE_LIB,libcompiler-rt.a),),),) + $$(foreach object,$$(INSTALLED_OBJECTS) $$(INSTALLED_OBJECTS_$(2)),\ + $$(call PREPARE_LIB,$$(object))),),),) endef define INSTALL_GDB_DEBUGGER_SCRIPTS_COMMANDS diff --git a/mk/rt.mk b/mk/rt.mk index 70abce8b460..6ca14456441 100644 --- a/mk/rt.mk +++ b/mk/rt.mk @@ -74,7 +74,8 @@ $$(RT_OUTPUT_DIR_$(1))/%.o: $(S)src/rt/%.ll $$(MKFILE_DEPS) \ @mkdir -p $$(@D) @$$(call E, compile: $$@) $$(Q)$$(LLC_$$(CFG_BUILD)) $$(CFG_LLC_FLAGS_$(1)) \ - -filetype=obj -mtriple=$$(CFG_LLVM_TARGET_$(1)) -relocation-model=pic -o $$@ $$< + -filetype=obj -mtriple=$$(CFG_LLVM_TARGET_$(1)) \ + -relocation-model=pic -o $$@ $$< $$(RT_OUTPUT_DIR_$(1))/%.o: $(S)src/rt/%.c $$(MKFILE_DEPS) @mkdir -p $$(@D) @@ -110,6 +111,11 @@ $$(RT_OUTPUT_DIR_$(1))/$$(NATIVE_$(2)_$(1)): $$(OBJS_$(2)_$(1)) @$$(call E, link: $$@) $$(Q)$$(AR_$(1)) rcs $$@ $$^ +ifeq ($$(findstring windows,$(1)),windows) +$$(RT_OUTPUT_DIR_$(1))/lib$(2).a: $$(RT_OUTPUT_DIR_$(1))/$$(NATIVE_$(2)_$(1)) + $$(Q)cp $$< $$^ +endif + endef $(foreach target,$(CFG_TARGET), \ @@ -312,6 +318,19 @@ endif # endif for windowsy endif # endif for ios endif # endif for darwin +################################################################################ +# libc/libunwind for musl +# +# When we're building a musl-like target we're going to link libc/libunwind +# statically into the standard library and liblibc, so we need to make sure +# they're in a location that we can find +################################################################################ + +ifeq ($$(findstring musl,$(1)),musl) +$$(RT_OUTPUT_DIR_$(1))/%: $$(CFG_MUSL_ROOT)/lib/% + cp $$^ $$@ +endif + endef # Instantiate template for all stages/targets diff --git a/mk/target.mk b/mk/target.mk index 8cc74a9cbfb..319f44fd35b 100644 --- a/mk/target.mk +++ b/mk/target.mk @@ -35,7 +35,9 @@ CRATE_FULLDEPS_$(1)_T_$(2)_H_$(3)_$(4) := \ $$(foreach dep,$$(RUST_DEPS_$(4)), \ $$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$$(dep)) \ $$(foreach dep,$$(NATIVE_DEPS_$(4)), \ - $$(RT_OUTPUT_DIR_$(2))/$$(call CFG_STATIC_LIB_NAME_$(2),$$(dep))) + $$(RT_OUTPUT_DIR_$(2))/$$(call CFG_STATIC_LIB_NAME_$(2),$$(dep))) \ + $$(foreach dep,$$(NATIVE_DEPS_$(4)_T_$(2)), \ + $$(RT_OUTPUT_DIR_$(2))/$$(dep)) endef $(foreach host,$(CFG_HOST), \ @@ -143,14 +145,7 @@ $$(TBIN$(1)_T_$(2)_H_$(3))/: $$(TLIB$(1)_T_$(2)_H_$(3))/: mkdir -p $$@ -$$(TLIB$(1)_T_$(2)_H_$(3))/libcompiler-rt.a: \ - $$(RT_OUTPUT_DIR_$(2))/$$(call CFG_STATIC_LIB_NAME_$(2),compiler-rt) \ - | $$(TLIB$(1)_T_$(2)_H_$(3))/ $$(SNAPSHOT_RUSTC_POST_CLEANUP) - @$$(call E, cp: $$@) - $$(Q)cp $$< $$@ - -$$(TLIB$(1)_T_$(2)_H_$(3))/libmorestack.a: \ - $$(RT_OUTPUT_DIR_$(2))/$$(call CFG_STATIC_LIB_NAME_$(2),morestack) \ +$$(TLIB$(1)_T_$(2)_H_$(3))/%: $$(RT_OUTPUT_DIR_$(2))/% \ | $$(TLIB$(1)_T_$(2)_H_$(3))/ $$(SNAPSHOT_RUSTC_POST_CLEANUP) @$$(call E, cp: $$@) $$(Q)cp $$< $$@