Creating New Repos
When starting a new project using Plywood, you must typically create a new repo to hold that project. This new repo will hold the source code, modules and extern providers for your project. You can also combine multiple projects into a single repo, but either way, you'll have to create a new repo at some point.
Each repo is stored in a directory immediately below the repos
directory in the workspace root. At a minimum, each repo must contain the following:
- An
info.pylon
file. - A
.modules.cpp
file. - Some C++ source code for each module.
To demonstrate what an add-on repo looks like, there's a example repo on GitHub named primesieve. Try cloning this repo into your workspace and building the PrimeSieve
sample application it contains. This repo should be cloned directly underneath the repos
folder relative to your workspace root:
$ cd repos
$ git clone https://github.com/arc80/primesieve
After cloning this add-on repo, there should be a repos/primesieve
folder relative to the workspace root.
Let's look at the contents of primesieve
.
Contents of the primesieve
Repo
info.pylon
-
The
info.pylon
file holds basic information about the repo. This file contains a single JSON object. The object'sdependsOn
property lists other repos are required by this repo. In this case, theprimesieve
repo depends only on the built-inplywood
repo:{ "dependsOn": ["plywood"] }
Repos are only allowed to use modules and extern providers defined inside themselves, inside one of the repo dependencies listed in
info.pylon
, or inside a transitive dependency. Cyclic dependencies between repos are not allowed. src/PrimeSieve/PrimeSieve.modules.cpp
-
In Plywood, files having the filename suffix
.modules.cpp
that are located anywhere within a repo are used to add modules and extern providers to that repo. The file must begin with the directive#include <ply-build-repo/Module.h>
.In this case, the
PrimeSieve.modules.cpp
file contains a single C++ function. The comment before the function,// [ply module="PrimeSieve"]
, tells PlyTool that the function is a module function that defines a new module namedPrimeSieve
:#include <ply-build-repo/Module.h> // [ply module="PrimeSieve"] void module_PrimeSieve(ModuleArgs* args) { args->buildTarget->targetType = BuildTargetType::EXE; args->addSourceFiles(".", false); args->addTarget(Visibility::Private, "runtime"); }
Any time a target based on
PrimeSieve
is added to a build folder (by runningplytool target add PrimeSieve
) and a build system is generated for that build folder, PlyTool executes the C++ function provided here in order to initialize that target. In this case, the function does three things:- Marks the target as an executable.
- Adds all the source code in the current directory
"."
to the target. In this case, the current directory contains a single source file,Main.cpp
. Thefalse
argument tells PlyTool not to recurse into subdirectories, which isn't relevant here since there aren't any subdirectories. - Adds a target named
runtime
as a dependency of the current target. Becauseplywood
is listed as child repo of the current repo, the dependency target will be initialized from theruntime
module located in theplywood
repo.
src/PrimeSieve/Main.cpp
-
This is the only source file belonging to the
PrimeSieve
module. It contains the source code for thePrimeSieve
application itself. This source file begins with an#include
statement:#include <ply-runtime/Base.h>
Because the
plywood.runtime
module was listed as a dependency of the thePrimeSieve
module, the header file will be found inrepos/plywood/src/runtime
relative to the workspace root.
Building the PrimeSieve
Application
To build PrimeSieve
in its own build folder, execute the following commands in the workspace root, where the plytool
executable is located. (This executable was created when you set up the Plywood workspace.) If you're running on Linux or macOS, replace plytool
with ./plytool
instead:
$ plytool folder create PrimeSieve
$ plytool target add PrimeSieve
$ plytool generate
The plytool folder create
command creates a new build folder. The name of the build folder is not important as long as it's unique.
The plytool target add
command adds a new compilation target to the build folder based on the PrimeSieve
module. The PrimeSieve
module will be found in the primesieve
repo because that's the only repo that contains a module with that name. If you ever have multiple repos that define modules with the same name, you'll have to specify the fully qualified name of the module, which in this case would be primesieve.PrimeSieve
.
The plytool generate
command creates a new build system in the build folder. This build system will contain a compilation target based on the PrimeSieve
module as well as compilation targets for all dependencies of that module, which in this case are the runtime
module (defined in the plywood
repo) and the platform
module (also defined in the plywood
repo). Incidentally, you can view a tree diagram of the modules required by a build folder by running plytool target graph
:
$ plytool target graph
Initializing repo registry...
Dependency graph for folder 'PrimeSieve':
PrimeSieve
`-- runtime
`-- platform
The build system for PrimeSieve
should now be located in the data/build/PrimeSieve/build
directory relative to the workspace root. Open the project files in your IDE (such as Visual Studio or Xcode), then build and it yourself.