1[Important: this is mostly a historical document.]
2
3A makefile package for the GNUstep environment
4==============================================
5
6This document presents a makefile package for the GNUstep
7environment. It describes what are the goals the GNUstep environment
8should achieve and then presents some solutions.
9
10Goals
11=====
12
13There are several issues we tried to solve while designing a directory
14structure and the configuration/make procedures required to build a
15package.
16
17We tried to define a directory structure for keeping all the GNUstep
18related files. This structure makes the things more consistent and the
19configuration and compile process of various GNUstep packages more
20easier.
21
22An important issue is to let to a package the ability to deal with
23various libraries and configurations available now:
24
25* different Objective-C runtimes. In the Objective-C world there are
26currently two major runtimes: the NeXT runtime and the GNU
27runtime. They are different in several respects and a program or
28library that works at the runtime level should be aware of them.
29
30* different Foundation libraries. There are several Foundation libraries
31an OpenStep application can be written on top of: NeXT Foundation
32library which runs on NeXTStep/OPENSTEP systems, PDO (Portable
33Distributed Objects) which runs on a variety of Unix systems,
34gnustep-base and libFoundation.
35
36* different graphical interfaces. Until now two libraries provide or
37try to provide OpenStep compliant systems: the AppKit from NeXT and
38the GNUstep graphical libraries.
39
40The makefile package should be a simplistic, powerful and extensible
41way to write makefiles for a GNUstep project. It should allow the user
42to easily specify a library combination he/she wants to use when
43compiling a project. Also it should allow the user to easily create
44cross-compiled binaries.
45
46Library combinations
47====================
48
49If an application wants to work with all the possible combinations it
50will have to provide different binaries for each combination because
51it's not possible to have an application compiled for NeXT PDO that
52runs with gnustep-base or vice-versa. To summarize, an application can
53be compiled for these combinations:
54
55Objective-C runtime: NeXT, GNU
56Foundation library: NeXT, PDO, gnustep-base, libFoundation
57GUI library: NeXT, gnustep-gui
58
59Objective-C runtime: nx (for NeXT), gnu (for GNU)
60Foundation library: nx (for NeXT), pdo (for PDO), gnu (for gnustep-base),
61		fd (for libFoundation)
62GUI library: nx (for NeXT), gnu (for gnustep-gui)
63
64We'll denote the fact that an application was compiled for a certain
65combination of the above values by using the abbreviations of the
66different subsystems and placing dashes between them. For example
67an application compiled for NeXT Foundation using NeXT AppKit will
68have the compile attribute nx-nx-nx. An application compiled for
69PDO with the gnustep-gui library under Unix will be denoted by
70nx-pdo-gnu and another one compiled for gnustep-base using
71gnustep-gui under Unix will be denoted by gnu-gnu-gnu. Here is a
72list of some of the possible combinations:
73
74ObjC runtime	Foundation	GUI
75------------	----------	---
76    nx		    nx		nx
77    nx		    pdo		nx
78    nx		    pdo		gnu
79    gnu		    gnu		gnu
80    gnu		    gnu		gnu
81    nx		    fd		gnu
82    gnu		    fd		gnu
83
84Note that one can choose his/her own packages to build; it is not
85required to have all the packages installed on the system. Not having
86all of them installed limits only the ability to build and distribute
87binaries for those missing combinations.
88
89Directory structure
90===================
91
92There are several directories used in a GNUstep environment. The
93directories are relative to a top directory whose name is given by the
94variable GNUSTEP_SYSTEM_ROOT ($GNUSTEP_SYSTEM_ROOT in a shell or
95$(GNUSTEP_SYSTEM_ROOT) in a makefile). Below is the hierarchy of
96GNUstep directories:
97
98$(GNUSTEP_SYSTEM_ROOT)/
99    Headers/
100    Libraries/
101    Applications/
102    Tools/
103
104The Headers/ and Libraries/ directories, as their names suggest, keep
105the header files and the libraries required by a GNUstep project to
106compile and link. The libraries can be both shared or static,
107depending on the target system.
108
109The Applications/ directory is used by GNUstep graphical applications,
110those applications which have a graphical interface with the user. The
111Tools/ directory holds command line tools based on GNUstep libraries.
112
113The header files are grouped like this in the Headers/ directory:
114
115Headers/
116  gnustep/
117    base/
118    Foundation -> base
119    gui/
120    AppKit -> gui
121  libFoundation/
122    Foundation/
123
124The Libraries/ directory can hold libraries for several machines and
125several combinations of packages:
126
127Libraries/
128  i386/
129    linux-gnu/
130      gnu-gnu-gnu/
131	libgnustep-base.so
132	libgnustep-gui.so
133      gnu-fd-gnu/
134	libFoundation.so
135	libgnustep-gui.so
136  sparc/
137    solaris-2.5.1/
138      nx-pdo-gnu/
139	libgnustep-gui.so
140
141Please note that the Libraries/ directory contains only the libraries
142that come with GNUstep, the PDO library for example is not inside
143Libraries/. The compiler has to know where that library can be found,
144although the makefile package is responsible for passing all the
145necessary flags during compiling and linking.
146
147The libraries directory also contains resource files which belong to
148the GNUstep libraries, such as images and printer description
149files. Since the images can look different for different backends,
150each backend has its own images in a different directory based upon
151the interface look and feel:
152
153Libraries/
154  Resources/
155    Images/
156      NeXT/
157      Win32/
158    PrinterTypes/
159    Fonts/
160    gnustep/
161	NSCharacterSets/
162    libFoundation/
163      CharacterSets/
164      Defaults/
165      TimeZoneInfo/
166
167The resources that are specific to each Foundation libraries are kept
168in a subdirectory like above, except for NeXT Foundation and PDO which
169keep their resources in their own places.
170
171The Applications/ directory contains GNUstep graphical
172applications. Each application is kept in an app wrapper which
173contains all the binaries and all the resource files the application
174needs. The binaries organization resembles the one from libraries:
175
176Applications/
177  InterfaceModeller.app/
178    InterfaceModeller (for OPENSTEP systems compatibility)
179    i386/
180      linux-gnu/
181	gnu-gnu-gnu/
182	  InterfaceModeller
183    sparc/
184      solaris-2.5.1/
185	nx-pdo-gnu/
186	  InterfaceModeller
187
188The Tools/ directory contains command line tools.  Each tool
189executable is placed in a subdirectory corresponding to the CPU and
190operating system.
191
192Tools/
193  i386/
194    linux-gnu/
195	autoconf
196	gcc
197	dgs
198  sparc/
199    solaris-2.5.1/
200	autoconf
201	gcc
202
203
204The makefile package
205====================
206
207The GNUstep environment needs a makefile package whose purpose is to
208simplify writing a GNUstep project. This package should help
209developers easily write makefiles for compiling their projects.
210
211Theoretically an OpenStep application should only use OpenStep API, it
212should not rely at all on system specific header files. This is the
213most portable way to write an OpenStep application. For this kind of
214applications configuring is not necessary since no system specific
215header files or libraries need to be checked. The idea is to try
216eliminate the configuring process because of the problems it has in
217the presence of cross-compiling. Not relying on system files in a
218GNUstep project means that you don't need to check for them, so the
219project can simply be compiled by just typing `make'.
220
221This is the best scenario for a GNUstep package. If configuring is
222still needed the makefile package should support it without major
223changes.
224
225We identified until now the following types of projects:
226
227- application: for projects whose result are graphical GNUstep applications
228- tool: for command line programs which use GNUstep libraries
229- library: for creating libraries (both static and shared)
230- bundle: for creating a dynamically loaded bundle
231- aggregate: for projects that contain several other subprojects like
232  libraries, bundles and so on
233
234Another possible type of project could be "pallete", for adding
235functionality to the GNUstep InterfaceModeller application. Other
236project types can be added as well, the makefile package does not
237limit this in any way.
238
239A project consists from a collection of source code files and resource
240files. If a project has several subdirectories, those subdirectories
241are subprojects of the main project. A subproject type is not
242restricted in any way by the type of the project it's contained
243into. The only restriction is that you can not create multiple project
244types from the files in the same directory.
245
246For a project that does not need any additional configuring before
247compiling the only thing required to build the project should be
248typing
249
250  $ make
251
252in the command line :-).
253
254Where the object files go
255=========================
256
257The object files will go in a separate directory identified by the
258name of the target system and of the development environment used
259(ObjC runtime, Foundation library and GUI libraries). This way one can
260use the same source tree for building the project for multiple
261targets.
262
263How to choose the library combination
264=====================================
265
266The makefile package will allow the user to choose between different
267library combinations. To specify a combination you want to compile for
268just type:
269
270  $ make library_combo="library combination"
271
272For instance if you want to choose to compile using the NeXT's PDO
273Foundation and use the GNUstep GUI library on a Unix machine you can
274do like this:
275
276  $ make library_combo=nx-pdo-gnu
277
278
279Projects that require running configure before compiling
280========================================================
281
282There are two issues with this kind of projects. 'configure' is used
283to determine the existence of particular header files and/or of some
284specific functionality in the system header files. This thing is
285usually done by creating a config.h file which contains a couple of
286defines like HAVE_... which say if the checked functionality is
287present or not.
288
289Another usage of configure is to determine some specific libraries to
290link against to and/or some specific tools. A typical GNUstep program
291is not required to check for additional libraries because this step is
292done by the time the makefile package is installed. If the project
293still needs to check for additional libraries and/or tools, the
294recommended way is to output a config.mak file which is included by
295the main makefile, instead of using Makefile.in files which are
296modified by configure. The reason for not doing this is to avoid
297having the Makefiles contain target dependencies like above, this way
298keeping only one makefile instead of several for each target machine.
299
300The makefile package will be written for GNU make because it provides
301some very powerful features that save time both in writing the package
302but also at runtime, when you compile a project.
303
304How to build a package for different architectures
305==================================================
306
307In order to build a project for multiple architectures you'll need the
308development environment for the target machine installed on your
309machine. This includes a cross-compiler together with all the
310additional tools like the assembler and linker, the target header
311files and all the libraries you need.
312
313The GNUstep makefile package should be able to compile and link an
314application for another machine just by typing
315
316  $ make target="target machine"
317
318where "target machine" is the canonical system name as reported by
319config.guess.
320
321Building different types of a project
322=====================================
323
324During development you usually need to switch between a debug version and a
325profile one without having to recompile all of the sources. The makefile
326package allows you to do this by letting you define three boolean make
327variables. The values of these variables can be either "yes" or "no".
328
329* debug
330
331If the value is yes then it is assumed that the target is to be built with
332debugging info. By default the optimization is turned on but you can control
333this behavior via the OPTFLAGS make variable. The default is no.
334
335* shared
336
337It makes sense to specify this only for library targets. This variable says
338if the target needs to be built as a shared library. On systems that support
339shared libraries this is the default; the user has to explicitly specify
340shared=no in the command line.
341
342* profile
343
344When this variable is yes, a profile version of the target is built. The
345default is no.
346
347For example if you want to build a shared library with debug information
348enabled but no profile information, the command line would be:
349
350  $ make shared=yes debug=yes profile=no
351
352The last argument is not necessary because the default is to build a version
353without profile information.
354
355The object files will be output into the shared_debug_obj directory. If the
356profile is turned on the output directory would be shared_profile_debug_obj.
357
358Of course you also have to specify the library combo if it's different than the
359default.
360
361Naming conventions of the libraries
362===================================
363
364Sometimes you need to have different versions of a library compiled with
365different options. Suppose you want to compile a library with profiling
366information enabled so that you can profile your code. But you don't want to
367overwrite your existing installed library so that only some of the applications
368will work with the profile library, the rest will still use the normal library.
369
370The makefile package supports such a schema by having different names for
371different types of the same library. This works by appending an underscore
372after the name of the library followed by a letter which indicates the type of
373the library:
374
375's' for a static library
376'p' for a profile library
377'd' for a debug library
378
379So for example if you have the library 'example' compiled with debug
380information as a shared library it would be named libexample_d.so. If the same
381library is compiled as a static library its name would be named
382libexample_sd.a. The reason why the 's' letter for the static library appears
383in name of the library is for systems where the extensions of libraries don't
384matter.
385
386It is possible to compile a library with whatever combination of flags you
387want. The letters are appended in the order specified above, so if you compile
388the library as a static library, with profile and debug information enabled,
389the library name will have the _spd suffix appended.
390
391How a library is chosen
392=======================
393
394What happens if you compile an application with profile enabled and you don't
395have a library compiled with profile info into it, but you do have a normal
396library installed? It would be great if the normal library is chosen instead.
397This is a problem because the library that should be chosen has a different
398name than the profile library.
399
400We do support this schema by requiring the libraries to be specified using the
401short name, without any suffix appended to it. The `example' library in our
402case should be passed to the linker using -lexample, and not using -lexample_p.
403Based upon the shared, profile and debug variables, the makefile package will
404identify which are the libraries that exist on the system and it will come with
405the correct names when linking.
406
407The search order of libraries depending on what type of library is required is
408as follows. First of all an exact match is searched; if one is found it is
409returned. If either debug or profile are required, a library that matches at
410least one of these attributes is returned. For example if there is a
411profile+debug version of a library but only debug is required this library will
412match. If a static version is required but no static versions of the library
413exist, then no library is chosen; in this case the system simply prints out the
414name of the library, assuming a static library is somewhere else in the
415libraries search path of the linker.
416
417Building applications
418=====================
419
420In the makefile's package terminology an application is a program linked
421against the GUI libraries.
422
423An application is built as usualy, by compiling all of the sources and then
424linking the object files into the binary. The only difference between
425an application and any other project results is that the first is created into
426its own directory, instead of being a simple file. This directory is called
427the application wrapper and it contains the binaries for various architectures
428and resources needed by the application.
429
430The name of the application wrapper is taken to be the name of the application
431with the following extensions:
432
433.profile - if the application has been built with profile enabled
434.debug - if the application has been built with debug enabled
435.app - if the application has been built without debug or profile enabled
436
437If both debug and profile are enabled, the application extension will simply
438have the .profile extension. This is different from libraries were both options
439are reflected into the library's name.
440
441The structure of makefiles
442==========================
443
444The makefile package should be built so that a user project will only
445have to define what are the Objective-C files he/she uses, what are
446the C files, the header files and so on. All the rules that know how
447to build a library, an application or whatever type of project are
448defined in the internal files of the makefile package.
449
450This organization has several advantages. The main advantage is that
451we keep the makefiles in a GNUstep project small, only the makefile
452variable definitions. The other advantage is that all the build
453knowledge is centralized in a single place, the makefile
454package. Right now each GNUstep package tries to solve all of the
455issues related to the package building and nothing is reusable.
456
457The way the main makefile of a project should be written requires the
458user to specify the files needed by the make process and what kind of
459project needs to be built. This is defined by including a certain
460makefile package file. For example if the package to be built is an
461application then a possible Makefile can look like this:
462
463APP_NAME = test1 test2
464test1_OBJC_FILES = test1.m
465test2_OBJC_FILES = test2.m test21.m
466
467-include Makefile.preamble
468include application.make
469-include Makefile.postamble
470
471
472The main makefile will be generated automatically in the future by the
473ProjectCenter. This presents problems if the user wants to add his/her
474own makefiles targets or additional rules. Two additional files are
475provided: Makefile.preamble and Makefile.postamble. The first file is
476included before the makefile for the specific project type and is
477intended for redefining the standard variables or for adding to
478them. The second one is intended for adding additional rules or
479targets.
480
481The makefile package is installed under $(GNUSTEP_SYSTEM_ROOT)/Library/Makefiles.
482
483
484Ovidiu Predescu
485
486Last updated: April, 2001
487