Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8007639

Workaround for ccache in vm.make is incorrect

    Details

    • Subcomponent:
    • Introduced In Version:
      7u4
    • Resolved In Build:
      b20
    • OS:
      linux, os_x, solaris

      Backports

        Description

        7132779 introduced changes to enable ccache. As part of that a workaround was introduced in vm.make to only set the JRE_RELEASE_VERSION define when compiling vm_version.o, from vm.make:

        # This is VERY important! The version define must only be supplied to vm_version.o
        # If not, ccache will not re-use the cache at all, since the version string might contain
        # a time and date.
        vm_version.o: CXXFLAGS += ${JRE_VERSION}


        Unfortunately the workaround is incorrect, the above syntax does not only modify CXXFLAGS for vm_version.o - it will also make the same modification to any and all prerequisites of vm_version.o. From the make documentation:

        " There is one more special feature of target-specific variables: when
        you define a target-specific variable that variable value is also in
        effect for all prerequisites of this target, and all their
        prerequisites, etc. (unless those prerequisites override that variable
        with their own target-specific variable value). So, for example, a
        statement like this:

             prog : CFLAGS = -g
             prog : prog.o foo.o bar.o

        will set `CFLAGS' to `-g' in the command script for `prog', but it will
        also set `CFLAGS' to `-g' in the command scripts that create `prog.o',
        `foo.o', and `bar.o', and any command scripts which create their
        prerequisites."

        vm_version.o depends on all other object files:

        vm_version.o: $(filter-out vm_version.o,$(JVM_OBJ_FILES))

        Meaning the additional define will be added to CXXFLAGS for all object flags. Right?


        Right?! Only it isn't (that would be too easy). Thanks go out to David Holmes for helping figure this part out:

        There's another dependency. vm.def also depends on all object files:

        vm.def: $(Res_Files) $(Obj_Files)

        Also, remember that the object files are sorted by name.

        What happens is that vm.def is processed and since it depends on all object files it starts processing all the prerequisite object files, starting from 'a'. When it reaches vm_version.o it notices that there are additional dependencies for that file *and* because of the target-specific rule for vm_version.o and the fact that any prerequisites inherit that rule it executes those dependencies with the additional CXXFLAGS define, but some (most) of the object files are already compiled so only the files that are lexicographically after vm_version.o will actually get the additional define.

        Parallel make does make this a tad more complicated, but all in all the result is that the JRE_RELEASE_VERSION define may be added not only to vm_version.o which is the intended behavior, but also to other object files.

          Attachments

            Issue Links

              Activity

                People

                • Assignee:
                  mikael Mikael Vidstedt
                  Reporter:
                  mikael Mikael Vidstedt
                • Votes:
                  0 Vote for this issue
                  Watchers:
                  2 Start watching this issue

                  Dates

                  • Created:
                    Updated:
                    Resolved: