FPC Dotted RTL: what changed
Revision 1 to 2. Removed lines have a minus sign; added lines have a plus sign.
| Old | New | Line | |
|---|---|---|---|
| 1 | 1 | ## The project | |
| 2 | 2 | ||
| 3 | 3 | The FPC distribution has support for creating a "dotted RTL". This is a set of units from RTL/Packages where all unit names are namespaced (dotted). | |
| 4 | 4 | ||
| 5 | 5 | The units that are found in Delphi 2009 (and upwards) and FPC have the same name. For units that exist in FPC but not in Delphi, the occasion has been used to make the names more consistent. New namespaces have been chosen for all packages, and the last part of the unitname has been cleaned up. | |
| 6 | 6 | ||
| 7 | 7 | The uses clause of the units in the RTL and Packages have been modified so they refer to the correct unit | |
| 8 | 8 | ||
| 9 | 9 | This is managed entirely through makefiles and fpmake. | |
| 10 | 10 | ||
| 11 | 11 | Note that fpcmake (the older tool) has no knowledge of the dotted RTL, it does not need this knowledge. | |
| 12 | 12 | ||
| 13 | 13 | The files that are dotted reside in a subdirectory *namespaced*. They set a define and include the non-dotted unit file. | |
| 14 | 14 | ||
| 15 | 15 | ## Compiling | |
| 16 | 16 | ||
| 17 | 17 | Only the RTL and the packages can be compiled with dotted units. The creation of dotted units is managed through the FPC_DOTTEDUNITS define in the makefiles. | |
| 18 | 18 | ||
| 19 | 19 | To make the dotted rtl you must do, in the FPC dir | |
| 20 | 20 | ||
| 21 | 21 | make -C rtl FPC_DOTTEDUNITS=1 clean all | |
| 22 | 22 | make -C packages FPC_DOTTEDUNITS=1 clean all | |
| 23 | 23 | ||
| 24 | 24 | and a | |
| 25 | 25 | ||
| 26 | 26 | make -C rtl FPC_DOTTEDUNITS=1 install | |
| 27 | 27 | make -C packages FPC_DOTTEDUNITS=1 install | |
| 28 | 28 | ||
| 29 | 29 | afterwards. | |
| 30 | 30 | ||
| 31 | 31 | ## Makefiles | |
| 32 | 32 | ||
| 33 | 33 | Here we explain how the makefiles manage the creation of dotted RTL/Packages. | |
| 34 | 34 | ||
| 35 | 35 | ### RTL | |
| 36 | 36 | ||
| 37 | 37 | The Makefile.fpc files in the RTL directory have been cleaned up. The observation was made that almost all targets are common to all platforms (logical, it is the RTL). What differs per target for each os are the dependencies and possibly some compiler options. | |
| 38 | 38 | ||
| 39 | 39 | So a file was made **inc/Makefile.rtl**, which is used as an include file for the **Makefile.fpc** files in the OS-Specific directories. It is entirely parametrized. | |
| 40 | 40 | ||
| 41 | 41 | In the common **Makefile.rtl** the following definitions are made: | |
| 42 | 42 | ||
| 43 | 43 | - For each unit, a variable **NAMEUNIT** is defined. For example **SYSTEMUNIT** or **WINDOWSUNIT**. | |
| 44 | 44 | ||
| 45 | 45 | ||
| 46 | 46 | ||
| 47 | 47 | Depending on the **FPC_DOTTEDUNITS**, this will be the non-dotted or the dotted name. | |
| 48 | 48 | ||
| 49 | 49 | - For each unit, a **NAME_DEPS** variable is defined that specifies the dependencies for this unit. | |
| 50 | 50 | - In the **prerules** section of the os-specific **Makefile.fpc**, you can define **NAME_DEPS_OS** and **NAME_DEPS_CPU** for OS and CPU specific dependencies. | |
| 51 | 51 | ||
| 52 | 52 | ||
| 53 | 53 | ||
| 54 | 54 | These defines will be taken into account in the target rules (see below) | |
| 55 | 55 | ||
| 56 | 56 | You should only use *NAMEUNIT\$(PPUEXT)* when defining unit dependencies, to make sure the correct unit is taken. | |
| 57 | 57 | ||
| 58 | 58 | - For each unit, 2 targets are defined: | |
| 59 | 59 | ||
| 60 | 60 | name$(PPUEXT)''' : $(NAME_DEPS) $(NAME_DEPS_OS) $(NAME_DEPS_CPU) | |
| 61 | 61 | $(COMPILER) $(NAME_OPTS) $< | |
| 62 | 62 | ||
| 63 | 63 | dottedname$(PPUEXT) : $(NAME_DEPS) $(NAME_DEPS_OS) $(NAME_DEPS_CPU) | |
| 64 | 64 | $(COMPILER) $(NAME_OPTS) $< | |
| 65 | 65 | ||
| 66 | 66 | Depending on **FPC_DOTTEDUNITS**, one of these 2 units will be compiled. | |
| 67 | 67 | ||
| 68 | 68 | The common targets have been removed from the OS-specific **Makefile.fpc** files, but OS-Specific make rules for os-specific targets remain in these OS-specific **Makefile.fpc** files: | |
| 69 | 69 | ||
| 70 | 70 | - The build units. For build units (**buildrtl**), the uses clause of the build unit is modified so it uses either dotted or non-dotted units. | |
| 71 | 71 | - Loaders. (assembler files) | |
| 72 | 72 | - Other os-specific files. | |
| 73 | 73 | ||
| 74 | 74 | To regenerate the OS-Specific Makefiles, you must include the **inc/Makefile.rtl** using the -x option. For example: | |
| 75 | 75 | ||
| 76 | 76 | cd rtl/linux | |
| 77 | 77 | fpcmake -x ../inc/Makefile.rtl -Tlinux | |
| 78 | 78 | ||
| 79 | 79 | The **rtl/regenmakefiles.sh** script does this for all directories below the RTL. The **packages/regenmakefiles.sh** script does this for all directories in the packages. | |
| 80 | 80 | ||
| 81 | 81 | ### Packages | |
| 82 | 82 | ||
| 83 | 83 | Noting that, since the use of fpmake, all package makefiles were in essence the same except for the package name a single makefile exists now in **build/Makefile.pkg**. | |
| 84 | 84 | ||
| 85 | 85 | This file is generated from **build/Makefile.fpc** and contains the rules to regenerate *fpmake* correctly. | |
| 86 | 86 | ||
| 87 | 87 | The package-specific Makefile.fpc has been removed. All package-level Makefiles have now been replaced with a 2-line Makefile: | |
| 88 | 88 | ||
| 89 | 89 | - a single line to set the package name. | |
| 90 | 90 | - a single line to include the **build/Makefile.pkg** | |
| 91 | 91 | ||
| 92 | 92 | All the rest is handled by **fpmake**, see below. | |
| 93 | 93 | ||
| 94 | 94 | Every package directory now has a 'namespaces.lst' file which contains the mapping of non-dotted to dotted unit names (see below). it also contains some rule lines that specify how to map unit paths to include paths. | |
| 95 | 95 | ||
| 96 | 96 | ## fpmake | |
| 97 | 97 | ||
| 98 | 98 | ### working principle | |
| 99 | 99 | ||
| 100 | 100 | fpmake could already perfectly handle dotted names. What was needed was a way to keep the current files with as little modifications as possible. For this reason, a system was devised where the non-dotted names of units were mapped to dotted unit names. | |
| 101 | 101 | ||
| 102 | 102 | 2 changes have been made in fpmake to make this possible: | |
| 103 | 103 | ||
| 104 | 104 | - It now understands a *transformations* file. The transformations listed in this file are applied to all target and dependency definitions. | |
| 105 | 105 | ||
| 106 | - | ||
| 106 | + | ``` pascal | |
| 107 | + | This file can be specified with a property NameSpaceMap on the TPackage object. The name is relative to the package dir. | |
| 108 | + | ``` | |
| 107 | 109 | ||
| 108 | 110 | - a **--ns** or **--namespace** option was added. When added, the tranformations listed in the **NamespaceMap** are applied to the targets. | |
| 109 | 111 | ||
| 110 | 112 | ### Transformations file | |
| 111 | 113 | ||
| 112 | 114 | The transformations file is a file containing rules. There are 2 kinds of lines | |
| 113 | 115 | ||
| 114 | 116 | - A filename transformation line | |
| 115 | 117 | ||
| 116 | 118 | OldFile=NewFile | |
| 117 | 119 | ||
| 118 | 120 | ||
| 119 | 121 | ||
| 120 | 122 | for example | |
| 121 | 123 | ||
| 122 | 124 | src/mysql56dyn.pp=namespaced/Api.Mysql56dyn.pp | |
| 123 | 125 | ||
| 124 | 126 | - a path transformation line. This is of the form | |
| 125 | 127 | ||
| 126 | 128 | {<X><OP>:<dir>}[=DestDir] | |
| 127 | 129 | ||
| 128 | 130 | ||
| 129 | 131 | ||
| 130 | 132 | Here *X* is the path to transform, it is one of | |
| 131 | 133 | ||
| 132 | 134 | - **s** the source path | |
| 133 | 135 | - **i** the include path | |
| 134 | 136 | - **u** the unit path | |
| 135 | 137 | ||
| 136 | 138 | *OP* is the transformation operation to perform. It is one of | |
| 137 | 139 | ||
| 138 | 140 | - *'** It replaces the complete specified directory *dir* with *DestDir* | |
| 139 | 141 | - *'-* It removes the specified *dir* from the search path. | |
| 140 | 142 | - *'+* It adds the specified *dir* to the search path if it was not there yet. | |
| 141 | 143 | ||
| 142 | 144 | For example | |
| 143 | 145 | ||
| 144 | 146 | {s*:src/}=namespaced/ | |
| 145 | 147 | ||
| 146 | 148 | will replace all **src** directories in source paths with **namespaced** | |
| 147 | 149 | ||
| 148 | 150 | {i+:src/} | |
| 149 | 151 | ||
| 150 | 152 | Will a dd *src* as a include file path. | |
| 151 | 153 | ||
| 152 | 154 | ## Other utilities | |
| 153 | 155 | ||
| 154 | 156 | The utils/dotutils directory contain some utilities to help converting a project with non-dotted names to dotted names (or both) | |
| 155 | 157 | ||
| 156 | 158 | - **genunitnames** takes as input a list of tranformations (nondotted=dotted) and generates UNITNAME variables for use in a Makefile. | |
| 157 | 159 | ||
| 158 | 160 | - *'addnamespacetofpake* will add a line NameSpaceMap:='namespaces.lst' to a fpmake program source. It attempts to add this in the correct location. | |
| 159 | 161 | ||
| 160 | 162 | - **encloseunit** enclodes standard input in a IFDEF block | |
| 161 | 163 | ||
| 162 | 164 | {$IFDEF FPC_DOTTEDUNITS} | |
| 163 | 165 | {$ENDIF FPC_DOTTEDUNITS} | |
| 164 | 166 | ||
| 165 | 167 | ||
| 166 | 168 | ||
| 167 | 169 | if your editor supports filtering a selection in a block, this can be used to quickly enclose a a block of lines in an ifdef | |
| 168 | 170 | ||
| 169 | 171 | - **fixuses** takes as a parameter a list of transformations (nondotted=dotted) to apply, and as standard input a uses line. | |
| 170 | 172 | ||
| 171 | 173 | it will then transform the uses clause to a form like this: | |
| 172 | 174 | ||
| 173 | 175 | {$IFDEF FPC_DOTTEDUNITS} | |
| 174 | 176 | // dotted uses clause | |
| 175 | 177 | {$ELSE} | |
| 176 | 178 | // non-dotted uses clause | |
| 177 | 179 | {$ENDIF FPC_DOTTEDUNITS} | |
| 178 | 180 | ||
| 179 | 181 | ||
| 180 | 182 | ||
| 181 | 183 | if your editor supports filtering a selection in a block, this can be used to quickly enclose a a block of lines in the above-mentioned form | |
| 182 | 184 | ||
| 183 | 185 | - **makedottedfiles** will read a list of units and transform them to use a uses clause in the following form: | |
| 184 | 186 | ||
| 185 | 187 | {\$IFDEF FPC_DOTTEDUNITS} // dotted uses clause {\$ELSE} // non-dotted uses clause {\$ENDIF FPC_DOTTEDUNITS} The unit will then be written to a new file. It has various options which are listed with the **-h** command-line options. | |
| 186 | 188 | ||
| 187 | 189 | - **prefixunits** will read a single unit and transform it to use a uses clause in the following form: | |
| 188 | 190 | ||
| 189 | 191 | {\$IFDEF FPC_DOTTEDUNITS} // dotted uses clause {\$ELSE} // non-dotted uses clause {\$ENDIF FPC_DOTTEDUNITS} The unit will then be written to a new file. It has various options which are listed with the **-h** command-line options. | |
| 190 | 192 | ||
| 191 | 193 | - **proxyunit** is a small program that takes 2 names (non-dotted and dotted) of units and writes a dotted unit file which | |
| 192 | 194 | ||
| 193 | 195 | sets the correct define and includes the original filen. | |
| 194 | 196 | ||
| 195 | 197 | - **reworkmakefile** reworks makefile rules: it replaces hardcoded unit names xyz in a rule with variable XYZUNIT. | |
| 196 | 198 | ||
| 197 | 199 | ||
| 198 | 200 | ||
| 199 | 201 | (see genunitnames for how to create the variables) | |
| 200 | 202 | ||
| 201 | 203 | - **replaceunitnames** replaces unit names in a makefile with the **\$(NAMEUNIT)** macro. | |
| 202 | 204 | ||
| 203 | 205 | - **replaceword** replaces a word with another word in a list of files. | |
| 204 | 206 | ||
| 205 | 207 | The following units do the actual work: | |
| 206 | 208 | ||
| 207 | 209 | - **namespacetool** is a unit used to generate the **namespaces.lst** files in the packages directory, based on a list of known aliases. | |
| 208 | 210 | - **prefixer** is the unit used in **makedottedfiles** which actually rewrites the uses clause of a unit. | |
| 209 | 211 | - **rewritemakefile** is the unit used in **reworkmakfile** which does the actual work. | |
| 210 | 212 | ||
| 211 | 213 | There is a **readme.txt** file with more explanations, and the **known.txt** file contains all transformations used in RTL and packages | |
| 212 | 214 | ||
| 213 | 215 | --- | |
| 214 | 216 | *From the Free Pascal wiki, page "FPC Dotted RTL", as it stood on 2023-10-22 after a change by FPC user, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).* | |
| 215 | 217 | Category: RTL |
