AutoPackage Script Guide

Version:0.4



This is a draft document -- send feedback to tiroger@microsoft.com

Table of Contents


General Format

An annotated overview of a general .autopkg script:

#defines {
    // Global variables may be added here.
    // Variables on the "value" side of each definition will be processed at access time.
    GlobalVar1 = "";
}

configurations {
    // This node contains pivot information.
    // These are discussed in detail in the Pivots section.
}

nuget {


    #defines {
         // Variable definitions specific to this node (ie. "nuget").
        // Only available while inside this scope.
        // This metadata is not needed for most packages and is typically omitted.
    };


    // The nuspec file metadata.
    nuspec {

        // Unique package identifier
        id = MyNewPackage;

        // Version number. Follows NuGet standards. (currently SemVer 1.0)
        version : 1.1.0;

        // Display name for package.
        title: My new library;

        // List of package authors.  Braces may be ommited if only one author.
        authors: {bob, sam, mark};

        // List of owners.  Braces may be ommited if only one author.
        // Ignored by the default NuGet repository.
        owners: {bob, tom};

        // URL link to the license this package is released under.
        licenseUrl: "http://directory.fsf.org/wiki/License:Apache2.0";

        // URL to the project website (if any).
        projectUrl: "http://mysite.info/myproject"; 

        // URL to an image to be used for package icons.
        iconUrl: "http://mysite.info/myproject/logo.png"; 

        // If the license this package is being released
        // under has use restrictions, set this to "true".
        requireLicenseAcceptance:false; 

        // Brief summary of the package contents. Keep it short!
        summary:My new library package.  Now with features!; 

        // Extended description of the package contents.                                           
        description: My random description...; 

        // Brief notes about this version of the package.                                          
        releaseNotes: "Public release!";  

        // Copyright notice.
        copyright: Copyright 2013;       

        // Tags of arbitrary text for categorizing and filtering.
        tags: { stuff, native, random }; 

    };


    #output-packages {
        // Output file definitions.  These are covered in detail in Output Files.
        // This metadata is not needed for most packages and is typically omitted.
    }


    dependencies {
        // This node defines any outside items which may be needed to consume this package.
        packages : {
            // This is a list of other NuGet packages required to use this package.
            // Each item follows the format "<pkg_name>/<version>"
            my_pkg/1.0.0,
            my_other_pkg/2.1.5.33
        };
    }


    files {
        // File location information.  This node is critical for all packages, and is
        // where much of the effort is.  All file paths are relative to this .autopkg
        // file's location.

        // This node is frequently divided by multiple condition statements or rules.
        // Below is an example of how a typical package might be described.
        // For the below examples, we assume that this file is in
        //      <src_root>\contrib\coapp\
        // and that the compiled libraries are in a semi-logical directory tree in
        //      <src_root>\output\.

        // All .h and .hpp  files in <src_root>\include, but not in subdirectories.
        // Included for all conditions.
        include: { ..\include\*.h, ..\include\*.hpp }; 

        // All files in <src_root>\doc\, including all subdirectories recursively.
        // Included for all conditions.
        docs: {  ..\doc\**\* }; 

        // Include these specific files in the libpath and "copy to output" path only
        // under these pivot conditions.
        [Win32,dynamic] {  // x86, dll (dynamic linking)
            lib: { ..\output\x86\release\mylib.lib };
            bin: { ..\output\x86\release\mylib.dll };
        }

        [x64,dynamic] {  // x64, dll (dynamic linking)
            lib: { ..\output\x64\release\mylib.lib };
            bin: { ..\output\x64\release\mylib.dll };
        }

        [Win32,static] {  // x86, static linking
            lib: { ..\output\x86\release\mylib-static.lib };
        }

        [x64,static] {  // x64, static linking
            lib: { ..\output\x64\release\mylib-static.lib };
        }

    };


    props {
        // Additional declarations to insert into consuming projects before most of the
        // project settings. (These may be modified in visual studio by a developer
        // consuming this package.)
        // This node is typically not needed for most packages and may be omitted.
    }


    targets {
        // Additional declarations to insert into consuming projects after most of the
        // project settings. (These may NOT be modified in visual studio by a developer
        // consuming this package.)
        // This node is often used to set defines that are required that must be set by
        // the consuming project in order to correctly link to the libraries in this
        // package.  Such defines may be set either globally or only set under specific
        // conditions.
        Defines += HAS_MyLib;
        [dynamic]
            Defines += HAS_MyLib;
    }

}

Detailed Information

Pivots

A pivot is the generic term used for a unique set of mutually exclusive build/configuration options as viewed from the perspective of a Visual Studio project. As an example, one cannot build a Visual Studio project for both x64 and ARM simultaneously. These options therefore belong to a single pivot.

A single package script (.autopkg) may define many pivots, each of which may in turn contain many choices. The basic syntax for defining a pivot is presented below.

