mk: Stop using cmake for compiler-rt
The compiler-rt build system has been a never ending cause of pain for Rust unfortunately: * The build system is very difficult to invoke and configure to only build compiler-rt, especially across platforms. * The standard build system doesn't actually do what we want, not working for some of our platforms and requiring a significant number of patches on our end which are difficult to apply when updating compiler-rt. * Compiling compiler-rt requires LLVM to be compiled, which... is a big dependency! This also means that over time compiler-rt is not guaranteed to build against older versions of LLVM (or newer versions), and we often want to work with multiple versions of LLVM simultaneously. The makefiles and rustbuild already know how to compile C code, the code here is far from the *only* C code we're compiling. This patch jettisons all logic to work with compiler-rt's build system and just goes straight to the source. We just list all files manually (copied from compiler-rt's lib/builtins/CMakeLists.txt) and compile them into an archive. It's likely that this means we'll fail to pick up new files when we upgrade compiler-rt, but that seems like a much less significant cost to pay than what we're currently paying. cc #34400, first steps towards that
This commit is contained in:
parent
b45c15ecca
commit
ee6011fc71
476
mk/rt.mk
476
mk/rt.mk
@ -223,147 +223,373 @@ endif
|
||||
# compiler-rt
|
||||
################################################################################
|
||||
|
||||
ifdef CFG_ENABLE_FAST_MAKE
|
||||
COMPRT_DEPS := $(S)/.gitmodules
|
||||
else
|
||||
COMPRT_DEPS := $(wildcard \
|
||||
$(S)src/compiler-rt/* \
|
||||
$(S)src/compiler-rt/*/* \
|
||||
$(S)src/compiler-rt/*/*/* \
|
||||
$(S)src/compiler-rt/*/*/*/*)
|
||||
endif
|
||||
|
||||
# compiler-rt's build system is a godawful mess. Here we figure out
|
||||
# the ridiculous platform-specific values and paths necessary to get
|
||||
# useful artifacts out of it.
|
||||
# Everything below is a manual compilation of compiler-rt, disregarding its
|
||||
# build system. See comments in `src/bootstrap/native.rs` for more information.
|
||||
|
||||
COMPRT_NAME_$(1) := $$(call CFG_STATIC_LIB_NAME_$(1),compiler-rt)
|
||||
COMPRT_LIB_$(1) := $$(RT_OUTPUT_DIR_$(1))/$$(COMPRT_NAME_$(1))
|
||||
COMPRT_BUILD_DIR_$(1) := $$(RT_OUTPUT_DIR_$(1))/compiler-rt
|
||||
|
||||
COMPRT_ARCH_$(1) := $$(word 1,$$(subst -, ,$(1)))
|
||||
|
||||
# All this is to figure out the path to the compiler-rt bin
|
||||
ifeq ($$(findstring windows-msvc,$(1)),windows-msvc)
|
||||
COMPRT_DIR_$(1) := windows/Release
|
||||
COMPRT_LIB_NAME_$(1) := clang_rt.builtins-$$(patsubst i%86,i386,$$(COMPRT_ARCH_$(1)))
|
||||
endif
|
||||
|
||||
ifeq ($$(findstring windows-gnu,$(1)),windows-gnu)
|
||||
COMPRT_DIR_$(1) := windows
|
||||
COMPRT_LIB_NAME_$(1) := clang_rt.builtins-$$(COMPRT_ARCH_$(1))
|
||||
endif
|
||||
|
||||
ifeq ($$(findstring darwin,$(1)),darwin)
|
||||
COMPRT_DIR_$(1) := builtins
|
||||
COMPRT_LIB_NAME_$(1) := clang_rt.builtins_$$(patsubst i686,i386,$$(COMPRT_ARCH_$(1)))_osx
|
||||
endif
|
||||
|
||||
ifeq ($$(findstring ios,$(1)),ios)
|
||||
COMPRT_DIR_$(1) := builtins
|
||||
COMPRT_ARCH_$(1) := $$(patsubst armv7s,armv7em,$$(COMPRT_ARCH_$(1)))
|
||||
COMPRT_LIB_NAME_$(1) := clang_rt.hard_pic_$$(COMPRT_ARCH_$(1))_macho_embedded
|
||||
ifeq ($$(COMPRT_ARCH_$(1)),aarch64)
|
||||
COMPRT_LIB_NAME_$(1) := clang_rt.builtins_arm64_ios
|
||||
endif
|
||||
COMPRT_DEFINES_$(1) := -DCOMPILER_RT_ENABLE_IOS=ON
|
||||
endif
|
||||
|
||||
ifndef COMPRT_DIR_$(1)
|
||||
# NB: FreeBSD and NetBSD output to "linux"...
|
||||
COMPRT_DIR_$(1) := linux
|
||||
COMPRT_ARCH_$(1) := $$(patsubst i586,i386,$$(COMPRT_ARCH_$(1)))
|
||||
|
||||
ifeq ($$(findstring android,$(1)),android)
|
||||
ifeq ($$(findstring arm,$$(COMPRT_ARCH_$(1))),arm)
|
||||
COMPRT_ARCH_$(1) := armhf
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($$(findstring eabihf,$(1)),eabihf)
|
||||
ifeq ($$(findstring armv7,$(1)),)
|
||||
COMPRT_LIB_NAME_$(1) := clang_rt.builtins-armhf
|
||||
endif
|
||||
endif
|
||||
|
||||
ifndef COMPRT_LIB_NAME_$(1)
|
||||
COMPRT_LIB_NAME_$(1) := clang_rt.builtins-$$(COMPRT_ARCH_$(1))
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
ifeq ($$(findstring windows-gnu,$(1)),windows-gnu)
|
||||
COMPRT_LIB_FILE_$(1) := lib$$(COMPRT_LIB_NAME_$(1)).a
|
||||
endif
|
||||
|
||||
ifeq ($$(findstring android,$(1)),android)
|
||||
ifeq ($$(findstring arm,$(1)),arm)
|
||||
COMPRT_LIB_FILE_$(1) := $$(call CFG_STATIC_LIB_NAME_$(1),$$(COMPRT_LIB_NAME_$(1))-android)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifndef COMPRT_LIB_FILE_$(1)
|
||||
COMPRT_LIB_FILE_$(1) := $$(call CFG_STATIC_LIB_NAME_$(1),$$(COMPRT_LIB_NAME_$(1)))
|
||||
endif
|
||||
|
||||
COMPRT_OUTPUT_$(1) := $$(COMPRT_BUILD_DIR_$(1))/lib/$$(COMPRT_DIR_$(1))/$$(COMPRT_LIB_FILE_$(1))
|
||||
|
||||
ifeq ($$(findstring windows-msvc,$(1)),windows-msvc)
|
||||
COMPRT_BUILD_ARGS_$(1) := //v:m //nologo
|
||||
COMPRT_BUILD_TARGET_$(1) := lib/builtins/builtins
|
||||
COMPRT_BUILD_CC_$(1) :=
|
||||
else
|
||||
COMPRT_BUILD_ARGS_$(1) :=
|
||||
ifndef COMPRT_BUILD_TARGET_$(1)
|
||||
COMPRT_BUILD_TARGET_$(1) := $$(COMPRT_LIB_NAME_$(1))
|
||||
endif
|
||||
COMPRT_BUILD_CC_$(1) := -DCMAKE_C_COMPILER=$$(call FIND_COMPILER,$$(CC_$(1))) \
|
||||
-DCMAKE_CXX_COMPILER=$$(call FIND_COMPILER,$$(CXX_$(1)))
|
||||
# GENERIC_SOURCES in CMakeLists.txt
|
||||
COMPRT_OBJS_$(1) := \
|
||||
absvdi2.o \
|
||||
absvsi2.o \
|
||||
adddf3.o \
|
||||
addsf3.o \
|
||||
addvdi3.o \
|
||||
addvsi3.o \
|
||||
apple_versioning.o \
|
||||
ashldi3.o \
|
||||
ashrdi3.o \
|
||||
clear_cache.o \
|
||||
clzdi2.o \
|
||||
clzsi2.o \
|
||||
cmpdi2.o \
|
||||
comparedf2.o \
|
||||
comparesf2.o \
|
||||
ctzdi2.o \
|
||||
ctzsi2.o \
|
||||
divdc3.o \
|
||||
divdf3.o \
|
||||
divdi3.o \
|
||||
divmoddi4.o \
|
||||
divmodsi4.o \
|
||||
divsc3.o \
|
||||
divsf3.o \
|
||||
divsi3.o \
|
||||
divxc3.o \
|
||||
extendsfdf2.o \
|
||||
extendhfsf2.o \
|
||||
ffsdi2.o \
|
||||
fixdfdi.o \
|
||||
fixdfsi.o \
|
||||
fixsfdi.o \
|
||||
fixsfsi.o \
|
||||
fixunsdfdi.o \
|
||||
fixunsdfsi.o \
|
||||
fixunssfdi.o \
|
||||
fixunssfsi.o \
|
||||
fixunsxfdi.o \
|
||||
fixunsxfsi.o \
|
||||
fixxfdi.o \
|
||||
floatdidf.o \
|
||||
floatdisf.o \
|
||||
floatdixf.o \
|
||||
floatsidf.o \
|
||||
floatsisf.o \
|
||||
floatundidf.o \
|
||||
floatundisf.o \
|
||||
floatundixf.o \
|
||||
floatunsidf.o \
|
||||
floatunsisf.o \
|
||||
int_util.o \
|
||||
lshrdi3.o \
|
||||
moddi3.o \
|
||||
modsi3.o \
|
||||
muldc3.o \
|
||||
muldf3.o \
|
||||
muldi3.o \
|
||||
mulodi4.o \
|
||||
mulosi4.o \
|
||||
muloti4.o \
|
||||
mulsc3.o \
|
||||
mulsf3.o \
|
||||
mulvdi3.o \
|
||||
mulvsi3.o \
|
||||
mulxc3.o \
|
||||
negdf2.o \
|
||||
negdi2.o \
|
||||
negsf2.o \
|
||||
negvdi2.o \
|
||||
negvsi2.o \
|
||||
paritydi2.o \
|
||||
paritysi2.o \
|
||||
popcountdi2.o \
|
||||
popcountsi2.o \
|
||||
powidf2.o \
|
||||
powisf2.o \
|
||||
powixf2.o \
|
||||
subdf3.o \
|
||||
subsf3.o \
|
||||
subvdi3.o \
|
||||
subvsi3.o \
|
||||
truncdfhf2.o \
|
||||
truncdfsf2.o \
|
||||
truncsfhf2.o \
|
||||
ucmpdi2.o \
|
||||
udivdi3.o \
|
||||
udivmoddi4.o \
|
||||
udivmodsi4.o \
|
||||
udivsi3.o \
|
||||
umoddi3.o \
|
||||
umodsi3.o
|
||||
|
||||
ifeq ($$(findstring ios,$(1)),)
|
||||
COMPRT_BUILD_CC_$(1) := $$(COMPRT_BUILD_CC_$(1)) \
|
||||
-DCMAKE_C_FLAGS="$$(CFG_GCCISH_CFLAGS_$(1)) -Wno-error"
|
||||
COMPRT_OBJS_$(1) += \
|
||||
absvti2.o \
|
||||
addtf3.o \
|
||||
addvti3.o \
|
||||
ashlti3.o \
|
||||
ashrti3.o \
|
||||
clzti2.o \
|
||||
cmpti2.o \
|
||||
ctzti2.o \
|
||||
divtf3.o \
|
||||
divti3.o \
|
||||
ffsti2.o \
|
||||
fixdfti.o \
|
||||
fixsfti.o \
|
||||
fixunsdfti.o \
|
||||
fixunssfti.o \
|
||||
fixunsxfti.o \
|
||||
fixxfti.o \
|
||||
floattidf.o \
|
||||
floattisf.o \
|
||||
floattixf.o \
|
||||
floatuntidf.o \
|
||||
floatuntisf.o \
|
||||
floatuntixf.o \
|
||||
lshrti3.o \
|
||||
modti3.o \
|
||||
multf3.o \
|
||||
multi3.o \
|
||||
mulvti3.o \
|
||||
negti2.o \
|
||||
negvti2.o \
|
||||
parityti2.o \
|
||||
popcountti2.o \
|
||||
powitf2.o \
|
||||
subtf3.o \
|
||||
subvti3.o \
|
||||
trampoline_setup.o \
|
||||
ucmpti2.o \
|
||||
udivmodti4.o \
|
||||
udivti3.o \
|
||||
umodti3.o
|
||||
endif
|
||||
|
||||
ifeq ($$(findstring apple,$(1)),apple)
|
||||
COMPRT_OBJS_$(1) += \
|
||||
atomic_flag_clear.o \
|
||||
atomic_flag_clear_explicit.o \
|
||||
atomic_flag_test_and_set.o \
|
||||
atomic_flag_test_and_set_explicit.o \
|
||||
atomic_signal_fence.o \
|
||||
atomic_thread_fence.o
|
||||
endif
|
||||
|
||||
|
||||
ifeq ($$(findstring windows,$(1)),)
|
||||
COMPRT_OBJS_$(1) += emutls.o
|
||||
endif
|
||||
|
||||
ifeq ($$(findstring msvc,$(1)),)
|
||||
COMPRT_OBJS_$(1) += gcc_personality_v0.o
|
||||
COMPRT_OBJS_$(1) += emutls.o
|
||||
|
||||
ifeq ($$(findstring x86_64,$(1)),x86_64)
|
||||
COMPRT_OBJS_$(1) += \
|
||||
x86_64/chkstk.o \
|
||||
x86_64/chkstk2.o \
|
||||
x86_64/floatdidf.o \
|
||||
x86_64/floatdisf.o \
|
||||
x86_64/floatdixf.o \
|
||||
x86_64/floatundidf.o \
|
||||
x86_64/floatundisf.o \
|
||||
x86_64/floatundixf.o
|
||||
endif
|
||||
|
||||
ifeq ($$(findstring i686,$$(patsubts i%86,i686,$(1))),i686)
|
||||
COMPRT_OBJS_$(1) += \
|
||||
i386/ashldi3.o \
|
||||
i386/ashrdi3.o \
|
||||
i386/chkstk.o \
|
||||
i386/chkstk2.o \
|
||||
i386/divdi3.o \
|
||||
i386/floatdidf.o \
|
||||
i386/floatdisf.o \
|
||||
i386/floatdixf.o \
|
||||
i386/floatundidf.o \
|
||||
i386/floatundisf.o \
|
||||
i386/floatundixf.o \
|
||||
i386/lshrdi3.o \
|
||||
i386/moddi3.o \
|
||||
i386/muldi3.o \
|
||||
i386/udivdi3.o \
|
||||
i386/umoddi3.o
|
||||
endif
|
||||
|
||||
else
|
||||
|
||||
ifeq ($$(findstring x86_64,$(1)),x86_64)
|
||||
COMPRT_OBJS_$(1) += \
|
||||
x86_64/floatdidf.o \
|
||||
x86_64/floatdisf.o \
|
||||
x86_64/floatdixf.o
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
# Generic ARM sources, nothing compiles on iOS though
|
||||
ifeq ($$(findstring arm,$(1)),arm)
|
||||
ifeq ($$(findstring ios,$(1)),)
|
||||
COMPRT_OBJS_$(1) += \
|
||||
arm/aeabi_cdcmp.o \
|
||||
arm/aeabi_cdcmpeq_check_nan.o \
|
||||
arm/aeabi_cfcmp.o \
|
||||
arm/aeabi_cfcmpeq_check_nan.o \
|
||||
arm/aeabi_dcmp.o \
|
||||
arm/aeabi_div0.o \
|
||||
arm/aeabi_drsub.o \
|
||||
arm/aeabi_fcmp.o \
|
||||
arm/aeabi_frsub.o \
|
||||
arm/aeabi_idivmod.o \
|
||||
arm/aeabi_ldivmod.o \
|
||||
arm/aeabi_memcmp.o \
|
||||
arm/aeabi_memcpy.o \
|
||||
arm/aeabi_memmove.o \
|
||||
arm/aeabi_memset.o \
|
||||
arm/aeabi_uidivmod.o \
|
||||
arm/aeabi_uldivmod.o \
|
||||
arm/bswapdi2.o \
|
||||
arm/bswapsi2.o \
|
||||
arm/clzdi2.o \
|
||||
arm/clzsi2.o \
|
||||
arm/comparesf2.o \
|
||||
arm/divmodsi4.o \
|
||||
arm/divsi3.o \
|
||||
arm/modsi3.o \
|
||||
arm/switch16.o \
|
||||
arm/switch32.o \
|
||||
arm/switch8.o \
|
||||
arm/switchu8.o \
|
||||
arm/sync_synchronize.o \
|
||||
arm/udivmodsi4.o \
|
||||
arm/udivsi3.o \
|
||||
arm/umodsi3.o
|
||||
endif
|
||||
endif
|
||||
|
||||
# Thumb sources
|
||||
ifeq ($$(findstring armv7,$(1)),armv7)
|
||||
COMPRT_OBJS_$(1) += \
|
||||
arm/sync_fetch_and_add_4.o \
|
||||
arm/sync_fetch_and_add_8.o \
|
||||
arm/sync_fetch_and_and_4.o \
|
||||
arm/sync_fetch_and_and_8.o \
|
||||
arm/sync_fetch_and_max_4.o \
|
||||
arm/sync_fetch_and_max_8.o \
|
||||
arm/sync_fetch_and_min_4.o \
|
||||
arm/sync_fetch_and_min_8.o \
|
||||
arm/sync_fetch_and_nand_4.o \
|
||||
arm/sync_fetch_and_nand_8.o \
|
||||
arm/sync_fetch_and_or_4.o \
|
||||
arm/sync_fetch_and_or_8.o \
|
||||
arm/sync_fetch_and_sub_4.o \
|
||||
arm/sync_fetch_and_sub_8.o \
|
||||
arm/sync_fetch_and_umax_4.o \
|
||||
arm/sync_fetch_and_umax_8.o \
|
||||
arm/sync_fetch_and_umin_4.o \
|
||||
arm/sync_fetch_and_umin_8.o \
|
||||
arm/sync_fetch_and_xor_4.o \
|
||||
arm/sync_fetch_and_xor_8.o
|
||||
endif
|
||||
|
||||
# VFP sources
|
||||
ifeq ($$(findstring eabihf,$(1)),eabihf)
|
||||
COMPRT_OBJS_$(1) += \
|
||||
arm/adddf3vfp.o \
|
||||
arm/addsf3vfp.o \
|
||||
arm/divdf3vfp.o \
|
||||
arm/divsf3vfp.o \
|
||||
arm/eqdf2vfp.o \
|
||||
arm/eqsf2vfp.o \
|
||||
arm/extendsfdf2vfp.o \
|
||||
arm/fixdfsivfp.o \
|
||||
arm/fixsfsivfp.o \
|
||||
arm/fixunsdfsivfp.o \
|
||||
arm/fixunssfsivfp.o \
|
||||
arm/floatsidfvfp.o \
|
||||
arm/floatsisfvfp.o \
|
||||
arm/floatunssidfvfp.o \
|
||||
arm/floatunssisfvfp.o \
|
||||
arm/gedf2vfp.o \
|
||||
arm/gesf2vfp.o \
|
||||
arm/gtdf2vfp.o \
|
||||
arm/gtsf2vfp.o \
|
||||
arm/ledf2vfp.o \
|
||||
arm/lesf2vfp.o \
|
||||
arm/ltdf2vfp.o \
|
||||
arm/ltsf2vfp.o \
|
||||
arm/muldf3vfp.o \
|
||||
arm/mulsf3vfp.o \
|
||||
arm/negdf2vfp.o \
|
||||
arm/negsf2vfp.o \
|
||||
arm/nedf2vfp.o \
|
||||
arm/nesf2vfp.o \
|
||||
arm/restore_vfp_d8_d15_regs.o \
|
||||
arm/save_vfp_d8_d15_regs.o \
|
||||
arm/subdf3vfp.o \
|
||||
arm/subsf3vfp.o \
|
||||
arm/truncdfsf2vfp.o \
|
||||
arm/unorddf2vfp.o \
|
||||
arm/unordsf2vfp.o
|
||||
endif
|
||||
|
||||
ifeq ($$(findstring aarch64,$(1)),aarch64)
|
||||
COMPRT_OBJS_$(1) += \
|
||||
comparetf2.o \
|
||||
extenddftf2.o \
|
||||
extendsftf2.o \
|
||||
fixtfdi.o \
|
||||
fixtfsi.o \
|
||||
fixtfti.o \
|
||||
fixunstfdi.o \
|
||||
fixunstfsi.o \
|
||||
fixunstfti.o \
|
||||
floatditf.o \
|
||||
floatsitf.o \
|
||||
floatunditf.o \
|
||||
floatunsitf.o \
|
||||
multc3.o \
|
||||
trunctfdf2.o \
|
||||
trunctfsf2.o
|
||||
endif
|
||||
|
||||
ifeq ($$(findstring msvc,$(1)),msvc)
|
||||
$$(COMPRT_BUILD_DIR_$(1))/%.o: CFLAGS += -Zl -D__func__=__FUNCTION__
|
||||
else
|
||||
$$(COMPRT_BUILD_DIR_$(1))/%.o: CFLAGS += -fno-builtin -fvisibility=hidden \
|
||||
-fomit-frame-pointer -ffreestanding
|
||||
endif
|
||||
|
||||
COMPRT_OBJS_$(1) := $$(COMPRT_OBJS_$(1):%=$$(COMPRT_BUILD_DIR_$(1))/%)
|
||||
|
||||
$$(COMPRT_BUILD_DIR_$(1))/%.o: $(S)src/compiler-rt/lib/builtins/%.c
|
||||
@mkdir -p $$(@D)
|
||||
@$$(call E, compile: $$@)
|
||||
$$(Q)$$(call CFG_COMPILE_C_$(1),$$@,$$<)
|
||||
|
||||
$$(COMPRT_BUILD_DIR_$(1))/%.o: $(S)src/compiler-rt/lib/builtins/%.S \
|
||||
$$(LLVM_CONFIG_$$(CFG_BUILD))
|
||||
@mkdir -p $$(@D)
|
||||
@$$(call E, compile: $$@)
|
||||
$$(Q)$$(call CFG_ASSEMBLE_$(1),$$@,$$<)
|
||||
|
||||
ifeq ($$(findstring msvc,$(1)),msvc)
|
||||
$$(COMPRT_BUILD_DIR_$(1))/%.o: \
|
||||
export INCLUDE := $$(CFG_MSVC_INCLUDE_PATH_$$(HOST_$(1)))
|
||||
endif
|
||||
|
||||
ifeq ($$(findstring emscripten,$(1)),emscripten)
|
||||
|
||||
# FIXME: emscripten doesn't use compiler-rt and can't build it without
|
||||
# further hacks
|
||||
$$(COMPRT_LIB_$(1)):
|
||||
touch $$@
|
||||
|
||||
else
|
||||
|
||||
$$(COMPRT_LIB_$(1)): $$(COMPRT_DEPS) $$(MKFILE_DEPS) $$(LLVM_CONFIG_$$(CFG_BUILD))
|
||||
@$$(call E, cmake: compiler-rt)
|
||||
$$(Q)rm -rf $$(COMPRT_BUILD_DIR_$(1))
|
||||
$$(Q)mkdir $$(COMPRT_BUILD_DIR_$(1))
|
||||
$$(Q)cd "$$(COMPRT_BUILD_DIR_$(1))"; \
|
||||
$$(CFG_CMAKE) "$(S)src/compiler-rt" \
|
||||
-DCMAKE_BUILD_TYPE=$$(LLVM_BUILD_CONFIG_MODE) \
|
||||
-DLLVM_CONFIG_PATH=$$(LLVM_CONFIG_$$(CFG_BUILD)) \
|
||||
-DCOMPILER_RT_DEFAULT_TARGET_TRIPLE=$(1) \
|
||||
-DCOMPILER_RT_BUILD_SANITIZERS=OFF \
|
||||
-DCOMPILER_RT_BUILD_EMUTLS=OFF \
|
||||
$$(COMPRT_DEFINES_$(1)) \
|
||||
$$(COMPRT_BUILD_CC_$(1)) \
|
||||
-G"$$(CFG_CMAKE_GENERATOR)"
|
||||
ifneq ($$(CFG_NINJA),)
|
||||
$$(CFG_CMAKE) --build "$$(COMPRT_BUILD_DIR_$(1))" \
|
||||
--target $$(COMPRT_BUILD_TARGET_$(1)) \
|
||||
--config $$(LLVM_BUILD_CONFIG_MODE) \
|
||||
-- $$(COMPRT_BUILD_ARGS_$(1))
|
||||
else
|
||||
$$(Q)$$(CFG_CMAKE) --build "$$(COMPRT_BUILD_DIR_$(1))" \
|
||||
--target $$(COMPRT_BUILD_TARGET_$(1)) \
|
||||
--config $$(LLVM_BUILD_CONFIG_MODE) \
|
||||
-- $$(COMPRT_BUILD_ARGS_$(1)) $$(MFLAGS)
|
||||
COMPRT_OBJS_$(1) :=
|
||||
endif
|
||||
$$(Q)cp "$$(COMPRT_OUTPUT_$(1))" $$@
|
||||
|
||||
endif
|
||||
$$(COMPRT_LIB_$(1)): $$(COMPRT_OBJS_$(1))
|
||||
@$$(call E, link: $$@)
|
||||
$$(Q)$$(call CFG_CREATE_ARCHIVE_$(1),$$@) $$^
|
||||
|
||||
################################################################################
|
||||
# libbacktrace
|
||||
|
11
src/bootstrap/Cargo.lock
generated
11
src/bootstrap/Cargo.lock
generated
@ -5,7 +5,7 @@ dependencies = [
|
||||
"build_helper 0.1.0",
|
||||
"cmake 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.26 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.31 (git+https://github.com/alexcrichton/gcc-rs)",
|
||||
"getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"kernel32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -25,7 +25,7 @@ name = "cmake"
|
||||
version = "0.1.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"gcc 0.3.26 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gcc 0.3.31 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -38,7 +38,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "gcc"
|
||||
version = "0.3.26"
|
||||
version = "0.3.31"
|
||||
source = "git+https://github.com/alexcrichton/gcc-rs#b8e2400883f1a2749b323354dad372cdd1c838c7"
|
||||
|
||||
[[package]]
|
||||
name = "gcc"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
|
@ -29,6 +29,6 @@ getopts = "0.2"
|
||||
rustc-serialize = "0.3"
|
||||
winapi = "0.2"
|
||||
kernel32-sys = "0.2"
|
||||
gcc = "0.3.17"
|
||||
gcc = { git = "https://github.com/alexcrichton/gcc-rs" }
|
||||
libc = "0.2"
|
||||
md5 = "0.1"
|
||||
|
@ -133,86 +133,395 @@ fn check_llvm_version(build: &Build, llvm_config: &Path) {
|
||||
|
||||
/// Compiles the `compiler-rt` library, or at least the builtins part of it.
|
||||
///
|
||||
/// This uses the CMake build system and an existing LLVM build directory to
|
||||
/// compile the project.
|
||||
/// Note that while compiler-rt has a build system associated with it, we
|
||||
/// specifically don't use it here. The compiler-rt build system, written in
|
||||
/// CMake, is actually *very* difficult to work with in terms of getting it to
|
||||
/// compile on all the relevant platforms we want it to compile on. In the end
|
||||
/// it became so much pain to work with local patches, work around the oddities
|
||||
/// of the build system, etc, that we're just building everything by hand now.
|
||||
///
|
||||
/// In general compiler-rt is just a bunch of intrinsics that are in practice
|
||||
/// *very* stable. We just need to make sure that all the relevant functions and
|
||||
/// such are compiled somewhere and placed in an object file somewhere.
|
||||
/// Eventually, these should all be written in Rust!
|
||||
///
|
||||
/// So below you'll find a listing of every single file in the compiler-rt repo
|
||||
/// that we're compiling. We just reach in and compile with the `gcc` crate
|
||||
/// which should have all the relevant flags and such already configured.
|
||||
///
|
||||
/// The risk here is that if we update compiler-rt we may need to compile some
|
||||
/// new intrinsics, but to be honest we surely don't use all of the intrinsics
|
||||
/// listed below today so the likelihood of us actually needing a new intrinsic
|
||||
/// is quite low. The failure case is also just that someone reports a link
|
||||
/// error (if any) and then we just add it to the list. Overall, that cost is
|
||||
/// far far less than working with compiler-rt's build system over time.
|
||||
pub fn compiler_rt(build: &Build, target: &str) {
|
||||
let dst = build.compiler_rt_out(target);
|
||||
let arch = target.split('-').next().unwrap();
|
||||
let mode = if build.config.rust_optimize {"Release"} else {"Debug"};
|
||||
|
||||
let build_llvm_config = build.llvm_config(&build.config.build);
|
||||
let mut cfg = cmake::Config::new(build.src.join("src/compiler-rt"));
|
||||
cfg.target(target)
|
||||
.host(&build.config.build)
|
||||
.out_dir(&dst)
|
||||
.profile(mode)
|
||||
.define("LLVM_CONFIG_PATH", build_llvm_config)
|
||||
.define("COMPILER_RT_DEFAULT_TARGET_TRIPLE", target)
|
||||
.define("COMPILER_RT_BUILD_SANITIZERS", "OFF")
|
||||
.define("COMPILER_RT_BUILD_EMUTLS", "OFF")
|
||||
// inform about c/c++ compilers, the c++ compiler isn't actually used but
|
||||
// it's needed to get the initial configure to work on all platforms.
|
||||
.define("CMAKE_C_COMPILER", build.cc(target))
|
||||
.define("CMAKE_CXX_COMPILER", build.cc(target));
|
||||
|
||||
let (dir, build_target, libname) = if target.contains("linux") ||
|
||||
target.contains("freebsd") ||
|
||||
target.contains("netbsd") {
|
||||
let os_extra = if target.contains("android") && target.contains("arm") {
|
||||
"-android"
|
||||
} else {
|
||||
""
|
||||
};
|
||||
let builtins_arch = match arch {
|
||||
"i586" => "i386",
|
||||
"arm" | "armv7" if target.contains("android") => "armhf",
|
||||
"arm" if target.contains("eabihf") => "armhf",
|
||||
_ => arch,
|
||||
};
|
||||
let target = format!("clang_rt.builtins-{}", builtins_arch);
|
||||
("linux".to_string(),
|
||||
target.clone(),
|
||||
format!("{}{}", target, os_extra))
|
||||
} else if target.contains("apple-darwin") {
|
||||
let builtins_arch = match arch {
|
||||
"i686" => "i386",
|
||||
_ => arch,
|
||||
};
|
||||
let target = format!("clang_rt.builtins_{}_osx", builtins_arch);
|
||||
("builtins".to_string(), target.clone(), target)
|
||||
} else if target.contains("apple-ios") {
|
||||
cfg.define("COMPILER_RT_ENABLE_IOS", "ON");
|
||||
let target = match arch {
|
||||
"armv7s" => "hard_pic_armv7em_macho_embedded".to_string(),
|
||||
"aarch64" => "builtins_arm64_ios".to_string(),
|
||||
_ => format!("hard_pic_{}_macho_embedded", arch),
|
||||
};
|
||||
("builtins".to_string(), target.clone(), target)
|
||||
} else if target.contains("windows-gnu") {
|
||||
let target = format!("clang_rt.builtins-{}", arch);
|
||||
("windows".to_string(), target.clone(), target)
|
||||
} else if target.contains("windows-msvc") {
|
||||
let builtins_arch = match arch {
|
||||
"i586" | "i686" => "i386",
|
||||
_ => arch,
|
||||
};
|
||||
(format!("windows/{}", mode),
|
||||
"lib/builtins/builtins".to_string(),
|
||||
format!("clang_rt.builtins-{}", builtins_arch))
|
||||
} else {
|
||||
panic!("can't get os from target: {}", target)
|
||||
};
|
||||
let output = dst.join("build/lib").join(dir)
|
||||
.join(staticlib(&libname, target));
|
||||
let build_dir = build.compiler_rt_out(target);
|
||||
let output = build_dir.join(staticlib("compiler-rt", target));
|
||||
build.compiler_rt_built.borrow_mut().insert(target.to_string(),
|
||||
output.clone());
|
||||
if fs::metadata(&output).is_ok() {
|
||||
t!(fs::create_dir_all(&build_dir));
|
||||
|
||||
let mut cfg = gcc::Config::new();
|
||||
cfg.cargo_metadata(false)
|
||||
.out_dir(&build_dir)
|
||||
.target(target)
|
||||
.host(&build.config.build)
|
||||
.opt_level(2)
|
||||
.debug(false);
|
||||
|
||||
if target.contains("msvc") {
|
||||
// Don't pull in extra libraries on MSVC
|
||||
cfg.flag("/Zl");
|
||||
|
||||
// Emulate C99 and C++11's __func__ for MSVC prior to 2013 CTP
|
||||
cfg.define("__func__", Some("__FUNCTION__"));
|
||||
} else {
|
||||
// Turn off various features of gcc and such, mostly copying
|
||||
// compiler-rt's build system already
|
||||
cfg.flag("-fno-builtin");
|
||||
cfg.flag("-fvisibility=hidden");
|
||||
cfg.flag("-fomit-frame-pointer");
|
||||
cfg.flag("-ffreestanding");
|
||||
}
|
||||
|
||||
let mut sources = vec![
|
||||
"absvdi2.c",
|
||||
"absvsi2.c",
|
||||
"adddf3.c",
|
||||
"addsf3.c",
|
||||
"addvdi3.c",
|
||||
"addvsi3.c",
|
||||
"apple_versioning.c",
|
||||
"ashldi3.c",
|
||||
"ashrdi3.c",
|
||||
"clear_cache.c",
|
||||
"clzdi2.c",
|
||||
"clzsi2.c",
|
||||
"cmpdi2.c",
|
||||
"comparedf2.c",
|
||||
"comparesf2.c",
|
||||
"ctzdi2.c",
|
||||
"ctzsi2.c",
|
||||
"divdc3.c",
|
||||
"divdf3.c",
|
||||
"divdi3.c",
|
||||
"divmoddi4.c",
|
||||
"divmodsi4.c",
|
||||
"divsc3.c",
|
||||
"divsf3.c",
|
||||
"divsi3.c",
|
||||
"divxc3.c",
|
||||
"extendsfdf2.c",
|
||||
"extendhfsf2.c",
|
||||
"ffsdi2.c",
|
||||
"fixdfdi.c",
|
||||
"fixdfsi.c",
|
||||
"fixsfdi.c",
|
||||
"fixsfsi.c",
|
||||
"fixunsdfdi.c",
|
||||
"fixunsdfsi.c",
|
||||
"fixunssfdi.c",
|
||||
"fixunssfsi.c",
|
||||
"fixunsxfdi.c",
|
||||
"fixunsxfsi.c",
|
||||
"fixxfdi.c",
|
||||
"floatdidf.c",
|
||||
"floatdisf.c",
|
||||
"floatdixf.c",
|
||||
"floatsidf.c",
|
||||
"floatsisf.c",
|
||||
"floatundidf.c",
|
||||
"floatundisf.c",
|
||||
"floatundixf.c",
|
||||
"floatunsidf.c",
|
||||
"floatunsisf.c",
|
||||
"int_util.c",
|
||||
"lshrdi3.c",
|
||||
"moddi3.c",
|
||||
"modsi3.c",
|
||||
"muldc3.c",
|
||||
"muldf3.c",
|
||||
"muldi3.c",
|
||||
"mulodi4.c",
|
||||
"mulosi4.c",
|
||||
"muloti4.c",
|
||||
"mulsc3.c",
|
||||
"mulsf3.c",
|
||||
"mulvdi3.c",
|
||||
"mulvsi3.c",
|
||||
"mulxc3.c",
|
||||
"negdf2.c",
|
||||
"negdi2.c",
|
||||
"negsf2.c",
|
||||
"negvdi2.c",
|
||||
"negvsi2.c",
|
||||
"paritydi2.c",
|
||||
"paritysi2.c",
|
||||
"popcountdi2.c",
|
||||
"popcountsi2.c",
|
||||
"powidf2.c",
|
||||
"powisf2.c",
|
||||
"powixf2.c",
|
||||
"subdf3.c",
|
||||
"subsf3.c",
|
||||
"subvdi3.c",
|
||||
"subvsi3.c",
|
||||
"truncdfhf2.c",
|
||||
"truncdfsf2.c",
|
||||
"truncsfhf2.c",
|
||||
"ucmpdi2.c",
|
||||
"udivdi3.c",
|
||||
"udivmoddi4.c",
|
||||
"udivmodsi4.c",
|
||||
"udivsi3.c",
|
||||
"umoddi3.c",
|
||||
"umodsi3.c",
|
||||
];
|
||||
|
||||
if !target.contains("ios") {
|
||||
sources.extend(vec![
|
||||
"absvti2.c",
|
||||
"addtf3.c",
|
||||
"addvti3.c",
|
||||
"ashlti3.c",
|
||||
"ashrti3.c",
|
||||
"clzti2.c",
|
||||
"cmpti2.c",
|
||||
"ctzti2.c",
|
||||
"divtf3.c",
|
||||
"divti3.c",
|
||||
"ffsti2.c",
|
||||
"fixdfti.c",
|
||||
"fixsfti.c",
|
||||
"fixunsdfti.c",
|
||||
"fixunssfti.c",
|
||||
"fixunsxfti.c",
|
||||
"fixxfti.c",
|
||||
"floattidf.c",
|
||||
"floattisf.c",
|
||||
"floattixf.c",
|
||||
"floatuntidf.c",
|
||||
"floatuntisf.c",
|
||||
"floatuntixf.c",
|
||||
"lshrti3.c",
|
||||
"modti3.c",
|
||||
"multf3.c",
|
||||
"multi3.c",
|
||||
"mulvti3.c",
|
||||
"negti2.c",
|
||||
"negvti2.c",
|
||||
"parityti2.c",
|
||||
"popcountti2.c",
|
||||
"powitf2.c",
|
||||
"subtf3.c",
|
||||
"subvti3.c",
|
||||
"trampoline_setup.c",
|
||||
"ucmpti2.c",
|
||||
"udivmodti4.c",
|
||||
"udivti3.c",
|
||||
"umodti3.c",
|
||||
]);
|
||||
}
|
||||
|
||||
if target.contains("apple") {
|
||||
sources.extend(vec![
|
||||
"atomic_flag_clear.c",
|
||||
"atomic_flag_clear_explicit.c",
|
||||
"atomic_flag_test_and_set.c",
|
||||
"atomic_flag_test_and_set_explicit.c",
|
||||
"atomic_signal_fence.c",
|
||||
"atomic_thread_fence.c",
|
||||
]);
|
||||
}
|
||||
|
||||
if !target.contains("windows") {
|
||||
sources.push("emutls.c");
|
||||
}
|
||||
|
||||
if target.contains("msvc") {
|
||||
if target.contains("x86_64") {
|
||||
sources.extend(vec![
|
||||
"x86_64/floatdidf.c",
|
||||
"x86_64/floatdisf.c",
|
||||
"x86_64/floatdixf.c",
|
||||
]);
|
||||
}
|
||||
} else {
|
||||
sources.push("gcc_personality_v0.c");
|
||||
|
||||
if target.contains("x86_64") {
|
||||
sources.extend(vec![
|
||||
"x86_64/chkstk.S",
|
||||
"x86_64/chkstk2.S",
|
||||
"x86_64/floatdidf.c",
|
||||
"x86_64/floatdisf.c",
|
||||
"x86_64/floatdixf.c",
|
||||
"x86_64/floatundidf.S",
|
||||
"x86_64/floatundisf.S",
|
||||
"x86_64/floatundixf.S",
|
||||
]);
|
||||
}
|
||||
|
||||
if target.contains("i386") ||
|
||||
target.contains("i586") ||
|
||||
target.contains("i686") {
|
||||
sources.extend(vec![
|
||||
"i386/ashldi3.S",
|
||||
"i386/ashrdi3.S",
|
||||
"i386/chkstk.S",
|
||||
"i386/chkstk2.S",
|
||||
"i386/divdi3.S",
|
||||
"i386/floatdidf.S",
|
||||
"i386/floatdisf.S",
|
||||
"i386/floatdixf.S",
|
||||
"i386/floatundidf.S",
|
||||
"i386/floatundisf.S",
|
||||
"i386/floatundixf.S",
|
||||
"i386/lshrdi3.S",
|
||||
"i386/moddi3.S",
|
||||
"i386/muldi3.S",
|
||||
"i386/udivdi3.S",
|
||||
"i386/umoddi3.S",
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
if target.contains("arm") && !target.contains("ios") {
|
||||
sources.extend(vec![
|
||||
"arm/aeabi_cdcmp.S",
|
||||
"arm/aeabi_cdcmpeq_check_nan.c",
|
||||
"arm/aeabi_cfcmp.S",
|
||||
"arm/aeabi_cfcmpeq_check_nan.c",
|
||||
"arm/aeabi_dcmp.S",
|
||||
"arm/aeabi_div0.c",
|
||||
"arm/aeabi_drsub.c",
|
||||
"arm/aeabi_fcmp.S",
|
||||
"arm/aeabi_frsub.c",
|
||||
"arm/aeabi_idivmod.S",
|
||||
"arm/aeabi_ldivmod.S",
|
||||
"arm/aeabi_memcmp.S",
|
||||
"arm/aeabi_memcpy.S",
|
||||
"arm/aeabi_memmove.S",
|
||||
"arm/aeabi_memset.S",
|
||||
"arm/aeabi_uidivmod.S",
|
||||
"arm/aeabi_uldivmod.S",
|
||||
"arm/bswapdi2.S",
|
||||
"arm/bswapsi2.S",
|
||||
"arm/clzdi2.S",
|
||||
"arm/clzsi2.S",
|
||||
"arm/comparesf2.S",
|
||||
"arm/divmodsi4.S",
|
||||
"arm/divsi3.S",
|
||||
"arm/modsi3.S",
|
||||
"arm/switch16.S",
|
||||
"arm/switch32.S",
|
||||
"arm/switch8.S",
|
||||
"arm/switchu8.S",
|
||||
"arm/sync_synchronize.S",
|
||||
"arm/udivmodsi4.S",
|
||||
"arm/udivsi3.S",
|
||||
"arm/umodsi3.S",
|
||||
]);
|
||||
}
|
||||
|
||||
if target.contains("armv7") {
|
||||
sources.extend(vec![
|
||||
"arm/sync_fetch_and_add_4.S",
|
||||
"arm/sync_fetch_and_add_8.S",
|
||||
"arm/sync_fetch_and_and_4.S",
|
||||
"arm/sync_fetch_and_and_8.S",
|
||||
"arm/sync_fetch_and_max_4.S",
|
||||
"arm/sync_fetch_and_max_8.S",
|
||||
"arm/sync_fetch_and_min_4.S",
|
||||
"arm/sync_fetch_and_min_8.S",
|
||||
"arm/sync_fetch_and_nand_4.S",
|
||||
"arm/sync_fetch_and_nand_8.S",
|
||||
"arm/sync_fetch_and_or_4.S",
|
||||
"arm/sync_fetch_and_or_8.S",
|
||||
"arm/sync_fetch_and_sub_4.S",
|
||||
"arm/sync_fetch_and_sub_8.S",
|
||||
"arm/sync_fetch_and_umax_4.S",
|
||||
"arm/sync_fetch_and_umax_8.S",
|
||||
"arm/sync_fetch_and_umin_4.S",
|
||||
"arm/sync_fetch_and_umin_8.S",
|
||||
"arm/sync_fetch_and_xor_4.S",
|
||||
"arm/sync_fetch_and_xor_8.S",
|
||||
]);
|
||||
}
|
||||
|
||||
if target.contains("eabihf") {
|
||||
sources.extend(vec![
|
||||
"arm/adddf3vfp.S",
|
||||
"arm/addsf3vfp.S",
|
||||
"arm/divdf3vfp.S",
|
||||
"arm/divsf3vfp.S",
|
||||
"arm/eqdf2vfp.S",
|
||||
"arm/eqsf2vfp.S",
|
||||
"arm/extendsfdf2vfp.S",
|
||||
"arm/fixdfsivfp.S",
|
||||
"arm/fixsfsivfp.S",
|
||||
"arm/fixunsdfsivfp.S",
|
||||
"arm/fixunssfsivfp.S",
|
||||
"arm/floatsidfvfp.S",
|
||||
"arm/floatsisfvfp.S",
|
||||
"arm/floatunssidfvfp.S",
|
||||
"arm/floatunssisfvfp.S",
|
||||
"arm/gedf2vfp.S",
|
||||
"arm/gesf2vfp.S",
|
||||
"arm/gtdf2vfp.S",
|
||||
"arm/gtsf2vfp.S",
|
||||
"arm/ledf2vfp.S",
|
||||
"arm/lesf2vfp.S",
|
||||
"arm/ltdf2vfp.S",
|
||||
"arm/ltsf2vfp.S",
|
||||
"arm/muldf3vfp.S",
|
||||
"arm/mulsf3vfp.S",
|
||||
"arm/negdf2vfp.S",
|
||||
"arm/negsf2vfp.S",
|
||||
"arm/nedf2vfp.S",
|
||||
"arm/nesf2vfp.S",
|
||||
"arm/restore_vfp_d8_d15_regs.S",
|
||||
"arm/save_vfp_d8_d15_regs.S",
|
||||
"arm/subdf3vfp.S",
|
||||
"arm/subsf3vfp.S",
|
||||
"arm/truncdfsf2vfp.S",
|
||||
"arm/unorddf2vfp.S",
|
||||
"arm/unordsf2vfp.S",
|
||||
]);
|
||||
}
|
||||
|
||||
if target.contains("aarch64") {
|
||||
sources.extend(vec![
|
||||
"comparetf2.c",
|
||||
"extenddftf2.c",
|
||||
"extendsftf2.c",
|
||||
"fixtfdi.c",
|
||||
"fixtfsi.c",
|
||||
"fixtfti.c",
|
||||
"fixunstfdi.c",
|
||||
"fixunstfsi.c",
|
||||
"fixunstfti.c",
|
||||
"floatditf.c",
|
||||
"floatsitf.c",
|
||||
"floatunditf.c",
|
||||
"floatunsitf.c",
|
||||
"multc3.c",
|
||||
"trunctfdf2.c",
|
||||
"trunctfsf2.c",
|
||||
]);
|
||||
}
|
||||
|
||||
let mut out_of_date = false;
|
||||
for src in sources {
|
||||
let src = build.src.join("src/compiler-rt/lib/builtins").join(src);
|
||||
out_of_date = out_of_date || !up_to_date(&src, &output);
|
||||
cfg.file(src);
|
||||
}
|
||||
if !out_of_date {
|
||||
return
|
||||
}
|
||||
let _ = fs::remove_dir_all(&dst);
|
||||
t!(fs::create_dir_all(&dst));
|
||||
cfg.build_target(&build_target);
|
||||
cfg.build();
|
||||
cfg.compile("libcompiler-rt.a");
|
||||
}
|
||||
|
||||
/// Compiles the `rust_test_helpers.c` library which we used in various
|
||||
|
@ -347,9 +347,7 @@ impl<'a> Step<'a> {
|
||||
vec![self.libstd(compiler),
|
||||
self.target(host).rustc(compiler.stage)]
|
||||
}
|
||||
Source::CompilerRt { _dummy } => {
|
||||
vec![self.llvm(()).target(&build.config.build)]
|
||||
}
|
||||
Source::CompilerRt { _dummy } => Vec::new(),
|
||||
Source::Llvm { _dummy } => Vec::new(),
|
||||
Source::TestHelpers { _dummy } => Vec::new(),
|
||||
Source::DebuggerScripts { stage: _ } => Vec::new(),
|
||||
|
@ -103,7 +103,10 @@ pub fn add_lib_path(path: Vec<PathBuf>, cmd: &mut Command) {
|
||||
/// Uses last-modified time checks to verify this.
|
||||
pub fn up_to_date(src: &Path, dst: &Path) -> bool {
|
||||
let threshold = mtime(dst);
|
||||
let meta = t!(fs::metadata(src));
|
||||
let meta = match fs::metadata(src) {
|
||||
Ok(meta) => meta,
|
||||
Err(e) => panic!("source {:?} failed to get metadata: {}", src, e),
|
||||
};
|
||||
if meta.is_dir() {
|
||||
dir_up_to_date(src, &threshold)
|
||||
} else {
|
||||
|
Loading…
x
Reference in New Issue
Block a user