
This file contains the Standard Operating Procedures for Cygnites
hacking on newlib.

Please read this first before checking anything in.

Contents:
1) Divergence

	- background information
	- why is this a problem
	- what can I do to help

2) Coding Style

	- what is sanitize-redhat ?
	- third-party code
	- copyrights
	- naming conventions
	- industry and defacto standards
	- autoconf/automake

3) Collected papers/sites on standards, compilers, optimization, etc.

1) Divergence

Background Information
----------------------

Various forces tend to cause our tree to diverge from the Sourceware
tree (which is the master source tree):

- It is easier to fix a problem here and just check things into devo
  without trying to get the changes into the Sourceware tree.

- It is also easier to not account for the time it takes to get new
  features into the Sourceware tree when making estimates.

- There are some projects and customer requested additions we do that
  may never make it into the Sourceware tree.

- In order to distinguish our tree from what folks can get for free,
  new work of significance is contributed to devo *after* our paying
  customers have had it for a while.  Contact the current GCC manage
  for guidelines about what is "significant" and how long we want to
  wait before contributing the code to the net.

Thus over time our sources tend to diverge from Sourceware and without
constant diligence it can get out of hand.

Why is this a problem?
----------------------

Remember, the Sourceware tree is the master source tree.  Fixes to
bugs reported on the net go into the Sourceware tree, not ours.  Also,
there are more developers working on newlib outside of Red Hat than inside
and their work goes into the Sourceware tree, not ours.  The
divergence is a problem because it makes it harder to integrate these
changes and additions to the Sourceware tree into our tree.  If the
Sourceware team fixes a bug differently than you, yours must be thrown
out in favor of the Sourceware approved fix.  If Sourceware adds an
option that is slightly different than an option you've added, then
we'd like to replace your option with the Sourceware approved version
except we can't because a customer is now using yours and now we're
stuck with two options that do basically the same thing.


What can I do to help?
----------------------

Here are the guidelines for checking changes into devo/newlib.

First and foremost is: avoid checking changes into devo without also
checking them into the Sourceware.  This applies to several areas.  If
you're fixing a customer bug that is also a bug in the Sourceware
tree, get your bug fix approved by the appropriate Sourceware person
before sending the patch to the customer and checking it into devo
(*1).  If a customer is requesting an option or feature, get it
approved by the appropriate Sourceware person before sending the patch
to the customer and checking it into devo (*1).  Note that this
applies to changes that would otherwise be sanitized too (assuming the
option is of a generic enough nature that sending it to the Sourceware
doesn't violate any contractual requirements, of course)!

The best way to do this is to not work in devo - work with the
Sourceware tree instead (*2).  Let the merge process bring patches
into devo, and if that isn't soon enough, add the patches to devo
*after* you've added them to the Sourceware tree.  Merging gets done
about once a month.  Note that the frequency could be increased if the
divergence wasn't a problem.  The point is don't treat the Sourceware
tree as an afterthought.  And don't think of the periodic merges as 2
way merges (sourceware->Red Hat and Red Hat->sourceare).  They are one
way only (sourceware->Red Hat).

Once Sourceware has approved a patch it is your responsibility to
physically get the patch into the Sourceware source tree.  This may
simply involve forwarding the (already approved!) patch to someone
else to check in (eg: rth, law, nickc, ian) which is fine.

(*1) If the Sourceware folks do not reply quickly enough (they're busy
too!) or they reject the change then use your best judgement.  If you
don't want the customer to have to wait any longer then send them the
patch and check it into devo (and mark it sanitize-redhat!).  But
remember, it is *your* responsibility to continually try to get the
patch accepted into Sourceware afterwards.  Or you may wish to
continually revise your patch until it is accepted into Sourceware,
then check it into devo.

(*2) Obviously, there are times when this isn't doable, but it's a lot
more doable than is (or at least was) presently done.

2) Coding Style

What is "sanitize-redhat"?
-----------------------

Just like normal sanitization tag, except that we'll keep `redhat'
changes for a GnuPro release.

It is used to mark local changes.  It makes it easy to tell what is a
local change and what is not just by looking at diffs of the
Sourceware tree and ours.  It can also be used to speed up the merging
process as pure local additions can be recognized and dealt with
mechanically.

If there is any hard and fast rule for working in devo wrt newlib
it is this:

    Thou shalt mark all local changes with `sanitize-redhat'.

Third party code
----------------

Bits and pieces of newlib have been collected from various third
party sources: BSD, netlib, etc.  When we add reentrancy goop,
support for unusual microprocessors and microcontrollers, etc., we
should do our best not to destroy the formatting or indentation of
the code.  This makes it difficult to merge in new versions of the
code as it is updated.

Copyrights
----------

Make sure new code checked in has a clear copyright or disclaimer of 
copyright.

Our customers want to be assured that newlib is free from any licencing
or copyright issues.

Naming Conventions
------------------

Follow internal identifier naming conventions:

- no leading underscores (foo): External identifiers --- part of the
  newlib API.

- one leading underscore (_foo): External identifiers --- These are
  shadow functions for ANSI namespace purity.  For example, we need an
  open() function for POSIX.1 compatibility, but ANSI C alows the user
  to redefine open() yet still call fopen().  Newlib functions will
  call _open() instead of open().  open() will be mapped to _open()
  (if the user does not provide one) by linker magic or by a stub
  function.

- two leading underscores (__foo): Internal identifiers --- These
  are functions, data, etc. that the external functions use but
  are not part of the newlib API.

- Note that most of newlib does not yet follow these conventions.
  Follow them now, and there is less to fix up later.


Industry and defacto standards
------------------------------

Do a little reasearch before adding features requested in PRs.
There might be a POSIX, ANSI, Windows, etc. standard that describes
the feature in a more general way.  I'm going to try to get the
POSIX standards/drafts that describe real-time and embedded API's
in the library ASAP.

autoconf/automake
-----------------

Newlib is now configured and built using autoconf and automake.
Make sure you have up to date versions of the tools built and
installed on your PATH.

Configure with --enable-maintainer-mode to have the generated files
(configure, Makefile.in, aclocal.m4) get updated automatically.

All host (target) specific configuration information should go in
configure.host.

The file acinclude.m4 is shared by all the configure.in files.  It
defines the macro NEWLIB_CONFIGURE which is used in the configure.in
files.  NEWLIB_CONFIGURE sources configure.host.

To add a new machine or sys subdirectory:
	- change configure.host appropriately
	- copy Makefile.am and configure.in from an existing subdirectory
	- adjust AC_INIT in configure.in to one of your files
	- adjust lib_a_SOURCES in Makefile.am to list your files
	- in a sys subdirectory, consider whether all should depend
	  upon crt0.o
	- run aclocal -I ../../.. (see ACLOCAL_AMFLAGS in Makefile.am)
	- run autoconf
	- run automake
After that, you can configure with --enable-maintainer-mode and
the generated files will be rebuilt automatically as needed when you
run make.

