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