Hello World Package

We use the front-end script PkgCreate.py to help us compile source code and pack a Synology Package or a SPK file.
SPK is the file format used by Synology Package Center to properly install your application. For more details about the structural format of an SPK file, you may refer to Synology Package.

In the following sections, we will guide you on how to create a simple utility program that can print out system memory, and pack it into an SPK file by using PkgCreate.py.

For more complicated cases, you can refer to the following examples provided:

  • Compile Open Source Project: tmux: If you are interested in porting an open source project to DSM system using tmux or setting up any advanced configurations, you may refer to this section.
  • Compile Open Source Project: nmap: If you are interested in porting an open source project to DSM system using nmap or setting up any advanced configurations, you may refer to this section.
  • Compile Kernel Module: If you are interested in installing more kernel modules to your DSM system, you may refer to this section.

Create Package Workflow:

There are two stages in the PkgCreate.py package creation process, the Build Stage and the Pack Stage.

In the Build Stage, PkgCreate.py will compile your project and all dependent projects in the correct order. In the Pack Stage, PkgCreate.py will pack your project into an SPK file.

To create your SPK file with PkgCreate.py properly, you will need to provide additional configuration files and build scripts to describe how to build your project. These files are put in a folder named “SynoBuildConf” under your project. These files and their purpose are listed in below.

  • SynoBuildConf/depends: defines the dependency of your project. For further details, please refer to Build Stage
  • SynoBuildConf/build: specifies PkgCreate.py on how to compile your project. For further details, please refer to Build Stage
  • SynoBuildConf/install: specifies PkgCreate.py on how to pack your SPK file. For further details, please refer to Pack Stage
  • SynoBuildConf/install-dev: similar to SynoBuildConf/install, but this will pack your SPK file in chroot environment rather than general DSM system. For further details, please refer to Compile Open Source Project: nmap.

For more details about these configuration files, please refer to Build Stage and Pack Stage. The following figure shows the work flow of these two stages.

figure

You can use the following commands to tell PkgCreate.py how to run through both stages.

cd /toolkit
pkgscripts/PkgCreate.py -x0 -c ${project}

The -c option tells PkgCreate.py to build, pack, and sign your project. The -x0 option is meant to traverse and build all dependent projects in the correct order. Each project is built according to their own SynoBuildConf/build.

Note: PkgCreate.py compiles source code and packs your package under chroot environment. Therefore, you must run all commands with root permission or with sudo.

PkgCreate.py has many other options to control the build flow. The following subsections will explore deeper into those options or you may directly refer to the Advanced section for more details.

Source Code Layout:

In Build Stage, PkgCreate.py will try to link all the projects to the build environment. As a result, your project source code must be put in a folder (we call it a “project”) under /toolkit/source. The following figure shows the whole working directory as an example.

toolkit/
├── build_env/
│   └── ds.${platform}-${version}/
│       └── /usr/syno/
│           ├── bin
│           ├── include
│           └── lib
├── pkgscripts/
└── source/
    └──minimalPkg/
        ├── minimalPkg.c
        ├── INFO.sh
        ├── Makefile
        ├── PACKAGE_ICON.PNG
        ├── PACKAGE_ICON_256.PNG
        ├── scripts/
        │   ├── postinst
        │   ├── postuninst
        │   ├── postupgrade
        │   ├── preinst
        │   ├── preuninst
        │   ├── preupgrade
        │   └── start-stop-status
        └── SynoBuildConf/
            ├── build
            ├── depends
            └── install

Note: You may organize the source code in any structure you like as long as SynoBuildConf is edited correctly. The following sections will explain this in detail.

Below is some sample code that we will use as an example.

// Copyright (c) 2000-2016 Synology Inc. All rights reserved.

#include <sys/sysinfo.h>
#include <syslog.h>
#include <stdio.h>

int main(int argc, char** argv) {
    struct sysinfo info;
    int ret;

    if (ret != 0) {
        syslog(LOG_SYSLOG, "Failed to get info\n");
        return -1;
    }

    syslog(LOG_SYSLOG, "[MinimalPkg] %s sample package ...", argv[1]);
    syslog(LOG_SYSLOG, "[MinimalPkg] Total Ram: %u\n", (unsigned int)info.totalram);
    syslog(LOG_SYSLOG, "[MinimalPkg] Free RAM: %u\n", (unsigned int)info.freeram);

    return 0;
}

Environment Variables in Build and Install Script

Front-end scripts will pass some environment variables to SynoBuildConf/build and SynoBuildConf/install. You can utilize them to build and install your projects. You can also find most of them in /toolkit/build_env/ds.${platform}-${version}/{env.mak,env32/64.mak}. Some of the environment variables are listed in below.

  • CC: path of gcc cross compiler.
  • CXX: path of g++ cross compiler.
  • LD: path of cross compiler linker.
  • CFLAGS: global cflags includes.
  • AR: path of cross compiler ar.
  • NM: path of cross compiler nm.
  • STRIP: path of cross compiler strip.
  • RANLIB: path of cross compiler ranlib.
  • OBJDUMP: path of cross compiler objdump.
  • LDFLAGS: global ldflags includes.
  • ConfigOpt: options for configure.
  • ARCH: processor architecture.
  • SYNO_PLATFORM: Synology platform.
  • DSM_SHLIB_MAJOR: major number of DSM (integer).
  • DSM_SHLIB_MINOR: minor number of DSM (integer).
  • DSM_SHLIB_NUM: build number of DSM (integer).
  • ToolChainSysRoot: cross compiler sysroot path.
  • SysRootPrefix: cross compiler sysroot concat with prefix /usr.
  • SysRootInclude: cross compiler sysroot concat with include_dir /usr/include.
  • SysRootLib: cross compiler sysroot concat with lib_dir /usr/lib.