The new, preferred way to run PwnableHarness targets is with pwnmake
. This
invocation runs all build and Docker management commands in a Docker container
for increased portability and easier workspace configuration. You can also
still use make
from the PwnableHarness directory if you prefer.
Project-specific targets like docker-build[project]
can also be used without
an argument. When no argument is provided, it will run that target for all
projects. So docker-build
will build the Docker images for ALL projects.
Note that descendent projects are included automatically. If you only want
to run the target in the project but not its descendents, append "-one" to
the target name (docker-build[project]
becomes docker-build-one[project]
).
build[project]
: Compile and link all defined TARGETS for the given project. This is the default target, so runningpwnmake
without any provided target is the same as runningpwnmake build
.clean[project]
: Deletes all build products for the given project. Running this target without an argument is effectively the same asrm -rf .build
. Note that individual projects can provide customclean
actions by using theclean::
multi-recipe target.publish[project]
: Copy all files that a project requests to be published to thepublish
directory at the top level of the workspace. Projects can define thePUBLISH
,PUBLISH_BUILD
, andPUBLISH_TOP
variables in theirBuild.mk
file to specify which files should be published. All files to be published are ensured to be up to date. So, if a project definesPUBLISH_BUILD := $(TARGET)
and you runpublish
before building the executable, it will build that target and then copy it to thepublish
directory. Note that thepublish
directory mirrors your workspace's directory structure. So if you havefoo/bar/Build.mk
which publishes its target (namedbaz
), that will be copied topublish/foo/bar/baz
. For serving published files over HTTP(S), it is useful to create symlinks from/var/www/<path>
into thepublish
directory in your workspace. Just ensure that the http server has read access to the contents.deploy[project]
: Without an argument, this is shorthand fordocker-start publish
. Projects can optionally define theDEPLOY_COMMAND
variable in theirBuild.mk
file, which is a command to be run from the project's directory when runningdeploy
ordeploy[project]
.docker-build[project]
: Build the project's Docker image, ensuring all dependencies are up to date. For example, editing a C file and then running thedocker-build
target will recompile the binary and rebuild the Docker image.docker-rebuild[project]
: Force rebuild the project's Docker image, even if all of its dependencies are up to date.docker-start[project]
: Create and start the project's Docker container, ensuring the Docker image it is based on is up to date.docker-restart[project]
: Restart the project's Docker container.docker-stop[project]
: Stop the project's Docker container.docker-clean[project]
: Stop the project's Docker container, and delete its image and any workdir volumes.list
: Display a list of all discovered project directories.list-targets
: Display a list of all provided targets.
VERBOSE=1
: Echo each command as it executes instead of a concise description.WITH_EXAMPLES=1
: Include the example projects in the workspace.MKDEBUG=1
: Output additional debug information about the PwnableHarness project discovery logic in its Makefiles.
- To prevent a directory from being searched for
Build.mk
project files, you can rename it so it ends in.disabled
. For example:
# Don't use Build.mk files under OldRepo
mv OldRepo OldRepo.disabled
# More concisely:
mv OldRepo{,.disabled}
-
You can create a
Config.mk
file in the top-level of your workspace (or any direct subdirectory) that will be included before all of the PwnableHarness Makefile code. This is mainly intended for defining variables prefixed withCONFIG_*
orDEFAULT_*
. Examples:CONFIG_IGNORE_32BIT
: Don't build 32-bit versions of PwnableHarnessCONFIG_PUBLISH_LIBPWNABLEHARNESS
: Publishlibpwnableharness(32|64).so
DEFAULT_(BITS|OFLAGS|CFLAGS|CXXFLAGS|LDFLAGS|CC|CXX|LD|AR)
: Override the default value of each of these build variables for your workspace.
-
Any directory can contain an
After.mk
file, which is included during the project discovery phase after all subdirectories have been included. Project discovery is performed as a depth-first traversal. When visiting a directory, itsBuild.mk
file will be included, then all of its subdirectories will be visited, and then itsAfter.mk
file will be included. BothBuild.mk
andAfter.mk
are optional in each directory.After.mk
is a good place for a parent/ancestor project to collect settings defined by its descendants.