Fix build on Windows/VC++

- Stop defining custom architectures because VisualCpp toolchain doesn't
  allow it. Reference to built-in architectures 'x86' and 'x86_64' since
  they are supported by all toolchains.
- Remove 'local_arch' from platforms. For unsupported platform, we just
  do not specify the target.
- Target no more than one platform at a time. This simplifies the build
  script a lot.
- Remove the TARGET_ARCHS environment variable. Add system property
  ``arch`` to override ``osdetector.arch``.
- Add ``vc.disable`` to override the default choice of VisualCpp on
  Windows.
- Add ``vc.`` prefix to the properties that are only used with VC++
This commit is contained in:
Kun Zhang 2015-04-29 18:16:15 -07:00
parent b6eb9d763d
commit 221c534f11
10 changed files with 78 additions and 101 deletions

View File

@ -129,8 +129,7 @@ the header files and libraries of Protobuf.
#### Linux
```
$ export CXXFLAGS="-I$HOME/protobuf-32/include" \
LDFLAGS="-L$HOME/protobuf-32/lib -L$HOME/protobuf-64/lib" \
TARGET_ARCHS="x86_32 x86_64"
LDFLAGS="-L$HOME/protobuf-32/lib -L$HOME/protobuf-64/lib"
```
#### Windows 64-bit with MSYS2
@ -139,23 +138,20 @@ $ export CXXFLAGS="-I$HOME/protobuf-32/include" \
```
$ export CXXFLAGS="-I$HOME/protobuf-32/include" \
LDFLAGS="-L$HOME/protobuf-32/lib" \
TARGET_ARCHS="x86_32"
LDFLAGS="-L$HOME/protobuf-32/lib"
```
##### Under MinGW-w64 Win64 Shell
```
$ export CXXFLAGS="-I$HOME/protobuf-64/include" \
LDFLAGS="-L$HOME/protobuf-64/lib" \
TARGET_ARCHS="x86_64"
LDFLAGS="-L$HOME/protobuf-64/lib"
```
#### Mac
```
$ export CXXFLAGS="-I$HOME/protobuf/include" \
LDFLAGS="$HOME/protobuf/lib/libprotobuf.a $HOME/protobuf/lib/libprotoc.a" \
TARGET_ARCHS="x86_64"
LDFLAGS="$HOME/protobuf/lib/libprotobuf.a $HOME/protobuf/lib/libprotoc.a"
```
@ -174,19 +170,27 @@ artifacts will go to a freshly created staging repository.
### Deploy GRPC Codegen for Additional Platforms
The previous step will only deploy the codegen artifacts for the platform you
run on it. For a fully fledged deployment, you will need to deploy the codegen
for all other supported platforms. To do so, move on the next platform, set up
the prerequisites and environment variables, then
The previous step will only deploy the codegen artifacts for the OS you run on
it and the architecture of your JVM. For a fully fledged deployment, you will
need to deploy the codegen for all other supported OSes and architectures.
To deploy the codegen for an OS and architecture, you must run the following
commands on that OS and specify the architecture by the flag ``-Darch=<arch>``.
We currently distribute the following OSes and architectures:
- Linux: ``x86_32``, ``x86_64``
- Windows: ``x86_32``, ``x86_64``
- Mac: ``x86_64``
If you are doing a snapshot deployment:
```
grpc-java$ ./gradlew clean grpc-compiler:uploadArchives
grpc-java$ ./gradlew clean grpc-compiler:uploadArchives -Darch=<arch>
```
If you are doing a release deployment:
```
grpc-java$ ./gradlew clean grpc-compiler:uploadArchives -DrepositoryId=<repository-id>
grpc-java$ ./gradlew clean grpc-compiler:uploadArchives -Darch=<arch> \
-DrepositoryId=<repository-id>
```
where ``<repository-id>`` is the ID of the staging repository that you have
found from the OSSRH UI after the first deployment, usually in the form of

