|
| 1 | +#!/bin/bash -eu |
| 2 | + |
| 3 | +# Copyright 2016 The Bazel Authors. All rights reserved. |
| 4 | +# |
| 5 | +# Licensed under the Apache License, Version 2.0 (the "License"); |
| 6 | +# you may not use this file except in compliance with the License. |
| 7 | +# You may obtain a copy of the License at |
| 8 | +# |
| 9 | +# http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | +# |
| 11 | +# Unless required by applicable law or agreed to in writing, software |
| 12 | +# distributed under the License is distributed on an "AS IS" BASIS, |
| 13 | +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 14 | +# See the License for the specific language governing permissions and |
| 15 | +# limitations under the License. |
| 16 | + |
| 17 | +# It's not a good idea to link an MSYS dynamic library into a native Windows |
| 18 | +# JVM, so we need to build it with Visual Studio. However, Bazel doesn't |
| 19 | +# support multiple compilers in the same build yet, so we need to hack around |
| 20 | +# this limitation using a genrule. |
| 21 | + |
| 22 | +DLL="$1" |
| 23 | +shift 1 |
| 24 | + |
| 25 | +function fail() { |
| 26 | + echo >&2 "ERROR: $@" |
| 27 | + exit 1 |
| 28 | +} |
| 29 | + |
| 30 | +# Ensure the PATH is set up correctly. |
| 31 | +if ! which which >&/dev/null ; then |
| 32 | + PATH="/bin:/usr/bin:$PATH" |
| 33 | + which which >&/dev/null \ |
| 34 | + || fail "System PATH is not set up correctly, cannot run GNU bintools" |
| 35 | +fi |
| 36 | + |
| 37 | +# Create a temp directory. It will used for the batch file we generate soon and |
| 38 | +# as the temp directory for CL.EXE . |
| 39 | +VSTEMP=$(mktemp -d) |
| 40 | +trap "rm -fr \"$VSTEMP\"" EXIT |
| 41 | + |
| 42 | +# Find Visual Studio. We don't have any regular environment variables available |
| 43 | +# so this is the best we can do. |
| 44 | +if [ -z "${BAZEL_VS+set}" ]; then |
| 45 | + VSVERSION="$(ls "C:/Program Files (x86)" \ |
| 46 | + | grep -E "Microsoft Visual Studio [0-9]+" \ |
| 47 | + | sort --version-sort \ |
| 48 | + | tail -n 1)" |
| 49 | + [[ -n "$VSVERSION" ]] || fail "Visual Studio not found" |
| 50 | + BAZEL_VS="C:/Program Files (x86)/$VSVERSION" |
| 51 | +fi |
| 52 | +VSVARS="${BAZEL_VS}/VC/VCVARSALL.BAT" |
| 53 | + |
| 54 | +# Check if Visual Studio 2017 is installed. Look for it at the default |
| 55 | +# locations. |
| 56 | +if [ ! -f "${VSVARS}" ]; then |
| 57 | + VSVARS="C:/Program Files (x86)/Microsoft Visual Studio/2017/" |
| 58 | + VSEDITION="BuildTools" |
| 59 | + if [ -d "${VSVARS}Enterprise" ]; then |
| 60 | + VSEDITION="Enterprise" |
| 61 | + elif [ -d "${VSVARS}Professional" ]; then |
| 62 | + VSEDITION="Professional" |
| 63 | + elif [ -d "${VSVARS}Community" ]; then |
| 64 | + VSEDITION="Community" |
| 65 | + fi |
| 66 | + VSVARS+="$VSEDITION/VC/Auxiliary/Build/VCVARSALL.BAT" |
| 67 | +fi |
| 68 | + |
| 69 | +if [ ! -f "${VSVARS}" ]; then |
| 70 | + fail "VCVARSALL.bat not found, check your Visual Studio installation" |
| 71 | +fi |
| 72 | + |
| 73 | +# Find Java. $(JAVA) in the BUILD file points to external/local_jdk/..., which |
| 74 | +# is not very useful for anything not MSYS-based. |
| 75 | +JAVA=$(ls "C:/Program Files/java" | grep -E "^jdk" | sort | tail -n 1) |
| 76 | +[[ -n "$JAVA" ]] || fail "JDK not found" |
| 77 | +JAVAINCLUDES="C:/Program Files/java/$JAVA/include" |
| 78 | + |
| 79 | +# Convert all compilation units to Windows paths. |
| 80 | +WINDOWS_SOURCES=() |
| 81 | +for i in $*; do |
| 82 | + if [[ "$i" =~ ^.*\.cc$ ]]; then |
| 83 | + WINDOWS_SOURCES+=("\"$(cygpath -a -w $i)\"") |
| 84 | + fi |
| 85 | +done |
| 86 | + |
| 87 | +# Copy jni headers to src/main/native folder |
| 88 | +# Mimic genrule //src/main/native:copy_link_jni_md_header and //src/main/native:copy_link_jni_header |
| 89 | +JNI_HEADERS_DIR="${VSTEMP}/src/main/native" |
| 90 | +mkdir -p "$JNI_HEADERS_DIR" |
| 91 | +cp -f "$JAVAINCLUDES/jni.h" "$JNI_HEADERS_DIR/" |
| 92 | +cp -f "$JAVAINCLUDES/win32/jni_md.h" "$JNI_HEADERS_DIR/" |
| 93 | + |
| 94 | +# CL.EXE needs a bunch of environment variables whose official location is a |
| 95 | +# batch file. We can't make that have an effect on a bash instance, so |
| 96 | +# generate a batch file that invokes it. |
| 97 | +cat > "${VSTEMP}/windows_jni.bat" <<EOF |
| 98 | +@echo OFF |
| 99 | +@call "${VSVARS}" amd64 |
| 100 | +@cd $(cygpath -a -w "${PWD}") |
| 101 | +@set TMP=$(cygpath -a -w "${VSTEMP}") |
| 102 | +@CL /O2 /EHsc /LD /Fe:"$(cygpath -a -w ${DLL})" /I "${VSTEMP}" /I . ${WINDOWS_SOURCES[*]} |
| 103 | +EOF |
| 104 | + |
| 105 | +# Invoke the file and hopefully generate the .DLL . |
| 106 | +chmod +x "${VSTEMP}/windows_jni.bat" |
| 107 | +exec "${VSTEMP}/windows_jni.bat" |
0 commit comments