configurations {
    PivotName {
        // MSBuild property name.  This is only supplied if there is a direct mapping
        // between the pivot choices and an MSBuild property.
        key : "MSBuildPropertyName";

        // List of possible selections from this pivot.  When processing, only one
        // choice from each pivot may be selected simultaneously.
        choices: { option1, option2, option3 };

        // This is the description used by Visual Studio for this pivot if no key
        // was provided.
        description = "The option to use for this library";

        // These are alternate names by which to reference "option1".
        option1.aliases : { o1, opt1 };

        // This is what will display in the drop-down list in Visual Studio to identify
        // this choice for this pivot.  Defaults to the choice name (eg. "option2")
        // if this is not provided.
        option2.description = "Second option";

        // This will prevent Visual Studio from allowing this choice if "Win32" is not
        // selected in another pivot.
        option3.restricted-to = "Win32";
    };
}

NOTE! At this time it is expected that every choice across all pivots has a unique name. The behaviour if this is not the case is undefined.

There are a number of pivots that are pre-defined and will be automatically included in every .autopkg file:

    Toolset {
        key : "PlatformToolset";
        choices: { v110, v100, v90, v80, v71, v70, v60, gcc };
    };

    Platform {
        key : "Platform";
        choices: { Win32, x64, ARM, AnyCPU };
        Win32.aliases : { x86, win32, ia32, 386 };
        x64.aliases : { x64, amd64, em64t, intel64, x86-64, x86_64 };
        ARM.aliases : { arm, woa };
        AnyCPU.aliases : { anycpu, any };
    };

    Configuration {
        key : "Configuration";
        choices: { Release, Debug };
    };

    Linkage {
        choices : { dynamic, static, ltcg, sxs };
        description = "Which version of the .lib file to link to this library";

        ltcg.description = "Link Time Compiler Generation";
        dynamic.description = "Dynamic Library (DLL)";
        static.description = "Static";
        sxs.description = "Side-by-Side";
    };

    CallingConvention {
        // Only really applicable to x86
        choices : { cdecl, stdcall, fastcall, thiscall, clrcall };
        description = "Calling convention model to use (for x86 only)";
        cdecl.description = "cdecl";
        stdcall.description = "stdcall (Uncommon)";
        fastcall.description = "fastcall (Rare)";
        thiscall.description = "thiscall (Rare)";
        clrcall.description = "clrcall (Rare)";

        stdcall.restricted-to = "Win32";
        fastcall.restricted-to = "Win32";
        thiscall.restricted-to = "Win32";
        clrcall.restricted-to = "Win32";
    };

Output Files

This metadata node defines the .nupkg files which will be generated. These may be referenced by collections in the Files, Props, and Targets nodes to direct certain files and actions to be placed in different files. Below is presented the list of default output packages defined by AutoPackage. These exist automatically without needing to include them in your .autopkg file.

    // For reference,  ${pkgname} resolves to the ID specified in the nuspec node.

    #output-packages {
        default : ${pkgname};          //  eg.  bob.nupkg
        redist : ${pkgname}.redist;    //  eg.  bob.redist.nupkg
        symbols : ${pkgname}.symbols;  //  eg.  bob.symbols.nupkg
    }

File Collections

File collections in the files node may be defined or re-defined by the following syntax. All fields are optional for new collections. Re-defining a collection requires explicitly changing its existing properties.

    Collection_Name += {
        #output { // Assigns the output package file this collection is insterted into.
                  // Defaults to 'default' if not specified.
            package = <Output_File>;  // Must be named in #output-packages
                                                     // eg. default, redist, ...
        };

        // This will add each file in this collection to another collection in this script.
        #add-each-file : <collection_to_also_add_to>;

        // This will add the destination folder to another collection in this script.
        #add-folder : <collection_to_also_add_to>;

        // If true, this will flatten all files in this collection to be located in the
        // root of #destination.  Default is false, which will preserve minimum relative
        // paths when wildcards are used to select files.
        #flatten = true;

        // Assigns the folder within the package's directory tree where these files
        // should be placed.
        #destination = ${d_lib};
    };

Below is a sample of file collections as defined in the Implicit PackageScript.

    bin += {
        #output {
            package = redist;
        };
        #add-each-file : ::nuget.[redist]targets.[${condition}].CopyToOutput;
        #destination : ${d_bin};
    };

    lib += {
        // add each file as a link rule
        #add-each-file : ::nuget.targets.[${condition}].Libraries;
        #flatten = true;
        #destination = ${d_lib};
    };

    include += {
        #add-folder : ::nuget.targets.[${condition}].Includes;
        #destination : ${d_include};
    };

Other Resources

Implicit AutoPackage Rules

For a complete listing of the AutoPackage rules that are assigned automatically before the autopkg file is read, see the Implicit PackageScript.

How to have Include files nested in a subfolder

Sometimes the package creator wants to have files placed in a subdirectory so that consuming developers includes files like:

// sample include
#include <mylib/mylib.h> 

Autopackage tries to un-nest as much as possible. To work around this you can add a different file section and tell it how to add the files to the package:

nuget {
    files { 
        // instead of using something like this:
        include: { 
            "inc\*.h" 
        };

        // use this:
        nestedInclude: {
            #destination = ${d_include}\mylib;
             "inc\*.h"
        };
    };
};

This will copy the files into the subdirectory of the include folder.