소스 검색

Merge pull request #269 from zhangkun83/protoc-artifact-maven

Better support for cross-compilation
Jisi Liu 10 년 전
부모
커밋
8d9e51cf4e
2개의 변경된 파일66개의 추가작업 그리고 12개의 파일을 삭제
  1. 13 4
      protoc-artifacts/README.md
  2. 53 8
      protoc-artifacts/build-protoc.sh

+ 13 - 4
protoc-artifacts/README.md

@@ -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,
-but you can still build 32-bit protoc under a 64-bit system, with the following
-command:
+compilers installed.
+
+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:
 ```
 ```
 $ mvn clean deploy -P release
 $ mvn clean deploy -P release
 ```
 ```
-

+ 53 - 8
protoc-artifacts/build-protoc.sh

@@ -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"
 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 ()
     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
   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
 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
   fail "Unsupported system: $(uname)"
   fail "Unsupported system: $(uname)"
 fi
 fi
 
 
-# Override the default value set in configure.ac that has '-g' which produces
-# huge binary.
-export CXXFLAGS="-DNDEBUG"
+export CXXFLAGS
 
 
 # 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
   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