Commit f0b510ac authored by Jisi Liu's avatar Jisi Liu

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

Process to deploy artifacts for multiple platforms into a single release.
parents 8750f725 1c12612b
...@@ -54,7 +54,67 @@ Before you can upload artifacts to Maven Central repository, make sure you have ...@@ -54,7 +54,67 @@ Before you can upload artifacts to Maven Central repository, make sure you have
read [this page](http://central.sonatype.org/pages/apache-maven.html) on how to read [this page](http://central.sonatype.org/pages/apache-maven.html) on how to
configure GPG and Sonatype account. configure GPG and Sonatype account.
Use the following command to upload artifacts: You need to perform the deployment for every platform that you want to
suppport. DO NOT close the staging repository until you have done the
deployment for all platforms. Currently the following platforms are supported:
- Linux (x86_32 and x86_64)
- Windows (x86_32 and x86_64) with
- Cygwin with MinGW compilers (both x86_32 and x86_64)
- MSYS with MinGW32 (x86_32 only)
- MacOSX (x86_32 and x86_64)
Remove any ``SNAPSHOT`` or ``pre`` suffix from the version string before
deploying.
Use the following command to deploy artifacts for the host platform to a
staging repository.
``` ```
$ mvn clean deploy -P release $ mvn clean deploy -P release
``` ```
It creates a new staging repository. Go to
https://oss.sonatype.org/#stagingRepositories and find the repository, usually
in the name like ``comgoogle-123``.
You will want to run this command on a different platform. Remember, in
subsequent deployments you will need to provide the repository name that you
have found in the first deployment so that all artifacts go to the same
repository:
```
$ mvn clean deploy -P release -Dstaging.repository=comgoogle-123
```
A 32-bit artifact can be deployed from a 64-bit host with
``-Dos.detected.arch=x86_32``
When you have done deployment for all platforms, go to
https://oss.sonatype.org/#stagingRepositories, verify that the staging
repository has all the binaries, close and release this repository.
### Tips for deploying on Windows
Under Windows the following error may occur: ``gpg: cannot open tty `no tty':
No such file or directory``. This can be fixed by configuring gpg through an
active profile in ``.m2\settings.xml`` where also the Sonatype password is
stored:
```xml
<settings>
<servers>
<server>
<id>ossrh</id>
<username>[username]</username>
<password>[password]</password>
</server>
</servers>
<profiles>
<profile>
<id>gpg</id>
<properties>
<gpg.executable>gpg</gpg.executable>
<gpg.passphrase>[password]</gpg.passphrase>
</properties>
</profile>
</profiles>
<activeProfiles>
<activeProfile>gpg</activeProfile>
</activeProfiles>
</settings>
```
...@@ -25,7 +25,8 @@ E_ASSERT_FAILED=99 ...@@ -25,7 +25,8 @@ E_ASSERT_FAILED=99
# Usage: # Usage:
fail() fail()
{ {
echo "Error: $1" echo "ERROR: $1"
echo
exit $E_ASSERT_FAILED exit $E_ASSERT_FAILED
} }
...@@ -49,8 +50,11 @@ assertEq () ...@@ -49,8 +50,11 @@ assertEq ()
# Usage: checkArch <path-to-protoc> # Usage: checkArch <path-to-protoc>
checkArch () checkArch ()
{ {
echo
echo "Checking file format ..."
if [[ "$OS" == windows || "$OS" == linux ]]; then if [[ "$OS" == windows || "$OS" == linux ]]; then
format="$(objdump -f "$1" | grep -o "file format .*$" | grep -o "[^ ]*$")" format="$(objdump -f "$1" | grep -o "file format .*$" | grep -o "[^ ]*$")"
echo Format=$format
if [[ "$OS" == linux ]]; then if [[ "$OS" == linux ]]; then
if [[ "$ARCH" == x86_32 ]]; then if [[ "$ARCH" == x86_32 ]]; then
assertEq $format "elf32-i386" $LINENO assertEq $format "elf32-i386" $LINENO
...@@ -71,10 +75,54 @@ checkArch () ...@@ -71,10 +75,54 @@ checkArch ()
fi fi
elif [[ "$OS" == osx ]]; then elif [[ "$OS" == osx ]]; then
format="$(file -b "$1" | grep -o "[^ ]*$")" format="$(file -b "$1" | grep -o "[^ ]*$")"
assertEq $format "x86_64" $LINENO echo Format=$format
if [[ "$ARCH" == x86_32 ]]; then
assertEq $format "i386" $LINENO
elif [[ "$ARCH" == x86_64 ]]; then
assertEq $format "x86_64" $LINENO
else
fail "Unsupported arch: $ARCH"
fi
else else
fail "Unsupported system: $(uname)" fail "Unsupported system: $OS"
fi fi
echo
}
# Checks the dependencies of the artifact. Artifacts should only depend on
# system libraries.
# Usage: checkDependencies <path-to-protoc>
checkDependencies ()
{
if [[ "$OS" == windows ]]; then
dump_cmd='objdump -x '"$1"' | fgrep "DLL Name"'
white_list="KERNEL32\.dll\|msvcrt\.dll"
elif [[ "$OS" == linux ]]; then
dump_cmd='ldd '"$1"
if [[ "$ARCH" == x86_32 ]]; then
white_list="linux-gate\.so\.1\|libpthread\.so\.0\|libm\.so\.6\|libc\.so\.6\|ld-linux\.so\.2"
elif [[ "$ARCH" == x86_64 ]]; then
white_list="linux-vdso\.so\.1\|libpthread\.so\.0\|libm\.so\.6\|libc\.so\.6\|ld-linux-x86-64\.so\.2"
fi
elif [[ "$OS" == osx ]]; then
dump_cmd='otool -L '"$1"' | fgrep dylib'
white_list="libz\.1\.dylib\|libstdc++\.6\.dylib\|libSystem\.B\.dylib"
fi
if [[ -z "$white_list" || -z "$dump_cmd" ]]; then
fail "Unsupported platform $OS-$ARCH."
fi
echo "Checking for expected dependencies ..."
eval $dump_cmd | grep -i "$white_list" || fail "doesn't show any expected dependencies"
echo "Checking for unexpected dependencies ..."
eval $dump_cmd | grep -i -v "$white_list"
ret=$?
if [[ $ret == 0 ]]; then
fail "found unexpected dependencies (listed above)."
elif [[ $ret != 1 ]]; then
fail "Error when checking dependencies."
fi # grep returns 1 when "not found", which is what we expect
echo "Dependencies look good."
echo
} }
############################################################################ ############################################################################
...@@ -94,6 +142,7 @@ fi ...@@ -94,6 +142,7 @@ fi
# Override the default value set in configure.ac that has '-g' which produces # Override the default value set in configure.ac that has '-g' which produces
# huge binary. # huge binary.
CXXFLAGS="-DNDEBUG" CXXFLAGS="-DNDEBUG"
LDFLAGS=""
if [[ "$(uname)" == CYGWIN* ]]; then if [[ "$(uname)" == CYGWIN* ]]; then
assertEq "$OS" windows $LINENO assertEq "$OS" windows $LINENO
...@@ -110,7 +159,33 @@ elif [[ "$(uname)" == MINGW32* ]]; then ...@@ -110,7 +159,33 @@ elif [[ "$(uname)" == MINGW32* ]]; then
assertEq "$OS" windows $LINENO assertEq "$OS" windows $LINENO
assertEq "$ARCH" x86_32 $LINENO assertEq "$ARCH" x86_32 $LINENO
elif [[ "$(uname)" == Linux* ]]; then elif [[ "$(uname)" == Linux* ]]; then
assertEq "$OS" linux $LINENO if [[ "$OS" == linux ]]; then
if [[ "$ARCH" == x86_64 ]]; then
CXXFLAGS="$CXXFLAGS -m64"
elif [[ "$ARCH" == x86_32 ]]; then
CXXFLAGS="$CXXFLAGS -m32"
else
fail "Unsupported arch: $ARCH"
fi
elif [[ "$OS" == windows ]]; then
# Cross-compilation for Windows
# TODO(zhangkun83) MinGW 64 always adds dependency on libwinpthread-1.dll,
# which is undesirable for repository deployment.
CONFIGURE_ARGS="$CONFIGURE_ARGS"
if [[ "$ARCH" == x86_64 ]]; then
CONFIGURE_ARGS="$CONFIGURE_ARGS --host=x86_64-w64-mingw32"
elif [[ "$ARCH" == x86_32 ]]; then
CONFIGURE_ARGS="$CONFIGURE_ARGS --host=i686-w64-mingw32"
else
fail "Unsupported arch: $ARCH"
fi
else
fail "Cannot build $OS on $(uname)"
fi
elif [[ "$(uname)" == Darwin* ]]; then
assertEq "$OS" osx $LINENO
# Make the binary compatible with OSX 10.7 and later
CXXFLAGS="$CXXFLAGS -mmacosx-version-min=10.7"
if [[ "$ARCH" == x86_64 ]]; then if [[ "$ARCH" == x86_64 ]]; then
CXXFLAGS="$CXXFLAGS -m64" CXXFLAGS="$CXXFLAGS -m64"
elif [[ "$ARCH" == x86_32 ]]; then elif [[ "$ARCH" == x86_32 ]]; then
...@@ -118,25 +193,30 @@ elif [[ "$(uname)" == Linux* ]]; then ...@@ -118,25 +193,30 @@ elif [[ "$(uname)" == Linux* ]]; then
else else
fail "Unsupported arch: $ARCH" fail "Unsupported arch: $ARCH"
fi fi
elif [[ "$(uname)" == Darwin* ]]; then
assertEq "$OS" osx $LINENO
else else
fail "Unsupported system: $(uname)" fail "Unsupported system: $(uname)"
fi fi
export CXXFLAGS
# Statically link libgcc and libstdc++. # Statically link libgcc and libstdc++.
# -s to produce stripped binary. # -s to produce stripped binary.
# And they don't work under Mac. # And they don't work under Mac.
if [[ "$OS" != osx ]]; then if [[ "$OS" != osx ]]; then
export LDFLAGS="-static-libgcc -static-libstdc++ -s" LDFLAGS="$LDFLAGS -static-libgcc -static-libstdc++ -s"
fi fi
export CXXFLAGS LDFLAGS
TARGET_FILE=target/protoc.exe 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_FILE || cp ../src/protoc.exe $TARGET_FILE) && (cp ../src/protoc $TARGET_FILE || cp ../src/protoc.exe $TARGET_FILE) ||
checkArch $TARGET_FILE exit 1
if [[ "$OS" == osx ]]; then
# Since Mac linker doesn't accept "-s", we need to run strip
strip $TARGET_FILE || exit 1
fi
checkArch $TARGET_FILE && checkDependencies $TARGET_FILE
...@@ -90,6 +90,14 @@ ...@@ -90,6 +90,14 @@
<profiles> <profiles>
<profile> <profile>
<id>release</id> <id>release</id>
<properties>
<!-- Specify the staging repository to deploy to. This can be left
empty for the first deployment, and Sonatype will create one. For
subsequent deployments it should be set to what Sonatype has
created, so that all deployments will go to the same repository.
-->
<staging.repository></staging.repository>
</properties>
<build> <build>
<plugins> <plugins>
<plugin> <plugin>
...@@ -114,7 +122,9 @@ ...@@ -114,7 +122,9 @@
<configuration> <configuration>
<serverId>sonatype-nexus-staging</serverId> <serverId>sonatype-nexus-staging</serverId>
<nexusUrl>https://oss.sonatype.org/</nexusUrl> <nexusUrl>https://oss.sonatype.org/</nexusUrl>
<skipStagingRepositoryClose>true</skipStagingRepositoryClose>
<autoReleaseAfterClose>false</autoReleaseAfterClose> <autoReleaseAfterClose>false</autoReleaseAfterClose>
<stagingRepositoryId>${staging.repository}</stagingRepositoryId>
</configuration> </configuration>
</plugin> </plugin>
</plugins> </plugins>
......
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