getting rid of mkproto.sh from Samba3

tridge at samba.org tridge at samba.org
Mon Jun 4 02:51:37 GMT 2007


James,

 > >> mkproto.sh promotes lazing programming, leads to bad interfaces
 > >> and to monolithic code.
 > 
 > This is the basic reason why I don't like mkproto.sh. I'd also add that
 > 	- it makes it impossible to do incremental builds
 > 	- it makes it harder to find existing interfaces, raising the  
 > barrier to contributions
 > 	- it makes it harder to document existing interfaces
 > 	- leads to false sharing, forcing trivial tools to link most of lib/

This is not a result of mkproto. In Samba4 we do automatic prototype
generation for many of our subsystems but not for all, yet it doesn't
suffer from any of the above problems:

 - we do incremental builds, as each subsystem gets its own
    proto.h. So for example, the libcli/raw library gets
    libcli/raw/raw_proto.h. Only subsystems that need that library
    include that header

 - it is not hard to find existing interfaces, as we separate the
   headers for each interface. The generated headers are short, and
   are located in the same directory as the library code that are for

 - I think it makes it easier to document interfaces as the interfaces
   to the library are conveniently located next to the code

 - it doesn't lead to false sharing, as we separate the headers

 - the samba4 code is not monolithic

 - the samba4 code doesn't have bad interfaces.

The problems you are seeing are due to my original design of mkproto
which do it all as one big proto.h. Jelmer re-designed our mkproto to
split up the generated headers, and that got rid of all of the
problems you mentioned. Jelmer also did a much faster and cleaner
mkproto in perl.

We control which subsystems get automatic prototype generation using
options like this:

 [SUBSYSTEM::LIBCLI_RAW]
  PRIVATE_PROTO_HEADER = raw/raw_proto.h
  PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE 
  PUBLIC_DEPENDENCIES = samba-socket LIBPACKET gensec LIBCRYPTO
  LDFLAGS = $(SUBSYSTEM_LIBCLI_SMB_COMPOSITE_OUTPUT)
  OBJ_FILES = raw/rawfile.o \ (etc etc)

If you have a read through the generated prototypes, I think you'll
find them clean, and easy to read.

So you can use prototype generation without the problems you
mention. It just takes a bit more work upfront to get it right.

That said, we don't do automatic prototype generation for all of our
code. For some subsystems we choose to do it manually, which means we
leave out the PRIVATE_PROTO_HEADER option in the configuration for
that subsystem. That gives a lot of flexibility.

An intermediate option would be to have a pre-processor directory to
say "this function should be auto-prototyped". For example, you could
do this:

_AUTOPROTO_ NTSTATUS smb_raw_seek(struct smbcli_tree *tree,
			      union smb_seek *parms)
{
	struct smbcli_request *req = smb_raw_seek_send(tree, parms);
	return smb_raw_seek_recv(req, parms);
}

and teach mkproto to only prototype stuff with _AUTOPROTO_. That might
be a reaonable approach if you want most stuff not to be automatically
prototyped. 

This is similar to the _PUBLIC_ directive which Jelmer added so that
we can have most symbols only be usable internally, and not
accidentially export an internal symbol via a library.

Cheers, Tridge


More information about the samba-technical mailing list