# HG changeset patch # User Bruno Haible # Date 1170606481 0 # Node ID 0a080a2d054b2ea0943af5d6c45c65c3cbb9f31f # Parent 9cd2d21f40cc11eafbc65adb0759802d9f7ad4fd Make use of gcj-4.3's -fsource and -ftarget option. diff --git a/ChangeLog b/ChangeLog --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2007-02-04 Bruno Haible + + Make use of gcj-4.3's -fsource and -ftarget option. + * m4/javacomp.m4 (gt_JAVACOMP): Test whether gcj is in version >= 4.3, + and if so try the options -fsource and -ftarget. + * lib/javacomp.c (compile_using_gcj): Add fsource_option, + source_version, ftarget_option, target_version arguments. + (is_envjavac_gcj43, is_envjavac_gcj43_usable): New functions. + (is_envjavac_oldgcj_14_14_usable): Renamed from + is_envjavac_gcj_14_14_usable. + (is_envjavac_oldgcj_14_13_usable): Renamed from + is_envjavac_gcj_14_13_usable. + (is_gcj_present): Update. + (is_gcj_43, is_gcj43_usable): New functions. + (is_oldgcj_14_14_usable): Renamed from is_gcj_14_14_usable. Update. + (is_oldgcj_14_13_usable): Renamed from is_gcj_14_13_usable. Update. + (compile_java_class): Test whether gcj is in version >= 4.3, and if so + try the options -fsource and -ftarget. + 2007-02-03 Paul Eggert * lib/xalloc.h (x2nrealloc): Fix an unlikely bug in the overflow diff --git a/lib/javacomp.c b/lib/javacomp.c --- a/lib/javacomp.c +++ b/lib/javacomp.c @@ -284,6 +284,8 @@ compile_using_gcj (const char * const *java_sources, unsigned int java_sources_count, bool no_assert_option, + bool fsource_option, const char *source_version, + bool ftarget_option, const char *target_version, const char *directory, bool optimize, bool debug, bool verbose, bool null_stderr) @@ -292,11 +294,14 @@ unsigned int argc; char **argv; char **argp; + char *fsource_arg; + char *ftarget_arg; int exitstatus; unsigned int i; argc = - 2 + (no_assert_option ? 1 : 0) + (optimize ? 1 : 0) + (debug ? 1 : 0) + 2 + (no_assert_option ? 1 : 0) + (fsource_option ? 1 : 0) + + (ftarget_option ? 1 : 0) + (optimize ? 1 : 0) + (debug ? 1 : 0) + (directory != NULL ? 2 : 0) + java_sources_count; argv = (char **) xallocsa ((argc + 1) * sizeof (char *)); @@ -305,6 +310,24 @@ *argp++ = "-C"; if (no_assert_option) *argp++ = "-fno-assert"; + if (fsource_option) + { + fsource_arg = (char *) xallocsa (9 + strlen (source_version) + 1); + memcpy (fsource_arg, "-fsource=", 9); + strcpy (fsource_arg + 9, source_version); + *argp++ = fsource_arg; + } + else + fsource_arg = NULL; + if (ftarget_option) + { + ftarget_arg = (char *) xallocsa (9 + strlen (target_version) + 1); + memcpy (ftarget_arg, "-ftarget=", 9); + strcpy (ftarget_arg + 9, target_version); + *argp++ = ftarget_arg; + } + else + ftarget_arg = NULL; if (optimize) *argp++ = "-O"; if (debug) @@ -332,6 +355,10 @@ true, true); err = (exitstatus != 0); + if (ftarget_arg != NULL) + freesa (ftarget_arg); + if (fsource_arg != NULL) + freesa (fsource_arg); freesa (argv); return err; @@ -593,11 +620,258 @@ return envjavac_gcj; } -/* Test whether $JAVAC, known to be a version of gcj, can be used for +/* Return true if $JAVAC, known to be a version of gcj, is a version >= 4.3 + of gcj. */ +static bool +is_envjavac_gcj43 (const char *javac) +{ + static bool envjavac_tested; + static bool envjavac_gcj43; + + if (!envjavac_tested) + { + /* Test whether $JAVAC is gcj: + "$JAVAC --version 2>/dev/null | sed -e 's,^[^0-9]*,,' -e 1q \ + | sed -e '/^4\.[012]/d' | grep '^[4-9]' >/dev/null" */ + unsigned int command_length; + char *command; + char *argv[4]; + pid_t child; + int fd[1]; + FILE *fp; + char *line; + size_t linesize; + size_t linelen; + int exitstatus; + char *p; + + /* Setup the command "$JAVAC --version". */ + command_length = strlen (javac) + 1 + 9 + 1; + command = (char *) xallocsa (command_length); + p = command; + /* Don't shell_quote $JAVAC, because it may consist of a command + and options. */ + memcpy (p, javac, strlen (javac)); + p += strlen (javac); + memcpy (p, " --version", 1 + 9 + 1); + p += 1 + 9 + 1; + /* Ensure command_length was correctly calculated. */ + if (p - command > command_length) + abort (); + + /* Call $JAVAC --version 2>/dev/null. */ + argv[0] = "/bin/sh"; + argv[1] = "-c"; + argv[2] = command; + argv[3] = NULL; + child = create_pipe_in (javac, "/bin/sh", argv, DEV_NULL, true, true, + false, fd); + if (child == -1) + goto failed; + + /* Retrieve its result. */ + fp = fdopen (fd[0], "r"); + if (fp == NULL) + goto failed; + + line = NULL; linesize = 0; + linelen = getline (&line, &linesize, fp); + if (linelen == (size_t)(-1)) + { + fclose (fp); + goto failed; + } + p = line; + while (*p != '\0' && !(*p >= '0' && *p <= '9')) + p++; + envjavac_gcj43 = + !(*p == '4' && p[1] == '.' && p[2] >= '0' && p[2] <= '2') + && (*p >= '4' && *p <= '9'); + + fclose (fp); + + /* Remove zombie process from process list, and retrieve exit status. */ + exitstatus = wait_subprocess (child, javac, true, true, true, false); + if (exitstatus != 0) + envjavac_gcj43 = false; + + failed: + freesa (command); + + envjavac_tested = true; + } + + return envjavac_gcj43; +} + +/* Test whether $JAVAC, known to be a version of gcj >= 4.3, can be used, and + whether it needs a -fsource and/or -ftarget option. + Return a failure indicator (true upon error). */ +static bool +is_envjavac_gcj43_usable (const char *javac, + const char *source_version, + const char *target_version, + bool *usablep, + bool *fsource_option_p, bool *ftarget_option_p) +{ + /* The cache depends on the source_version and target_version. */ + struct result_t + { + bool tested; + bool usable; + bool fsource_option; + bool ftarget_option; + }; + static struct result_t result_cache[SOURCE_VERSION_BOUND][TARGET_VERSION_BOUND]; + struct result_t *resultp; + + resultp = &result_cache[source_version_index (source_version)] + [target_version_index (target_version)]; + if (!resultp->tested) + { + /* Try $JAVAC. */ + struct temp_dir *tmpdir; + char *conftest_file_name; + char *compiled_file_name; + const char *java_sources[1]; + struct stat statbuf; + + tmpdir = create_temp_dir ("java", NULL, false); + if (tmpdir == NULL) + return true; + + conftest_file_name = + concatenated_pathname (tmpdir->dir_name, "conftest.java", NULL); + if (write_temp_file (tmpdir, conftest_file_name, + get_goodcode_snippet (source_version))) + { + free (conftest_file_name); + cleanup_temp_dir (tmpdir); + return true; + } + + compiled_file_name = + concatenated_pathname (tmpdir->dir_name, "conftest.class", NULL); + register_temp_file (tmpdir, compiled_file_name); + + java_sources[0] = conftest_file_name; + if (!compile_using_envjavac (javac, + java_sources, 1, tmpdir->dir_name, + false, false, false, true) + && stat (compiled_file_name, &statbuf) >= 0 + && get_classfile_version (compiled_file_name) + <= corresponding_classfile_version (target_version)) + { + /* $JAVAC compiled conftest.java successfully. */ + /* Try adding -fsource option if it is useful. */ + char *javac_source = + xasprintf ("%s -fsource=%s", javac, source_version); + + unlink (compiled_file_name); + + java_sources[0] = conftest_file_name; + if (!compile_using_envjavac (javac_source, + java_sources, 1, tmpdir->dir_name, + false, false, false, true) + && stat (compiled_file_name, &statbuf) >= 0 + && get_classfile_version (compiled_file_name) + <= corresponding_classfile_version (target_version)) + { + const char *failcode = get_failcode_snippet (source_version); + + if (failcode != NULL) + { + free (compiled_file_name); + free (conftest_file_name); + + conftest_file_name = + concatenated_pathname (tmpdir->dir_name, + "conftestfail.java", + NULL); + if (write_temp_file (tmpdir, conftest_file_name, failcode)) + { + free (conftest_file_name); + free (javac_source); + cleanup_temp_dir (tmpdir); + return true; + } + + compiled_file_name = + concatenated_pathname (tmpdir->dir_name, + "conftestfail.class", + NULL); + register_temp_file (tmpdir, compiled_file_name); + + java_sources[0] = conftest_file_name; + if (!compile_using_envjavac (javac, + java_sources, 1, + tmpdir->dir_name, + false, false, false, true) + && stat (compiled_file_name, &statbuf) >= 0) + { + unlink (compiled_file_name); + + java_sources[0] = conftest_file_name; + if (compile_using_envjavac (javac_source, + java_sources, 1, + tmpdir->dir_name, + false, false, false, true)) + /* $JAVAC compiled conftestfail.java successfully, and + "$JAVAC -fsource=$source_version" rejects it. So + the -fsource option is useful. */ + resultp->fsource_option = true; + } + } + } + + free (javac_source); + + resultp->usable = true; + } + else + { + /* Try with -fsource and -ftarget options. */ + char *javac_target = + xasprintf ("%s -fsource=%s -ftarget=%s", + javac, source_version, target_version); + + unlink (compiled_file_name); + + java_sources[0] = conftest_file_name; + if (!compile_using_envjavac (javac_target, + java_sources, 1, tmpdir->dir_name, + false, false, false, true) + && stat (compiled_file_name, &statbuf) >= 0 + && get_classfile_version (compiled_file_name) + <= corresponding_classfile_version (target_version)) + { + /* "$JAVAC -fsource $source_version -ftarget $target_version" + compiled conftest.java successfully. */ + resultp->fsource_option = true; + resultp->ftarget_option = true; + resultp->usable = true; + } + + free (javac_target); + } + + free (compiled_file_name); + free (conftest_file_name); + + resultp->tested = true; + } + + *usablep = resultp->usable; + *fsource_option_p = resultp->fsource_option; + *ftarget_option_p = resultp->ftarget_option; + return false; +} + +/* Test whether $JAVAC, known to be a version of gcj < 4.3, can be used for compiling with target_version = 1.4 and source_version = 1.4. Return a failure indicator (true upon error). */ static bool -is_envjavac_gcj_14_14_usable (const char *javac, bool *usablep) +is_envjavac_oldgcj_14_14_usable (const char *javac, bool *usablep) { static bool envjavac_tested; static bool envjavac_usable; @@ -648,11 +922,11 @@ return false; } -/* Test whether $JAVAC, known to be a version of gcj, can be used for +/* Test whether $JAVAC, known to be a version of gcj < 4.3, can be used for compiling with target_version = 1.4 and source_version = 1.3. Return a failure indicator (true upon error). */ static bool -is_envjavac_gcj_14_13_usable (const char *javac, +is_envjavac_oldgcj_14_13_usable (const char *javac, bool *usablep, bool *need_no_assert_option_p) { static bool envjavac_tested; @@ -1134,6 +1408,7 @@ java_sources[0] = conftest_file_name; if (compile_using_gcj (java_sources, 1, false, + false, NULL, false, NULL, tmpdir->dir_name, false, false, false, true)) gcj_present = false; @@ -1151,11 +1426,232 @@ return gcj_present; } -/* Test gcj can be used for compiling with target_version = 1.4 and - source_version = 1.4. +static bool +is_gcj_43 (void) +{ + static bool gcj_tested; + static bool gcj_43; + + if (!gcj_tested) + { + /* Test for presence of gcj: + "gcj --version 2> /dev/null | \ + sed -e 's,^[^0-9]*,,' -e 1q | \ + sed -e '/^4\.[012]/d' | grep '^[4-9]'" */ + char *argv[3]; + pid_t child; + int fd[1]; + int exitstatus; + + argv[0] = "gcj"; + argv[1] = "--version"; + argv[2] = NULL; + child = create_pipe_in ("gcj", "gcj", argv, DEV_NULL, true, true, + false, fd); + gcj_43 = false; + if (child != -1) + { + /* Read the subprocess output, drop all lines except the first, + drop all characters before the first digit, and test whether + the remaining string starts with a digit >= 4, but not with + "4.0" or "4.1" or "4.2". */ + char c[3]; + size_t count = 0; + + while (safe_read (fd[0], &c[count], 1) > 0) + { + if (c[count] == '\n') + break; + if (count == 0) + { + if (!(c[0] >= '0' && c[0] <= '9')) + continue; + gcj_43 = (c[0] >= '4'); + } + count++; + if (count == 3) + { + if (c[0] == '4' && c[1] == '.' && c[2] >= '0' && c[2] <= '2') + gcj_43 = false; + break; + } + } + while (safe_read (fd[0], &c[0], 1) > 0) + ; + + close (fd[0]); + + /* Remove zombie process from process list, and retrieve exit + status. */ + exitstatus = + wait_subprocess (child, "gcj", false, true, true, false); + if (exitstatus != 0) + gcj_43 = false; + } + + gcj_tested = true; + } + + return gcj_43; +} + +/* Test whether gcj >= 4.3 can be used, and whether it needs a -fsource and/or + -ftarget option. Return a failure indicator (true upon error). */ static bool -is_gcj_14_14_usable (bool *usablep) +is_gcj43_usable (const char *source_version, + const char *target_version, + bool *usablep, + bool *fsource_option_p, bool *ftarget_option_p) +{ + /* The cache depends on the source_version and target_version. */ + struct result_t + { + bool tested; + bool usable; + bool fsource_option; + bool ftarget_option; + }; + static struct result_t result_cache[SOURCE_VERSION_BOUND][TARGET_VERSION_BOUND]; + struct result_t *resultp; + + resultp = &result_cache[source_version_index (source_version)] + [target_version_index (target_version)]; + if (!resultp->tested) + { + /* Try gcj. */ + struct temp_dir *tmpdir; + char *conftest_file_name; + char *compiled_file_name; + const char *java_sources[1]; + struct stat statbuf; + + tmpdir = create_temp_dir ("java", NULL, false); + if (tmpdir == NULL) + return true; + + conftest_file_name = + concatenated_pathname (tmpdir->dir_name, "conftest.java", NULL); + if (write_temp_file (tmpdir, conftest_file_name, + get_goodcode_snippet (source_version))) + { + free (conftest_file_name); + cleanup_temp_dir (tmpdir); + return true; + } + + compiled_file_name = + concatenated_pathname (tmpdir->dir_name, "conftest.class", NULL); + register_temp_file (tmpdir, compiled_file_name); + + java_sources[0] = conftest_file_name; + if (!compile_using_gcj (java_sources, 1, false, false, NULL, false, NULL, + tmpdir->dir_name, false, false, false, true) + && stat (compiled_file_name, &statbuf) >= 0 + && get_classfile_version (compiled_file_name) + <= corresponding_classfile_version (target_version)) + { + /* gcj compiled conftest.java successfully. */ + /* Try adding -fsource option if it is useful. */ + unlink (compiled_file_name); + + java_sources[0] = conftest_file_name; + if (!compile_using_gcj (java_sources, 1, + false, true, source_version, false, NULL, + tmpdir->dir_name, false, false, false, true) + && stat (compiled_file_name, &statbuf) >= 0 + && get_classfile_version (compiled_file_name) + <= corresponding_classfile_version (target_version)) + { + const char *failcode = get_failcode_snippet (source_version); + + if (failcode != NULL) + { + free (compiled_file_name); + free (conftest_file_name); + + conftest_file_name = + concatenated_pathname (tmpdir->dir_name, + "conftestfail.java", + NULL); + if (write_temp_file (tmpdir, conftest_file_name, failcode)) + { + free (conftest_file_name); + cleanup_temp_dir (tmpdir); + return true; + } + + compiled_file_name = + concatenated_pathname (tmpdir->dir_name, + "conftestfail.class", + NULL); + register_temp_file (tmpdir, compiled_file_name); + + java_sources[0] = conftest_file_name; + if (!compile_using_gcj (java_sources, 1, + false, false, NULL, false, NULL, + tmpdir->dir_name, + false, false, false, true) + && stat (compiled_file_name, &statbuf) >= 0) + { + unlink (compiled_file_name); + + java_sources[0] = conftest_file_name; + if (compile_using_gcj (java_sources, 1, + false, true, source_version, + false, NULL, + tmpdir->dir_name, + false, false, false, true)) + /* gcj compiled conftestfail.java successfully, and + "gcj -fsource=$source_version" rejects it. So + the -fsource option is useful. */ + resultp->fsource_option = true; + } + } + } + + resultp->usable = true; + } + else + { + /* Try with -fsource and -ftarget options. */ + unlink (compiled_file_name); + + java_sources[0] = conftest_file_name; + if (!compile_using_gcj (java_sources, 1, + false, true, source_version, + true, target_version, + tmpdir->dir_name, + false, false, false, true) + && stat (compiled_file_name, &statbuf) >= 0 + && get_classfile_version (compiled_file_name) + <= corresponding_classfile_version (target_version)) + { + /* "gcj -fsource $source_version -ftarget $target_version" + compiled conftest.java successfully. */ + resultp->fsource_option = true; + resultp->ftarget_option = true; + resultp->usable = true; + } + } + + free (compiled_file_name); + free (conftest_file_name); + + resultp->tested = true; + } + + *usablep = resultp->usable; + *fsource_option_p = resultp->fsource_option; + *ftarget_option_p = resultp->ftarget_option; + return false; +} + +/* Test whether gcj < 4.3 can be used for compiling with target_version = 1.4 + and source_version = 1.4. + Return a failure indicator (true upon error). */ +static bool +is_oldgcj_14_14_usable (bool *usablep) { static bool gcj_tested; static bool gcj_usable; @@ -1188,8 +1684,8 @@ register_temp_file (tmpdir, compiled_file_name); java_sources[0] = conftest_file_name; - if (!compile_using_gcj (java_sources, 1, false, tmpdir->dir_name, - false, false, false, true) + if (!compile_using_gcj (java_sources, 1, false, false, NULL, false, NULL, + tmpdir->dir_name, false, false, false, true) && stat (compiled_file_name, &statbuf) >= 0) /* Compilation succeeded. */ gcj_usable = true; @@ -1206,11 +1702,11 @@ return false; } -/* Test whether gcj can be used for compiling with target_version = 1.4 and - source_version = 1.3. +/* Test whether gcj < 4.3 can be used for compiling with target_version = 1.4 + and source_version = 1.3. Return a failure indicator (true upon error). */ static bool -is_gcj_14_13_usable (bool *usablep, bool *need_no_assert_option_p) +is_oldgcj_14_13_usable (bool *usablep, bool *need_no_assert_option_p) { static bool gcj_tested; static bool gcj_usable; @@ -1245,8 +1741,8 @@ register_temp_file (tmpdir, compiled_file_name); java_sources[0] = conftest_file_name; - if (!compile_using_gcj (java_sources, 1, true, tmpdir->dir_name, - false, false, false, true) + if (!compile_using_gcj (java_sources, 1, true, false, NULL, false, NULL, + tmpdir->dir_name, false, false, false, true) && stat (compiled_file_name, &statbuf) >= 0) /* Compilation succeeded. */ { @@ -1258,8 +1754,9 @@ unlink (compiled_file_name); java_sources[0] = conftest_file_name; - if (!compile_using_gcj (java_sources, 1, false, tmpdir->dir_name, - false, false, false, true) + if (!compile_using_gcj (java_sources, 1, false, + false, NULL, false, NULL, + tmpdir->dir_name, false, false, false, true) && stat (compiled_file_name, &statbuf) >= 0) /* Compilation succeeded. */ { @@ -1593,31 +2090,51 @@ bool no_assert_option = false; bool source_option = false; bool target_option = false; + bool fsource_option = false; + bool ftarget_option = false; if (target_version == NULL) target_version = default_target_version (); if (is_envjavac_gcj (javac)) { - /* It's a version of gcj. Ignore the version of the class files - that it creates. */ - if (strcmp (target_version, "1.4") == 0 - && strcmp (source_version, "1.4") == 0) + /* It's a version of gcj. */ + if (is_envjavac_gcj43 (javac)) { - if (is_envjavac_gcj_14_14_usable (javac, &usable)) + /* It's a version of gcj >= 4.3. Assume the classfile versions + are correct. */ + if (is_envjavac_gcj43_usable (javac, + source_version, target_version, + &usable, + &fsource_option, &ftarget_option)) { err = true; goto done1; } } - else if (strcmp (target_version, "1.4") == 0 - && strcmp (source_version, "1.3") == 0) + else { - if (is_envjavac_gcj_14_13_usable (javac, - &usable, &no_assert_option)) + /* It's a version of gcj < 4.3. Ignore the version of the + class files that it creates. */ + if (strcmp (target_version, "1.4") == 0 + && strcmp (source_version, "1.4") == 0) { - err = true; - goto done1; + if (is_envjavac_oldgcj_14_14_usable (javac, &usable)) + { + err = true; + goto done1; + } + } + else if (strcmp (target_version, "1.4") == 0 + && strcmp (source_version, "1.3") == 0) + { + if (is_envjavac_oldgcj_14_13_usable (javac, + &usable, + &no_assert_option)) + { + err = true; + goto done1; + } } } } @@ -1646,12 +2163,16 @@ javac_with_options = (no_assert_option ? xasprintf ("%s -fno-assert", javac) - : xasprintf ("%s%s%s%s%s", + : xasprintf ("%s%s%s%s%s%s%s%s%s", javac, source_option ? " -source " : "", source_option ? source_version : "", target_option ? " -target " : "", - target_option ? target_version : "")); + target_option ? target_version : "", + fsource_option ? " -fsource=" : "", + fsource_option ? source_version : "", + ftarget_option ? " -ftarget=" : "", + ftarget_option ? target_version : "")); err = compile_using_envjavac (javac_with_options, java_sources, java_sources_count, @@ -1678,31 +2199,49 @@ if (is_gcj_present ()) { - /* Test whether it supports the desired target-version and - source-version. But ignore the version of the class files that - it creates. */ + /* It's a version of gcj. */ bool usable = false; bool no_assert_option = false; + bool fsource_option = false; + bool ftarget_option = false; if (target_version == NULL) target_version = default_target_version (); - if (strcmp (target_version, "1.4") == 0 - && strcmp (source_version, "1.4") == 0) + if (is_gcj_43 ()) { - if (is_gcj_14_14_usable (&usable)) + /* It's a version of gcj >= 4.3. Assume the classfile versions + are correct. */ + if (is_gcj43_usable (source_version, target_version, + &usable, &fsource_option, &ftarget_option)) { err = true; goto done1; } } - else if (strcmp (target_version, "1.4") == 0 - && strcmp (source_version, "1.3") == 0) + else { - if (is_gcj_14_13_usable (&usable, &no_assert_option)) + /* It's a version of gcj < 4.3. Ignore the version of the class + files that it creates. + Test whether it supports the desired target-version and + source-version. */ + if (strcmp (target_version, "1.4") == 0 + && strcmp (source_version, "1.4") == 0) { - err = true; - goto done1; + if (is_oldgcj_14_14_usable (&usable)) + { + err = true; + goto done1; + } + } + else if (strcmp (target_version, "1.4") == 0 + && strcmp (source_version, "1.3") == 0) + { + if (is_oldgcj_14_13_usable (&usable, &no_assert_option)) + { + err = true; + goto done1; + } } } @@ -1720,6 +2259,8 @@ err = compile_using_gcj (java_sources, java_sources_count, no_assert_option, + fsource_option, source_version, + ftarget_option, target_version, directory, optimize, debug, verbose, false); /* Reset CLASSPATH. */ diff --git a/m4/javacomp.m4 b/m4/javacomp.m4 --- a/m4/javacomp.m4 +++ b/m4/javacomp.m4 @@ -1,5 +1,5 @@ -# javacomp.m4 serial 8 (gettext-0.15) -dnl Copyright (C) 2001-2003, 2006 Free Software Foundation, Inc. +# javacomp.m4 serial 9 (gettext-0.16.2) +dnl Copyright (C) 2001-2003, 2006-2007 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. @@ -145,17 +145,18 @@ dnl dnl The support of GNU gcj for target-version and source-version: dnl - dnl gcj 3.0.4 to 4.1 does not have a way to specify the target-version. + dnl gcj 3.0.4 to 4.2 does not have a way to specify the target-version. dnl It always assumes target-version=1.4 but labels the class files as 1.1. dnl One consequence of this is that gcj compiles GetURL.java to invalid dnl bytecode, which crashes with a VerifyError when executed by Sun Java dnl 1.3.1. The bug is registered as java/7066, see dnl http://gcc.gnu.org/bugzilla/show_bug.cgi?id=7066 - dnl FIXME: Check new versions of gcj as they come out. + dnl gcj 4.3 and newer has an option -ftarget=1.X. dnl dnl For gcj < 3.3, the source-version always is 1.3. - dnl For gcj >= 3.3, the source-version defaults to 1.4; option + dnl For 3.3 <= gcj < 4.3, the source-version defaults to 1.4; option dnl "-fno-assert" switches to source-version 1.3. + dnl gcj >= 4.3 has an option -fsource=1.X. dnl dnl The support of Sun javac for target-version and source-version: dnl @@ -206,60 +207,111 @@ if test -n "$JAVAC"; then dnl Try the original $JAVAC. if $JAVAC --version 2>/dev/null | sed -e 1q | grep gcj > /dev/null; then - dnl It's a version of gcj. Ignore the version of conftest.class. - if test "$target_version" = 1.4 && test "$source_version" = 1.4; then + dnl It's a version of gcj. +changequote(,)dnl + if $JAVAC --version 2>/dev/null | sed -e 's,^[^0-9]*,,' -e 1q | sed -e '/^4\.[012]/d' | grep '^[4-9]' >/dev/null; then +changequote([,])dnl + dnl It's a version of gcj >= 4.3. Assume the classfile versions are correct. dnl Try $JAVAC. rm -f conftest.class if { echo "$as_me:__oline__: $JAVAC -d . conftest.java" >&AS_MESSAGE_LOG_FD $JAVAC -d . conftest.java >&AS_MESSAGE_LOG_FD 2>&1 } \ - && test -f conftest.class; then - CONF_JAVAC="$JAVAC" - HAVE_JAVAC_ENVVAR=1 - HAVE_JAVACOMP=1 + && test -f conftest.class \ + && expr `func_classfile_version conftest.class` '<=' $cfversion >/dev/null 2>&AS_MESSAGE_LOG_FD; then + dnl Try adding -fsource option if it is useful. + rm -f conftest.class + rm -f conftestfail.class + if { echo "$as_me:__oline__: $JAVAC -fsource=$source_version -d . conftest.java" >&AS_MESSAGE_LOG_FD + $JAVAC -fsource="$source_version" -d . conftest.java >&AS_MESSAGE_LOG_FD 2>&1 + } \ + && test -f conftest.class \ + && expr `func_classfile_version conftest.class` '<=' $cfversion >/dev/null 2>&AS_MESSAGE_LOG_FD \ + && { echo "$as_me:__oline__: $JAVAC -d . conftestfail.java" >&AS_MESSAGE_LOG_FD + $JAVAC -d . conftestfail.java >&AS_MESSAGE_LOG_FD 2>&1 + } \ + && test -f conftestfail.class \ + && ! { echo "$as_me:__oline__: $JAVAC -fsource=$source_version -d . conftestfail.java" >&AS_MESSAGE_LOG_FD + $JAVAC -fsource="$source_version" -d . conftestfail.java >&AS_MESSAGE_LOG_FD 2>&1 + }; then + CONF_JAVAC="$JAVAC -fsource=$source_version" + HAVE_JAVAC_ENVVAR=1 + HAVE_JAVACOMP=1 + else + CONF_JAVAC="$JAVAC" + HAVE_JAVAC_ENVVAR=1 + HAVE_JAVACOMP=1 + fi + else + dnl Try with -fsource and -ftarget options. + rm -f conftest.class + rm -f conftestfail.class + if { echo "$as_me:__oline__: $JAVAC -fsource=$source_version -ftarget=$target_version -d . conftest.java" >&AS_MESSAGE_LOG_FD + $JAVAC -fsource="$source_version" -ftarget="$target_version" -d . conftest.java >&AS_MESSAGE_LOG_FD 2>&1 + } \ + && test -f conftest.class \ + && expr `func_classfile_version conftest.class` '<=' $cfversion >/dev/null 2>&AS_MESSAGE_LOG_FD; then + CONF_JAVAC="$JAVAC -fsource=$source_version -ftarget=$target_version" + HAVE_JAVAC_ENVVAR=1 + HAVE_JAVACOMP=1 + fi fi else - if test "$target_version" = 1.4 && test "$source_version" = 1.3; then - dnl Try $JAVAC and "$JAVAC -fno-assert". But add -fno-assert only if - dnl it makes a difference. (It could already be part of $JAVAC.) - javac_works= + dnl It's a version of gcj < 4.3. Ignore the version of conftest.class. + if test "$target_version" = 1.4 && test "$source_version" = 1.4; then + dnl Try $JAVAC. rm -f conftest.class if { echo "$as_me:__oline__: $JAVAC -d . conftest.java" >&AS_MESSAGE_LOG_FD $JAVAC -d . conftest.java >&AS_MESSAGE_LOG_FD 2>&1 } \ && test -f conftest.class; then - javac_works=1 - fi - javac_noassert_works= - rm -f conftest.class - if { echo "$as_me:__oline__: $JAVAC -fno-assert -d . conftest.java" >&AS_MESSAGE_LOG_FD - $JAVAC -fno-assert -d . conftest.java >&AS_MESSAGE_LOG_FD 2>&1 - } \ - && test -f conftest.class; then - javac_noassert_works=1 - fi - if test -n "$javac_works" && test -n "$javac_noassert_works"; then - rm -f conftestfail.class - if { echo "$as_me:__oline__: $JAVAC -d . conftestfail.java" >&AS_MESSAGE_LOG_FD - $JAVAC -d . conftestfail.java >&AS_MESSAGE_LOG_FD 2>&1 - } \ - && test -f conftestfail.class \ - && ! { echo "$as_me:__oline__: $JAVAC -fno-assert -d . conftestfail.java" >&AS_MESSAGE_LOG_FD - $JAVAC -fno-assert -d . conftestfail.java >&AS_MESSAGE_LOG_FD 2>&1 - }; then - dnl "$JAVAC -fno-assert" works better than $JAVAC. - javac_works= - fi - fi - if test -n "$javac_works"; then CONF_JAVAC="$JAVAC" HAVE_JAVAC_ENVVAR=1 HAVE_JAVACOMP=1 - else - if test -n "$javac_noassert_works"; then - CONF_JAVAC="$JAVAC -fno-assert" + fi + else + if test "$target_version" = 1.4 && test "$source_version" = 1.3; then + dnl Try $JAVAC and "$JAVAC -fno-assert". But add -fno-assert only if + dnl it makes a difference. (It could already be part of $JAVAC.) + javac_works= + rm -f conftest.class + if { echo "$as_me:__oline__: $JAVAC -d . conftest.java" >&AS_MESSAGE_LOG_FD + $JAVAC -d . conftest.java >&AS_MESSAGE_LOG_FD 2>&1 + } \ + && test -f conftest.class; then + javac_works=1 + fi + javac_noassert_works= + rm -f conftest.class + if { echo "$as_me:__oline__: $JAVAC -fno-assert -d . conftest.java" >&AS_MESSAGE_LOG_FD + $JAVAC -fno-assert -d . conftest.java >&AS_MESSAGE_LOG_FD 2>&1 + } \ + && test -f conftest.class; then + javac_noassert_works=1 + fi + if test -n "$javac_works" && test -n "$javac_noassert_works"; then + rm -f conftestfail.class + if { echo "$as_me:__oline__: $JAVAC -d . conftestfail.java" >&AS_MESSAGE_LOG_FD + $JAVAC -d . conftestfail.java >&AS_MESSAGE_LOG_FD 2>&1 + } \ + && test -f conftestfail.class \ + && ! { echo "$as_me:__oline__: $JAVAC -fno-assert -d . conftestfail.java" >&AS_MESSAGE_LOG_FD + $JAVAC -fno-assert -d . conftestfail.java >&AS_MESSAGE_LOG_FD 2>&1 + }; then + dnl "$JAVAC -fno-assert" works better than $JAVAC. + javac_works= + fi + fi + if test -n "$javac_works"; then + CONF_JAVAC="$JAVAC" HAVE_JAVAC_ENVVAR=1 HAVE_JAVACOMP=1 + else + if test -n "$javac_noassert_works"; then + CONF_JAVAC="$JAVAC -fno-assert" + HAVE_JAVAC_ENVVAR=1 + HAVE_JAVACOMP=1 + fi fi fi fi @@ -366,39 +418,90 @@ gcj -C -d . conftestlib.java >&AS_MESSAGE_LOG_FD 2>&1 }; then dnl OK, gcj works. - dnl Now test whether it supports the desired target-version and - dnl source-version. But ignore the version of conftest.class. - if test "$target_version" = 1.4 && test "$source_version" = 1.4; then +changequote(,)dnl + if gcj --version 2>/dev/null | sed -e 's,^[^0-9]*,,' -e 1q | sed -e '/^4\.[012]/d' | grep '^[4-9]' >/dev/null; then +changequote([,])dnl + dnl It's a version of gcj >= 4.3. Assume the classfile versions are correct. + dnl Try gcj. rm -f conftest.class if { echo "$as_me:__oline__: gcj -C -d . conftest.java" >&AS_MESSAGE_LOG_FD gcj -C -d . conftest.java >&AS_MESSAGE_LOG_FD 2>&1 } \ - && test -f conftest.class; then - CONF_JAVAC="gcj -C" - HAVE_GCJ_C=1 - HAVE_JAVACOMP=1 + && test -f conftest.class \ + && expr `func_classfile_version conftest.class` '<=' $cfversion >/dev/null 2>&AS_MESSAGE_LOG_FD; then + dnl Try adding -fsource option if it is useful. + rm -f conftest.class + rm -f conftestfail.class + if { echo "$as_me:__oline__: gcj -C -fsource=$source_version -d . conftest.java" >&AS_MESSAGE_LOG_FD + gcj -C -fsource="$source_version" -d . conftest.java >&AS_MESSAGE_LOG_FD 2>&1 + } \ + && test -f conftest.class \ + && expr `func_classfile_version conftest.class` '<=' $cfversion >/dev/null 2>&AS_MESSAGE_LOG_FD \ + && { echo "$as_me:__oline__: gcj -C -d . conftestfail.java" >&AS_MESSAGE_LOG_FD + gcj -C -d . conftestfail.java >&AS_MESSAGE_LOG_FD 2>&1 + } \ + && test -f conftestfail.class \ + && ! { echo "$as_me:__oline__: gcj -C -fsource=$source_version -d . conftestfail.java" >&AS_MESSAGE_LOG_FD + gcj -C -fsource="$source_version" -d . conftestfail.java >&AS_MESSAGE_LOG_FD 2>&1 + }; then + CONF_JAVAC="gcj -C -fsource=$source_version" + HAVE_JAVAC_ENVVAR=1 + HAVE_JAVACOMP=1 + else + CONF_JAVAC="gcj -C" + HAVE_JAVAC_ENVVAR=1 + HAVE_JAVACOMP=1 + fi + else + dnl Try with -fsource and -ftarget options. + rm -f conftest.class + rm -f conftestfail.class + if { echo "$as_me:__oline__: gcj -C -fsource=$source_version -ftarget=$target_version -d . conftest.java" >&AS_MESSAGE_LOG_FD + gcj -C -fsource="$source_version" -ftarget="$target_version" -d . conftest.java >&AS_MESSAGE_LOG_FD 2>&1 + } \ + && test -f conftest.class \ + && expr `func_classfile_version conftest.class` '<=' $cfversion >/dev/null 2>&AS_MESSAGE_LOG_FD; then + CONF_JAVAC="gcj -C -fsource=$source_version -ftarget=$target_version" + HAVE_JAVAC_ENVVAR=1 + HAVE_JAVACOMP=1 + fi fi else - if test "$target_version" = 1.4 && test "$source_version" = 1.3; then - dnl Try gcj and "gcj -fno-assert". But add -fno-assert only if - dnl it works (not gcj < 3.3). + dnl It's a version of gcj < 4.3. Ignore the version of conftest.class. + dnl Now test whether it supports the desired target-version and + dnl source-version. + if test "$target_version" = 1.4 && test "$source_version" = 1.4; then rm -f conftest.class - if { echo "$as_me:__oline__: gcj -C -fno-assert -d . conftest.java" >&AS_MESSAGE_LOG_FD - gcj -C -fno-assert -d . conftest.java >&AS_MESSAGE_LOG_FD 2>&1 + if { echo "$as_me:__oline__: gcj -C -d . conftest.java" >&AS_MESSAGE_LOG_FD + gcj -C -d . conftest.java >&AS_MESSAGE_LOG_FD 2>&1 } \ && test -f conftest.class; then - CONF_JAVAC="gcj -C -fno-assert" + CONF_JAVAC="gcj -C" HAVE_GCJ_C=1 HAVE_JAVACOMP=1 - else + fi + else + if test "$target_version" = 1.4 && test "$source_version" = 1.3; then + dnl Try gcj and "gcj -fno-assert". But add -fno-assert only if + dnl it works (not gcj < 3.3). rm -f conftest.class - if { echo "$as_me:__oline__: gcj -C -d . conftest.java" >&AS_MESSAGE_LOG_FD - gcj -C -d . conftest.java >&AS_MESSAGE_LOG_FD 2>&1 + if { echo "$as_me:__oline__: gcj -C -fno-assert -d . conftest.java" >&AS_MESSAGE_LOG_FD + gcj -C -fno-assert -d . conftest.java >&AS_MESSAGE_LOG_FD 2>&1 } \ && test -f conftest.class; then - CONF_JAVAC="gcj -C" + CONF_JAVAC="gcj -C -fno-assert" HAVE_GCJ_C=1 HAVE_JAVACOMP=1 + else + rm -f conftest.class + if { echo "$as_me:__oline__: gcj -C -d . conftest.java" >&AS_MESSAGE_LOG_FD + gcj -C -d . conftest.java >&AS_MESSAGE_LOG_FD 2>&1 + } \ + && test -f conftest.class; then + CONF_JAVAC="gcj -C" + HAVE_GCJ_C=1 + HAVE_JAVACOMP=1 + fi fi fi fi