Skip to content
Martin Nowak edited this page Feb 28, 2018 · 20 revisions

Various Dub Recipes

Creating a library package that also comes with an executable

A common use-case for this is a library with an executable CLI tool, e.g. convert for ImageMagick, a compression tool like zip and it's library, but also dub itself can be used as executable and library.

The simplest way to support this is using multiple configurations, one with targetType "executable" and the other with "library".

Then you either exclude the executable's sources from the library config, see dub as example, or you include them by adjusting mainSourceFile/sourceFiles/sourcePaths in your application configuration, see example.

Dub will only choose "library" targets when using packages as dependencies, so you can place your "application" first to make it the default. This allows to execute your package via dub run mypkg.

Creating windows package that has 32 and 64-bit dlls

  1. Create lib and lib64 folders in your project root (the same folder as dub.json)

  2. Put your 32-bit dll files in a lib folder and 64-bit dlls in lib64 Dub offers copyFiles build setting that we will use to get things done. This option allows to copy files to the applications directory. Also this option can have platform specific suffixes, which we will use to copy specific files to each platform.

  3. Put these lines in your dub.json. They will copy every .dll file found in lib folder into application folder.

"copyFiles-windows-x86" : ["lib/*.dll"],
"copyFiles-windows-x86_64" : ["lib64/*.dll"],
  • Final folder structure:
  project
      dub.json
      /lib
            freetype.dll, etc.
      /lib64
            freetype.dll, etc. 64-bit version

Working with submodules or packages that are not in the registry

It is a common practice to either have a project as a git submodule of a master project, or to use an unregistered project as a dependency for development. In this setup, setting the project to depend on a project at a given path, rather than looking up the repository, can come handy. Here's an example of such a package:

{
	"name": "dlang-org",
	"dependencies": {
		"libddoc": { "path": "./libddoc" },
		"libdparse": { "path": "./libdparse" }
	}
}

Another possibility is to add-local a package. This is particular useful during development, when you want to test a package with some libraries using that package.

dub add-local myrepo
dub list

Adding multiple versions of a local package

To use different versions of a local package, one can clone the local repo, check out specific versions, and dub add-local each clone.

git clone -b v0.2.0 myrepo myrepo-0.2.0
dub add-local myrepo-0.2.0
git clone -b v0.2.1 myrepo myrepo-0.2.1
dub add-local myrepo-0.2.1

See #525 for more details.

Creating a custom main for the test build

You can override the main function that dub creates by passing the path of the file with the custom main implementation to --main-file flag.

example customTest.d

import dub_test_root; //import the list of all modules

int main() {
  // allModules contains a list of all modules from your project
  // you might want to call something like this:
  return runUnitTests!allModules;
}

execute: dub test --main-file=customTest.d

Getting a list of import paths

By parsing the output of dub describe with jq you can get a list of import paths of a project.

dub describe | jq '.packages | .[] | .path as $path | .importPaths | .[] | $path + .'
dub describe | jq '.packages | .[] | .path as $path | .stringImportPaths | .[] | $path + .'

Building for older versions of macOS

By default when compiling on macOS a binary for the current version of the operating system is created. If you want to be able to run the binary on an older version of macOS it's necessary to specify the minimum deployment target. This can be done with the -macosx_version_min linker flag.

"lflags-osx": ["-macosx_version_min", "10.7", "-lcrt1.o"]

When specifying the -macosx_version_min flag it's also necessary to link with crt1.o, which is part of the C runtime, for the linker to be able to find the start symbol. Adding the -osx suffix to lflags makes sure that these linker flags will only be used when building on macOS.

Compiling a C dependency

Use preBuildCommands to compile C code and sourceFiles to add object files or archives. See linenoise/dub.sdl for an example configuration in a deimos package.

configuration "vendored" {
    targetType "sourceLibrary"
    preBuildCommands "cd $PACKAGE_DIR; [ -f C/linenoise.o ] || cc -c -fPIC -o C/linenoise.o C/linenoise.c" platform="posix"
    sourceFiles "C/linenoise.o" platform="posix"
}

Users of the library can select subConfiguration "linenoise" "vendored" to use the vendored C code instead of linking against a system-wide library.