View File

@ -59,20 +59,32 @@ On Linux, Mac or MinGW:
$ ./gradlew install
```
### Notes for Visual C++
When building on Windows and VC++, you need to specify project properties for
Gradle to find protobuf:
```
.\gradlew install -Pprotobuf.include=C:\path\to\protobuf-3.0.0-alpha-2\src ^
-Pprotobuf.libs=C:\path\to\protobuf-3.0.0-alpha-2\vsprojects\Release
.\gradlew install ^
-Pvc.protobuf.include=C:\path\to\protobuf-3.0.0-alpha-2\src ^
-Pvc.protobuf.libs=C:\path\to\protobuf-3.0.0-alpha-2\vsprojects\Release
```
Since specifying those properties every build is bothersome, you can instead
create ``%HOMEDRIVE%%HOMEPATH%\.gradle\gradle.properties`` with contents like:
```
protobuf.include=C:\\path\\to\\protobuf-3.0.0-alpha-2\\src
protobuf.libs=C:\\path\\to\\protobuf-3.0.0-alpha-2\\vsprojects\\Release
vc.protobuf.include=C:\\path\\to\\protobuf-3.0.0-alpha-2\\src
vc.protobuf.libs=C:\\path\\to\\protobuf-3.0.0-alpha-2\\vsprojects\\Release
```
The build script will build the codegen for the same architecture as the Java
runtime installed on your system. If you are using 64-bit JVM, the codegen will
be compiled for 64-bit, that means you must have compiled Protobuf in 64-bit.
### Notes for MinGW on Windows
If you have both MinGW and VC++ installed on Windows, VC++ will be used by
default. To override this default and use MinGW, add ``-Dvc.disable`` to your
Gradle command line.
Navigating Around the Source
----------------------------

View File

@ -82,7 +82,7 @@ applicationDistribution.into("bin") {
protobufCodeGenPlugins = ["java_plugin:$javaPluginPath"]
project.afterEvaluate {
generateProto.dependsOn ':grpc-compiler:local_archJava_pluginExecutable'
generateProto.dependsOn ':grpc-compiler:java_pluginExecutable'
}
// Allow intellij projects to refer to generated-sources

View File

@ -69,7 +69,7 @@ subprojects {
def exeSuffix = osdetector.os == 'windows' ? ".exe" : ""
protocPluginBaseName = 'protoc-gen-grpc-java'
javaPluginPath = "$rootDir/compiler/build/binaries/java_pluginExecutable/local_arch/$protocPluginBaseName$exeSuffix"
javaPluginPath = "$rootDir/compiler/build/binaries/java_pluginExecutable/$protocPluginBaseName$exeSuffix"
}
dependencies {

View File

@ -23,7 +23,7 @@ $ cd $GRPC_JAVA_ROOT/compiler
To compile the plugin:
```
$ ../gradlew local_archJava_pluginExecutable
$ ../gradlew java_pluginExecutable
```
To test the plugin with the compiler:
@ -34,12 +34,12 @@ You will see a `PASS` if the test succeeds.
To compile a proto file and generate Java interfaces out of the service definitions:
```
$ protoc --plugin=protoc-gen-java_rpc=build/binaries/java_pluginExecutable/local_arch/protoc-gen-grpc-java \
$ protoc --plugin=protoc-gen-java_rpc=build/binaries/java_pluginExecutable/protoc-gen-grpc-java \
--java_rpc_out="$OUTPUT_FILE" --proto_path="$DIR_OF_PROTO_FILE" "$PROTO_FILE"
```
To generate Java interfaces with protobuf nano:
```
$ protoc --plugin=protoc-gen-java_rpc=build/binaries/java_pluginExecutable/local_arch/protoc-gen-grpc-java \
$ protoc --plugin=protoc-gen-java_rpc=build/binaries/java_pluginExecutable/protoc-gen-grpc-java \
--java_rpc_out=nano=true:"$OUTPUT_FILE" --proto_path="$DIR_OF_PROTO_FILE" "$PROTO_FILE"
```

View File

@ -13,25 +13,7 @@ buildscript {
}
}
// When there is only one platform available, Gradle doesn't create a directory
// for the sole platform. In order to keep the script simple, we intentionally
// always build the 'local_arch' even though it's duplicate with one of the
// targetArchs, so that we always have at least two platforms.
def targetArchs = ['local_arch'] as HashSet
def artifactStagingPath = "$buildDir/artifacts" as File
def artifactPath = { arch ->
return "$artifactStagingPath/java_pluginExecutable/" + arch + "/${protocPluginBaseName}.exe"
}
if (System.env.TARGET_ARCHS != null) {
def archs = System.env.TARGET_ARCHS.split(' +')
targetArchs.addAll(archs)
} else {
targetArchs.add(osdetector.arch)
}
// Adds space-delimited arguments from the environment variable env to the
// argList.
def addEnvArgs = { env, argList ->
@ -53,55 +35,40 @@ def addLibraryIfNotLinked = { libName, argList ->
}
}
def String arch = osdetector.arch
if (System.getProperty('arch')) {
arch = System.getProperty('arch')
}
model {
toolChains {
// If you have both VC and Gcc installed, VC will be selected, unless you
// use '-Dvc.disable'
if (System.getProperty('vc.disable') == null) {
visualCpp(VisualCpp) {
}
}
gcc(Gcc) {
target("x86_64") {
cppCompiler.withArguments { args ->
args << "-m64"
}
linker.withArguments { args ->
args << "-m64"
}
}
target("x86_32") {
cppCompiler.withArguments { args ->
args << "-m32"
}
linker.withArguments { args ->
args << "-m32"
}
}
target('local_arch') { }
}
clang(Clang) {
target("x86_64") {
cppCompiler.withArguments { args ->
args << "-m64"
}
linker.withArguments { args ->
args << "-m64"
}
}
target('local_arch') { }
}
}
platforms {
x86_32 {
architecture "x86_32"
architecture "x86"
}
x86_64 {
architecture "x86_64"
}
local_arch {
architecture 'local_arch'
}
}
components {
java_plugin(NativeExecutableSpec) {
targetArchs.each {
targetPlatform it
if (arch in ['x86_32', 'x86_64']) {
// If arch is not within the defined platforms, we do not specify the
// targetPlatform so that Gradle will choose what is appropriate.
targetPlatform arch
}
baseName "$protocPluginBaseName"
}
@ -134,20 +101,18 @@ binaries.all {
addEnvArgs("LDFLAGS", linker.args)
} else if (toolChain in VisualCpp) {
cppCompiler.args "/EHsc", "/MD"
if (rootProject.hasProperty('protobuf.include')) {
cppCompiler.args "/I" + rootProject.properties['protobuf.include']
if (rootProject.hasProperty('vc.protobuf.include')) {
cppCompiler.args "/I" + rootProject.properties['vc.protobuf.include']
}
linker.args "libprotobuf.lib", "libprotoc.lib"
if (rootProject.hasProperty('protobuf.libs')) {
linker.args "/LIBPATH:" + rootProject.properties['protobuf.libs']
if (rootProject.hasProperty('vc.protobuf.libs')) {
linker.args "/LIBPATH:" + rootProject.properties['vc.protobuf.libs']
}
}
}
task buildArtifacts(type: Copy) {
targetArchs.each {
dependsOn it + 'Java_pluginExecutable'
}
dependsOn 'java_pluginExecutable'
from("$buildDir/binaries") {
if (osdetector.os != 'windows') {
rename 'protoc-gen-grpc-java', '$0.exe'
@ -159,13 +124,11 @@ task buildArtifacts(type: Copy) {
archivesBaseName = "$protocPluginBaseName"
artifacts {
for (arch in (targetArchs - 'local_arch')) {
archives(artifactPath(arch) as File) {
classifier osdetector.os + "-" + arch
type "exe"
extension "exe"
builtBy buildArtifacts
}
archives("$artifactStagingPath/java_pluginExecutable/${protocPluginBaseName}.exe" as File) {
classifier osdetector.os + "-" + arch
type "exe"
extension "exe"
builtBy buildArtifacts
}
}
@ -181,21 +144,19 @@ artifacts {
[
uploadArchives.repositories.mavenDeployer,
]*.beforeDeployment {
for (arch in (targetArchs - 'local_arch')) {
def ret = exec {
executable 'bash'
args 'check-artifact.sh', osdetector.os, arch
}
if (ret.exitValue != 0) {
throw new GradleException("check-artifact.sh exited with " + ret.exitValue)
}
def ret = exec {
executable 'bash'
args 'check-artifact.sh', osdetector.os, arch
}
if (ret.exitValue != 0) {
throw new GradleException("check-artifact.sh exited with " + ret.exitValue)
}
}
protobufCodeGenPlugins = ["java_plugin:$javaPluginPath"]
project.afterEvaluate {
generateTestProto.dependsOn 'local_archJava_pluginExecutable'
generateTestProto.dependsOn 'java_pluginExecutable'
}
// Ignore test for the moment on Windows. It will be easier to run once the
@ -216,7 +177,7 @@ task testGolden(type: Exec, dependsOn: 'generateTestProto') {
"$projectDir/src/test/golden/TestService.java.txt"
}
task testNanoGolden(type: Exec, dependsOn: 'local_archJava_pluginExecutable') {
task testNanoGolden(type: Exec, dependsOn: 'java_pluginExecutable') {
doFirst {
temporaryDir.createNewFile();
}

View File

@ -125,5 +125,5 @@ checkDependencies ()
echo
}
FILE="build/artifacts/java_pluginExecutable/$ARCH/protoc-gen-grpc-java.exe"
FILE="build/artifacts/java_pluginExecutable/protoc-gen-grpc-java.exe"
checkArch "$FILE" && checkDependencies "$FILE"

View File

@ -12,7 +12,7 @@ OUTPUT_FILE="$TEST_TMP_DIR/TestServiceGrpc.src.jar"
GRPC_FILE="$TEST_TMP_DIR/io/grpc/testing/integration/TestServiceGrpc.java"
GOLDEN_FILE="golden/TestServiceNano.java.txt"
protoc --plugin=protoc-gen-java_rpc=../../build/binaries/java_pluginExecutable/local_arch/protoc-gen-grpc-java \
protoc --plugin=protoc-gen-java_rpc=../../build/binaries/java_pluginExecutable/protoc-gen-grpc-java \
--java_rpc_out=nano=true:"$OUTPUT_FILE" "$INPUT_FILE" && \
unzip -o -d "$TEST_TMP_DIR" "$OUTPUT_FILE" && \
diff "$GRPC_FILE" "$GOLDEN_FILE" && \

View File

@ -25,7 +25,7 @@ dependencies {
protobufCodeGenPlugins = ["java_plugin:$javaPluginPath"]
project.afterEvaluate {
generateProto.dependsOn ':grpc-compiler:local_archJava_pluginExecutable'
generateProto.dependsOn ':grpc-compiler:java_pluginExecutable'
}
task routeGuideServer(type: JavaExec) {

View File

@ -57,7 +57,7 @@ task execute(dependsOn: classes, type:JavaExec) {
protobufCodeGenPlugins = ["java_plugin:$javaPluginPath"]
project.afterEvaluate {
generateProto.dependsOn ':grpc-compiler:local_archJava_pluginExecutable'
generateProto.dependsOn ':grpc-compiler:java_pluginExecutable'
}
// Allow intellij projects to refer to generated-sources