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
read [this page](http://central.sonatype.org/pages/apache-maven.html) on how to
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
```
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
# Usage:
fail()
{
echo "Error: $1"
echo "ERROR: $1"
echo
exit $E_ASSERT_FAILED
}
......@@ -49,8 +50,11 @@ assertEq ()
# Usage: checkArch <path-to-protoc>
checkArch ()
{
echo
echo "Checking file format ..."
if [[ "$OS" == windows || "$OS" == linux ]]; then
format="$(objdump -f "$1" | grep -o "file format .*$" | grep -o "[^ ]*$")"
echo Format=$format
if [[ "$OS" == linux ]]; then
if [[ "$ARCH" == x86_32 ]]; then
assertEq $format "elf32-i386" $LINENO
......@@ -71,10 +75,54 @@ checkArch ()
fi
elif [[ "$OS" == osx ]]; then
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
fail "Unsupported system: $(uname)"
fail "Unsupported system: $OS"
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
# Override the default value set in configure.ac that has '-g' which produces
# huge binary.
CXXFLAGS="-DNDEBUG"
LDFLAGS=""
if [[ "$(uname)" == CYGWIN* ]]; then
assertEq "$OS" windows $LINENO
......@@ -110,7 +159,33 @@ elif [[ "$(uname)" == MINGW32* ]]; then
assertEq "$OS" windows $LINENO
assertEq "$ARCH" x86_32 $LINENO
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
CXXFLAGS="$CXXFLAGS -m64"
elif [[ "$ARCH" == x86_32 ]]; then
......@@ -118,25 +193,30 @@ elif [[ "$(uname)" == Linux* ]]; then
else
fail "Unsupported arch: $ARCH"
fi
elif [[ "$(uname)" == Darwin* ]]; then
assertEq "$OS" osx $LINENO
else
fail "Unsupported system: $(uname)"
fi
export CXXFLAGS
# Statically link libgcc and libstdc++.
# -s to produce stripped binary.
# And they don't work under Mac.
if [[ "$OS" != osx ]]; then
export LDFLAGS="-static-libgcc -static-libstdc++ -s"
LDFLAGS="$LDFLAGS -static-libgcc -static-libstdc++ -s"
fi
export CXXFLAGS LDFLAGS
TARGET_FILE=target/protoc.exe
cd "$WORKING_DIR"/.. && ./configure $CONFIGURE_ARGS &&
cd src && make clean && make $MAKE_TARGET &&
cd "$WORKING_DIR" && mkdir -p target &&
(cp ../src/protoc $TARGET_FILE || cp ../src/protoc.exe $TARGET_FILE) &&
checkArch $TARGET_FILE
(cp ../src/protoc $TARGET_FILE || cp ../src/protoc.exe $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 @@
<profiles>
<profile>
<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>
<plugins>
<plugin>
......@@ -114,7 +122,9 @@
<configuration>
<serverId>sonatype-nexus-staging</serverId>
<nexusUrl>https://oss.sonatype.org/</nexusUrl>
<skipStagingRepositoryClose>true</skipStagingRepositoryClose>
<autoReleaseAfterClose>false</autoReleaseAfterClose>
<stagingRepositoryId>${staging.repository}</stagingRepositoryId>
</configuration>
</plugin>
</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