Postrelease thoughts Part I: Headers
Thoughts on what’s going to happen next.
The topic today is headers and it ties into a previous post The beauty of generic header-names, which will be helpful to have read before.
Headers is a topic, that will probably span more than two blog entries.
mulle-sde recap
If you don’t know by now, the basic concept of
mulle-sde
is that you use the filesystem and not some vendor specific .xcodeproj
or .vcproj
to structure your project files. You use environment
variables to keep your project settings. Dependencies are kept in a
sourcetree, that acts similiar to what npm’s package.json does.
After reorganisation of the sourcetree or the filesystem, you let mulle-sde reflect your changes back into - typically - cmake files and C header files. Ideally you should never need to write any cmake files, nor should you touch any other header files. This ideal works so far well with respect to cmake. For headers it’s lacking though.
Envelope header creation
Typically all mulle-objc libraries contain an envelope header of the same name as the project, which includes all public header of the project.
So a library “foo” with files a.h
and b.h
would have a header foo.h
that
would then include both a.h
and b.h
.
#ifndef foo__h__
#define foo__h__
#include "a.h"
#include "b.h"
#endif
When you add a header c.h
to your project, you currently have to manually
edit the envelope header to include it as well. This task is automatable
with reflection though.
Header categorization by convention
Header files are categorized by patternfiles. These patternfiles extrapolate the “category” of a file from the filename.
As an example, any file that matches *-private.h
is considered a private
header. Let’s look at the categorization in a real life example. When we look
at MulleObjCKVCFoundation with mulle-match list -f "%c: %b\\n" -cf '*headers'
,
we get:
private-generated-headers: _MulleObjCKVCFoundation-import-private.h
private-generated-headers: _MulleObjCKVCFoundation-include-private.h
private-headers: import-private.h
private-headers: include-private.h
public-generated-headers: _MulleObjCKVCFoundation-import.h
public-generated-headers: _MulleObjCKVCFoundation-include.h
public-headers: MulleObjCContainerKeyValueCoding.h
public-headers: MulleObjCKVCFoundation.h
public-headers: MulleObjCLoader+MulleObjCKVCFoundation.h
public-headers: NSNumber+MulleObjCKVCArithmetic.h
public-headers: NSObject+KVCSupport.h
public-headers: NSObject+KeyValueCoding.h
public-headers: NSObject+_MulleObjCKVCInformation.h
public-headers: _MulleObjCInstanceVariableAccess.h
public-headers: _MulleObjCKVCInformation.h
public-headers: import.h
public-headers: include.h
Private headers shouldn’t be part of the envelope header. Also generated headers are of no interest. These headers are supposed to be included by the generic headers “include.h”/”import.h” and their private variants. So the pruned down list is now:
public-headers: MulleObjCContainerKeyValueCoding.h
public-headers: MulleObjCKVCFoundation.h
public-headers: MulleObjCLoader+MulleObjCKVCFoundation.h
public-headers: NSNumber+MulleObjCKVCArithmetic.h
public-headers: NSObject+KVCSupport.h
public-headers: NSObject+KeyValueCoding.h
public-headers: NSObject+_MulleObjCKVCInformation.h
public-headers: _MulleObjCInstanceVariableAccess.h
public-headers: _MulleObjCKVCInformation.h
public-headers: import.h
public-headers: include.h
“include.h” and “import.h” are generic headers, that are second stage headers.
They are to be included by the projects headers. So we can also
remove them from the list. I will introduce a new patternfiles category
public-generic-headers
to single them out.
Headers that start with a _
are semi-public in mulle-objc projects. A private
header. The normal API consumer doesn’t include a private header or directly
or indirectly. A semi-public header is required for proper compilation, but
its symbols shouldn’t be used directly. An example would be a hidden base
class. One could call them third-stage headers.
A semi-public header may be included by other header files though. There are
no patternfiles for header files starting with a _
and I don’t think there
will be, as I don’t want to fragmentize the patternfiles too much.
Memo: Not sure this distinction is as clear cut in actual usage :) The bottom line is though, that these headers are only indirectly exposed. We don’t want them to show up in the envelope header.
MulleObjCKVCFoundation.h
is the envelope header itself, which we surely don’t
want to include (although it would be harmless, because of include guards or
use of #import
).
Filtering out MulleObjCKVCFoundation.h
with a patternfile is inconvenient,
because it is dependent on the PROJECT_NAME
and there is no expansion of
environment variables in the patternfile (yet).
In the end I will probably filter the envelope header itself and the semi-
public headers out “by convention”. With special code in the script, that
creates the #include
statements for the envelope file.
The result should be the remaining first stage headers:
public-headers: MulleObjCContainerKeyValueCoding.h
public-headers: MulleObjCLoader+MulleObjCKVCFoundation.h
public-headers: NSNumber+MulleObjCKVCArithmetic.h
public-headers: NSObject+KVCSupport.h
public-headers: NSObject+KeyValueCoding.h
public-headers: NSObject+_MulleObjCKVCInformation.h
NSObject+_MulleObjCKVCInformation.h
is semi-public also due to the +_
,
so actually the result should be:
public-headers: MulleObjCContainerKeyValueCoding.h
public-headers: MulleObjCLoader+MulleObjCKVCFoundation.h
public-headers: NSNumber+MulleObjCKVCArithmetic.h
public-headers: NSObject+KVCSupport.h
public-headers: NSObject+KeyValueCoding.h
Post a comment
All comments are held for moderation; basic HTML formatting accepted.