diff --git a/scripts/build_windows.sh b/scripts/build_windows.sh index c9d4bd860..efbefda0e 100755 --- a/scripts/build_windows.sh +++ b/scripts/build_windows.sh @@ -2,6 +2,12 @@ echo "- - - - - - - - - - Windows Setup Script - - - - - - - - - -" +# Mirrors the steps in .github/workflows/windows-build.yml so a local MSYS2 +# build matches CI. Builds go through the nimble build system: Nim/Nimble are +# installed via scripts/install_nim.sh + install_nimble.sh, dependencies are +# fetched into nimbledeps/ by `nimble setup --localdeps`, and the nat-libs and +# bearssl C sources are rebuilt from there. + success_count=0 failure_count=0 @@ -18,39 +24,38 @@ execute_command() { } echo "1. -.-.-.-- Set PATH -.-.-.-" -export PATH="/c/msys64/usr/bin:/c/msys64/mingw64/bin:/c/msys64/usr/lib:/c/msys64/mingw64/lib:$PATH" +export PATH="$HOME/.nimble/bin:/c/msys64/usr/bin:/c/msys64/mingw64/bin:/c/msys64/usr/lib:/c/msys64/mingw64/lib:$PATH" echo "2. -.-.-.- Verify dependencies -.-.-.-" -execute_command "which gcc g++ make cmake cargo upx rustc python" +execute_command "which gcc g++ make cmake cargo upx rustc python nasm" echo "3. -.-.-.- Updating submodules -.-.-.-" execute_command "git submodule update --init --recursive" -echo "4. -.-.-.- Creating tmp directory -.-.-.-" +echo "4. -.-.-.- Installing nasm -.-.-.-" +execute_command "bash scripts/install_nasm_in_windows.sh" + +echo "5. -.-.-.- Installing Nim and Nimble -.-.-.-" +execute_command "make install-nimble" + +echo "6. -.-.-.- Patch nimble.lock for Windows nim checksum -.-.-.-" +# nimble.exe uses Windows Git (core.autocrlf=true by default), which converts +# LF->CRLF on checkout. This changes the SHA1 of the nim package source tree +# relative to the Linux-computed checksum stored in nimble.lock. Patch the lock +# file with the Windows-computed checksum before nimble reads it. +execute_command "sed -i 's/68bb85cbfb1832ce4db43943911b046c3af3caab/a092a045d3a427d127a5334a6e59c76faff54686/g' nimble.lock" + +echo "7. -.-.-.- Installing nimble deps -.-.-.-" +execute_command "nimble setup --localdeps -y" +execute_command "make rebuild-nat-libs-nimbledeps CC=gcc" +execute_command "make rebuild-bearssl-nimbledeps CC=gcc" +execute_command "touch nimbledeps/.nimble-setup" + +echo "8. -.-.-.- Creating tmp directory -.-.-.-" execute_command "mkdir -p tmp" -echo "5. -.-.-.- Building Nim -.-.-.-" -cd vendor/nimbus-build-system/vendor/Nim -execute_command "./build_all.bat" -cd ../../../.. - -echo "6. -.-.-.- Building libunwind -.-.-.-" -cd vendor/nim-libbacktrace -execute_command "make all V=1 -j8" -cd ../../ - -echo "7. -.-.-.- Building miniupnpc -.-.-.- " -cd vendor/nim-nat-traversal/vendor/miniupnp/miniupnpc -execute_command "make -f Makefile.mingw CC=gcc CXX=g++ libminiupnpc.a V=1 -j8" -cd ../../../../.. - -echo "8. -.-.-.- Building libnatpmp -.-.-.- " -cd ./vendor/nim-nat-traversal/vendor/libnatpmp-upstream -make CC="gcc -fPIC -D_WIN32_WINNT=0x0600 -DNATPMP_STATICLIB" libnatpmp.a V=1 -j8 -cd ../../../../ - echo "9. -.-.-.- Building wakunode2 -.-.-.- " -execute_command "make wakunode2 LOG_LEVEL=DEBUG V=1 -j8" +execute_command "make wakunode2 LOG_LEVEL=DEBUG V=3 -j8" echo "10. -.-.-.- Building libwaku -.-.-.- " execute_command "make libwaku STATIC=0 LOG_LEVEL=DEBUG V=1 -j8" diff --git a/scripts/install_nim.sh b/scripts/install_nim.sh index 42aa88ecd..b75826378 100755 --- a/scripts/install_nim.sh +++ b/scripts/install_nim.sh @@ -5,8 +5,9 @@ # Installs to ~/.nim/nim-/ and symlinks binaries into ~/.nimble/bin/, # which is the idiomatic Nim location already on PATH. # -# Pre-built binaries are downloaded from nim-lang.org when available. -# Falls back to building from source otherwise (e.g. macOS on older releases). +# Pre-built binaries are downloaded from nim-lang.org: a .zip on Windows +# (nim-_x64.zip), a .tar.xz on Linux/macOS. On Unix, falls back to +# building from source when no pre-built tarball exists. set -e @@ -44,16 +45,64 @@ if [ -n "${nim_ver}" ]; then echo "INFO: Nim ${nim_ver} found in PATH; installing Nim ${NIM_VERSION} to ${NIM_DEST}." >&2 fi +<<<<<<< HEAD +======= OS=$(uname -s | tr 'A-Z' 'a-z' | sed 's/darwin/macosx/') ARCH=$(uname -m | sed 's/x86_64/x64/;s/aarch64/arm64/') BINARY_URL="https://nim-lang.org/download/nim-${NIM_VERSION}-${OS}_${ARCH}.tar.xz" +>>>>>>> master WORK_DIR=$(mktemp -d) trap 'rm -rf "${WORK_DIR}"' EXIT -echo "Checking for pre-built Nim ${NIM_VERSION} (${OS}_${ARCH})..." -HTTP_STATUS=$(curl -sI "${BINARY_URL}" | head -1 | grep -oE '[0-9]{3}' || true) +case "$(uname -s)" in +MINGW* | MSYS* | CYGWIN*) + # Windows: Nim ships as a zip named nim-_.zip + # (no OS segment, .zip rather than .tar.xz, and no source-build fallback). + case "$(uname -m)" in + x86_64 | amd64) WIN_ARCH=x64 ;; + *) WIN_ARCH=x32 ;; + esac + BINARY_URL="https://nim-lang.org/download/nim-${NIM_VERSION}_${WIN_ARCH}.zip" +<<<<<<< HEAD + echo "Downloading pre-built Nim ${NIM_VERSION} (windows_${WIN_ARCH}) from ${BINARY_URL}..." + curl -fL "${BINARY_URL}" -o "${WORK_DIR}/nim.zip" + unzip -q "${WORK_DIR}/nim.zip" -d "${WORK_DIR}" + SRC_DIR="${WORK_DIR}/nim-${NIM_VERSION}" + ;; +*) + OS=$(uname -s | tr 'A-Z' 'a-z' | sed 's/darwin/macosx/') + ARCH=$(uname -m | sed 's/x86_64/x64/;s/aarch64/arm64/') + + BINARY_URL="https://nim-lang.org/download/nim-${NIM_VERSION}-${OS}_${ARCH}.tar.xz" + + echo "Checking for pre-built Nim ${NIM_VERSION} (${OS}_${ARCH})..." + HTTP_STATUS=$(curl -sI "${BINARY_URL}" | head -1 | grep -oE '[0-9]{3}' || true) + + if [ "${HTTP_STATUS}" = "200" ]; then + echo "Downloading pre-built binary from ${BINARY_URL}..." + curl -fL "${BINARY_URL}" -o "${WORK_DIR}/nim.tar.xz" + tar -xJf "${WORK_DIR}/nim.tar.xz" -C "${WORK_DIR}" + SRC_DIR="${WORK_DIR}/nim-${NIM_VERSION}" + else + echo "No pre-built binary found for ${OS}_${ARCH}. Building from source..." + SRC_URL="https://github.com/nim-lang/Nim/archive/refs/tags/v${NIM_VERSION}.tar.gz" + curl -fL "${SRC_URL}" -o "${WORK_DIR}/nim-src.tar.gz" + tar -xzf "${WORK_DIR}/nim-src.tar.gz" -C "${WORK_DIR}" + cd "${WORK_DIR}/Nim-${NIM_VERSION}" + sh build_all.sh + SRC_DIR="${WORK_DIR}/Nim-${NIM_VERSION}" + fi + ;; +esac + +# rm -rf can fail with "Directory not empty" on overlay filesystems (e.g. Docker). +# Using cp -r src/. dst/ handles both cases: dst absent (clean) or partially present. +rm -rf "${NIM_DEST}" 2>/dev/null || true +mkdir -p "${NIM_DEST}" +cp -r "${SRC_DIR}/." "${NIM_DEST}/" +======= if [ "${HTTP_STATUS}" = "200" ]; then echo "Downloading pre-built binary from ${BINARY_URL}..." curl -fL "${BINARY_URL}" -o "${WORK_DIR}/nim.tar.xz" @@ -68,6 +117,7 @@ else sh build_all.sh SRC_DIR="${WORK_DIR}/Nim-${NIM_VERSION}" fi +>>>>>>> master # rm -rf can fail with "Directory not empty" on overlay filesystems (e.g. Docker). # Using cp -r src/. dst/ handles both cases: dst absent (clean) or partially present. diff --git a/scripts/install_nimble.sh b/scripts/install_nimble.sh index dba2d6612..871f6d784 100755 --- a/scripts/install_nimble.sh +++ b/scripts/install_nimble.sh @@ -19,7 +19,17 @@ if [ -z "${NIMBLE_VERSION}" ]; then exit 1 fi +<<<<<<< HEAD +# On Windows (MSYS2) the binaries carry a .exe extension. +EXE="" +case "$(uname -s)" in +MINGW* | MSYS* | CYGWIN*) EXE=".exe" ;; +esac + +NIMBLE_BIN="${HOME}/.nimble/bin/nimble${EXE}" +======= NIMBLE_BIN="${HOME}/.nimble/bin/nimble" +>>>>>>> master # 1. Already installed at the right version? if [ -x "${NIMBLE_BIN}" ]; then @@ -32,7 +42,11 @@ if [ -x "${NIMBLE_BIN}" ]; then fi # 2. Already compiled into pkgs2/ from a previous (possibly partial) run? +<<<<<<< HEAD +PKGS2_NIMBLE=$(ls -dt "${HOME}/.nimble/pkgs2/nimble-${NIMBLE_VERSION}-"*/nimble${EXE} \ +======= PKGS2_NIMBLE=$(ls -dt "${HOME}/.nimble/pkgs2/nimble-${NIMBLE_VERSION}-"*/nimble \ +>>>>>>> master 2>/dev/null | head -1 || true) if [ -n "${PKGS2_NIMBLE}" ] && [ -x "${PKGS2_NIMBLE}" ]; then echo "Nimble ${NIMBLE_VERSION} found in pkgs2, re-linking to ${NIMBLE_BIN}." @@ -42,7 +56,11 @@ if [ -n "${PKGS2_NIMBLE}" ] && [ -x "${PKGS2_NIMBLE}" ]; then fi # 3. Build from source. +<<<<<<< HEAD +NIM_BIN="${HOME}/.nimble/bin/nim${EXE}" +======= NIM_BIN="${HOME}/.nimble/bin/nim" +>>>>>>> master if [ ! -x "${NIM_BIN}" ]; then NIM_BIN="$(command -v nim)" fi @@ -60,11 +78,19 @@ echo "Building nimble ${NIMBLE_VERSION} with $("${NIM_BIN}" --version | head -1) cd "${WORK_DIR}/nimble" # nim reads nim.cfg / config.nims in the current dir, which sets vendor paths. "${NIM_BIN}" c -d:release --path:src \ +<<<<<<< HEAD + -o:"${WORK_DIR}/nimble_new${EXE}" src/nimble.nim + +mkdir -p "${HOME}/.nimble/bin" +# Atomic rename: avoids ETXTBSY when the old binary at NIMBLE_BIN is still running. +cp "${WORK_DIR}/nimble_new${EXE}" "${NIMBLE_BIN}.new.$$" +======= -o:"${WORK_DIR}/nimble_new" src/nimble.nim mkdir -p "${HOME}/.nimble/bin" # Atomic rename: avoids ETXTBSY when the old binary at NIMBLE_BIN is still running. cp "${WORK_DIR}/nimble_new" "${NIMBLE_BIN}.new.$$" +>>>>>>> master mv -f "${NIMBLE_BIN}.new.$$" "${NIMBLE_BIN}" echo "Nimble ${NIMBLE_VERSION} installed to ${NIMBLE_BIN}" \ No newline at end of file