Skip to content

Commit

Permalink
Fix build on Windows/VC++
Browse files Browse the repository at this point in the history
- 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++
  • Loading branch information
zhangkun83 committed May 4, 2015
1 parent b6eb9d7 commit 221c534
Show file tree
Hide file tree
Showing 10 changed files with 78 additions and 101 deletions.
32 changes: 18 additions & 14 deletions DEPLOYING.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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"
```


Expand All @@ -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
Expand Down
20 changes: 16 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
----------------------------

Expand Down
2 changes: 1 addition & 1 deletion benchmarks/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
6 changes: 3 additions & 3 deletions compiler/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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"
```

Expand Down
109 changes: 35 additions & 74 deletions compiler/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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 ->
Expand All @@ -53,55 +35,40 @@ def addLibraryIfNotLinked = { libName, argList ->
}
}

def String arch = osdetector.arch
if (System.getProperty('arch')) {
arch = System.getProperty('arch')
}

model {
toolChains {
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"
}
// 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) {
}
target('local_arch') { }
}
gcc(Gcc) {
}
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"
}
Expand Down Expand Up @@ -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'
Expand All @@ -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
}
}

Expand All @@ -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
Expand All @@ -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();
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/check-artifact.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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"
2 changes: 1 addition & 1 deletion compiler/src/test/run_nano_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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" && \
Expand Down
2 changes: 1 addition & 1 deletion examples/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
2 changes: 1 addition & 1 deletion integration-testing/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 221c534

Please sign in to comment.