diff options
author | Bruno Haible <bruno@clisp.org> | 2018-03-24 12:54:42 +0100 |
---|---|---|
committer | Bruno Haible <bruno@clisp.org> | 2018-03-24 13:05:42 +0100 |
commit | 2d3dd35cb263f6566b2924a2adae99385c440f46 (patch) | |
tree | 9a0002017f5e5dfe30ca63cefc83a1bd051325a4 /lib | |
parent | 70a913d7d4d0683c1fdf1988049b2add1095c276 (diff) | |
download | gnulib-2d3dd35cb263f6566b2924a2adae99385c440f46.tar.gz |
javacomp-script, javacomp: Fix support for Java 7, 8, 9.
* lib/javaversion.h: Update comments.
* lib/javacomp.h: Likewise.
* lib/javacomp.c (default_target_version, source_version_index,
get_goodcode_snippet, get_failcode_snippet): Recognize "9" instead of
"1.9".
(TARGET_VERSION_BOUND): Bump to 9.
(target_version_index, corresponding_classfile_version): Recognize "9"
instead of "1.9".
(get_source_version_for_javac): New function.
(is_envjavac_nongcj_usable, is_javac_usable): Add
source_version_for_javac argument.
(compile_java_class): Determine and pass source_version_for_javac.
* m4/javacomp.m4: Recognize version '9' instead of '1.9'. When invoking
$JAVAC or javac, pass '-source 1.6' instead of '-source 1.5' when
appropriate.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/javacomp.c | 105 | ||||
-rw-r--r-- | lib/javacomp.h | 6 | ||||
-rw-r--r-- | lib/javaversion.h | 4 |
3 files changed, 76 insertions, 39 deletions
diff --git a/lib/javacomp.c b/lib/javacomp.c index f9e7292d0c..1b19f17126 100644 --- a/lib/javacomp.c +++ b/lib/javacomp.c @@ -99,9 +99,12 @@ default_target_version (void) /* Determine the version from the found JVM. */ java_version_cache = javaexec_version (); if (java_version_cache == NULL - || !(java_version_cache[0] == '1' && java_version_cache[1] == '.' - && (java_version_cache[2] >= '1' && java_version_cache[2] <= '9') - && java_version_cache[3] == '\0')) + || !((java_version_cache[0] == '1' + && java_version_cache[1] == '.' + && java_version_cache[2] >= '1' && java_version_cache[2] <= '8' + && java_version_cache[3] == '\0') + || (java_version_cache[0] == '9' + && java_version_cache[1] == '\0'))) java_version_cache = "1.1"; } return java_version_cache; @@ -119,10 +122,12 @@ source_version_index (const char *source_version) if ((source_version[2] >= '3' && source_version[2] <= '5') && source_version[3] == '\0') return source_version[2] - '3'; - if ((source_version[2] >= '7' && source_version[2] <= '9') + if ((source_version[2] >= '7' && source_version[2] <= '8') && source_version[3] == '\0') return source_version[2] - '4'; } + else if (source_version[0] == '9' && source_version[1] == '\0') + return 5; error (EXIT_FAILURE, 0, _("invalid source_version argument to compile_java_class")); return 0; } @@ -141,7 +146,7 @@ get_goodcode_snippet (const char *source_version) return "class conftest { void foo () { switch (\"A\") {} } }\n"; if (strcmp (source_version, "1.8") == 0) return "class conftest { void foo () { Runnable r = () -> {}; } }\n"; - if (strcmp (source_version, "1.9") == 0) + if (strcmp (source_version, "9") == 0) return "interface conftest { private void foo () {} }\n"; error (EXIT_FAILURE, 0, _("invalid source_version argument to compile_java_class")); return NULL; @@ -163,7 +168,7 @@ get_failcode_snippet (const char *source_version) return "class conftestfail { void foo () { Runnable r = () -> {}; } }\n"; if (strcmp (source_version, "1.8") == 0) return "interface conftestfail { private void foo () {} }\n"; - if (strcmp (source_version, "1.9") == 0) + if (strcmp (source_version, "9") == 0) return NULL; error (EXIT_FAILURE, 0, _("invalid source_version argument to compile_java_class")); return NULL; @@ -172,14 +177,16 @@ get_failcode_snippet (const char *source_version) /* ======================= Target version dependent ======================= */ /* Convert a target version to an index. */ -#define TARGET_VERSION_BOUND 6 /* exclusive upper bound */ +#define TARGET_VERSION_BOUND 9 /* exclusive upper bound */ static unsigned int target_version_index (const char *target_version) { if (target_version[0] == '1' && target_version[1] == '.' - && (target_version[2] >= '1' && target_version[2] <= '6') + && (target_version[2] >= '1' && target_version[2] <= '8') && target_version[3] == '\0') return target_version[2] - '1'; + else if (target_version[0] == '9' && target_version[1] == '\0') + return 8; error (EXIT_FAILURE, 0, _("invalid target_version argument to compile_java_class")); return 0; } @@ -205,12 +212,28 @@ corresponding_classfile_version (const char *target_version) return 51; if (strcmp (target_version, "1.8") == 0) return 52; - if (strcmp (target_version, "1.9") == 0) + if (strcmp (target_version, "9") == 0) return 53; error (EXIT_FAILURE, 0, _("invalid target_version argument to compile_java_class")); return 0; } +/* Return the source version to pass to javac. */ +static const char * +get_source_version_for_javac (const char *source_version, + const char *target_version) +{ + /* The javac option '-source 1.5' has the same meaning as '-source 1.6', + but since Java 9 supports only the latter, prefer the latter if a + target_version >= 1.6 is requested. */ + if (strcmp (source_version, "1.5") == 0 + && !(target_version[0] == '1' && target_version[1] == '.' + && (target_version[2] >= '1' && target_version[2] <= '5') + && target_version[3] == '\0')) + return "1.6"; + return source_version; +} + /* ======================== Compilation subroutines ======================== */ /* Try to compile a set of Java sources with $JAVAC. @@ -1081,6 +1104,7 @@ is_envjavac_oldgcj_14_13_usable (const char *javac, static bool is_envjavac_nongcj_usable (const char *javac, const char *source_version, + const char *source_version_for_javac, const char *target_version, bool *usablep, bool *source_option_p, bool *target_option_p) @@ -1136,7 +1160,7 @@ is_envjavac_nongcj_usable (const char *javac, /* $JAVAC compiled conftest.java successfully. */ /* Try adding -source option if it is useful. */ char *javac_source = - xasprintf ("%s -source %s", javac, source_version); + xasprintf ("%s -source %s", javac, source_version_for_javac); unlink (compiled_file_name); @@ -1188,8 +1212,8 @@ is_envjavac_nongcj_usable (const char *javac, tmpdir->dir_name, false, false, false, true)) /* $JAVAC compiled conftestfail.java successfully, and - "$JAVAC -source $source_version" rejects it. So the - -source option is useful. */ + "$JAVAC -source $source_version_for_javac" rejects it. + So the -source option is useful. */ resultp->source_option = true; } } @@ -1220,7 +1244,7 @@ is_envjavac_nongcj_usable (const char *javac, successfully. */ /* Try adding -source option if it is useful. */ char *javac_target_source = - xasprintf ("%s -source %s", javac_target, source_version); + xasprintf ("%s -source %s", javac_target, source_version_for_javac); unlink (compiled_file_name); @@ -1276,7 +1300,7 @@ is_envjavac_nongcj_usable (const char *javac, true)) /* "$JAVAC -target $target_version" compiled conftestfail.java successfully, and - "$JAVAC -target $target_version -source $source_version" + "$JAVAC -target $target_version -source $source_version_for_javac" rejects it. So the -source option is useful. */ resultp->source_option = true; } @@ -1294,7 +1318,7 @@ is_envjavac_nongcj_usable (const char *javac, -target and -source options. (Supported by Sun javac 1.4 and higher.) */ char *javac_target_source = - xasprintf ("%s -source %s", javac_target, source_version); + xasprintf ("%s -source %s", javac_target, source_version_for_javac); unlink (compiled_file_name); @@ -1306,7 +1330,7 @@ is_envjavac_nongcj_usable (const char *javac, && get_classfile_version (compiled_file_name) <= corresponding_classfile_version (target_version)) { - /* "$JAVAC -target $target_version -source $source_version" + /* "$JAVAC -target $target_version -source $source_version_for_javac" compiled conftest.java successfully. */ resultp->source_option = true; resultp->target_option = true; @@ -1826,7 +1850,9 @@ is_javac_present (void) -target option. Return a failure indicator (true upon error). */ static bool -is_javac_usable (const char *source_version, const char *target_version, +is_javac_usable (const char *source_version, + const char *source_version_for_javac, + const char *target_version, bool *usablep, bool *source_option_p, bool *target_option_p) { /* The cache depends on the source_version and target_version. */ @@ -1871,7 +1897,7 @@ is_javac_usable (const char *source_version, const char *target_version, java_sources[0] = conftest_file_name; if (!compile_using_javac (java_sources, 1, - false, source_version, + false, source_version_for_javac, false, target_version, tmpdir->dir_name, false, false, false, true) && stat (compiled_file_name, &statbuf) >= 0 @@ -1884,7 +1910,7 @@ is_javac_usable (const char *source_version, const char *target_version, java_sources[0] = conftest_file_name; if (!compile_using_javac (java_sources, 1, - true, source_version, + true, source_version_for_javac, false, target_version, tmpdir->dir_name, false, false, false, true) && stat (compiled_file_name, &statbuf) >= 0 @@ -1917,7 +1943,7 @@ is_javac_usable (const char *source_version, const char *target_version, java_sources[0] = conftest_file_name; if (!compile_using_javac (java_sources, 1, - false, source_version, + false, source_version_for_javac, false, target_version, tmpdir->dir_name, false, false, false, true) @@ -1927,13 +1953,13 @@ is_javac_usable (const char *source_version, const char *target_version, java_sources[0] = conftest_file_name; if (compile_using_javac (java_sources, 1, - true, source_version, + true, source_version_for_javac, false, target_version, tmpdir->dir_name, false, false, false, true)) /* javac compiled conftestfail.java successfully, and - "javac -source $source_version" rejects it. So the - -source option is useful. */ + "javac -source $source_version_for_javac" rejects it. + So the -source option is useful. */ resultp->source_option = true; } } @@ -1949,7 +1975,7 @@ is_javac_usable (const char *source_version, const char *target_version, java_sources[0] = conftest_file_name; if (!compile_using_javac (java_sources, 1, - false, source_version, + false, source_version_for_javac, true, target_version, tmpdir->dir_name, false, false, false, true) @@ -1964,7 +1990,7 @@ is_javac_usable (const char *source_version, const char *target_version, java_sources[0] = conftest_file_name; if (!compile_using_javac (java_sources, 1, - true, source_version, + true, source_version_for_javac, true, target_version, tmpdir->dir_name, false, false, false, true) @@ -1999,7 +2025,7 @@ is_javac_usable (const char *source_version, const char *target_version, java_sources[0] = conftest_file_name; if (!compile_using_javac (java_sources, 1, - false, source_version, + false, source_version_for_javac, true, target_version, tmpdir->dir_name, false, false, false, true) @@ -2009,13 +2035,13 @@ is_javac_usable (const char *source_version, const char *target_version, java_sources[0] = conftest_file_name; if (compile_using_javac (java_sources, 1, - true, source_version, + true, source_version_for_javac, true, target_version, tmpdir->dir_name, false, false, false, true)) /* "javac -target $target_version" compiled conftestfail.java successfully, and - "javac -target $target_version -source $source_version" + "javac -target $target_version -source $source_version_for_javac" rejects it. So the -source option is useful. */ resultp->source_option = true; } @@ -2034,7 +2060,7 @@ is_javac_usable (const char *source_version, const char *target_version, java_sources[0] = conftest_file_name; if (!compile_using_javac (java_sources, 1, - true, source_version, + true, source_version_for_javac, true, target_version, tmpdir->dir_name, false, false, false, true) @@ -2042,7 +2068,7 @@ is_javac_usable (const char *source_version, const char *target_version, && get_classfile_version (compiled_file_name) <= corresponding_classfile_version (target_version)) { - /* "javac -target $target_version -source $source_version" + /* "javac -target $target_version -source $source_version_for_javac" compiled conftest.java successfully. */ resultp->source_option = true; resultp->target_option = true; @@ -2113,10 +2139,14 @@ compile_java_class (const char * const *java_sources, bool target_option = false; bool fsource_option = false; bool ftarget_option = false; + const char *source_version_for_javac; if (target_version == NULL) target_version = default_target_version (); + source_version_for_javac = + get_source_version_for_javac (source_version, target_version); + if (is_envjavac_gcj (javac)) { /* It's a version of gcj. */ @@ -2163,7 +2193,9 @@ compile_java_class (const char * const *java_sources, { /* It's not gcj. Assume the classfile versions are correct. */ if (is_envjavac_nongcj_usable (javac, - source_version, target_version, + source_version, + source_version_for_javac, + target_version, &usable, &source_option, &target_option)) { @@ -2187,7 +2219,7 @@ compile_java_class (const char * const *java_sources, : xasprintf ("%s%s%s%s%s%s%s%s%s", javac, source_option ? " -source " : "", - source_option ? source_version : "", + source_option ? source_version_for_javac : "", target_option ? " -target " : "", target_option ? target_version : "", fsource_option ? " -fsource=" : "", @@ -2296,11 +2328,16 @@ compile_java_class (const char * const *java_sources, bool usable = false; bool source_option = false; bool target_option = false; + const char *source_version_for_javac; if (target_version == NULL) target_version = default_target_version (); - if (is_javac_usable (source_version, target_version, + source_version_for_javac = + get_source_version_for_javac (source_version, target_version); + + if (is_javac_usable (source_version, source_version_for_javac, + target_version, &usable, &source_option, &target_option)) { err = true; @@ -2320,7 +2357,7 @@ compile_java_class (const char * const *java_sources, verbose); err = compile_using_javac (java_sources, java_sources_count, - source_option, source_version, + source_option, source_version_for_javac, target_option, target_version, directory, optimize, debug, verbose, false); diff --git a/lib/javacomp.h b/lib/javacomp.h index 3d0a02d615..3d73a9205b 100644 --- a/lib/javacomp.h +++ b/lib/javacomp.h @@ -31,7 +31,7 @@ 1.6 (not supported) 1.7 switch(string) 1.8 lambdas - 1.9 private interface methods + 9 private interface methods target_version can be: classfile version: 1.1 45.3 1.2 46.0 @@ -41,7 +41,7 @@ 1.6 50.0 1.7 51.0 1.8 52.0 - 1.9 53.0 + 9 53.0 target_version can also be given as NULL. In this case, the required target_version is determined from the found JVM (see javaversion.h). Specifying target_version is useful when building a library (.jar) that is @@ -53,7 +53,7 @@ - target_version < 1.6 with source_version >= 1.6, or - target_version < 1.7 with source_version >= 1.7, or - target_version < 1.8 with source_version >= 1.8, or - - target_version < 1.9 with source_version >= 1.9, + - target_version < 9 with source_version >= 9, because even Sun's/Oracle's javac doesn't support these combinations. It is redundant to ask for a target_version > source_version, since the smaller target_version = source_version will also always work and newer JVMs diff --git a/lib/javaversion.h b/lib/javaversion.h index e4646e2f5e..86cbd1a33e 100644 --- a/lib/javaversion.h +++ b/lib/javaversion.h @@ -26,8 +26,8 @@ extern "C" { /* Return information about the Java version used by execute_java_class(). This is the value of System.getProperty("java.specification.version"). - Some possible values are: 1.1, 1.2, 1.3, 1.4, 1.5, 1.6. Return NULL if - the Java version cannot be determined. */ + Some possible values are: 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 9. + Return NULL if the Java version cannot be determined. */ extern char * javaexec_version (void); |