diff --git a/nix/bootstrap.nix b/nix/bootstrap.nix index 7fcc6c70c2..b0af203064 100644 --- a/nix/bootstrap.nix +++ b/nix/bootstrap.nix @@ -95,12 +95,13 @@ lib.warn "The Nix-based build is deprecated" rec { Lean = attachSharedLib leanshared Lean' // { allExternalDeps = [ Std ]; }; Lake = build { name = "Lake"; + sharedLibName = "Lake_shared"; src = src + "/src/lake"; deps = [ Init Lean ]; }; Lake-Main = build { - name = "Lake.Main"; - roots = [ "Lake.Main" ]; + name = "LakeMain"; + roots = [{ glob = "one"; mod = "LakeMain"; }]; executableName = "lake"; deps = [ Lake ]; linkFlags = lib.optional stdenv.isLinux "-rdynamic"; @@ -133,7 +134,7 @@ lib.warn "The Nix-based build is deprecated" rec { mods = foldl' (mods: pkg: mods // pkg.mods) {} stdlib; print-paths = Lean.makePrintPathsFor [] mods; leanc = writeShellScriptBin "leanc" '' - LEAN_CC=${stdenv.cc}/bin/cc ${Leanc.executable}/bin/leanc -I${lean-bin-tools-unwrapped}/include ${stdlibLinkFlags} -L${libInit_shared} -L${leanshared_1} -L${leanshared} "$@" + LEAN_CC=${stdenv.cc}/bin/cc ${Leanc.executable}/bin/leanc -I${lean-bin-tools-unwrapped}/include ${stdlibLinkFlags} -L${libInit_shared} -L${leanshared_1} -L${leanshared} -L${Lake.sharedLib} "$@" ''; lean = runCommand "lean" { buildInputs = lib.optional stdenv.isDarwin darwin.cctools; } '' mkdir -p $out/bin @@ -144,7 +145,7 @@ lib.warn "The Nix-based build is deprecated" rec { name = "lean-${desc}"; buildCommand = '' mkdir -p $out/bin $out/lib/lean - ln -sf ${leancpp}/lib/lean/* ${lib.concatMapStringsSep " " (l: "${l.modRoot}/* ${l.staticLib}/*") (lib.reverseList stdlib)} ${libInit_shared}/* ${leanshared_1}/* ${leanshared}/* $out/lib/lean/ + ln -sf ${leancpp}/lib/lean/* ${lib.concatMapStringsSep " " (l: "${l.modRoot}/* ${l.staticLib}/*") (lib.reverseList stdlib)} ${libInit_shared}/* ${leanshared_1}/* ${leanshared}/* ${Lake.sharedLib}/* $out/lib/lean/ # put everything in a single final derivation so `IO.appDir` references work cp ${lean}/bin/lean ${leanc}/bin/leanc ${Lake-Main.executable}/bin/lake $out/bin # NOTE: `lndir` will not override existing `bin/leanc` diff --git a/nix/buildLeanPackage.nix b/nix/buildLeanPackage.nix index 2d7e7feab1..c8b82ebde6 100644 --- a/nix/buildLeanPackage.nix +++ b/nix/buildLeanPackage.nix @@ -30,7 +30,7 @@ lib.makeOverridable ( pluginDeps ? [], # `overrideAttrs` for `buildMod` overrideBuildModAttrs ? null, - debug ? false, leanFlags ? [], leancFlags ? [], linkFlags ? [], executableName ? lib.toLower name, libName ? name, + debug ? false, leanFlags ? [], leancFlags ? [], linkFlags ? [], executableName ? lib.toLower name, libName ? name, sharedLibName ? libName, srcTarget ? "..#stage0", srcArgs ? "(\${args[*]})", lean-final ? lean-final' }@args: with builtins; let # "Init.Core" ~> "Init/Core" @@ -233,7 +233,7 @@ in rec { cTree = symlinkJoin { name = "${name}-cTree"; paths = map (mod: mod.c) (attrValues mods); }; oTree = symlinkJoin { name = "${name}-oTree"; paths = (attrValues objects); }; iTree = symlinkJoin { name = "${name}-iTree"; paths = map (mod: mod.ilean) (attrValues mods); }; - sharedLib = mkSharedLib "lib${libName}" '' + sharedLib = mkSharedLib "lib${sharedLibName}" '' ${if stdenv.isDarwin then "-Wl,-force_load,${staticLib}/lib${libName}.a" else "-Wl,--whole-archive ${staticLib}/lib${libName}.a -Wl,--no-whole-archive"} \ ${lib.concatStringsSep " " (map (d: "${d.sharedLib}/*") deps)}''; executable = lib.makeOverridable ({ withSharedStdlib ? true }: let diff --git a/script/lib/update-stage0 b/script/lib/update-stage0 index de85b3c5b2..10b5878a30 100755 --- a/script/lib/update-stage0 +++ b/script/lib/update-stage0 @@ -18,7 +18,7 @@ done # special handling for Lake files due to its nested directory # copy the README to ensure the `stage0/src/lake` directory is comitted -for f in $(git ls-files 'src/lake/Lake/*' src/lake/Lake.lean src/lake/README.md ':!:src/lakefile.toml'); do +for f in $(git ls-files 'src/lake/Lake/*' src/lake/Lake.lean src/lake/LakeMain.lean src/lake/README.md ':!:src/lakefile.toml'); do if [[ $f == *.lean ]]; then f=${f#src/lake} f=${f%.lean}.c diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 825c3ec998..6ccb39580d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -333,7 +333,12 @@ if(NOT LEAN_STANDALONE) endif() # flags for user binaries = flags for toolchain binaries + Lake -string(APPEND LEANC_STATIC_LINKER_FLAGS " ${TOOLCHAIN_STATIC_LINKER_FLAGS} -lLake") +set(LEANC_STATIC_LINKER_FLAGS " ${TOOLCHAIN_STATIC_LINKER_FLAGS} -lLake") +if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") + set(LEANC_SHARED_LINKER_FLAGS " ${TOOLCHAIN_SHARED_LINKER_FLAGS} -Wl,--as-needed -lLake_shared -Wl,--no-as-needed") +else() + set(LEANC_SHARED_LINKER_FLAGS " ${TOOLCHAIN_SHARED_LINKER_FLAGS} -lLake_shared") +endif() if (LLVM) string(APPEND LEANSHARED_LINKER_FLAGS " -L${LLVM_CONFIG_LIBDIR} ${LLVM_CONFIG_LDFLAGS} ${LLVM_CONFIG_LIBS} ${LLVM_CONFIG_SYSTEM_LIBS}") @@ -378,16 +383,20 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") string(APPEND CMAKE_CXX_FLAGS " -fPIC -ftls-model=initial-exec") string(APPEND LEANC_EXTRA_FLAGS " -fPIC") string(APPEND TOOLCHAIN_SHARED_LINKER_FLAGS " -Wl,-rpath=\\$$ORIGIN/..:\\$$ORIGIN") + string(APPEND LAKESHARED_LINKER_FLAGS " -Wl,--whole-archive ${CMAKE_BINARY_DIR}/lib/temp/libLake.a.export -Wl,--no-whole-archive") string(APPEND CMAKE_EXE_LINKER_FLAGS " -Wl,-rpath=\\\$ORIGIN/../lib:\\\$ORIGIN/../lib/lean") elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") string(APPEND CMAKE_CXX_FLAGS " -ftls-model=initial-exec") string(APPEND INIT_SHARED_LINKER_FLAGS " -install_name @rpath/libInit_shared.dylib") string(APPEND LEANSHARED_1_LINKER_FLAGS " -install_name @rpath/libleanshared_1.dylib") string(APPEND LEANSHARED_LINKER_FLAGS " -install_name @rpath/libleanshared.dylib") + string(APPEND LAKESHARED_LINKER_FLAGS " -Wl,-force_load,${CMAKE_BINARY_DIR}/lib/temp/libLake.a.export -install_name @rpath/libLake_shared.dylib") string(APPEND CMAKE_EXE_LINKER_FLAGS " -Wl,-rpath,@executable_path/../lib -Wl,-rpath,@executable_path/../lib/lean") elseif(${CMAKE_SYSTEM_NAME} MATCHES "Emscripten") string(APPEND CMAKE_CXX_FLAGS " -fPIC") string(APPEND LEANC_EXTRA_FLAGS " -fPIC") +elseif(${CMAKE_SYSTEM_NAME} MATCHES "Windows") + string(APPEND LAKESHARED_LINKER_FLAGS " -Wl,--out-implib,${CMAKE_BINARY_DIR}/lib/lean/libLake_shared.dll.a -Wl,--whole-archive ${CMAKE_BINARY_DIR}/lib/temp/libLake.a.export -Wl,--no-whole-archive") endif() if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") @@ -587,8 +596,13 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Emscripten") ) add_custom_target(leanshared ALL DEPENDS Init_shared leancpp + COMMAND touch ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/libleanshared_1${CMAKE_SHARED_LIBRARY_SUFFIX} COMMAND touch ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/libleanshared${CMAKE_SHARED_LIBRARY_SUFFIX} ) + add_custom_target(lake_shared ALL + DEPENDS leanshared + COMMAND touch ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/libLake_shared${CMAKE_SHARED_LIBRARY_SUFFIX} + ) else() add_custom_target(Init_shared ALL WORKING_DIRECTORY ${LEAN_SOURCE_DIR} @@ -606,11 +620,21 @@ else() endif() if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "Emscripten") - add_custom_target(lake ALL + add_custom_target(lake_lib ALL WORKING_DIRECTORY ${LEAN_SOURCE_DIR} DEPENDS leanshared COMMAND $(MAKE) -f ${CMAKE_BINARY_DIR}/stdlib.make Lake VERBATIM) + add_custom_target(lake_shared ALL + WORKING_DIRECTORY ${LEAN_SOURCE_DIR} + DEPENDS lake_lib + COMMAND $(MAKE) -f ${CMAKE_BINARY_DIR}/stdlib.make libLake_shared + VERBATIM) + add_custom_target(lake ALL + WORKING_DIRECTORY ${LEAN_SOURCE_DIR} + DEPENDS lake_shared + COMMAND $(MAKE) -f ${CMAKE_BINARY_DIR}/stdlib.make lake + VERBATIM) endif() if(PREV_STAGE) diff --git a/src/lake/Lake/Main.lean b/src/lake/LakeMain.lean similarity index 100% rename from src/lake/Lake/Main.lean rename to src/lake/LakeMain.lean diff --git a/src/stdlib.make.in b/src/stdlib.make.in index 785908775d..dc35254d01 100644 --- a/src/stdlib.make.in +++ b/src/stdlib.make.in @@ -29,7 +29,7 @@ ifeq "${STAGE}" "0" LEANMAKE_OPTS+=C_ONLY=1 C_OUT=${LEAN_SOURCE_DIR}/../stdlib/ endif -.PHONY: Init Std Lean leanshared Lake lean +.PHONY: Init Std Lean leanshared Lake Lake_shared lake lean # These can be phony since the inner Makefile will have the correct dependencies and avoid rebuilds Init: @@ -100,9 +100,24 @@ leanshared: ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/libleanshared${CMAKE_SHARED_LIBRAR Lake: # lake is in its own subdirectory, so must adjust relative paths... - +"${LEAN_BIN}/leanmake" -C lake bin lib PKG=Lake BIN_NAME=lake${CMAKE_EXECUTABLE_SUFFIX} $(LEANMAKE_OPTS) LINK_OPTS='${CMAKE_EXE_LINKER_FLAGS_MAKE_MAKE}' OUT="../${LIB}" LIB_OUT="../${LIB}/lean" OLEAN_OUT="../${LIB}/lean" + +"${LEAN_BIN}/leanmake" -C lake lib lib.export ../${LIB}/temp/LakeMain.o.export PKG=Lake $(LEANMAKE_OPTS) OUT="../${LIB}" LIB_OUT="../${LIB}/lean" TEMP_OUT="../${LIB}/temp" OLEAN_OUT="../${LIB}/lean" EXTRA_SRC_ROOTS=LakeMain.lean -${CMAKE_BINARY_DIR}/bin/lean${CMAKE_EXECUTABLE_SUFFIX}: ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/libInit_shared${CMAKE_SHARED_LIBRARY_SUFFIX} ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/libleanshared${CMAKE_SHARED_LIBRARY_SUFFIX} ${LIB}/temp/libleanmain.a +${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/libLake_shared${CMAKE_SHARED_LIBRARY_SUFFIX}: ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/libInit_shared${CMAKE_SHARED_LIBRARY_SUFFIX} ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/libleanshared_1${CMAKE_SHARED_LIBRARY_SUFFIX} ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/libleanshared${CMAKE_SHARED_LIBRARY_SUFFIX} ${LIB}/temp/libLean.a.export ${LIB}/temp/libLake.a.export + @echo "[ ] Building $@" + "${CMAKE_BINARY_DIR}/leanc.sh" -shared -o $@ \ + ${LAKESHARED_LINKER_FLAGS} -lleanshared -lleanshared_1 -lInit_shared ${TOOLCHAIN_SHARED_LINKER_FLAGS} ${LEANC_OPTS} + +libLake_shared: ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/libLake_shared${CMAKE_SHARED_LIBRARY_SUFFIX} + +${CMAKE_BINARY_DIR}/bin/lake${CMAKE_EXECUTABLE_SUFFIX}: ${LIB}/temp/LakeMain.o.export ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/libLake_shared${CMAKE_SHARED_LIBRARY_SUFFIX} + @echo "[ ] Building $@" +# on Windows, must remove file before writing a new one (since the old one may be in use) + @rm -f $@ + "${CMAKE_BINARY_DIR}/leanc.sh" $^ ${CMAKE_EXE_LINKER_FLAGS_MAKE} ${LEANC_OPTS} -o $@ + +lake: ${CMAKE_BINARY_DIR}/bin/lake${CMAKE_EXECUTABLE_SUFFIX} + +${CMAKE_BINARY_DIR}/bin/lean${CMAKE_EXECUTABLE_SUFFIX}: ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/libInit_shared${CMAKE_SHARED_LIBRARY_SUFFIX} ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/libleanshared_1${CMAKE_SHARED_LIBRARY_SUFFIX} ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/libleanshared${CMAKE_SHARED_LIBRARY_SUFFIX} ${LIB}/temp/libleanmain.a @echo "[ ] Building $@" # on Windows, must remove file before writing a new one (since the old one may be in use) @rm -f $@