I'm changing the compiler of a medium-sized codebase, mostly Ada (with some C & C++ modules), from ObjectAda (PTC) to Gnat.
The product consists of ~100 Windows executables and ~20 dlls (~1500 Ada packages + ~20 C & 5 C++ compilation units)
The sources files are anized by "components", in the following way:
- a top folder contains packages shared by almost all components (tools)
- sources of each components are gathered under a top folder per component
Packages in component A don't have dependencies outside A (except to the shared part).
src\
+-- shared
| \ ...
+-- comp-A
| \ ...
+-- comp-B
| \ ...
...
Note that there is no naming collision (nor package or file name).
Several executables and dll are built from each component, + fews dll from the shared components (no executables)
With ObjectAda, the C/C++ modules are compiled (MsVC toolchain) using a dedicated Makefile, and corresponding object files are bundled into a static lib. The Ada sources are all managed using a single (ObjectAda) "library", which allows (during dev) to "cherry pick" an executables to be build with a minimal rebuild of dependencies (only the effectively changed dependant packages).
For Gnat, I've wrote several GPR files:
src
| +-- product.gpr : an aggregate project of each component (sub-aggregate projects)
|
+-- shared
| +-- shared.gpr : an aggregate project of the library and the dlls
| +-- lib_shared.gpr : a static library project of all Ada packages
| +-- dll_1.gpr : a dynamic (encapsulated) library extending the lib_shared.gpr
| +-- dll_2.gpr : ...
+-- comp-A
| +-- comp-A.gpr : an aggregate project of the library, executables and dlls
| +-- lib_comp-A.gpr : a static library project of all Ada packages (executables excluded)
| +-- exe_comp-A.gpr : a standard project (including the lib through "with" clause) with Main
| | and link instructions for every executables
| +-- dll_A1.gpr : a dynamic (encapsulated) library extending the lib_comp-A.gpr
| +-- dll_A2.gpr : ...
+-- comp-B
| | (same as comp-A)
...
(I've kept the static lib of the C/C++ content up to now, but the goal is to also move this part to Gnat).
This structure works well to build the overall product (all executables and dll) - typically on CI, but is not ideal for the development phase (eg build a single executable, while other parts of the basecode is "in edition" - and cannot be compiled yet), because it move the dependencies from package level to library (component) level.
Do you see a better way to deal with the GPR, or should I switch to Makefile (Gnatmake / Gnatdll)?