Commit b00a5d7e authored by Kun Zhang's avatar Kun Zhang

Document more about cross-compilation; Post-build check for the actual arch of the artifact

parent 53df3201
...@@ -32,9 +32,19 @@ $ mvn install ...@@ -32,9 +32,19 @@ $ mvn install
The Maven script will try to detect the OS and the architecture from Java The Maven script will try to detect the OS and the architecture from Java
system properties. It's possible to build a protoc binary for an architecture system properties. It's possible to build a protoc binary for an architecture
that is different from what Java has detected, as long as you have the proper that is different from what Java has detected, as long as you have the proper
compilers installed. For example, MingGW32 only ships with 32-bit compilers, compilers installed.
but you can still build 32-bit protoc under a 64-bit system, with the following
command: You can override the Maven properties ``os.detected.name`` and
``os.detected.arch`` to force the script to generate binaries for a specific OS
and/or architecture. Valid values are defined as the return values of
``normalizeOs()`` and ``normalizeArch()`` of ``Detector`` from
[os-maven-plugin](https://github.com/trustin/os-maven-plugin/blob/master/src/main/java/kr/motd/maven/os/Detector.java).
Frequently used values are:
- ``os.detected.name``: ``linux``, ``osx``, ``windows``.
- ``os.detected.arch``: ``x86_32``, ``x86_64``
For example, MingGW32 only ships with 32-bit compilers, but you can still build
32-bit protoc under 64-bit Windows, with the following command:
``` ```
$ mvn install -Dos.detected.arch=x86_32 $ mvn install -Dos.detected.arch=x86_32
``` ```
...@@ -48,4 +58,3 @@ Use the following command to upload artifacts: ...@@ -48,4 +58,3 @@ Use the following command to upload artifacts:
``` ```
$ mvn clean deploy -P release $ mvn clean deploy -P release
``` ```
...@@ -7,6 +7,11 @@ ...@@ -7,6 +7,11 @@
OS=$1 OS=$1
ARCH=$2 ARCH=$2
if [[ $# < 2 ]]; then
echo "No arguments provided. This script is intended to be run from Maven."
exit 1
fi
# Under Cygwin, bash doesn't have these in PATH when called from Maven which # Under Cygwin, bash doesn't have these in PATH when called from Maven which
# runs in Windows version of Java. # runs in Windows version of Java.
export PATH="/bin:/usr/bin:$PATH" export PATH="/bin:/usr/bin:$PATH"
...@@ -17,6 +22,7 @@ export PATH="/bin:/usr/bin:$PATH" ...@@ -17,6 +22,7 @@ export PATH="/bin:/usr/bin:$PATH"
E_PARAM_ERR=98 E_PARAM_ERR=98
E_ASSERT_FAILED=99 E_ASSERT_FAILED=99
# Usage:
fail() fail()
{ {
echo "Error: $1" echo "Error: $1"
...@@ -38,11 +44,45 @@ assertEq () ...@@ -38,11 +44,45 @@ assertEq ()
exit $E_ASSERT_FAILED exit $E_ASSERT_FAILED
fi fi
} }
# Checks the artifact is for the expected architecture
# Usage: checkArch <path-to-protoc>
checkArch ()
{
if [[ "$OS" == windows || "$OS" == linux ]]; then
format="$(objdump -f "$1" | grep -o "file format .*$" | grep -o "[^ ]*$")"
if [[ "$OS" == linux ]]; then
if [[ "$ARCH" == x86_32 ]]; then
assertEq $format "elf32-i386" $LINENO
elif [[ "$ARCH" == x86_64 ]]; then
assertEq $format "elf64-x86-64" $LINENO
else
fail "Unsupported arch: $ARCH"
fi
else
# $OS == windows
if [[ "$ARCH" == x86_32 ]]; then
assertEq $format "pei-i386" $LINENO
elif [[ "$ARCH" == x86_64 ]]; then
assertEq $format "pei-x86-64" $LINENO
else
fail "Unsupported arch: $ARCH"
fi
fi
elif [[ "$OS" == osx ]]; then
format="$(file -b "$1" | grep -o "[^ ]*$")"
assertEq $format "x86_64" $LINENO
else
fail "Unsupported system: $(uname)"
fi
}
############################################################################ ############################################################################
echo "Building protoc, OS=$OS ARCH=$ARCH" echo "Building protoc, OS=$OS ARCH=$ARCH"
cd "$(dirname \"$0\")" # Nested double quotes are unintuitive, but it works.
cd "$(dirname "$0")"
WORKING_DIR=$(pwd) WORKING_DIR=$(pwd)
CONFIGURE_ARGS="--disable-shared" CONFIGURE_ARGS="--disable-shared"
...@@ -51,6 +91,10 @@ if [[ "$OS" == windows ]]; then ...@@ -51,6 +91,10 @@ if [[ "$OS" == windows ]]; then
MAKE_TARGET="${MAKE_TARGET}.exe" MAKE_TARGET="${MAKE_TARGET}.exe"
fi fi
# Override the default value set in configure.ac that has '-g' which produces
# huge binary.
CXXFLAGS="-DNDEBUG"
if [[ "$(uname)" == CYGWIN* ]]; then if [[ "$(uname)" == CYGWIN* ]]; then
assertEq "$OS" windows $LINENO assertEq "$OS" windows $LINENO
# Use mingw32 compilers because executables produced by Cygwin compiler # Use mingw32 compilers because executables produced by Cygwin compiler
...@@ -68,11 +112,11 @@ elif [[ "$(uname)" == MINGW32* ]]; then ...@@ -68,11 +112,11 @@ elif [[ "$(uname)" == MINGW32* ]]; then
elif [[ "$(uname)" == Linux* ]]; then elif [[ "$(uname)" == Linux* ]]; then
assertEq "$OS" linux $LINENO assertEq "$OS" linux $LINENO
if [[ "$ARCH" == x86_64 ]]; then if [[ "$ARCH" == x86_64 ]]; then
CONFIGURE_ARGS="$CONFIGURE_ARGS --host=x86_64-linux-gnu" CXXFLAGS="$CXXFLAGS -m64"
elif [[ "$ARCH" == x86_32 ]]; then elif [[ "$ARCH" == x86_32 ]]; then
CONFIGURE_ARGS="$CONFIGURE_ARGS --host=i686-linux-gnu" CXXFLAGS="$CXXFLAGS -m32"
else else
fail "Unsupported arch by CYGWIN: $ARCH" fail "Unsupported arch: $ARCH"
fi fi
elif [[ "$(uname)" == Darwin* ]]; then elif [[ "$(uname)" == Darwin* ]]; then
assertEq "$OS" osx $LINENO assertEq "$OS" osx $LINENO
...@@ -80,9 +124,7 @@ else ...@@ -80,9 +124,7 @@ else
fail "Unsupported system: $(uname)" fail "Unsupported system: $(uname)"
fi fi
# Override the default value set in configure.ac that has '-g' which produces export CXXFLAGS
# huge binary.
export CXXFLAGS="-DNDEBUG"
# Statically link libgcc and libstdc++. # Statically link libgcc and libstdc++.
# -s to produce stripped binary. # -s to produce stripped binary.
...@@ -91,7 +133,10 @@ if [[ "$OS" != osx ]]; then ...@@ -91,7 +133,10 @@ if [[ "$OS" != osx ]]; then
export LDFLAGS="-static-libgcc -static-libstdc++ -s" export LDFLAGS="-static-libgcc -static-libstdc++ -s"
fi fi
TARGET_FILE=target/protoc.exe
cd "$WORKING_DIR"/.. && ./configure $CONFIGURE_ARGS && cd "$WORKING_DIR"/.. && ./configure $CONFIGURE_ARGS &&
cd src && make clean && make $MAKE_TARGET && cd src && make clean && make $MAKE_TARGET &&
cd "$WORKING_DIR" && mkdir -p target && cd "$WORKING_DIR" && mkdir -p target &&
(cp ../src/protoc target/protoc.exe || cp ../src/protoc.exe target/protoc.exe) (cp ../src/protoc $TARGET_FILE || cp ../src/protoc.exe $TARGET_FILE) &&
checkArch $TARGET_FILE
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment