diff --git a/bin/idea.sh b/bin/idea.sh index 2a2378e6eb2..a7bba24a4ca 100644 --- a/bin/idea.sh +++ b/bin/idea.sh @@ -25,7 +25,21 @@ # Shell script for generating an IDEA project from a given list of modules usage() { - echo "usage: $0 [-h|--help] [-v|--verbose] [-o|--output ] [modules]+" + echo "Usage: $0 [-h|--help] [-q|--quiet] [-a|--absolute-paths] [-o|--output ] [modules...]" + echo " -h | --help" + echo " -q | --quiet + No stdout output" + echo " -a | --absolute-paths + Use absolute paths to this jdk, so that generated .idea + project files can be moved independently of jdk sources" + echo " -o | --output + Where .idea directory with project files will be generated + (e.g. using '-o .' will place project files in './.idea') + Default: $TOPLEVEL_DIR" + echo " [modules...] + Generate project modules for specific java modules + (e.g. 'java.base java.desktop') + Default: all existing modules (java.* and jdk.*)" exit 1 } @@ -33,11 +47,12 @@ SCRIPT_DIR=`dirname $0` #assume TOP is the dir from which the script has been called TOP=`pwd` cd $SCRIPT_DIR; SCRIPT_DIR=`pwd` +cd .. ; TOPLEVEL_DIR=`pwd` cd $TOP; -IDEA_OUTPUT=$TOP/.idea -CUSTOM_IDEA_OUTPUT=false -VERBOSE="false" +IDEA_OUTPUT=$TOPLEVEL_DIR/.idea +VERBOSE=true +ABSOLUTE_PATHS=false while [ $# -gt 0 ] do case $1 in @@ -45,13 +60,16 @@ do usage ;; - -v | --vebose ) - VERBOSE="true" + -q | --quiet ) + VERBOSE=false + ;; + + -a | --absolute-paths ) + ABSOLUTE_PATHS=true ;; -o | --output ) IDEA_OUTPUT=$2/.idea - CUSTOM_IDEA_OUTPUT=true shift ;; @@ -68,14 +86,9 @@ done mkdir -p $IDEA_OUTPUT || exit 1 cd $IDEA_OUTPUT; IDEA_OUTPUT=`pwd` +cd ..; IDEA_OUTPUT_PARENT=`pwd` -if [ "x$TOPLEVEL_DIR" = "x" ] ; then - cd $SCRIPT_DIR/.. - TOPLEVEL_DIR=`pwd` - cd $IDEA_OUTPUT -fi - -MAKE_DIR="$SCRIPT_DIR/../make" +MAKE_DIR="$TOPLEVEL_DIR/make" IDEA_MAKE="$MAKE_DIR/ide/idea/jdk" IDEA_TEMPLATE="$IDEA_MAKE/template" @@ -88,17 +101,17 @@ if [ -d "$TEMPLATES_OVERRIDE" ] ; then done fi -if [ "$VERBOSE" = "true" ] ; then - echo "output dir: $IDEA_OUTPUT" - echo "idea template dir: $IDEA_TEMPLATE" +if [ "$VERBOSE" = true ] ; then + echo "Will generate IDEA project files in \"$IDEA_OUTPUT\" for project \"$TOPLEVEL_DIR\"" fi -cd $TOP ; make -f "$IDEA_MAKE/idea.gmk" -I $MAKE_DIR/.. idea MAKEOVERRIDES= OUT=$IDEA_OUTPUT/env.cfg MODULES="$*" || exit 1 +cd $TOP ; make -f "$IDEA_MAKE/idea.gmk" -I "$TOPLEVEL_DIR" idea \ + MAKEOVERRIDES= IDEA_OUTPUT_PARENT="$IDEA_OUTPUT_PARENT" OUT="$IDEA_OUTPUT/env.cfg" MODULES="$*" || exit 1 cd $SCRIPT_DIR . $IDEA_OUTPUT/env.cfg -# Expect MODULES, MODULE_NAMES, BOOT_JDK & SPEC to be set +# Expect MODULES, MODULE_NAMES, RELATIVE_PROJECT_DIR, RELATIVE_BUILD_DIR to be set if [ "xMODULES" = "x" ] ; then echo "FATAL: MODULES is empty" >&2; exit 1 fi @@ -107,12 +120,12 @@ if [ "x$MODULE_NAMES" = "x" ] ; then echo "FATAL: MODULE_NAMES is empty" >&2; exit 1 fi -if [ "x$BOOT_JDK" = "x" ] ; then - echo "FATAL: BOOT_JDK is empty" >&2; exit 1 +if [ "x$RELATIVE_PROJECT_DIR" = "x" ] ; then + echo "FATAL: RELATIVE_PROJECT_DIR is empty" >&2; exit 1 fi -if [ "x$SPEC" = "x" ] ; then - echo "FATAL: SPEC is empty" >&2; exit 1 +if [ "x$RELATIVE_BUILD_DIR" = "x" ] ; then + echo "FATAL: RELATIVE_BUILD_DIR is empty" >&2; exit 1 fi if [ -d "$TOPLEVEL_DIR/.hg" ] ; then @@ -123,6 +136,29 @@ if [ -d "$TOPLEVEL_DIR/.git" ] ; then VCS_TYPE="Git" fi +if [ "$ABSOLUTE_PATHS" = true ] ; then + if [ "x$PATHTOOL" != "x" ]; then + PROJECT_DIR="`$PATHTOOL -am $TOPLEVEL_DIR`" + else + PROJECT_DIR="$TOPLEVEL_DIR" + fi + MODULE_DIR="$PROJECT_DIR" + cd "$TOPLEVEL_DIR" && cd "$RELATIVE_BUILD_DIR" && BUILD_DIR="`pwd`" +else + if [ "$RELATIVE_PROJECT_DIR" = "." ] ; then + PROJECT_DIR="" + else + PROJECT_DIR="/$RELATIVE_PROJECT_DIR" + fi + MODULE_DIR="\$MODULE_DIR\$$PROJECT_DIR" + PROJECT_DIR="\$PROJECT_DIR\$$PROJECT_DIR" + BUILD_DIR="\$PROJECT_DIR\$/$RELATIVE_BUILD_DIR" +fi +if [ "$VERBOSE" = true ] ; then + echo "Project root: $PROJECT_DIR" + echo "Generating IDEA project files..." +fi + ### Replace template variables NUM_REPLACEMENTS=0 @@ -146,18 +182,13 @@ add_replacement() { eval TO$NUM_REPLACEMENTS='$2' } +add_replacement "###PROJECT_DIR###" "$PROJECT_DIR" +add_replacement "###MODULE_DIR###" "$MODULE_DIR" add_replacement "###MODULE_NAMES###" "$MODULE_NAMES" add_replacement "###VCS_TYPE###" "$VCS_TYPE" -SPEC_DIR=`dirname $SPEC` -RELATIVE_SPEC_DIR="`realpath --relative-to=\"$TOPLEVEL_DIR\" \"$SPEC_DIR\"`" -add_replacement "###BUILD_DIR###" "$RELATIVE_SPEC_DIR" -add_replacement "###IMAGES_DIR###" "$RELATIVE_SPEC_DIR/images/jdk" +add_replacement "###BUILD_DIR###" "$BUILD_DIR" if [ "x$PATHTOOL" != "x" ]; then - if [ "$CUSTOM_IDEA_OUTPUT" = true ]; then - add_replacement "###BASH_RUNNER_PREFIX###" "`$PATHTOOL -am $IDEA_OUTPUT/.idea/bash.bat`" - else - add_replacement "###BASH_RUNNER_PREFIX###" ".idea\\\\bash.bat" - fi + add_replacement "###BASH_RUNNER_PREFIX###" "\$PROJECT_DIR\$/.idea/bash.bat" else add_replacement "###BASH_RUNNER_PREFIX###" "" fi @@ -184,37 +215,32 @@ replace_template_dir "$IDEA_OUTPUT" ### Generate module project files +if [ "$VERBOSE" = true ] ; then + echo "Generating project modules:" + fi ( DEFAULT_IFS="$IFS" IFS='#' -if [ "x$PATHTOOL" != "x" ]; then - TOPDIR_FOR_RELATIVITY_CHECKS="`echo \"$TOPLEVEL_DIR\" | tr '[:upper:]' '[:lower:]'`" -else - TOPDIR_FOR_RELATIVITY_CHECKS="$TOPLEVEL_DIR" -fi for value in $MODULES; do ( eval "$value" - if [ "$VERBOSE" = "true" ] ; then - echo "generating project module: $module" + if [ "$VERBOSE" = true ] ; then + echo " $module" fi - add_replacement "###MODULE_DIR###" "src/$module" + add_replacement "###MODULE_CONTENT###" "src/$module" SOURCE_DIRS="" IFS=' ' for dir in $moduleSrcDirs; do - if [ "x$PATHTOOL" != "x" ]; then - dir="`echo \"$dir\" | tr '[:upper:]' '[:lower:]'`" - fi - dir="`realpath --relative-to=\"$TOPDIR_FOR_RELATIVITY_CHECKS\" \"$dir\"`" case $dir in # Exclude generated sources to avoid module-info conflicts, see https://youtrack.jetbrains.com/issue/IDEA-185108 - "$SPEC_DIR"*) ;; - *) SOURCE_DIRS="$SOURCE_DIRS " + "src/"*) SOURCE_DIRS="$SOURCE_DIRS " esac done add_replacement "###SOURCE_DIRS###" "$SOURCE_DIRS" DEPENDENCIES="" for dep in $moduleDependencies; do - DEPENDENCIES="$DEPENDENCIES " + case $MODULE_NAMES in # Exclude skipped modules from dependencies + *"$dep"*) DEPENDENCIES="$DEPENDENCIES " + esac done add_replacement "###DEPENDENCIES###" "$DEPENDENCIES" cp "$IDEA_OUTPUT/module.iml" "$IDEA_OUTPUT/$module.iml" diff --git a/make/common/Utils.gmk b/make/common/Utils.gmk index a7df32065ae..aba9a7cb417 100644 --- a/make/common/Utils.gmk +++ b/make/common/Utils.gmk @@ -92,40 +92,58 @@ SetIfEmpty = \ # foo/bar/baz, /foo/bar -> # # The x prefix is used to preserve the presence of the initial slash +# On Windows paths are treated as case-insensitive # # $1 - Path to compare # $2 - Other path to compare FindCommonPathPrefix = \ - $(patsubst x%,%,$(subst $(SPACE),/,$(strip \ - $(call FindCommonPathPrefixHelper, \ - $(subst /,$(SPACE),x$(strip $1)), $(subst /,$(SPACE),x$(strip $2))) \ - ))) + $(call DecodeSpace,$(patsubst x%,%,$(subst $(SPACE),/,$(strip \ + $(call FindCommonPathPrefixHelper1, \ + $(subst /,$(SPACE),x$(call EncodeSpace,$(strip $1))), \ + $(subst /,$(SPACE),x$(call EncodeSpace,$(strip $2)))) \ + )))) -FindCommonPathPrefixHelper = \ +FindCommonPathPrefixHelper1 = \ + $(if $(filter $(OPENJDK_TARGET_OS), windows), \ + $(call FindCommonPathPrefixHelper2,$(call uppercase,$1),$(call uppercase,$2),$1), \ + $(call FindCommonPathPrefixHelper2,$1,$2,$1)) + +FindCommonPathPrefixHelper2 = \ $(if $(call equals, $(firstword $1), $(firstword $2)), \ - $(firstword $1) \ - $(call FindCommonPathPrefixHelper, \ - $(wordlist 2, $(words $1), $1), $(wordlist 2, $(words $2), $2) \ + $(if $(call equals, $(firstword $1),),, \ + $(firstword $3) \ + $(call FindCommonPathPrefixHelper2, \ + $(wordlist 2, $(words $1), $1), \ + $(wordlist 2, $(words $2), $2), \ + $(wordlist 2, $(words $3), $3) \ + ) \ ) \ ) -# Convert a partial path into as many directory levels of ../, removing -# leading and following /. -# Ex: foo/bar/baz/ -> ../../.. -# foo/bar -> ../.. -# /foo -> .. -DirToDotDot = \ - $(subst $(SPACE),/,$(foreach d, $(subst /,$(SPACE),$1),..)) - # Computes the relative path from a directory to a file # $1 - File to compute the relative path to # $2 - Directory to compute the relative path from RelativePath = \ - $(eval $1_prefix := $(call FindCommonPathPrefix, $1, $2)) \ - $(eval $1_dotdots := $(call DirToDotDot, $(patsubst $($(strip $1)_prefix)%, %, $2))) \ - $(eval $1_dotdots := $(if $($(strip $1)_dotdots),$($(strip $1)_dotdots),.)) \ - $(eval $1_suffix := $(patsubst $($(strip $1)_prefix)/%, %, $1)) \ - $($(strip $1)_dotdots)/$($(strip $1)_suffix) + $(call DecodeSpace,$(strip $(call RelativePathHelper,$(call EncodeSpace \ + ,$(strip $1)),$(call EncodeSpace \ + ,$(strip $2)),$(call EncodeSpace \ + ,$(call FindCommonPathPrefix,$1,$2))))) + +RelativePathHelper = \ + $(eval $3_prefix_length := $(words $(subst /,$(SPACE),$3))) \ + $(eval $1_words := $(subst /,$(SPACE),$1)) \ + $(eval $2_words := $(subst /,$(SPACE),$2)) \ + $(if $(call equals,$($3_prefix_length),0),, \ + $(eval $1_words := $(wordlist 2,$(words $($1_words)),$(wordlist \ + $($3_prefix_length),$(words $($1_words)),$($1_words)))) \ + $(eval $2_words := $(wordlist 2,$(words $($2_words)),$(wordlist \ + $($3_prefix_length),$(words $($2_words)),$($2_words)))) \ + ) \ + $(eval $1_suffix := $(subst $(SPACE),/,$($1_words))) \ + $(eval $2_dotdots := $(subst $(SPACE),/,$(foreach d,$($2_words),..))) \ + $(if $($1_suffix), \ + $(if $($2_dotdots), $($2_dotdots)/$($1_suffix), $($1_suffix)), \ + $(if $($2_dotdots), $($2_dotdots), .)) ################################################################################ # Filter out duplicate sub strings while preserving order. Keeps the first occurance. diff --git a/make/ide/idea/jdk/idea.gmk b/make/ide/idea/jdk/idea.gmk index 455ac182c62..a729c96bd25 100644 --- a/make/ide/idea/jdk/idea.gmk +++ b/make/ide/idea/jdk/idea.gmk @@ -46,17 +46,15 @@ else #with SPEC endif idea: - $(ECHO) "SUPPORT=$(SUPPORT_OUTPUTDIR)" > $(OUT) $(ECHO) "MODULES=\"$(foreach mod, $(SEL_MODULES), \ module='$(mod)' \ - moduleSrcDirs='$(call FindModuleSrcDirs,$(mod))' \ + moduleSrcDirs='$(foreach m,$(call FindModuleSrcDirs,$(mod)),$(call RelativePath,$m,$(topdir)))' \ moduleDependencies='$(call FindTransitiveDepsForModule,$(mod))' \ - #)\"" >> $(OUT) + #)\"" > $(OUT) $(ECHO) "MODULE_NAMES=\"$(strip $(foreach mod, $(SEL_MODULES), $(mod)))\"" >> $(OUT) - $(ECHO) "SEL_MODULES=\"$(SEL_MODULES)\"" >> $(OUT) - $(ECHO) "BOOT_JDK=\"$(BOOT_JDK)\"" >> $(OUT) + $(ECHO) "RELATIVE_PROJECT_DIR=\"$(call RelativePath,$(topdir),$(IDEA_OUTPUT_PARENT))\"" >> $(OUT) + $(ECHO) "RELATIVE_BUILD_DIR=\"$(call RelativePath,$(OUTPUTDIR),$(IDEA_OUTPUT_PARENT))\"" >> $(OUT) $(ECHO) "PATHTOOL=\"$(PATHTOOL)\"" >> $(OUT) - $(ECHO) "SPEC=\"$(SPEC)\"" >> $(OUT) $(ECHO) "JT_HOME=\"$(JT_HOME)\"" >> $(OUT) $(ECHO) "WINENV_ROOT=\"$(WINENV_ROOT)\"" >> $(OUT) diff --git a/make/ide/idea/jdk/template/compiler.xml b/make/ide/idea/jdk/template/compiler.xml index 309f5608043..9281fa10db7 100644 --- a/make/ide/idea/jdk/template/compiler.xml +++ b/make/ide/idea/jdk/template/compiler.xml @@ -3,10 +3,10 @@