Description of a workspace
Basic concepts
The workspace is the place where developpers work with deployment units (either those they develop or those they simply use).
Deployment units
Deployment units is the generic term to denote what can be put into workspace by users. Each deployment unit respects unity and deployability:
-
unitydenotes the fact that the whole content of the deployment unit is bound to the deployment unit itself and cannot be considered independently from the unit. In other words there is aunique lifecyclefor all elements of the deployment unit. -
deployabilitydenotes the fact that the unit can be referenced into workspace (and so can be found online) and can be put into a user local workspace.
There are currenlty four types of deployment units:
packagesare used to develop, publish and deploy C/C++ projects. Concrete result of packages arebinarieslike libraries and executable.wrappersare used to build and deploy external C/C++ projects (not directly developped within the PID methodology) so that these later can be used as if they were native packages.frameworksare used to document and reference a group of related packages. Concrete result of a framework is a static website providing online documentation and online binaries repository for its packages’s binaries.environmentsare used to configure the build environment in a workspace.
Contribution spaces
Contribution spaces are marketplaces where user can share their contributions. This is the place where knowledge on available deployment units is stored.
A workspace can contain one or more contribution spaces, whose content is used to deploy and configure packages, wrappers, frameworks and environments. To know more about contribution space, please have a look at this page.
Platforms
Platforms are description of target execution environments for packages. A workspace can have many platforms defined but a workspace defines only one current platform at a given moment of packages development lifecycle.
Platforms is the basic concept used to manage compatiblity between packages binaries.
A platform is described with following information:
- the target processor familly, for instance the most common architecture familly is
x86but you can also use the namearmto target arm processors. - the target processor architecture, for instance 32 or 64 bits are the most common values.
- the target operating system, for instance
linuxormacos. - the target C++ ABI. This reflects the ABI of the c++ standard library in use. Most of time there is only one ABI type per standard library, for instance
c++standard library has one ABI. Thestdc++has dual ABI support whose usage can be selected using a specific compilation flag. So possible values of ABI for this library isstdc++11for using the new ABI orstdc++for using former ABI.
Binaries generated for a given platform will not be compatible with another one generated for another platform. This rule is in fact true most of time but not every time. We decided to force incompatiblity between binaries generated for different platforms to avoid falling into a very complex decision process to know if they are compatible or not…
Technically, a platform is a specific folder into install folder of the workspace, for instance a folder named x86_64_linux_stdc++11. Practically, all binary packages built or deployed for this platform will be placed into the corresponding folder: <pid-workspace>/install/x86_64_linux_stdc++11.
Profiles
Profiles are used to configure the workspace with a set of tools. A profile defines default /alternative toolchains for supported languages and/or additional behaviors for using tools that are not supported by default in PID. By default, PID generates a default profile based on current detected features of the user’s workstation and this profile is the current profile. Profile are used to memorize various possible configurations of your workspace, but there is only one profile, called current profile that is used at a time. What is important to notice is that the current profile undirectly specifies for which target platform the code will be built.
For instance, first time you configure your workspace:
cd <pid-workspace>
pid configureYou should see an output looking like:
...
[PID] INFO: using default profile, based on host native development environment.
[PID] INFO : ASM language available with gcc toolchain.
[PID] INFO : C language available with gcc toolchain (version 9.3.0).
[PID] INFO : C++ language available with gcc toolchain (version 9.3.0).
[PID] INFO : Python language available (version 2.7). To use python modules installed in workspace please set the PYTHONPATH to =/home/robin/soft/PID/pid-workspace/install/x86_64_linux_stdc++11/__python2.7__
[PID] INFO : CUDA language available (version 11.0). Building for architecture 6.1.
[PID] INFO : Fortran language available with GNU toolchain (version 5.5.0).
[PID] INFO : Target platform in use is x86_64_linux_stdc++11:
+ processor family = x86 (optimizations: SSE, SSE2, SSE3, SSSE3, SSE4_1, POPCNT, SSE4_2, FP16, FMA3, AVX, AVX2, AVX_512F, AVX512_SKX)
+ binary architecture= 64
+ operating system=linux (ubuntu 16.04, apt packaging)
+ C++ ABI= stdc++11The first line indicates which profile you are currenlty using, at first configuration it is the default profile. From this current profile, PID evaluates the target platform you are building for. Here the target platform is x86_64_linux_stdc++11. PID also provides some more precise informations about target platform like possible optimizations for the target processor or distribution of the target operating system, if it can detect them.
A profile is described using environments. Environments are used to configure the user’s workstation in order to provide new language toolchains (e.g. using clang toolchain), to provide some cross compilation means (e.g. building packages for an arm 32 bits processor on a host with a x86 64 bits processor) or even to provide new behaviors implementing the usage of additional tools (kind of plugins to augment PID capabilities). Anytime a profile is set to become the current one, the workspace is reconfigured with information coming from environments this profile uses. This information will be automatically transmitted to packages so that, finally, toolchains and other configuration information will be used by packages and wrappers to build binaries: this process ensures that they will generate code for same target platform.
Users have to notice that a change of the current environment may not change the target platform simply because different toolchains may be used to generate code for same execution platform.
Workspace structure
Technically, a workspace is a local folder hierarchy in users’ workstations. In this folder hierarchy packages are developed, installed and referenced given a predetermined pattern : they are put into specific subfolders. As compared to a classical do as you wish organization, the workspace way of doing as several advantages:
- there is a reference path in the deploy process in such a way that classifying and finding software artefacts is made easy.
- there is no need to use system dependencies intensively. As far as possible, every dependency should be satisfied by workspace content, except for system dependencies that cannot reasonnably be packaged into workspace.
- developers can handle many version of a package in the same build/execution environment, without risking to break OS dependencies. Furthermore they can used multiple versions of the same package (but not for same build).
CMake project
A workspace is a specific CMake project. It consists in a root folder (named pid-workspace) with the following internal structure:
- the
.gitfolder contains version control related information, managed by the git tool. - the
.gitignorefile is used to excludeinstall,packages,wrappers,environments,sitesandcontributionfolders content from version control. This is mandatory since these folders content is supposed to be purely local in a user workstation. - the
CMakeLists.txtfile is the workspace configuration file from which workspace specific commands will be generated. - the
Use_PID.cmakefile is cmake script to include when using a PID workspace from an external project. - the
installfolder contains packages’ binaries installed by the user. - the
packagesfolder contains all the packages developed by an author. Each sub-folder ofpackagesis a local repository of a given package. - the
wrappersfolder contains all the wrapper developed/used. Each sub-folder ofwrappersis a local repository of a given external project wrapper. - the
environmentsfolder contains the definitions of specific development environments that can be used by the workspace to configure packages build process. Il also contains the fileprofiles_list.cmakethat contains the description of all profiles currenlty defined in workspace. - the
sitesfolder contains the definitions of static sites used to deploy frameworks (inframeworkssubfolder) and packages (inpackagessubfolder) documentation and binaries. - the
contributionsfolder contains thecontribution spacesin use. It also contain the filecontribution_spaces_list.cmakethat define all availablecontribution spacesand their priorities. - the files
README.md,CONTRIBUTING.mdandlicense.txtare used forpid-workspaceproject documentation. - the
cmakefolder contains PID system APIs.- The
.docssub-folder contains documentation about PID APIs - the
apisub-folder contains cmake modules implementing the core PID functionnalities. - the
commandssub-folder contains cmake scripts implementing PID commands. - the
patternssub-folder contains pattern files and folder used to generate most of general information on the packages and frameworks. - the
platformscontains cmake scripts used to deduce target platform currenlty used in the workspace.
- The
- the
buildfolder is the build directory for the workspace that contains all workspace generated file used for global configuration of projects.
Git repository
The workspace is also a git repository. It exists under different state in users workstations and online. The worskpace lying in a user workstation simply reflects the user own development environment while online workspace is used to provide PID system (well like any online git repositories).
There are different workspaces we quickly classify them here:
-
the
official workspace: It contains an up to date official PID APIs and command on themasterbranch. It also contains work in progress on the PID API (unstable) on theintegrationbranch. -
private workspaces: these are git project forked from the official workspace project. As everyone has not write access to the official repository, the best way to do is to fork the official workspace using git hosting service dedicated functionnality (use the fork functionaity in github and gitlab). This allows anyone, even groups of people, to have their ownpid-workspacein which they can update the PID system and propose their changes to the official workspace by creating a merge request of the git hosting service they use. -
local workspace: this is a clone ofofficialor aprivateworkspace of a user workstation. This is finally a folder where the user develops its C/C++ projects.
Source projects
All source projects are deployed into specific folders of the local workspace: they do not exist in the workspace repository.
- All deployment units’ source projects are directly deployed in:
packages,wrappers,environments,sites/packagesandsites/frameworksdepending on their nature. But each deployment units’ source project has a distinct lifecycle than thepid-workspaceproject.
Each direct subfolder of packages contains a git repository for a given native package, each direct subfolder of wrappers is a repository for a given external package wrapper, and so on.
- Contribution spaces projects are directly cloned into the
contributionsfolder. They also have a distinct lifecycle than thepid-workspaceproject.
Installed packages
The install folder contains installed binary version(s) of packages (either externa or native packages. Each of its direct sub directories is a folder representing a given target platform. For instance there may have a x86_64_linux_stdc++11 subfolder and also a x86_32_linux_stdc++ subfolder if the packages have been built for these two platforms. Then each of these subfolders directly contains:
- a
__system__folder that contains scripts used to check target platform configuration. - other folders specifying target platform related features. Those folders follow the pattern
__name__where name is a specific feature of the platform. For instance if target platform supports Python 2.7 you will find a folder__python2.7__that itself contains symlinks to all python packages defined in binary packages. It contains a set of symlinks pointing to python modules defined by some binary packages. The main utility of such folder is to simplify the boring task of setting thePYTHONPATHfor individual packages. Some environment may places their generated artefact into a specific folder, for instance thepkg-configenvironment generates configuration files into__pkg-config__folder. -
as many folders as there are binary packages available for the target platform. Such a folder simply takes the name of the corresponding package and itself contains:
- as many folders as they are installed versions of the binary package. The name of the version folder reflects the installed package version (e.g. :
1.3.5,0.2.0, etc.). - an
installersfolder that contains all installable binary archives with each archive matching a specific version in a specific build mode (release, debug).
- as many folders as they are installed versions of the binary package. The name of the version folder reflects the installed package version (e.g. :
For native packages each version folder is organized according to the following structure:
- the
binfolder contains all executables provided by the package, except tests, in both debug and release modes. In other words it contains the result of the compilation of its corresponding package repositoryappsfolder. - the
includefolder contains the exported interfaces of libraries. Basically, its direct sub-folders are libraries’ root folder hierarchically organized the same way as in the package repositoryincludefolder. - the
libfolder contains libraries provided by the package in both debug and release modes: it contains the result of the compilation of its corresponding package repositorysrcfolder. - the
.rpathfolder contains a subfolder for each installed runtime component (shared or module libraries, executables). Each of these subfolders contains the symlinks resolving the binary relocation. - the
sharefolder contains documents and scripts that are useful to the package users:- the
Use<Package><Version>.cmakefile is a specific cmake module used to identify components and dependencies defined by the installed package version. This file is generated automatically by native PID packages. docsub-folder contains API documentation generated by doxygencmakesub-folder contains cmake modules files that are required to use the package, like find scripts used to configure external packagesresourcessub-folder contains installed elements contained in the correspondingresourcessubfolder of the package repositorysharefoldercisub-folder contains bash scripts used for by the continuous integration system.scriptsub-folder contains a subfolder for each installed python module. Each of these subfolders contains the symlinks resolving the binary relocation specifically required by python.
- the
license.txtfile describes the license that applies to the software. This is a copy of the license file in package repository.
Organization inside external packages is mostly the same than for native packages, except :
- there is no
.rpathfolder. - the share folder is organized according to what is proposed by the external project, which may vary a bit from one external package to another. There is always a
Use<Package><Version>.cmakefile generated by PID.