Skip to content

Improve_quickstart

daar edited this page Mar 23, 2018 · 18 revisions

Proposal to improve pmake --quickstart

The current --quickstart is a very naïve way of creating a build environment suitable for pmake to build a project. Currently all files are (recursively as option) searched and ordered per folder. Once that is done, all files per folder are parsed and written to a PMake.txt file. Found files are not clustered into one pmake call, but rather for each entry an API call is written. This leads for instance for include files to duplicate calls and for units one line is added each time. This proposal is about improving the generation of PMake.txt and adding additional functionality such as adding calls to add_subdirectory and install and creating a clean and ordered PMake.txt file. The result is a number of PMake.txt files that are able to be compiled into a make2 file. It is not guaranteed to produce a valid build system.

General outline

In general the idea is to scan the source folder starting from the base directory as it is the case now, but making a more thorough analysis by traversing the source tree. To do this the PMake definitions are being created in memory. Items are being added as required to a data structure. The items that are being tracked are;

  • units
  • executables/dynamic libraries
  • include files
  • subdirectories
  • install targets
  • test files

Once the whole source tree is traversed and all relevant data is extracted, all PMake files are saved to their respective file locations.

PMake data structure

All parsed data is stored in one big data structure that contains all data that needs to be written to PMake.txt files. The data structure contains different information depending on the type of source file. By definition there is one package name defined per folder.

  ITM_type = (itLibrary, itExecutable, itInclude, itSubDirectory, itInstall, itTest);

  pmkItem = record
    next, prev: pointer;
    vtype: ITM_type ;
    name: shortstring;
    case word of
      itLibrary:      (srcfile    : string;
		       depends    : string);
      itExecutable:   (executable : string;
		       srcfile    : string;
		       depends    : string);
      itInclude:      (directory  : string);
      itSubDirectory: (directory  : string);
      itInstall:      (directory  : string;
		       destination: string; 
		       pattern    : string;
		       depends    : string);
      itTest:         (executable : string;
		       srcfile    : string;
		       depends    : string;
		       description: string);
  end;

  pmkFile = record
    next, prev: pointer;
    directory : shortstring;
    pkgname   : shortstring;
    executable: PMK_ListBase;
    include   : boolean;
    install   : PMK_ListBase;
    library_  : PMK_ListBase;
    subdir    : PMK_ListBase;
    test      : PMK_ListBase;
  end;

General procedure

  • search all folders (excluding the build folder) starting from the base folder supplied
  • for each folder do the following in this order;
    • create a pmkFile variable and add to the list
    • search all files according the following file extensions: *.pp; *.pas; *.inc
    • any found include file is added to the pmkFile
    • any found unit file is added to the pmkFile
    • any found executable file is added to the pmkFile
    • any found dynamic library file is added to the pmkFile
    • depending on the folder name (user selectable eg test) the executable is added as test to the pmkFile
    • depending on the user selection, executables are added to as install target to the pmkFile
    • if a previous pmkFile definition is found (and any entry above was made, and this folder is a subfolder of the previous definition) then add the add_subdirectory command to this previous definition
    • proceed to the next folder in the tree
  • once done then traverse the pmkFiles variable and output each PMake.txt file accordingly, however do the following for the PMake.txt in the base folder
    • write compiler_minimum_required function to PMake.txt
    • write project function to PMake.txt

Output

The output of the PMake.txt file is as nicely formatted as possible, making it easy to understand and adjust manually later. To make it clear that the file has been generated, some additional information is added in the header of the file. An example is shown below.

(* This file was auto-generated
 *   
 * PMake version: 0.0.2
 * Generated by : dblaszyk
 * Date         : march 22, 2018
 *)

// sub directories
add_subdirectory('subdirectory1');
add_subdirectory('subdirectory2');

// include files
include_directories('pkgname', ['$(PMAKE_CURRENT_SOURCE_DIR)']);

// libraries
add_library('pkgname', 
[
  'unit1.pas',
  'unit2.pas',
  'unit3.pas',
  'unit4.pas'
], []);

// executables
add_executable('pkgname', 'executable', 'srcfile.pp', []);

// install
install('$(BINOUTPUTDIR)', '$(PMAKE_PACKAGE_DIR)', 'executable$(EXE)', 'pkgname');

// tests
add_test('executable', 'srcfile.pp', [], 'test file description');

The root PMake.txt file will contain the following to give an example.

(* This file was auto-generated
 *   
 * PMake version: 0.0.2
 * Generated by : dblaszyk
 * Date         : march 22, 2018
 *)

compiler_minimum_required(3,0,0);
project('project name', 'version');

// sub directories
add_subdirectory('subdirectory1');
add_subdirectory('subdirectory2');

//create the package
create_package('$(PMAKE_PROJECT_NAME)-$(PROJECT_VERSION)-$(PMAKE_HOST_SYSTEM_PROCESSOR)-$(PMAKE_HOST_SYSTEM_NAME)', 'package');

Out of scope work

  • Dependencies are not attempted to be resolved. One could add this later, but requires a full resolution of all unit dependencies in all source files. Unit names not possible to be resolved from within the project are then just skipped.
  • quickstart produces a number of PMake.txt files one per each folder that contains source files. It does not guarantee a working build system, however it should work for simple projects. For complex projects some manual adjustments are needed. This is considered a too complex task to automate, plus when conditional compiling is needed there is almost no way to tell how to act upfront.

Clone this wiki locally