From 7536adcf64fd77e4902efab172c44047d2195a54 Mon Sep 17 00:00:00 2001 From: GheisMohammadi Date: Mon, 17 Feb 2025 17:59:59 +0800 Subject: [PATCH 1/4] Add a new script to build a linux static executable from macOS --- scripts/build_linux_executable_from_macos.sh | 73 ++++++++++++++++++++ scripts/macos_docker/Dockerfile | 64 +++++++++++++++++ 2 files changed, 137 insertions(+) create mode 100755 scripts/build_linux_executable_from_macos.sh create mode 100644 scripts/macos_docker/Dockerfile diff --git a/scripts/build_linux_executable_from_macos.sh b/scripts/build_linux_executable_from_macos.sh new file mode 100755 index 0000000000..7259788234 --- /dev/null +++ b/scripts/build_linux_executable_from_macos.sh @@ -0,0 +1,73 @@ +#!/bin/bash + +# Define paths +SCRIPT_DIR=$(dirname $0) +PROJECT_ROOT=$(realpath "$SCRIPT_DIR/..") +HARMONY_DIR="$PROJECT_ROOT" +DOCKER_IMAGE="harmony-one" # This is the name we'll use for the Docker image +CONTAINER_PATH="/harmony" # The container's path to mount the harmony folder +OUTPUT_DIR="$HARMONY_DIR/bin/linux_static_bin" # The folder where we want to store the generated binaries + +echo "SCRIPT_DIR: $SCRIPT_DIR" +echo "PROJECT_ROOT: $PROJECT_ROOT" +echo "HARMONY_DIR: $HARMONY_DIR" +echo "OUTPUT_DIR: $OUTPUT_DIR" + +# Create the output directory if it doesn't exist +mkdir -p $OUTPUT_DIR +rm $OUTPUT_DIR/harmony +rm $OUTPUT_DIR/bootnode + +# Check if Docker is running +if ! docker info > /dev/null 2>&1; then + echo "Docker is not running. Please start Docker and try again." + exit 1 +fi + +# Build the Docker image (if it's not already built) +if ! docker image inspect $DOCKER_IMAGE > /dev/null 2>&1; then + echo "Docker image '$DOCKER_IMAGE' not found. Building the Docker image from the Dockerfile..." + echo "build docker file: $PROJECT_ROOT/scripts/macos_docker" + cd $PROJECT_ROOT/scripts/macos_docker #$PROJECT_ROOT + docker build -t $DOCKER_IMAGE -f $PROJECT_ROOT/scripts/macos_docker/Dockerfile $PROJECT_ROOT/scripts/macos_docker +else + echo "Docker image '$DOCKER_IMAGE' already exists. Skipping build." +fi + +# Run the Docker container +echo "Running Docker container and get the container ID..." +CONTAINER_ID=$(docker run -d $DOCKER_IMAGE tail -f /dev/null) + +# Copy all files from project directory to Docker container +echo "Copying all files from project directory to Docker container..." +docker cp $HARMONY_DIR/. $CONTAINER_ID:/root/go/src/github.com/harmony-one/tmp + +# Run the Docker container, mount the harmony folder and output folder, and build the project +echo "Building Linux static binary in Docker container..." +docker exec $CONTAINER_ID bash -c " + set -e # Exit on error + cd "/root/go/src/github.com/harmony-one" + echo 'Current Directory: ' && pwd + ls -l + rm -rf harmony + mv tmp harmony + cd harmony/bin + rm -rf * + cd .. + echo 'Current Directory: ' && pwd + ls -l + git config --global --add safe.directory /root/go/src/github.com/harmony-one/harmony + make linux_static +" + +echo 'Copying generated harmony and bootnode binaries to output directory...' +docker cp $CONTAINER_ID:/root/go/src/github.com/harmony-one/harmony/bin/harmony $OUTPUT_DIR +docker cp $CONTAINER_ID:/root/go/src/github.com/harmony-one/harmony/bin/bootnode $OUTPUT_DIR + +# Check if the binaries were copied to the output directory +if [ "$(ls -A $OUTPUT_DIR)" ]; then + echo "Build completed. The binaries should be in the '$OUTPUT_DIR' directory." +else + echo "Build failed: No binaries were found in the output directory." + exit 1 +fi diff --git a/scripts/macos_docker/Dockerfile b/scripts/macos_docker/Dockerfile new file mode 100644 index 0000000000..e8ad312bb6 --- /dev/null +++ b/scripts/macos_docker/Dockerfile @@ -0,0 +1,64 @@ +FROM ubuntu:22.04 + +ARG TARGETARCH +ARG GOLANG_VERSION="1.22.5" + +SHELL ["/bin/bash", "-c"] + +ENV GOPATH=/root/go +ENV GO111MODULE=on +ENV HMY_PATH=${GOPATH}/src/github.com/harmony-one +ENV OPENSSL_DIR=/usr/lib/ssl +ENV MCL_DIR=${HMY_PATH}/mcl +ENV BLS_DIR=${HMY_PATH}/bls +ENV CGO_CFLAGS="-I${BLS_DIR}/include -I${MCL_DIR}/include" +ENV CGO_LDFLAGS="-L${BLS_DIR}/lib" +ENV LD_LIBRARY_PATH=${BLS_DIR}/lib:${MCL_DIR}/lib +ENV GIMME_GO_VERSION=${GOLANG_VERSION} +ENV PATH="/root/bin:${PATH}" + +RUN apt update && apt upgrade -y && \ + apt install libgmp-dev libssl-dev curl git \ + psmisc dnsutils jq make gcc g++ bash tig tree sudo vim \ + silversearcher-ag unzip emacs-nox nano bash-completion -y + +RUN mkdir ~/bin && \ + curl -sL -o ~/bin/gimme \ + https://raw.githubusercontent.com/travis-ci/gimme/master/gimme && \ + chmod +x ~/bin/gimme + +RUN eval "$(~/bin/gimme ${GIMME_GO_VERSION})" + +#RUN git clone https://github.com/harmony-one/harmony.git ${HMY_PATH}/harmony + +RUN git clone https://github.com/harmony-one/mcl.git ${HMY_PATH}/mcl && \ + echo "mcl repository cloned" && \ + ls -la ${HMY_PATH}/mcl # List the contents of the mcl directory + +RUN git clone https://github.com/harmony-one/bls.git ${HMY_PATH}/bls && \ + echo "bls repository cloned" && \ + ls -la ${HMY_PATH}/bls # List the contents of the bls directory + +RUN git clone https://github.com/harmony-one/go-sdk.git ${HMY_PATH}/go-sdk + +RUN cd ${HMY_PATH}/bls && make -j8 BLS_SWAP_G=1 + +RUN touch /root/.bash_profile && \ + gimme ${GIMME_GO_VERSION} >> /root/.bash_profile && \ + echo "GIMME_GO_VERSION='${GIMME_GO_VERSION}'" >> /root/.bash_profile && \ + echo "GO111MODULE='on'" >> /root/.bash_profile && \ + echo ". ~/.bash_profile" >> /root/.profile && \ + echo ". ~/.bash_profile" >> /root/.bashrc + +ENV PATH="/root/.gimme/versions/go${GIMME_GO_VERSION}.linux.${TARGETARCH:-amd64}/bin:${GOPATH}/bin:${PATH}" + +RUN . ~/.bash_profile; \ + go install golang.org/x/tools/cmd/goimports; \ + go install golang.org/x/lint/golint ; \ + go install github.com/rogpeppe/godef ; \ + go install github.com/go-delve/delve/cmd/dlv; \ + go install github.com/golang/mock/mockgen; \ + go install github.com/stamblerre/gocode; \ + go install golang.org/x/tools/...; \ + go install honnef.co/go/tools/cmd/staticcheck/... + From c2c53f705c00623900794de07a12fbeab8159148 Mon Sep 17 00:00:00 2001 From: GheisMohammadi Date: Mon, 17 Feb 2025 18:05:35 +0800 Subject: [PATCH 2/4] add a new command to make file to build linux static executable from macOS --- Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Makefile b/Makefile index 622822c231..bd1c0dc162 100644 --- a/Makefile +++ b/Makefile @@ -38,6 +38,7 @@ help: @echo "test-rosetta-attach - attach onto the rosetta testing docker container for inspection" @echo "linux_static - static build the harmony binary & bootnode along with the MCL & BLS libs (for linux)" @echo "linux_static_quick - static build the harmony binary & bootnode more quickly without recompiling dependencies (for linux)" + @echo "linux_static_from_macos - static build the harmony binary & bootnode from macOS" @echo "rpm_init - prepare the RPM build environment by creating directories, copying files, and generating the spec file and source tarball" @echo "rpm_build - build an RPM package for x86_64 architecture using the spec file (/SPECS/harmony.spec)" @echo "rpm - build a harmony RPM pacakge" @@ -166,6 +167,9 @@ linux_static: linux_static_quick: bash ./scripts/go_executable_build.sh -s +linux_static_from_macos: + bash ./scripts/build_linux_executable_from_macos.sh -s + deb_init: rm -rf $(DEBBUILD) mkdir -p $(DEBBUILD)/$(PKGNAME)-$(VERSION)-$(RELEASE)/{etc/systemd/system,usr/sbin,etc/sysctl.d,etc/harmony} From 72392d707e93e821199c918072e878df38bbe310 Mon Sep 17 00:00:00 2001 From: GheisMohammadi Date: Thu, 20 Feb 2025 11:52:04 +0800 Subject: [PATCH 3/4] update the macos build command name and description in Makefile --- Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index bd1c0dc162..6287c371ec 100644 --- a/Makefile +++ b/Makefile @@ -38,7 +38,7 @@ help: @echo "test-rosetta-attach - attach onto the rosetta testing docker container for inspection" @echo "linux_static - static build the harmony binary & bootnode along with the MCL & BLS libs (for linux)" @echo "linux_static_quick - static build the harmony binary & bootnode more quickly without recompiling dependencies (for linux)" - @echo "linux_static_from_macos - static build the harmony binary & bootnode from macOS" + @echo "linux_static_cross_build - cross-compile static Linux binaries for Harmony and Bootnode from macOS" @echo "rpm_init - prepare the RPM build environment by creating directories, copying files, and generating the spec file and source tarball" @echo "rpm_build - build an RPM package for x86_64 architecture using the spec file (/SPECS/harmony.spec)" @echo "rpm - build a harmony RPM pacakge" @@ -167,8 +167,8 @@ linux_static: linux_static_quick: bash ./scripts/go_executable_build.sh -s -linux_static_from_macos: - bash ./scripts/build_linux_executable_from_macos.sh -s +linux_static_cross_build: + bash ./scripts/linux_executable_from_macos.sh -s deb_init: rm -rf $(DEBBUILD) From 3c0c0d72316198349308abc56d6d227ced5e63f0 Mon Sep 17 00:00:00 2001 From: GheisMohammadi Date: Thu, 20 Feb 2025 11:52:49 +0800 Subject: [PATCH 4/4] refactor and optimize linux executable shell file for mocOS --- scripts/build_linux_executable_from_macos.sh | 73 -------------------- scripts/linux_executable_from_macos.sh | 71 +++++++++++++++++++ 2 files changed, 71 insertions(+), 73 deletions(-) delete mode 100755 scripts/build_linux_executable_from_macos.sh create mode 100755 scripts/linux_executable_from_macos.sh diff --git a/scripts/build_linux_executable_from_macos.sh b/scripts/build_linux_executable_from_macos.sh deleted file mode 100755 index 7259788234..0000000000 --- a/scripts/build_linux_executable_from_macos.sh +++ /dev/null @@ -1,73 +0,0 @@ -#!/bin/bash - -# Define paths -SCRIPT_DIR=$(dirname $0) -PROJECT_ROOT=$(realpath "$SCRIPT_DIR/..") -HARMONY_DIR="$PROJECT_ROOT" -DOCKER_IMAGE="harmony-one" # This is the name we'll use for the Docker image -CONTAINER_PATH="/harmony" # The container's path to mount the harmony folder -OUTPUT_DIR="$HARMONY_DIR/bin/linux_static_bin" # The folder where we want to store the generated binaries - -echo "SCRIPT_DIR: $SCRIPT_DIR" -echo "PROJECT_ROOT: $PROJECT_ROOT" -echo "HARMONY_DIR: $HARMONY_DIR" -echo "OUTPUT_DIR: $OUTPUT_DIR" - -# Create the output directory if it doesn't exist -mkdir -p $OUTPUT_DIR -rm $OUTPUT_DIR/harmony -rm $OUTPUT_DIR/bootnode - -# Check if Docker is running -if ! docker info > /dev/null 2>&1; then - echo "Docker is not running. Please start Docker and try again." - exit 1 -fi - -# Build the Docker image (if it's not already built) -if ! docker image inspect $DOCKER_IMAGE > /dev/null 2>&1; then - echo "Docker image '$DOCKER_IMAGE' not found. Building the Docker image from the Dockerfile..." - echo "build docker file: $PROJECT_ROOT/scripts/macos_docker" - cd $PROJECT_ROOT/scripts/macos_docker #$PROJECT_ROOT - docker build -t $DOCKER_IMAGE -f $PROJECT_ROOT/scripts/macos_docker/Dockerfile $PROJECT_ROOT/scripts/macos_docker -else - echo "Docker image '$DOCKER_IMAGE' already exists. Skipping build." -fi - -# Run the Docker container -echo "Running Docker container and get the container ID..." -CONTAINER_ID=$(docker run -d $DOCKER_IMAGE tail -f /dev/null) - -# Copy all files from project directory to Docker container -echo "Copying all files from project directory to Docker container..." -docker cp $HARMONY_DIR/. $CONTAINER_ID:/root/go/src/github.com/harmony-one/tmp - -# Run the Docker container, mount the harmony folder and output folder, and build the project -echo "Building Linux static binary in Docker container..." -docker exec $CONTAINER_ID bash -c " - set -e # Exit on error - cd "/root/go/src/github.com/harmony-one" - echo 'Current Directory: ' && pwd - ls -l - rm -rf harmony - mv tmp harmony - cd harmony/bin - rm -rf * - cd .. - echo 'Current Directory: ' && pwd - ls -l - git config --global --add safe.directory /root/go/src/github.com/harmony-one/harmony - make linux_static -" - -echo 'Copying generated harmony and bootnode binaries to output directory...' -docker cp $CONTAINER_ID:/root/go/src/github.com/harmony-one/harmony/bin/harmony $OUTPUT_DIR -docker cp $CONTAINER_ID:/root/go/src/github.com/harmony-one/harmony/bin/bootnode $OUTPUT_DIR - -# Check if the binaries were copied to the output directory -if [ "$(ls -A $OUTPUT_DIR)" ]; then - echo "Build completed. The binaries should be in the '$OUTPUT_DIR' directory." -else - echo "Build failed: No binaries were found in the output directory." - exit 1 -fi diff --git a/scripts/linux_executable_from_macos.sh b/scripts/linux_executable_from_macos.sh new file mode 100755 index 0000000000..7cce7290b2 --- /dev/null +++ b/scripts/linux_executable_from_macos.sh @@ -0,0 +1,71 @@ +#!/bin/bash +set -e # Exit on first error + +# Define paths +SCRIPT_DIR=$(dirname "$0") +PROJECT_ROOT=$(realpath "$SCRIPT_DIR/..") +HARMONY_DIR="$PROJECT_ROOT" +DOCKER_IMAGE="harmony-one" # Name of the Docker image +OUTPUT_DIR="$HARMONY_DIR/bin/linux_static_bin" # Folder for generated binaries + +echo "=== Paths ===" +echo "SCRIPT_DIR: $SCRIPT_DIR" +echo "PROJECT_ROOT: $PROJECT_ROOT" +echo "HARMONY_DIR: $HARMONY_DIR" +echo "OUTPUT_DIR: $OUTPUT_DIR" + +# Ensure output directory exists and clean old binaries +mkdir -p "$OUTPUT_DIR" +rm -f "$OUTPUT_DIR/harmony" "$OUTPUT_DIR/bootnode" + +# Check if Docker is running +if ! docker info > /dev/null 2>&1; then + echo "Docker is not running. Please start Docker and try again." + exit 1 +fi + +# Build Docker image if not found +if ! docker image inspect "$DOCKER_IMAGE" > /dev/null 2>&1; then + echo "Building Docker image '$DOCKER_IMAGE'..." + pushd "$PROJECT_ROOT/scripts/macos_docker" + docker build -t "$DOCKER_IMAGE" -f Dockerfile . + popd +else + echo "Docker image '$DOCKER_IMAGE' already exists. Skipping build." +fi + +# Run the container in the background +echo "Running Docker container..." +CONTAINER_ID=$(docker run -d "$DOCKER_IMAGE" tail -f /dev/null) +trap 'docker stop "$CONTAINER_ID" > /dev/null; docker rm "$CONTAINER_ID" > /dev/null' EXIT # Ensure cleanup on exit + +# Copy project files into the container +echo "Copying project files to Docker container..." +docker cp "$HARMONY_DIR/." "$CONTAINER_ID:/root/go/src/github.com/harmony-one/tmp" + +# Build binaries inside the container +echo "Building Linux static binary..." +docker exec "$CONTAINER_ID" bash -c " + set -e + cd /root/go/src/github.com/harmony-one + echo 'Current Directory: ' && pwd + rm -rf harmony + mv tmp harmony + cd harmony/bin && rm -rf * # Clear previous binaries + cd .. + git config --global --add safe.directory /root/go/src/github.com/harmony-one/harmony + make linux_static +" + +# Copy built binaries back to host machine +echo "Copying binaries to output directory..." +docker cp "$CONTAINER_ID:/root/go/src/github.com/harmony-one/harmony/bin/harmony" "$OUTPUT_DIR" +docker cp "$CONTAINER_ID:/root/go/src/github.com/harmony-one/harmony/bin/bootnode" "$OUTPUT_DIR" + +# Validate build output +if [ "$(ls -A "$OUTPUT_DIR")" ]; then + echo "✅ Build completed successfully. Binaries are in '$OUTPUT_DIR'." +else + echo "❌ Build failed: No binaries found in '$OUTPUT_DIR'." + exit 1 +fi \ No newline at end of file