summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorBruno Haible <bruno@clisp.org>2018-03-24 12:54:42 +0100
committerBruno Haible <bruno@clisp.org>2018-03-24 13:05:42 +0100
commit2d3dd35cb263f6566b2924a2adae99385c440f46 (patch)
tree9a0002017f5e5dfe30ca63cefc83a1bd051325a4 /lib
parent70a913d7d4d0683c1fdf1988049b2add1095c276 (diff)
downloadgnulib-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.c105
-rw-r--r--lib/javacomp.h6
-rw-r--r--lib/javaversion.h4
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);