This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Compiler/TMS570LC4357: best practices for repeatable binary (.hex) builds

Expert 1226 points
Part Number: TMS570LC4357

Tool/software: TI C/C++ Compiler

I have occasionally seen George Mock say something like the following, for example in https://e2e.ti.com/support/development_tools/compiler/f/343/p/624681/2306594#2306594:

TI has never documented that bit identical object files will result from multiple builds with the same conditions.  We don't test for it.  Therefore, it is not wise for you to rely on it.

This statement only applies to object files, correct?  .obj and .lib and .out files?

We need to be able to verify that our binary images can be built and rebuilt identically; that our images built on our developer machines match those built on the build server, and that we can rebuild identical code later on and create an identical binary images.  Where by "binary image" I mean just the binary code/data that gets programmed into our MCUs, not any metadata for debugging or otherwise.  Our first preference for validating this would be to generate identical .hex files. We don't have any particular need to verify .obj or .out files.  (I appreciate that the objdiff tool is available if this verification need were to arise.)

Does TI officially support generating bit identical binary images from multiple builds with the same conditions?

(Is there a phrase you would prefer to use other than "binary image" to capture this concept?)

We're specifically interested in TI's ARM compiler while compiling C code.

When we speak of "the same conditions", what are those conditions?  Of course we need to use the same version of compiler and linker.  (We'll certainly use the same version of the hex conversion utility as well, although I'd hope that that would be quite compatible across a range of versions.)

I am hoping that we do not need to:

  • Use identical absolute directory paths for the root directory of our CCS project.
  • Use identical absolute directory paths for the installation of CCS and the compiler.
  • Use the same version of OS.  (Meaning the OS we run our build environment in, of course, not any RTOS we might compile into our binary image.)
  • Use the same kind of CPU or any other hardware on the computer running the build environment.

Certainly we need to be careful about embedding timestamps and datestamps.  We will plan on avoiding __TIME__ and __DATE__ macros.  I don't believe TI provides any way to control those values, correct?    It would be useful to support a way to control those, potentially using the SOURCE_DATE_EPOCH environment variable supported by GCC.

I don't believe that we need to worry about any C locale issues, because those are hard-coded to the C locale in the TI library, correct?

We will consider placing the compiled run-time library into source control.  Do you recommend doing so?  Even if we do, we would still want to follow whatever approach we need to do such that we could get a repeatable build using the default CCS approach (i.e. using the run-time library compiled from scratch in the tools directory).

Are there other pieces we need to explicitly control in order to reliably generate repeatable binary images?

--thx

  • 1138 said:
    This statement only applies to object files, correct?  .obj and .lib and .out files?

    Yes.  But this also means it says nothing at all about hex files or binary images.

    1138 said:
    Does TI officially support generating bit identical binary images from multiple builds with the same conditions?

    No.

    I realize that is frustrating to you. I share that frustration. I'll try to explain.

    This is not a design constraint.  It is not part of any standard.  We have no tests for it.

    I agree that comparing binary images avoids many problems that come from comparing object files.

    Note how your post tries to enumerate all the things which must be done or avoided to guarantee bit identical binary images.  You missed one.  The linker must see all inputs in the same order.  Did you miss any more?  This is the key question.  Here is the answer.  No one knows.  This is why TI cannot accept responsibility in this matter.  Some innocently overlooked factor can suddenly show up and cause an unexpected difference.

    Trust me, this is frustrating for all of us.  But there is no avoiding it.

    It is possible, and worthwhile, to work towards the ideal of bit identical binary images.  It is worthwhile because, most of the time, the ideal is in fact realized.  But you must accept that, in the unlikely event a comparison fails, it remains your responsibility to deal with the aftermath.  Note you are not being left entirely alone.   We continue to support you, as we do all our customers.  But that is a different thing than accepting full responsibility.

    Since you are exploring this issue so carefully, I'll point out one more thing for you to consider.  A comparison done with objdiff is more comprehensive than a comparison of binary images.  A binary image, by definition, only contains the bits in the initialized sections in the executable file.  What about the uninitialized sections, like .bss or the stack? I cannot think of any scenario under which a difference in an uninitialized section causes no difference in the code.  But, in purely theoretical terms, it is possible.  Supposing that somehow occurs, a comparison of binary images would miss that difference.  But objdiff, which looks at all the sections which affect execution, would see it.

    Another point in favor of objdiff ... It comes with the Perl source code for it.

    Thanks and regards,

    -George