Skip to content

Commit

Permalink
Improved Eclipse support for the Bazel project
Browse files Browse the repository at this point in the history
Now the paths are 100% determined using Bazel query. To adapt to
another project, change the variables at the top of the
setup-eclipse.sh file. It also handles correctly java_plugins now.

Because we must do queries on the full workspace, it is not easy to
embed in a bazel build. I made a prototype for it but it is really
impractical.

--
MOS_MIGRATED_REVID=91580472
  • Loading branch information
damienmg authored and hanwen committed Apr 20, 2015
1 parent d95efa3 commit f9971e6
Show file tree
Hide file tree
Showing 5 changed files with 252 additions and 86 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
/.settings
/.project
/.classpath
/.factorypath
/fromhost/
/base_workspace/bazel-bin
/base_workspace/bazel-genfiles
Expand Down
160 changes: 160 additions & 0 deletions scripts/eclipse-generate.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
#!/bin/bash
# Copyright 2015 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Generates eclipse files for Bazel

set -eu

progname=$0
function usage() {
echo "Usage: $progname command args..." >&2
echo "Possible commands are:" >&2
echo " classpath java_paths lib_paths jre output_path" >&2
echo " factorypath project_name plugin_paths" >&2
echo " project project_name" >&2
echo " apt_settings output_path" >&2
exit 1
}

function read_entry() {
if [[ -e "${1// /_}" ]]; then
cat "$1"
else
echo "$1"
fi
}

function generate_classpath() {
if [[ "$#" != 4 ]]; then
usage
fi

java_paths="$(read_entry "$1")"
lib_paths="$(read_entry "$2")"
jre="$3"
output_path="$4"

cat <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
EOF

for path in $java_paths; do
echo " <classpathentry kind=\"src\" path=\"$path\"/>"
done

for path_pair in $lib_paths; do
path_arr=(${path_pair//:/ })
jar=${path_arr[0]}
source_path=${path_arr[1]-}
if [ -n "${source_path}" ]; then
echo " <classpathentry kind=\"lib\" path=\"${jar}\" sourcepath=\"${source_path}\"/>"
else
echo " <classpathentry kind=\"lib\" path=\"${jar}\"/>"
fi
done

# Write the end of the .classpath file
cat <<EOF
<classpathentry kind="output" path="${output_path}"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/${jre}">
<accessrules>
<accessrule kind="accessible" pattern="**"/>
</accessrules>
</classpathentry>
</classpath>
EOF
}

function generate_factorypath() {
if [ "$#" != 2 ]; then
usage
fi
project_name="$1"
plugin_paths="$(read_entry "$2")"

cat <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<factorypath>
EOF

for path in $plugin_paths; do
echo " <factorypathentry kind=\"WKSPJAR\" id=\"/${project_name}/${path}\" enabled=\"true\" runInBatchMode=\"false\" />"
done

# Write the end of the .factorypath file
cat <<EOF
</factorypath>
EOF
}

function generate_project() {
if [ "$#" != 1 ]; then
usage
fi
project_name=$1
cat <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>${project_name}</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>
EOF
}

function generate_apt_settings() {
if [ "$#" != 1 ]; then
usage
fi
output_path=$1
cat <<EOF
eclipse.preferences.version=1
org.eclipse.jdt.apt.aptEnabled=true
org.eclipse.jdt.apt.genSrcDir=${output_path}
org.eclipse.jdt.apt.reconcileEnabled=true
EOF
}

command=$1
shift
case "${command}" in
classpath)
generate_classpath "$@"
;;
factorypath)
generate_factorypath "$@"
;;
project)
generate_project "$@"
;;
apt_settings)
generate_apt_settings "$@"
;;
*)
usage
;;
esac
61 changes: 0 additions & 61 deletions scripts/generate-classpath.sh

This file was deleted.

72 changes: 72 additions & 0 deletions scripts/get_project_paths.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#!/bin/bash
# Copyright 2015 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Gets all libraries needed for IDE support of a Bazel workspace

set -eu

cd $(dirname "$0")
cd ..

function query() {
./output/bazel query "$@"
}

# Compile bazel
([ -f "output/bazel" ] && [ -f "tools/jdk/JavaBuilder_deploy.jar" ] \
&& [ -f "tools/jdk/ijar" ] && [ -f "tools/jdk/SingleJar_deploy.jar" ] \
&& [ -e "tools/jdk/jdk" ]) || ./compile.sh >&2 || exit $?

# Build everything
./output/bazel build ${TARGET} >&2 || exit $?

# Now for java each targets, find all sources and all jars
DEPS=$(query 'filter("\.java$",
deps(kind("(java_binary|java_library|java_test|java_plugin)",
deps('"$TARGET"')))
except deps(//tools/...))')
PATHS=$(echo "$DEPS" | sed 's|:|/|' | sed 's|^//||')

# Java Files:
JAVA_PATHS=$(echo "$PATHS" | sed 's_\(/java\(tests\)\{0,1\}\)/.*$_\1_' | sort -u)

# Java plugins
JAVA_PLUGINS_DEPS=$(query 'filter("\.jar$",
deps(kind(java_import,
deps(kind(java_plugin,
deps('"$TARGET"')))))
except deps(//tools/...))')
PLUGIN_PATHS=$(echo "$JAVA_PLUGINS_DEPS" | sed 's|:|/|' | sed 's|^//||' | sort -u)

# Jar Files:
JAR_DEPS=$(query 'filter("\.jar$", deps(kind(java_import, deps('"$TARGET"')))
except deps(//tools/...))')
JAR_FILES=$(echo "$JAR_DEPS" | sed 's|:|/|' | sed 's|^//||' | sort -u)

# Generated files are direct dependencies of java rules that are not java rules,
# filegroup or binaries.
# We also handle genproto separately it is output in bazel-genfiles not in
# bazel-bin.
# We suppose that all files are generated in the same package than the library.
GEN_LIBS=$(query 'let gendeps = kind(rule, deps(kind(java_*, deps('"$TARGET"')), 1))
- kind("(java_.*|filegroup|.*_binary|genproto)", deps('"$TARGET"'))
- deps(//tools/...)
in rdeps('"$TARGET"', set($gendeps), 1) - set($gendeps)' \
| sed 's|^//\(.*\):\(.*\)|bazel-bin/\1/lib\2.jar:bazel-genfiles/\1|')

# Hack for genproto
PROTOBUFS=$(bazel query 'kind(genproto, deps('"$TARGET"'))' \
| sed 's|^//\(.*\):\(.*\)$|bazel-bin/\1/lib\2.jar:bazel-bin/\1/lib\2.jar.proto_output/|')
LIB_PATHS="${JAR_FILES} ${PROTOBUFS} ${GEN_LIBS}"
44 changes: 19 additions & 25 deletions scripts/setup-eclipse.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,34 +20,28 @@
#

set -eu
TARGET=//src/...
JRE="JavaSE-1.8"
PROJECT_NAME="bazel"
OUTPUT_PATH="bazel-out/ide/classes"
GENERATED_PATH="bazel-out/ide/generated"
EXTRA_JARS="bazel-bazel/external/local-jdk/lib/tools.jar"
source $(dirname "$0")/get_project_paths.sh

cd $(dirname "$0")
cd ..
mkdir -p ${OUTPUT_PATH} ${GENERATED_PATH}

# Simply creates a Eclipse java project
if [ ! -f ".project" ]; then
cat >.project <<'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>bazel</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>
EOF
# Overwrite .classpath and .factorypath.
./scripts/eclipse-generate.sh classpath "$JAVA_PATHS" "$LIB_PATHS $EXTRA_JARS" "$JRE" "$OUTPUT_PATH" >.classpath
if [ -n "$PLUGIN_PATHS" ]; then
./scripts/eclipse-generate.sh factorypath "$PROJECT_NAME" "$PLUGIN_PATHS" >.factorypath
mkdir -p .settings
# Write apt settings if not present.
[ -e ".settings/org.eclipse.jdt.apt.core.prefs" ] || \
./scripts/eclipse-generate.sh apt_settings "$GENERATED_PATH" > .settings/org.eclipse.jdt.apt.core.prefs
fi

./scripts/generate-classpath.sh >.classpath
# Write .project if not present.
[ -e ".project" ] || \
./scripts/eclipse-generate.sh project "$PROJECT_NAME" > .project

echo
echo '***'
Expand Down

0 comments on commit f9971e6

Please sign in to comment.