Module directory structure
Version: $Id: modulestructure.html,v 1.4 2001/02/01 14:47:32 nzc Exp $
This document describes the structure of Blender modules, and the
reasoning behind this structure. The following structure is the
currently advised one.
[module name]--
|-intern - All .c and internal .h files
|-test - .c, .cpp, .h and Makefiles for
| module tests
|-[module name].h - The external .h file
This structure will be applied to new modules. For existing modules an
individual decision needs to take place.
Index
- 1. Introduction
- 2. Development Environment
- 2.1. Platforms
- 2.2. Availability of sources
- 3. Functions of the structure
- 4. Required documentation
- 5. Possible structures
- 5.1. Option 1: Explicit tree
- 5.2. Option 2: Minimal tree
- 5.3. Option 3: Shallow tree
- 5.4. Option 4: Shallow tree 2
- 6. Evaluation and Conclusion
1. Introduction
This document describes the directory structure of Blender modules,
and the reasoning behind this structure. It is intended for everyone
who has to construct a new module.
2. Development Environment
2.1. Platforms
Modules should be usable on any of the platforms in use within
NaN:
- Windows xxxx/NT (i386)
- Linux (i386, Alpha, PPC)
- FreeBSD (i386)
- Irix (SGI, mips)
- Beos (i386)
- Solaris (Sun, sparc)
Some platforms are not in use at this moment, but will be soon. We
have to make sure we will be capable of supporting them without extra
effort:
- Playstation 2 (Playstation development requires a Linux (preferred)
or Windows machine for the development activities themselves.)
- Mac OSX (Close to FreeBSD, as rumours go.)
- Handheld devices (No details available yet, but it seems that
these will require an additional i386 machine for the development as
well.)
- Set-top boxes (No details available yet. These will also probably
need an extra machine for development.)
Except for Windows machines, we use gcc as the default compiler. On
Windows, we use either Visual C++, or CygWin/cl.exe. All external releases
are made with gcc and Cygwin/cl.exe. The makefiles work on all platforms.
2.2. Availability of sources
There is a single CVS repository that holds all code. There are no
branches. This means that it is necessary that developers are able to
preview and pretest changes on several platforms without having to
commit those changes. For this purpose, NFS is used on the
unix-platforms in combination with SAMBA for the windows-machines. It
is also possible to mount unix-directories on windows and vice-versa.
3. Functions of the structure
There are several reasons why we want to organise the code into
modules. Some of these have direct impact on the requirements on the
module structure. These reasons are:
- There must be a clear top-level view of responsibilities of
modules.
- There must be a uniform module structure.
- Cross-module changes should be rare.
- Module couplings should be small (narrow interfaces).
- A module must be stand-alone testable.
(Check the architecture document on
the details of the modularization.)
Apart from that, there are requirements related to maintainability,
usability, extensibility of the module-structure itself.
- (maintainability) separate 'physically' internal and external
items
- internal = sources and headers that are only needed for the module
itself
- external = the external header and the lib (the .a, .obj or
whatever)
- (usability) allow a uniform way of addressing modules (using a
module should not be more than a few lines of code/script)
- (maintainability) allow a uniform way of maintaining makefiles,
(same set of makefiles for each module) (what about project files?)
- (maintainability) allow a high-level view on dependencies between
modules (central location per module stating which other modules are
required)
- (extensibility, maintainability) allow an internal directory
structure in the module (may be needed for large modules)
4. Required documentation
For each module, there must be high-level and low-level
documentation.
- High-level documentation deals with the functional requirements
and the context in which the module operates. This includes a
description of the offered interface, and a listing of the required
interfaces for this module.
- The low-level documentation contains all implementation-specific
details. This will (most likely) be mainly documentation generated
from formatted comments.
5. Possible structures
This section lists possible structures and their pros and cons. The
listed benefits and drawbacks exclude those that come with all
proposed stuctures.
5.1. Option 1: Explicit tree
5.1.1. Proposed structure
[module name]--
|-intern---
| |-source - All .c and .cpp files
| |-include - All internal .h files
|
|-extern---
| |-include - All external .h files
|
|-test - .c, .cpp, .h and Makefiles for
| module tests
|
|- - Files with general module
information
The makefile set becomes uniform over modules. Inside the
[module]/intern/{source,include} directories, there is space for
extending the directory structure.
5.1.2. Benefits
- There is a clear separation between files with different
functions. Location and function are directly linked.
- The external part of the module can be easily extracted.
5.1.3. Drawbacks
- The deep directory structure costs extra time when makefiles
traverse them. This can be an issue with NFS. (This may be corrected
by changing makefile behaviour.)
- Extending the directory structure causes two parallel trees to
grow.
- Lots of directories can cause confusion.
5.2. Option 2: Minimal tree
5.2.1. Proposed structure
[module name]--
|-include - All internal .h files
|-source - All .c and .cpp files
|-test - Module tests
|-[module name].h - The external .h file
There is only an explicit separation between headers and source.
5.2.2. Benefits
- Since the tree is shallow, it can be traversed fast. This can be
an issue with NFS.
- Compact and still reasonably clean
5.2.3. Drawbacks
- Modules with multiple external .h files start to pollute their
root.
5.3. Option 3: Shallow tree
5.3.1. Proposed structure
[module name]--
|-intern - All .c and internal .h files
|-extern - External .h files
|-test - .c, .cpp, .h and Makefiles for
module tests
The makefile set becomes uniform over modules. Inside the
[module]/intern/ directory, there is space for extending the directory
structure.
5.3.2. Benefits
- There is a clear separation between files with different
functions. Location and function are directly linked.
- The external part of the module can be easily extracted.
5.3.3. Drawbacks
- Modules with multiple external .h files start to pollute their
root.
- Adding an internal directory structure to the /intern directory
will require writing new makefiles on a per-module basis. (This might
be corrected by having a few templates for new makefiles.)
5.4. Option 4: Shallow tree 2
5.3.1. Proposed structure
[module name]--
|-intern - All .c and internal .h files
|-test - .c, .cpp, .h and Makefiles for
| module tests
|-[module name].h - The external .h file
The makefile set becomes uniform over modules. Inside the
[module]/intern/ directory, there is space for extending the directory
structure.
5.3.2. Benefits
- The number of subdirectories is minimal.
5.3.3. Drawbacks
- Modules with multiple external .h files start to pollute their
root.
- Adding an internal directory structure to the /intern directory
will require writing new makefiles on a per-module basis. (This might
be corrected by having a few templates for new makefiles.)
6. Evaluation and Conclusion
We do not expect modules to become very extensive: most modules will
contain in the order of several 10's of source files. Therefore option
1 seems to be overorganised. With a limited number of headers, it also
seems superfluous to separate these from the sources. This would
eliminate option 2. To keep the number of subdirectories limited,
option 4 is preferrable over option 3.
To conclude: the advised directory structure is option 4.