Nat! bio photo

Nat!

Senior Mull

Twitter Github Twitch

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.

Name:
E-mail: (not published)
Website: