{"id":19973237,"url":"https://github.com/zeromq/zproject","last_synced_at":"2025-05-16T12:05:35.406Z","repository":{"id":22151771,"uuid":"25483047","full_name":"zeromq/zproject","owner":"zeromq","description":"CLASS Project Generator","archived":false,"fork":false,"pushed_at":"2024-11-22T16:42:23.000Z","size":3583,"stargazers_count":148,"open_issues_count":31,"forks_count":105,"subscribers_count":19,"default_branch":"master","last_synced_at":"2025-03-26T08:01:34.709Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zeromq.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS","dei":null,"publiccode":null,"codemeta":null}},"created_at":"2014-10-20T19:32:00.000Z","updated_at":"2024-12-14T20:57:57.000Z","dependencies_parsed_at":"2024-12-13T15:08:29.850Z","dependency_job_id":"fe6d8144-0dd4-425d-9a81-b667ec841476","html_url":"https://github.com/zeromq/zproject","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zeromq%2Fzproject","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zeromq%2Fzproject/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zeromq%2Fzproject/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zeromq%2Fzproject/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zeromq","download_url":"https://codeload.github.com/zeromq/zproject/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246785427,"owners_count":20833490,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-13T03:10:45.226Z","updated_at":"2025-04-02T09:01:12.462Z","avatar_url":"https://github.com/zeromq.png","language":"Shell","funding_links":[],"categories":["Build Systems","构建系统"],"sub_categories":[],"readme":"\n# zproject - CLASS Project Generator\n\n## Contents\n\n\n**[Overview](#overview)**\n*  [Scope and Goals](#scope-and-goals)\n\n**[Tutorial](#tutorial)**\n\n**[Installation](#installation)**\n\n**[Getting started](#getting-started)**\n*  [Setup your project environment](#setup-your-project-environment)\n*  [Configuration](#configuration)\n*  [Project dependencies](#project-dependencies)\n*  [Optional : Class filename configuration](#optional--class-filename-configuration)\n*  [Targets](#targets)\n\u0026emsp;[Target Options](#target-options)\n\u0026emsp;[Android target options](#android-target-options)\n\u0026emsp;[Target Scopes](#target-scopes)\n*  [Modifying generated files in an already existent project](#modifying-generated-files-in-an-already-existent-project)\n\n**[API models](#api-models)**\n*  [Sample API model](#sample-api-model)\n*  [Supported API Model Attributes](#supported-api-model-attributes)\n*  [API Types](#api-types)\n*  [Tips](#tips)\n*  [Generate API model from C header files](#generate-api-model-from-c-header-files)\n\u0026emsp;[Known caveats](#known-caveats)\n\n**[Language Binding Notes](#language-binding-notes)**\n*  [Java Language Binding](#java-language-binding)\n\n**[Draft API Support](#draft-api-support)**\n\n**[Removal](#removal)**\n*  [autotools](#autotools)\n\n**[Additional files](#additional-files)**\n*  [Design goals](#design-goals)\n*  [Example](#example)\n\n**[Notes for Writing Targets](#notes-for-writing-targets)**\n*  [Snippets](#snippets)\n\n**[Notes for Writing Language Targets](#notes-for-writing-language-targets)**\n*  [Schema/Architecture Overview](#schemaarchitecture-overview)\n*  [Informal Summary](#informal-summary)\n*  [Semantic Attributes](#semantic-attributes)\n\n**[Ownership and License](#ownership-and-license)**\n*  [Ownership and License of generated sources](#ownership-and-license-of-generated-sources)\n*  [Hints to Contributors](#hints-to-contributors)\n*  [This Document](#this-document)\n\n## Overview\n\nzproject is a community project, like most ZeroMQ projects, built using the C4.1 process, and licensed under MPL v2. It solves the Makefile problem really well. It is unashamedly for C, and more pointedly, for that modern C dialect we call CLASS. CLASS is the Minecraft of C: fun, easy, playful, mind-opening, and social. Read more about it [hintjens#79](http://hintjens.com/blog:79).\n\nzproject grew out of the work that has been done to automatically generate the build environment in CZMQ. It allows to share these automations with other projects like [zyre](https://github.com/zeromq/zyre), [malamute](https://github.com/zeromq/malamute) or [hydra](https://github.com/edgenet/hydra) and at the same time keep everything in sync.\n\n### Scope and Goals\n\nzproject has these primary goals:\n\n* generate cross-platform build environments.\n* generate CLASS ([ZeroMQ RFC/21](http://rfc.zeromq.org/spec:21)) compliant header and source skeletons for new classes.\n* generate a public header file for your library so it can be easily included by others.\n* generate stubs for man page documentation which uses the comment based approach from CZMQ.\n\nAll you need is a project.xml file in the project's root directory which is your\n\n    One file to rule them all\n\nAt least the following build environments are currently supported:\n\n* Autotools\n* CMake\n* Mingw32\n* Android\n* iOS\n* Visual Studio\n\nThanks to the ZeroMQ community, you can do all the heavy lifting in C and then easily generate bindings in the following languages:\n\n* Delphi\n* Java (JNI)\n* Python\n* QML\n* Qt\n* Ruby\n\nThe language bindings are minimal, meant to be wrapped in a handwritten idiomatic layer later.\n\n## Tutorial\n\nTo understand step by step what zproject can do for you, read chapter 3 of\n[@hintjens](https://github.com/hintjens) book [Scalable C](https://booksbyus.gitbooks.io/scalable-c/content/chapter3.html). Note that\nthe book is still work in progress!\n\n## Installation\n\nzproject uses the universal code generator called GSL to process its XML inputs\nand create its outputs. Before you start you'll need to install GSL\n(https://github.com/zeromq/gsl) on your system.\n\n```sh\ngit clone https://github.com/zeromq/gsl.git\ncd gsl/src\nmake\nmake install\n```\n\nGSL must be able to find the zproject resources on your system. Therefore you'll\nneed to install them. The following will install the zproject files to\n`/usr/local/bin`.\n\n```sh\ngit clone https://github.com/zeromq/zproject.git\ncd zproject\n./autogen.sh\n./configure\nmake\nmake install\n```\n\nNB: You may need to use the `sudo` command when running `make install` to elevate your privileges, e.g.\n\n```sh\nsudo make install\n```\n\nNB: If you don't have superuser rights on a system you'll have to make sure zproject's gsl scripts can be found on your PATH.\n\n## Getting started\n\n### Setup your project environment\n\nThe easiest way to start is to create a minimal project.xml.\n\n```xml\n\u003cproject script = \"zproject.gsl\"\u003e\n    \u003cuse project = \"czmq\" /\u003e\n    \u003cmain name = \"hello\" private = \"1\" /\u003e\n\u003c/project\u003e\n```\n\nOnce you're done you can create your project's build environment and start compiling:\n\n```sh\ngsl project.xml\nautogen.sh\nconfigure.sh\nmake\n```\n\nNB: To get a more comprehensive example copy zproject's project.xml. It contains all possible configurations and according documentation.\n\nLicensing your project is important thus you'll need a license file. Here's an overview that might help you decide to [choose a license](http://choosealicense.com/). zproject allows you to add an appropriate disclaimer of your license as a xml file, e.g. license.xml:\n\n```xml\n\u003clicense\u003e\n    Your license disclaimer goes here!\n\u003c/license\u003e\n```\n\nThis disclaimer can be included in your project.xml and is used whenever zproject is generating new files e.g. CLASS skeletons or bindings.\n\n```xml\n\u003cinclude filename = \"license.xml\" /\u003e\n```\n\n### Configuration\n\nzproject's `project.xml` contains an extensive description of the available configuration: The following snippet is taken from the `project.xml`:\n\n```xml\n\u003c!--\n    The project.xml generates build environments for:\n\n        autotools           GNU build system (default)\n        cmake               CMake build system (default)\n\n        android             Native shared library for Android\n        cucumber            Integration with cucumber-c\n        cygwin              Cygwin build system\n        debian              packaging for Debian\n        delphi              Delphi binding\n        docker              packaging for Docker\n        ios                 Native library for iOS\n        java                Java JNI binding\n        java-msvc           MSVC builds for Java JNI binding\n        jenkins             Jenkins pipeline build\n        mingw32             Mingw32 build system\n        nuget               Packaging for NuGet\n        python              Python binding\n        qml                 QML binding\n        qt                  Qt binding\n        redhat              Packaging for RedHat\n        ruby                Ruby binding\n        gh_actions          Github Actions configuration (same options as travis)\n        travis              Travis CI scripts\n            \u003coption name=\"dist\" value=\"trusty\" /\u003e Select a Linux distribution to use by default on Travis CI, also impacts the OBS-served repository of ZMQ-family packages to use (if not building from source all the time per use_pkg_deps_prereqs_source below). By default it would be \"xenial\" as of now.\n            \u003coption name=\"distcheck\" value=\"0\" /\u003e \"0\" will disable run of make distcheck in Travis CI, \"2\" will enable it as a special testcase allowed to fail (default: 1 to enable and require to pass)\n            \u003coption name=\"use_pkg_deps_prereqs_source\" value=\"0\" /\u003e \"0\" will disable use of use_pkg_deps_prereqs_source list in Travis CI and so cause rebuild of everything from scratch (default: 1, recently packaged prereqs must exist then)\n            \u003coption name=\"use_cmake\" value=\"0\" /\u003e \"0\" will disable use of CMake recipes in Travis CI (default: 1)\n            \u003coption name=\"require_gitignore\" value=\"1\" /\u003e \"1\" will require that the workspace is clean with regard to .gitignore settings after build (default: 0)\n            \u003coption name=\"clangformat_allow_failures\" value=\"0\" /\u003e \"1\" will generate the option allowing non-fatal failure of clang-format test in Travis CI (default: 1)\n            \u003coption name=\"clangformat_require_good\" value=\"0\" /\u003e \"1\" will generate the option allowing to report and not ignore failure of clang-format test in Travis CI (otherwise \"0\" hides the failure, and devs must look in test logs) (default: same as allow_failures)\n            \u003coption name=\"clangformat_implem\" value=\"cmake|autotools\" /\u003e will pick one of two implems of the clang-format test in Travis CI (cmake is default and faster if available, since autotools needs to configure first)\n            \u003coption name=\"check_abi_compliance\" value=\"0\" /\u003e \"1\" will compare the currently tested commit's ABI to the one in a \"latest_release\" branch or tag, using packaged prerequisites. Due to these limitations, the option is off by default.\n            \u003coption name=\"check_zproject\" value=\"0\" /\u003e \"1\" will regenerate the zproject of the tested commit, and will verify that nothing changed, \"2\" will enable it as a special testcase allowed to fail. Many projects do customize their originally generated codebase, so to avoid surprises this option is off by default.\n            \u003coption name=\"shadow_gcc\" value=\"0\" /\u003e \"1\" will enable builds with warnings configured as fatal in additional recent versions of GCC, and \"2\" will make failures in these cases non-fatal so you can take time to modernize your code with modern best practices in mind. This is off \"0\" by default.\n            \u003coption name=\"shadow_clang\" value=\"0\" /\u003e \"1\" will enable builds with warnings configured as fatal in additional recent versions of CLANG, and \"2\" will make failures in these cases non-fatal so you can take time to modernize your code with modern best practices in mind. This is off \"0\" by default.\n        vs2008              Microsoft Visual Studio 2008\n        vs2010              Microsoft Visual Studio 2010\n        vs2012              Microsoft Visual Studio 2012\n        vs2013              Microsoft Visual Studio 2013\n        vs2015              Microsoft Visual Studio 2015\n\n    Classes are automatically added to all build environments. Further as you\n    add new classes to your project you can generate skeleton header and source\n    files according to http://rfc.zeromq.org/spec:21.\n\n    script := The gsl script to generate all the stuff !!! DO NOT CHANGE !!!\n    name := The name of your project (optional)\n    description := A short description for your project (optional)\n    email := The email address where to reach you (optional)\n    url := The website or similar resource about the project or its ecosystem (optional)\n    repository := git repository holding project (optional)\n    unique_class_name := \"0\"|\"1\" (optional, defaults to 0) As a failsafe, forbid naming agents or classes same as the project itself (can cause conflicts in generated header filenames). Disable explicitly (set to 0) only in legacy projects that can not regenerate otherwise, and try to fix those.\n    license := optional common tag of the project's license (\"MPLv2\", \"GPL-2.0+\", \"CompanyName Proprietary\" etc.); see also license.xml for longer wording\n    check_license_years := \"0\"|\"1\"|\"2\" (optional, defaults to 0) When a project is regenerated, and if any license text(s) are defined, we check that at least one Copyright line in at least one license text contains the current year, and warn if not. If this option is set to \"1\", we also pause so that interactive developers can see this warning better and intervene. With \"2\" require that the year is mentioned, abort GSL with year if it is not.\n--\u003e\n\u003cproject script = \"zproject.gsl\" name = \"zproject\"\n    email = \"zeromq-dev@lists.zeromq.org\"\n    license = \"MPL-2.0\"\n    check_license_years = \"0\"\n    url = \"https://github.com/zeromq/zproject\"\n    repository = \"https://github.com/zeromq/zproject\"\u003e\n\n    \u003c!--\n        Includes are processed first, so XML in included files will be\n        part of the XML tree. This file can provide content of such tags\n        as \u003clicense\u003e (detailed text to put in generated file headers)\n        and \u003cstarting_year\u003e (a number to put in packaging copyright\n        summaries). Note that a verbatim \"license.xml\" file would be\n        created if it is currently missing but the tag is present, and\n        then it would be seeded with a current starting_year and some\n        boilerplate reminder to specify a real license and copyright.\n    --\u003e\n    \u003cinclude filename = \"license.xml\" /\u003e\n\n    \u003c!--\n        Current version of your project.\n        This will be used to package your distribution\n    --\u003e\n    \u003cversion major = \"1\" minor = \"1\" patch = \"0\" /\u003e\n\n    \u003c!--\n        Current libtool ABI version of your project's shared library.\n        Start at 0:0:0 and see:\n        http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html\n        for details on how/when to increment it.\n        If not defined 0:0:0 will be used.\n    \u003cabi current = \"0\" revision = \"0\" age = \"0\" /\u003e\n    --\u003e\n\n    \u003c!--\n        Check that the \u003csymbol\u003e is available after including a given \u003cheader\u003e\n        and store the result in a macro HAVE_DECL_SYMBOL. When the symbol is\n        declared, HAVE_DECL_SYMBOL is defined to '1' otherwise '0'. Use\n        HAVE_DECL_SYMBOL in #if:\n\n          #if HAVE_DECL_SYMBOL\n            // Do something with the symbol\n          #endif\n\n          #if !HAVE_DECL_SYMBOL\n            // Alternative action without the symbol\n          #endif\n    \u003ccheck_symbol_exists symbol = AI_V4MAPPED\"\" header = \"netdb.h\" /\u003e\n    --\u003e\n\n    \u003c!--\n        Specify which other projects this depends on.\n        These projects must be known by zproject, and the list of\n        known projects is maintained in the zproject_known_projects.xml model.\n        You need not specify sub-dependencies if they are implied.\n        Dependencies that support the autotools build system are automatically\n        built by travis ci if you supply a git repository or a tarball URI.\n        Set type to \"runtime\" to have the packages install-depend on it rather\n        than build-depend (default type is \"build\").\n        The travis ci will use the installed packages when building instead of\n        rebuilding if available.\n    \u003cuse project = \"zyre\" min_major= \"1\" min_minor = \"1\" min_patch = \"0\" /\u003e\n    \u003cuse project = \"czmq\"\n        min_major= \"3\" min_minor = \"0\" min_patch = \"2\"\n        next_incompatible_major = \"4\"\n        /\u003e\n    \u003cuse project = \"uuid\" optional= \"1\" implied = \"1\" /\u003e\n    \u003cuse project = \"myfirstlib\" repository = \"http://myfirstlib.org/myfirstlib.git\" /\u003e\n    \u003cuse project = \"mysecondlib\" tarball = \"http://mysecondlib.org/mysecondlib-1.2.3.tar.gz\" /\u003e\n    \u003cuse project = \"lua-5.1\" am_lib_macro = \"LUA_5_1\" tarball = \"...\" /\u003e\n    --\u003e\n\n    \u003cuse project = \"gsl\" type = \"runtime\" /\u003e\n\n    \u003c!-- Header Files\n         name := The name the header file to include without file ending\n    \u003cheader name = \"myproject_prelude\" /\u003e\n    --\u003e\n\n    \u003c!--\n        Classes, if the class header or source file doesn't exist, this will\n        generate a skeletons for them.\n        Use private = \"1\" for internal classes\n        Use selftest = \"0\" to not generate selftest code\n    \u003cclass name = \"myclass\"\u003ePublic class description\u003c/class\u003e\n    \u003cclass name = \"someother\" private = \"1\"\u003ePrivate class description\u003c/class\u003e\n    --\u003e\n\n    \u003c!--\n        Actors, are built using the simple actor framework from czmq. If the\n        actors class header or source file doesn't exist, this will generate a\n        skeleton for them. The generated test method of the actor will teach\n        you how to use them. Also have a look at the CZMQ docs to learn more\n        about actors.\n        Use selftest = \"0\" to not generate selftest code\n    \u003cactor name = \"myactor\"\u003ePublic actor description\u003c/actor\u003e\n    \u003cactor name = \"someactor\" private = \"1\"\u003ePrivate actor description\u003c/actor\u003e\n    --\u003e\n\n    \u003c!--\n        Main programs built by the project\n                 use private = \"1\" for internal tools\n    \u003cmain name = \"progname\"\u003eExported public tool\u003c/main\u003e\n    \u003cmain name = \"progname\" private = \"1\"\u003eInternal tool\u003c/main\u003e\n    \u003cmain name = \"progname\" service = \"1\"\u003eInstalled as system service, single-instance\u003c/main\u003e\n    \u003cmain name = \"progname\" service = \"2\"\u003eInstalled as system service, multi-instance (@)\u003c/main\u003e\n    \u003cmain name = \"progname\" service = \"3\"\u003eInstalled as system service, both single and multi-instance (@)\u003c/main\u003e\n    \u003cmain name = \"progname\" timer = \"3\"\u003eInstalled as system timer unit, both single and multi-instance (@)\u003c/main\u003e\n    \u003cmain name = \"progname\" service = \"1\" timer = \"1\"\u003eInstalled with both system timer and service units, single-instance - probably the former triggers the latter occasionally\u003c/main\u003e\n        Note that \u003cbin\u003e tags for secondary distributed programs (or scripts)\n        now also support the service and timer attributes with same semantics.\n    --\u003e\n\n    \u003c!--\n        Benchmark programs built by the project\n    \u003cbench name = \"benchname\"\u003eBenchmark for class/function...\u003c/main\u003e\n    --\u003e\n\n    \u003c!--\n        Models that we build using GSL.\n        This will generate a 'make code' target to build the models.\n    \u003cmodel name = \"sockopts\" /\u003e\n    \u003cmodel name = \"zgossip\" /\u003e\n    \u003cmodel name = \"zgossip_msg\" /\u003e\n\n        If a model should be generated using a specific gsl script,\n        this can be set through the script attribute:\n    \u003cmodel name = \"hydra_msg\" script = \"zproto_codec_java.gsl\" /\u003e\n\n        Additional parameters to the script can be set via nested\n        param elements:\n    \u003cmodel name = \"hydra_msg\" script = \"zproto_codec_java.gsl\"\u003e\n        \u003cparam name = \"root_path\" value = \"../main\" /\u003e\n    \u003c/model\u003e\n    --\u003e\n\n    \u003c!-- Other source files that we need to package\n    \u003cextra name = \"some_resource\" /\u003e\n    --\u003e\n    \u003c!-- Specify targets to build; autotools and cmake are\n         built in all cases.\n    \u003ctarget name = \"cmake\" /\u003e\n    \u003ctarget name = \"autotools\" /\u003e\n    --\u003e\n    \u003c!-- Targets may be customizable with their own options --\u003e\n    \u003ctarget name = \"cmake\"\u003e\n        \u003coption name = \"single setting\" value = \"value\" /\u003e\n        \u003coption name = \"list setting\"\u003e\n            \u003citem name = \"item name\" value = \"item value\" /\u003e\n        \u003c/option\u003e\n    \u003c/target\u003e\n\n    \u003ctarget name = \"obs\" /\u003e\n    \u003ctarget name = \"debian\" /\u003e\n    \u003ctarget name = \"redhat\" /\u003e\n\n    \u003c!-- Cucumber target\n    \u003ctarget name = \"cucumber\"\u003e\n        For each step_defs a cucumber steps runner will be registered\n        in the build scripts and the project's cucumber_selftest is\n        generated appropriately. Points the the source file\n        $(step_defs.name)_step_defs.c\n        \u003cstep_defs name = \"brilliant_ideas\" /\u003e\n    \u003c/target\u003e\n    --\u003e\n\n    \u003c!-- Note: zproject itself uses a customized CI-testing routine\n         on Travis CI, not a generated one, so DO NOT ENABLE this one:\n        \u003ctarget name = \"travis\" /\u003e\n    --\u003e\n\n    \u003c!-- Jenkins target creates jenkins pipeline\n         Pipeline file is not overwritten if it exists.\n\n         Your projects can build under a docker container OR agents\n         matched by a label OR under an \"any\" agent by default.\n         If you specify a complex label expression, be sure to use\n         XML escaping of the ampersand character (\u0026amp;) if some of\n         your tooling expects project.xml to be valid XML (the GSL\n         parser accepts a verbatim ampersand character as well).\n\n         The agent_single option is a flag that enables parallel\n         builds of this component on several agents (specified by\n         label or docker) vs. a sequential build on a single agent.\n\n         Similarly, a check_sequential option can be defined so that\n         self-testing stages would run sequentially. This can be needed\n         at early stages of a project's evolution, where hard-coding is\n         prevalent so parallel runs in same operating environment cause\n         conflicts to each other. Ultimately a project should remove\n         this flag ;)\n\n         The build_* and test_* options influence the default setting\n         of corresponding build arguments for the project. You can\n         still run a custom Jenkins Build with Arguments with other\n         checkboxes clicked, e.g. while developing a missing feature.\n         If not explicitly set to 0, most of these options are assumed\n         \"true\", as normally a project should be capable of all these\n         aspects. Note however that a project with no classes marked\n         \"stable\" would by default not test non-DRAFT builds as the\n         configure.ac script would have no support for those anyway.\n\n         The require_gitignore option (enabled by default) also causes\n         the test to fail, rather than warn, if untracked or changed\n         files are found as a result of some build or test stage.\n\n         Also note, that after successful build and test steps, the\n         job generated by this Jenkinsfile can optionally trigger\n         some other job specific to your installation of a Jenkins\n         server, to handle the deployment of tested code (whichever\n         way you'd define that). For this optional feature, your\n         Jenkins master should define (and propagate to its agents)\n         the environment values DEFAULT_DEPLOY_BRANCH_PATTERN (regex)\n         and DEFAULT_DEPLOY_JOB_NAME (note to start with a slash for\n         absolute naming; jobs in a folder may use relative paths too).\n         That job should accept parameters DEPLOY_GIT_URL (URL of repo),\n         DEPLOY_GIT_BRANCH (name for decision-making), DEPLOY_GIT_COMMIT\n         (actual commit to check out and shrink-wrap into packaging.\n\n         The test_install check tries to \"make DESTDIR=... install\" where\n         the DESTDIR is test_install_DESTDIR value (must be an absolute\n         path), or BUILD_DIR/tmp/_inst if the option is unspecified/empty.\n\n         The test_cppcheck is different, as it calls the \"cppcheck\" tool\n         which may be not installed on a particular Jenkins deployment.\n         The `make cppcheck` recipe is safe to call in either case, so by\n         default this option is enabled if not set explicitly. Same idea\n         goes for build_docs as it requires asciidoc and xmlto toolkits,\n         except it is off by default to avoid churning CPUs with no tools.\n         A further dist_docs enables preparation of a \"dist\" tarball from\n         the workspace configured with docs, so you can forward it to the\n         publishing helper job and avoid rebuilding man pages for packaging.\n\n         Similarly, a test_check_clang_format requires an external tool,\n         the clang-format-5.0 (or newer) to process the codebase and decide\n         if it is stylish. By default the test is enabled but not required\n         to pass (is just informative) and will run if the tool is available\n         in the build system. Eventually, a project should define and uphold\n         its coding style -- then this test can become one of requirements\n         for new pull requests.\n\n         The triggers_pollSCM option sets up the pipeline-generated job\n         for regular polling of the original SCM repository, using the\n         Jenkins cron syntax. The default is approximately every 5 minutes\n         with a spread to minimize burst-loads vs quiet times. An explicit\n         empty string disables polling, so you'd only run the job manually.\n         Note that the most frequent working setting is \"H/2\", NOT a \"H/1\".\n\n         On the Jenkins setup used by generated projects, sometimes it was\n         re-scheduling the same commits over and over and even overlapping.\n         Usually this was linked to some lagginess of the build system or\n         its internet connection, but the result was a growing queue of\n         same (and redundant) builds. To remedy this, projects can set a\n         few experimental options now (and regenerate their Jenkinsfile):\n         * use_earlymilestone -- uses a milestone to cancel builds that\n            got to it later than the running one\n         * use_deploymilestone -- uses a milestone to cancel builds that\n            got to the 'deploy if appropriate' phase later than the\n            running one\n         * use_build_nonconcurrent -- sets a disableConcurrentBuilds option\n         * use_checkout_explicit -- sets a skipDefaultCheckout option and\n            defines a step to check out code explicitly; it is believed\n            this may better succeed in recording which commits are already\n            being processed by the server\n\n         The use_test_timeout option sets up the default timeout for test\n         steps (further configurable at run-time as a build argument).\n         Generally unit tests should not take pathologically long, so the\n         default of 30 minutes should commonly suffice even for distchecks.\n         If your selftests are known to take a lot of time, perhaps due to\n         using an occasionally overloaded Jenkins CI farm, set this option.\n\n         A use_test_retry option allows to retry each failing test step\n         for the specified amount of attempts; it is deemed good if the\n         test passes at least once. This option should not normally need\n         to be used -- only if selftests somehow depend on environmental\n         circumstances and fail occasionally but not always. Ultimately,\n         project developers should find and fix the issue in tests (or in\n         the production codebase) so it always works on the first try,\n         bulletproof.\n\n         As a workaround for some versions of Jenkins, if your project uses\n         \"weird\" (generally non-ASCII) filenames in the build directory,\n         their removal with Pipeline deleteDir() can fail even though it\n         should not. If this bites you, set use_deleteDir_rm_first=1 in\n         the project, so the OS native \"rm\" is tried first.\n\n         The two options do_cleanup_after_build (for parallelized tests)\n         and do_cleanup_after_job control whether the pipeline would by\n         default remove the build/test subdirectory after successful end\n         of stage, and/or cleans the build workspace after the whole job\n         succeeded, respectively. If not set, cleanup is enabled for both\n         and in either case the active options are among build parameters.\n         In opposite fashion, a do_cleanup_after_failed_build is disabled\n         by default to allow post-mortem inspection of errors on CI server.\n         You might want to keep the built sources to analyze the behavior\n         of your build recipes in a particular environment, thought at a\n         risk of using excessive disk space there. In case of failure the\n         workspace remains on disk to make an in-place analysis possible,\n         and would eat space until you clean it up manually or it would\n         expire according to your Jenkins old-build retention policies.\n\n    \u003ctarget name = \"jenkins\"\u003e\n        \u003coption name = \"file\" value = \"Jenkinsfile\" /\u003e\n        \u003coption name = \"agent_docker\" value = \"zeromqorg/czmq\" /\u003e\n        \u003coption name = \"agent_label\" value = \"linux || macosx || bsd || solaris || posix || windows\" /\u003e\n        \u003coption name = \"agent_single\" value = \"1\" /\u003e\n        \u003coption name = \"check_sequential\" value = \"1\" /\u003e\n        \u003coption name = \"triggers_pollSCM\" value = \"H/5 * * * *\" /\u003e\n        \u003coption name = \"build_without_draft_api\" value = \"0\" /\u003e\n        \u003coption name = \"build_with_draft_api\" value = \"0\" /\u003e\n        \u003coption name = \"build_docs\" value = \"1\" /\u003e\n        \u003coption name = \"dist_docs\" value = \"1\" /\u003e\n        \u003coption name = \"require_gitignore\" value = \"0\" /\u003e\n        \u003coption name = \"use_deleteDir_rm_first\" value = \"1\" /\u003e\n        \u003coption name = \"use_test_timeout\" value = \"60\" /\u003e\n        \u003coption name = \"use_test_retry\" value = \"3\" /\u003e\n        \u003coption name = \"test_check\" value = \"0\" /\u003e\n        \u003coption name = \"test_memcheck\" value = \"0\" /\u003e\n        \u003coption name = \"test_distcheck\" value = \"0\" /\u003e\n        \u003coption name = \"test_install\" value = \"0\" /\u003e\n        \u003coption name = \"test_install_DESTDIR\" value = \"/tmp/proto-area\" /\u003e\n        \u003coption name = \"test_cppcheck\" value = \"1\" /\u003e\n        \u003coption name = \"test_check_clang_format\" value = \"1\" /\u003e\n        \u003coption name = \"use_clang_format_prog\" value = \"clang-format-5.0\" /\u003e\n        \u003coption name = \"require_good_clang_format\" value = \"0\" /\u003e\n    \u003c/target\u003e\n    --\u003e\n    \u003ctarget name = \"jenkins\" \u003e\n        \u003coption name = \"agent_label\" value = \"linux || macosx || bsd || solaris || posix || windows\" /\u003e\n        \u003coption name = \"agent_single\" value = \"1\" /\u003e\n        \u003c!-- Note: for zproject itself, all the *check jobs are\n             essentially a loopback to distcheck itself --\u003e\n        \u003coption name = \"test_check\" value = \"1\" /\u003e\n        \u003coption name = \"test_memcheck\" value = \"0\" /\u003e\n        \u003coption name = \"test_distcheck\" value = \"0\" /\u003e\n        \u003coption name = \"test_cppcheck\" value = \"0\" /\u003e\n    \u003c/target\u003e\n\n    \u003c!-- In order loaded by zproject.gsl --\u003e\n    \u003cbin name = \"zproject.gsl\" /\u003e\n    \u003cbin name = \"zproject_projects.gsl\" /\u003e\n    \u003cbin name = \"zproject_class_api.gsl\" /\u003e\n\n    \u003c!-- Mainline generation code --\u003e\n    \u003cbin name = \"zproject_skeletons.gsl\" /\u003e\n    \u003cbin name = \"zproject_bench.gsl\" /\u003e\n    \u003cbin name = \"zproject_class.gsl\" /\u003e\n    \u003cbin name = \"zproject_git.gsl\" /\u003e\n    \u003cbin name = \"zproject_valgrind.gsl\" /\u003e\n\n    \u003c!-- Targets --\u003e\n    \u003cbin name = \"zproject_android.gsl\" /\u003e\n    \u003cbin name = \"zproject_autotools.gsl\" /\u003e\n    \u003cbin name = \"zproject_cmake.gsl\" /\u003e\n    \u003cbin name = \"zproject_cucumber.gsl\" /\u003e\n    \u003cbin name = \"zproject_cygwin.gsl\" /\u003e\n    \u003cbin name = \"zproject_debian.gsl\" /\u003e\n    \u003cbin name = \"zproject_delphi.gsl\" /\u003e\n    \u003cbin name = \"zproject_docker.gsl\" /\u003e\n    \u003cbin name = \"zproject_gh_actions.gsl\" /\u003e\n    \u003cbin name = \"zproject_gyp.gsl\" /\u003e\n    \u003cbin name = \"zproject_ios.gsl\" /\u003e\n    \u003cbin name = \"zproject_java.gsl\" /\u003e\n    \u003cbin name = \"zproject_java_lib.gsl\" /\u003e\n    \u003cbin name = \"zproject_java_msvc.gsl\" /\u003e\n    \u003cbin name = \"zproject_jenkins.gsl\" /\u003e\n    \u003cbin name = \"zproject_lua_ffi.gsl\" /\u003e\n    \u003cbin name = \"zproject_mingw32.gsl\" /\u003e\n    \u003cbin name = \"zproject_nodejs.gsl\" /\u003e\n    \u003cbin name = \"zproject_nuget.gsl\" /\u003e\n    \u003cbin name = \"zproject_obs.gsl\" /\u003e\n    \u003cbin name = \"zproject_python.gsl\" /\u003e\n    \u003cbin name = \"zproject_python_cffi.gsl\" /\u003e\n    \u003cbin name = \"zproject_qml.gsl\" /\u003e\n    \u003cbin name = \"zproject_qt.gsl\" /\u003e\n    \u003cbin name = \"zproject_redhat.gsl\" /\u003e\n    \u003cbin name = \"zproject_rpi.gsl\" /\u003e\n    \u003cbin name = \"zproject_ruby.gsl\" /\u003e\n    \u003cbin name = \"zproject_systemd.gsl\" /\u003e\n    \u003cbin name = \"zproject_travis.gsl\" /\u003e\n    \u003cbin name = \"zproject_vagrant.gsl\" /\u003e\n    \u003cbin name = \"zproject_vs2008.gsl\" /\u003e\n    \u003cbin name = \"zproject_vs20xx.gsl\" /\u003e\n    \u003cbin name = \"zproject_vs20xx_props.gsl\" /\u003e\n\n    \u003cbin name = \"zproject_known_projects.xml\" /\u003e\n\u003c/project\u003e\n```\n\n### Project dependencies\n\nzproject's `use` element defines project dependencies.\nModel is described in `zproject_known_projects.xml` file:\n\n```xml\n\u003cknown_projects\u003e\n\n    \u003c!-- ZeroMQ Projects --\u003e\n    \u003c!--\n        Problem: naming style is inconsistent\n        we sometimes use libxxx and sometimes xxx; the git repo name\n        is unpredictable; sometimes we override with the prefix and\n        sometimes with libname.\n\n        Proposed solution: project name should always be git repo\n        name; prefix and libname should always be specified. For\n        compatibility, we can define aliases. E.g.:\n\n        Also, 'cmake name' is target specific and must go.\n\n        Suggested model:\n        \u003cuse\n            project = \"libzmq\"          required\n            master = \"https://github.com/zeromq\"\n                                        required\n            libname = \"libzmq\"          default = lib\u003cprefix\u003e\n            prefix = \"zmq\"              default = project\n            test = \"zmq_init\"           required same as AC_CHECK_LIB in autoconf\n            release = \"\u003ctagname\u003e\"       default = \"master\"\n            abi = \"version\"             default = \"0:0:0\"\n            header = \"\u003cfilename\u003e\"       default = \u003cprefix\u003e.h\n            language = \"C|C++\"          default = \"C\"\n            optional = \"1\"              default = \"0\"\n            debian_name = \"libzmq5-dev\" default = lib\u003cname\u003e-dev\n            redhat_name = \"zeromq-devel\" default = \u003cname\u003e-devel\n                \u003cadd_config_opts\u003e--with-dep1=nuance\u003c/add_config_opts\u003e\n                \u003cadd_config_opts\u003e--enable-feature2\u003c/add_config_opts\u003e\n        \u003c/use\u003e\n    --\u003e\n\n    \u003cuse project = \"libzmq\" prefix = \"zmq\" debian_name = \"libzmq3-dev\" redhat_name = \"zeromq-devel\" brew_name = \"zeromq\"\n        repository = \"https://github.com/zeromq/libzmq.git\"\n        test = \"zmq_init\" /\u003e\n\n    \u003c!-- Note: if your project requires an older CZMQ (e.g. if you need\n        `release = \"v3.0.2\"`), you may need to `test = \"zctx_test\"`.\n        Also note that you can instead require particular package\n        version (as reported by pkg-config records). --\u003e\n    \u003cuse project = \"czmq\" libname = \"libczmq\"\n        repository = \"https://github.com/zeromq/czmq.git\"\n        test = \"zhashx_test\"\u003e\n        \u003cuse project = \"libzmq\" /\u003e\n    \u003c/use\u003e\n\n    \u003cuse project = \"zyre\" libname = \"libzyre\"\n        repository = \"https://github.com/zeromq/zyre.git\"\n        test = \"zyre_test\"\u003e\n        \u003cuse project = \"czmq\" /\u003e\n    \u003c/use\u003e\n\n    \u003cuse project = \"malamute\" libname = \"libmlm\"\n        repository = \"https://github.com/zeromq/malamute.git\"\n        header = \"malamute.h\"\n        prefix = \"mlm\"\n        test = \"mlm_server_test\"\u003e\n        \u003cuse project = \"libzmq\" /\u003e\n        \u003cuse project = \"czmq\" /\u003e\n    \u003c/use\u003e\n\n    \u003cuse project = \"gsl\" libname = \"\"\n        repository = \"https://github.com/zeromq/gsl.git\"\n        debian_name = \"generator-scripting-language\"\n        redhat_name = \"generator-scripting-language\"\u003e\n    \u003c/use\u003e\n\n    \u003c!-- Edgenet Projects --\u003e\n\n    \u003cuse project = \"drops\" libname = \"libdrops\"\n        repository = \"https://github.com/edgenet/drops.git\"\n        test = \"drops_test\"\u003e\n        \u003cuse project = \"czmq\" /\u003e\n        \u003cuse project = \"zyre\" /\u003e\n    \u003c/use\u003e\n\n    \u003cuse project = \"hydra\" libname = \"libhydra\"\n        repository = \"https://github.com/edgenet/hydra.git\"\n        test = \"hydra_server_test\"\u003e\n        \u003cuse project = \"czmq\" /\u003e\n    \u003c/use\u003e\n\n    \u003c!-- Various known third-party projects\n        (If you're unsure of where a project belongs, add it here) --\u003e\n\n    \u003cuse project = \"cucumber\"\n         header = \"cucumber_c.h\"\n         test = \"cucumber_new\"\n         repository = \"https://github.com/sappo/cucumber-c\"\u003e\n        \u003cuse project = \"gherkin\" private = \"1\" /\u003e\n        \u003cuse project = \"cJSON\" private = \"1\" /\u003e\n    \u003c/use\u003e\n\n    \u003cuse project = \"gherkin\"\n         header = \"compiler.h\"\n         repository = \"https://github.com/cucumber/gherkin-c\"\n         test = \"Compiler_new\" /\u003e\n\n    \u003cuse project = \"cJSON\"\n         debian_name = \"libcjson-dev\"\n         header = \"cjson/cJSON.h\"\n         repository = \"https://github.com/DaveGamble/cJSON\"\n         test = \"cJSON_Parse\" /\u003e\n\n    \u003cuse project = \"libsodium\" prefix = \"sodium\"\n        repository = \"https://github.com/jedisct1/libsodium.git\"\n        release = \"stable\"\n        test = \"sodium_init\" /\u003e\n\n    \u003cuse project = \"libcurl\"\n        prefix = \"curl\"\n        repository = \"https://github.com/curl/curl.git\"\n        debian_name = \"libcurl4-nss-dev\"\n        brew_name = \"curl\"\n        test = \"curl_easy_init\"\n        header = \"curl/curl.h\" /\u003e\n\n    \u003cuse project = \"libmicrohttpd\"\n         brew_name = \"libmicrohttpd\"\n         prefix = \"microhttpd\"\n         repository = \"https://git.gnunet.org/libmicrohttpd.git\"\n         tarball = \"http://ftp.gnu.org/gnu/libmicrohttpd/libmicrohttpd-0.9.44.tar.gz\"\n         test = \"MHD_start_daemon\" /\u003e\n\n    \u003cuse project = \"editline\"\n        repository = \"https://github.com/troglobit/editline.git\"\n        test = \"readline\" /\u003e\n\n    \u003cuse project = \"fuse\"\n        repository = \"http://git.code.sf.net/p/fuse/fuse.git\"\n        test = \"fuse_main\" /\u003e\n\n    \u003cuse project = \"jansson\"\n        repository = \"https://github.com/akheron/jansson.git\"\n        test = \"json_object\" /\u003e\n\n    \u003cuse project = \"jemalloc\"\n        repository = \"https://github.com/jemalloc/jemalloc.git\"\n        test = \"malloc\"\n        header = \"jemalloc/jemalloc.h\" /\u003e\n\n    \u003cuse project = \"msgpack\"\n        repository = \"https://github.com/msgpack/msgpack-c.git\"\n        test = \"msgpack_version\" /\u003e\n\n    \u003cuse project = \"uuid\"\n        test = \"uuid_generate\"\n        header = \"uuid/uuid.h\"\n        brew_name = \"ossp-uuid\"\n        redhat_name = \"libuuid-devel\"\n        debian_name = \"uuid-dev\" /\u003e\n\n    \u003cuse project = \"asound\"\n        test = \"snd_asoundlib_version\"\n        header = \"alsa/asoundlib.h\" /\u003e\n\n    \u003cuse project = \"zdb\"\n        repository = \"https://bitbucket.org/tildeslash/libzdb.git\"\n        test = \"ConnectionPool_start\" /\u003e\n\n    \u003cuse project = \"json-c\"\n        header = \"json-c/json.h\"\n        test = \"json_object_to_json_string\" /\u003e\n\n    \u003cuse project = \"libfastjson\"\n        repository = \"https://github.com/rsyslog/libfastjson/\"\n        header = \"libfastjson/json.h\"\n        test = \"json_object_to_json_string\" /\u003e\n\n    \u003cuse project = \"lognorm\"\n        repository = \"https://github.com/rsyslog/liblognorm/\"\n        test = \"ln_initCtx\"\u003e\n        \u003cuse project = \"libfastjson\" /\u003e\n    \u003c/use\u003e\n\n    \u003cuse project = \"zdiscgo\"\n        repository = \"https://github.com/zeromq/zdiscgo.git\"\n        test = \"zdiscgoplugin_new\" /\u003e\n\n    \u003cuse project = \"systemd\"\n        libname = \"libsystemd\"\n        prefix = \"libsystemd\"\n        linkname = \"systemd\"\n        header = \"systemd/sd-daemon.h\"\n        test = \"sd_listen_fds\" /\u003e\n\n    \u003cuse project = \"protobuf-c\"\n         repository = \"https://github.com/protobuf-c/protobuf-c/\"\n         test = \"protobuf_c_version\"\n         header = \"protobuf-c/protobuf-c.h\"/\u003e\n\n    \u003c!-- 42ITY project https://github.com/42ity https://42ity.org --\u003e\n    \u003cuse project = \"fty-proto\" libname = \"libfty_proto\" header=\"ftyproto.h\"\n        repository = \"https://github.com/42ity/fty-proto\"\n        test = \"fty_proto_test\"\u003e\n        \u003cuse project = \"libzmq\"/\u003e\n        \u003cuse project = \"czmq\"/\u003e\n        \u003cuse project = \"malamute\"/\u003e\n    \u003c/use\u003e\n\n    \u003c!-- OS packagers make life hard by renaming the package, binaries and\n         even library SONAMEs - so we have to guess a bit; note that for\n         practical purposes, lua-5.2 suffices as lua-5.1 (if fixes happen\n         to be needed, they are trivial and googlable) --\u003e\n    \u003cuse project = \"lua-5.1\" libname = \"lua\" prefix=\"lua\"\n        optional = \"0\" am_lib_macro = \"LUA_5_1\"\n        min_major = \"5\" min_minor = \"1\" min_patch = \"0\"\n        debian_name=\"liblua5.1-0-dev\" redhat_name=\"lua-devel\"\n        test = \"lua_close\"\u003e\n            \u003clinkname\u003elua5.2\u003c/linkname\u003e\n            \u003clinkname\u003elua52\u003c/linkname\u003e\n            \u003clinkname\u003elua5.1\u003c/linkname\u003e\n            \u003clinkname\u003elua51\u003c/linkname\u003e\n            \u003clinkname\u003elua\u003c/linkname\u003e\n            \u003cpkgconfig\u003elua5.2\u003c/pkgconfig\u003e\n            \u003cpkgconfig\u003elua52\u003c/pkgconfig\u003e\n            \u003cpkgconfig\u003elua5.1\u003c/pkgconfig\u003e\n            \u003cpkgconfig\u003elua51\u003c/pkgconfig\u003e\n            \u003cpkgconfig\u003elua\u003c/pkgconfig\u003e\n    \u003c/use\u003e\n\n    \u003cuse project = \"lz4\"\n        libname = \"liblz4\"\n        redhat_name = \"liblz4-devel\"\n        header = \"lz4.h\"\n        test = \"LZ4_decompress_safe\" /\u003e\n\n    \u003cuse project = \"nss\"\n        debian_name = \"libnss3-dev\"\n        redhat_name = \"nss-devel\"\n        header = \"sechash.h\"\n        test = \"HASH_Create\" /\u003e\n\n\u003c/known_projects\u003e\n```\n\n### Optional : Class filename configuration\n\nExample:\n```classfilename\n\u003cclassfilename use-cxx = \"true\" use-cxx-gcc-4-9 = \"true\" pkgincludedir = \"false\" keep-tree = \"true\" pretty-print = \"no\" source-extension = \"cpp\" header-extension = \"hpp\" /\u003e\n```\n\n* use-cxx will force usage (or not) of c++.\n* use-cxx-gcc-4-9 will enable \"use-cxx\" AND enforce the use of gcc-4.9 on Travis CI for nearly complete C++11 language support that is lacking in default gcc-4.8 there.\n* keep-tree will keep the include tree structure on the install (as opposed to flat delivery of include files basenames into the single-level target directory), must be used with a conservative name format (ex: pretty-print = \"no\"). Currently only supported with autotool.\n* pkgincludedir option chooses whether headers of this project should be dumped into the common system includedir (legacy default), or into an includedir/projname subdirectory?. Currently only supported with autotool.\n* pretty-print define the type of class name format change in order to generate the filename. It uses the pretty-print option of gsl (see Substituting Symbols and Expressions on https://github.com/zeromq/gsl#expressions for more information).\n* source-extension define the filename extension for source files in this project.\n* header-extension define the filename extension for header files in this project.\n\nDefault value :\n* pretty-print : substitute_non_alpha_to_make_c_identifier (c option)\n* header-extension : h\n* source-extension : c (unless a cc file is present, then cc)\n* use-cxx : true if a cc file is present, false otherwise\n* use-cxx-gcc-4-9 : false by default, older GCC versions still suffice for many C++11 features\n\n### Targets\n\nEach target produces scripts and code for a specific build system, platform, or language binding.\n\nTo see a list of available targets:\n\n    gsl -target:? project.xml\n\nTo build a specific target:\n\n    gsl -target:android project.xml\n\nTo run zproject without building any targets:\n\n    gsl -target:- project.xml\n\nTo request specific targets in your project.xml file (autotools and cmake are automatic):\n\n    \u003ctarget name = \"android\" /\u003e\n    \u003ctarget name = \"java\" /\u003e\n\nTo request all targets in your project.xml file:\n\n    \u003ctarget name = \"*\" /\u003e\n\n#### Target Options\n\nA target can accept options via project.xml like this:\n\n```\n\u003cproject\n    name = \"...\"\n    \u003e\n    ...\n    \u003ctarget name = \"*\" /\u003e\n    \u003ctarget name = \"nuget\"\u003e\n        \u003coption name = \"id\" value = \"czmq_vc120\" /\u003e\n        \u003coption name = \"dependency\"\u003e\n            \u003citem name = \"libzmq_vc120\" value = \"4.2.0.0\" /\u003e\n        \u003c/option\u003e\n    \u003c/target\u003e\n\u003c/project\u003e\n```\n\nThis generates all targets (`name = \"*\"`) and then configures the `nuget` target with options. Zproject aare provided to the target handler as:\n\n```\nproject.nuget_id = \"czmq_vc120\"\nproject.nuget_dependency.name = \"libzmq_vc120\"\nproject.nuget_dependency.value = \"4.2.0.0\"\n```\n\n##### Android target options\n\nThe target `android` accepts the following options:\n\n```\n\u003ctarget name = \"android\" \u003e\n    \u003coption name = \"ndk_version\" value = \"nnn\" /\u003e\n    \u003coption name = \"min_sdk_version\" value = \"sss\" /\u003e\n\u003c/target\u003e\n```\n\nGenerated files will have their default values like:\n\n```\nproject.android_ndk_version = \"nnn\"\nproject.android_min_sdk_version = \"sss\"\n```\n\nNote: these 2 default values can be overridden via the `export` mechanism\nas explained in generated `builds/android/README.md` and\n`bindings/jni/README.md`.\n\nIf these options are not provided, default hard-coded values are applied\nfrom `zproject_android.gsl` code.\n\n#### Target Scopes\n\nEach target works in its own copy of 'project'. It can therefore modify and extend 'project' as wanted, without affecting other targets.\n\n### Modifying generated files in an already existent project\n\nYou may encounter a warning in a file you want to modify like this:\n```\n ################################################################################\n #  THIS FILE IS 100% GENERATED BY ZPROJECT; DO NOT EDIT EXCEPT EXPERIMENTALLY  #\n #  Read the zproject/README.md for information about making permanent changes. #\n ################################################################################\n```\n\nIf that happens, you need to follow these steps to make the modifications and then regenerate the code for czmq, malamute and zyre (all zeromq projects).\n\n1. Prior making any changes, run the script tstgenbld.sh and save its output to a log file. This  will save the state of the world by regenerating several projects, building and running tests.\n```sh\n~/git/zproject$ ./tstgenbld.sh \u003e ../before.log\n```\n2. Search for a specific string from the file in the zproject files (use *.*)\n3. When you find it, make the modification in that file (most likely extensions will be .XML or .GSL)\n4. Then execute these steps in a Linux machine to regenerate all files for your project. This will build, install and run tests on them again, after your changes have been made.\n```sh\n~/git/zproject$ ./tstgenbld.sh \u003e ../after.log\n~/git/zproject$ meld ../after.log ../before.log\n```\n4. Be aware that many files in the regenerated projects will change.\n5. This also means you will need to commit changes on zproject (your mods) and in czmq, malamute, zyre (the regenerated files with your mods). From git documentation, it seems like the command \"git add -uv\" could help to find out what files were actually modified from all the files that were regenerated. Supposedly this will only add the ones that were actually modified, but you should double check them. Make sure to double check even line termination (or use a comparisson tool that flags those differences). Windows specific files should have (CR+LF) termination, while Linux specific should have (LF) only termination. Best is to look for \".terminator=\" examples in existing .GSL files.\n\n## API models\n\nUsing an API model zproject can generate the `@interface` section your class\nheaders. Further it allows zproject to generate various language bindings on top\nof your CLASS project.\n\n### Sample API model\n\nAll API models are placed into the `api` directory which resides in the root\ndirectory of your project. For example, if your `project.xml` contains\n`\u003cclass name = \"myclass\"/\u003e`, you could create the following `api/myclass.api`\nfile:\n\n```xml\n\u003cclass name = \"myclass\"\u003e\n    \u003c!--\n        This model defines a public API for binding.\n\n        It shows a language binding developer what to expect from the API XML\n        files.\n    --\u003e\n    My Feature-Rich Class\n\n    \u003cinclude filename = \"license.xml\" /\u003e\n\n    \u003cconstant name = \"default port\" value = \"8080\"\u003eregistered with IANA\u003c/constant\u003e\n\n    \u003cconstant name = \"normal\" value = \"1\" /\u003e\n    \u003cconstant name = \"fast\"   value = \"2\" /\u003e\n    \u003cconstant name = \"safe\"   value = \"3\" /\u003e\n\n    \u003c!-- Constructor is optional; default one has no arguments --\u003e\n    \u003cconstructor\u003e\n        Create a new myclass with the given name.\n        \u003cargument name = \"name\" type = \"string\" /\u003e\n    \u003c/constructor\u003e\n\n    \u003c!-- Destructor is optional; default one follows standard style --\u003e\n    \u003cdestructor\u003e\n        Destructors implicitly get a new argument prepended, which:\n\n        * is called `self_p`\n        * is of this class' type\n        * is passed by reference\n        * is marked as the self pointer for the destructor (`destructor_self = \"1\"`)\n    \u003c/destructor\u003e\n\n    \u003c!-- This models an CZMQ actor. By default the actor method equals the\n         class name.\n    --\u003e\n    \u003cactor\u003e\n        To work with my_actor, use the CZMQ zactor API:\n\n        Create new my_actor instance.\n\n            zactor_t *actor = zactor_new (my_actor, NULL);\n\n        Destroy my_actor instance\n\n            zactor_destroy (\u0026amp;actor);\n\n        Enable verbose logging of commands and activity:\n\n            zstr_send (actor, \"VERBOSE\");\n    \u003c/actor\u003e\n\n    \u003c!-- This models a method with no return value --\u003e\n    \u003cmethod name = \"sleep\"\u003e\n        Put the myclass to sleep for the given number of milliseconds.\n        No messages will be processed by it during this time.\n        \u003cargument name = \"duration\" type = \"integer\" /\u003e\n    \u003c/method\u003e\n\n    \u003c!-- This models an accessor method --\u003e\n    \u003cmethod name = \"has feature\"\u003e\n        Return true if the myclass has the given feature.\n        \u003cargument name = \"feature\" type = \"string\" /\u003e\n        \u003creturn type = \"boolean\" /\u003e\n    \u003c/method\u003e\n\n    \u003cmethod name = \"send strings\"\u003e\n        This does something with a series of strings (until NULL). The strings\n        won't be touched.\n\n        Because the next method has the same name with a prepended \"v\", it's\n        recognized as this method's `va_list` sibling (in GSL:\n        `method.has_va_list_sibling = \"1\"`). This information might be used by\n        the various language bindings.\n        \u003cargument name = \"string\" type = \"string\" variadic = \"1\" /\u003e\n        \u003creturn type = \"boolean\" /\u003e\n    \u003c/method\u003e\n\n    \u003cmethod name = \"vsend strings\"\u003e\n        This does something with a series of strings (until NULL). The strings\n        won't be touched (they're declared immutable by default).\n        \u003cargument name = \"string\" type = \"string\" variadic = \"1\" /\u003e\n        \u003creturn type = \"boolean\" /\u003e\n    \u003c/method\u003e\n\n    \u003c!-- Callback typedefs can be declared like methods --\u003e\n    \u003ccallback_type name = \"handler_fn\"\u003e\n        \u003cargument name = \"self\" type = \"myclass\" /\u003e\n        \u003cargument name = \"action\" type = \"string\" /\u003e\n        \u003creturn type = \"boolean\" /\u003e\n    \u003c/callback_type\u003e\n\n    \u003c!-- Callback types can be used as method arguments --\u003e\n    \u003cmethod name = \"add handler\"\u003e\n        Store the given callback function for later\n        \u003cargument name = \"handler\" type = \"my_class_handler_fn\" callback = \"1\" /\u003e\n    \u003c/method\u003e\n\n    \u003c!-- If singleton = \"1\", no class struct pointer is required. --\u003e\n    \u003cmethod name = \"test\" singleton = \"1\"\u003e\n        Self test of this class\n        \u003cargument name = \"verbose\" type = \"boolean\" /\u003e\n    \u003c/method\u003e\n\n    \u003cmethod name = \"new thing\" singleton = \"1\" \u003e\n\tCreates a new myclass. The caller is responsible for destroying it when\n\tfinished with it.\n        \u003creturn type = \"myclass\" fresh = \"1\" /\u003e\n    \u003c/method\u003e\n\n    \u003cmethod name = \"free\" singleton = \"1\"\u003e\n        Frees a provided string, and nullify the parent pointer. Setting\n        `mutable = \"1\"` is not needed here, because transfering ownership from\n        the caller to the function using `by_reference = \"1\"` implies that it's\n        mutable.\n        \u003cargument name = \"string pointer\" type = \"string\" by_reference = \"1\" /\u003e\n    \u003c/method\u003e\n\n    \u003cmethod name = \"rotate\" singleton = \"1\"\u003e\n        Rotates the characters in `data` in-place. This means that all\n        characters are shifted to the left by one, removing the left-most\n        character and appending it to the end.\n        \u003cargument name = \"data\" type = \"string\" mutable = \"1\" /\u003e\n    \u003c/method\u003e\n\n    \u003c!-- These are the types we support\n         Not all of these are supported in all language bindings;\n         see each language binding's file for supported types in that\n         language, and add more types as needed where appropriate.\n\n         Also, see zproject_class_api.gsl to see how they're handled exactly.\n         --\u003e\n    \u003cmethod name = \"tutorial\"\u003e\n        \u003cargument name = \"void pointer\" type = \"anything\" /\u003e\n        \u003cargument name = \"standard int\" type = \"integer\" /\u003e\n        \u003cargument name = \"default float\" type = \"real\" /\u003e\n        \u003cargument name = \"standard float\" type = \"real\" size = \"4\" /\u003e\n        \u003cargument name = \"standard double\" type = \"real\" size = \"8\" /\u003e\n        \u003cargument name = \"standard bool\" type = \"boolean\" /\u003e\n        \u003cargument name = \"fixed size unsigned integer\" type = \"number\" size = \"4\"\u003e\n            Supported sizes are 1, 2, 4, and 8.\n        \u003c/argument\u003e\n        \u003cargument name = \"a byte\" type = \"byte\" /\u003e\n        \u003cargument name = \"conversion mode\" type = \"integer\" /\u003e\n        \u003cargument name = \"char pointer to C string\" type = \"string\" /\u003e\n        \u003cargument name = \"byte pointer to buffer\" type = \"buffer\" /\u003e\n        \u003cargument name = \"buffer size\" type = \"size\" /\u003e\n        \u003cargument name = \"file handle\" type = \"FILE\" /\u003e\n        \u003cargument name = \"file size\" type = \"file_size\" /\u003e\n        \u003cargument name = \"time\" type = \"time\" /\u003e\n        \u003cargument name = \"format\" type = \"format\"\u003e\n            This makes the function is variadic (will cause a new argument to be\n            added to represent the variadic arguments).\n        \u003c/argument\u003e\n        \u003cargument name = \"variadic list argument\" type = \"va_list\" /\u003e\n        \u003cargument name = \"custom pointer\" type = \"my custom class\"\u003e\n            Any other type is valid, as long as there is a corresponding C\n            type, in this case `my_custom_class_t`.\n        \u003c/argument\u003e\n        \u003creturn type = \"nothing\"\u003evoid method\u003c/return\u003e\n    \u003c/method\u003e\n\n    \u003cmethod name = \"set foo\" polymorphic = \"1\"\u003e\n      Set attribute foo to a new value. Note that this method takes a\n      polymorphic reference (`void *`) as its first argument, which could point\n      to structs of different types.\n\n      This also means that high-level bindings might give you the choice to\n      call this method directly on an instance, or with an explicit receiver.\n      \u003cargument name = \"new value\" type=\"integer\" /\u003e\n    \u003c/method\u003e\n\n    \u003cmethod name = \"set bar\"\u003e\n        This method takes an argument type of the (descriptive) type `foo`, but\n        resolving it to a corresponding C type will be skipped because it's\n        overridden to `foobarbaz_t` by the `c_type` attribute.\n        \u003cargument name = \"new foo\" type=\"foo\" c_type=\"foobarbaz_t\" /\u003e\n    \u003c/method\u003e\n\u003c/class\u003e\n```\n\nThis model will cause the following `@interface` to be generated inside of\n`include/myclass.h`. Note that if `include/myclass.h` has other handwritten\ncontent outside the `@interface` section this content will be retained. If\nthe header file does not exist zproject will create it.\n\n```c\n//  @warning THE FOLLOWING @INTERFACE BLOCK IS AUTO-GENERATED BY ZPROJECT!\n//  @warning Please edit the model at \"api/myclass.api\" to make changes.\n//  @interface\n//  Create a new myclass with the given name.\nMYPROJECT_EXPORT myclass_t *\n    myclass_new (const char *name);\n\n//  Destroy the myclass.\nMYPROJECT_EXPORT void\n    myclass_destroy (myclass_t **self_p);\n\n//  Return true if the myclass has the given feature.\nMYPROJECT_EXPORT bool\n    myclass_has_feature (myclass_t *self, const char *feature);\n\n//  Put the myclass to sleep for the given number of milliseconds.\n//  No messages will be processed by the actor during this time.\nMYPROJECT_EXPORT void\n    myclass_sleep (myclass_t *self, int duration);\n\n//  Self test of this class\nMYPROJECT_EXPORT void\n    myclass_test (bool verbose);\n//  @end\n```\n\n### Supported API Model Attributes\n\nThe following attributes are supported for methods:\n\n- `name` - the name of the method (mandatory).\n- `singleton = \"1\"` - the method is not invoked within the context of a specific instance of an object. Use this if your method does not need to be passed a `self` pointer as the first argument as normal. Implicit for all `constructor`s and `destructor`s and for the implicit `test` method.\n\nThe following attributes are supported for arguments and return values:\n\n- `type` - the conceptual type or class name of the argument or return value (default: `\"nothing\"`, which translates to `void` in C).\n- `mutable = \"1\"` - the argument or the return value can be modified. All string, format, and buffer arguments are immutable by default.\n- `by_reference = \"1\"` - ownership of the argument (and responsibility for freeing it) is transferred from the caller to the function - in practice, the implementation code should also nullify the caller's reference, though this is not enforced by the API model. If a string or buffer is passed by reference, it is also mutable by default.\n- `fresh = \"1\"` - the return value is freshly allocated, and the caller receives ownership of the object and the responsibility for destroying it. Implies mutable = \"1\".\n- `variadic = \"1\"` - used for representing variadic arguments.\n\nFor integer arguments you can specify one or more 'map' values, which a binding target can use to generate alternative methods. For example:\n\n```xml\n\u003cargument name = \"socket type\" type = \"integer\"\u003e\n    \u003cmap name = \"PAIR\" value = \"ZMQ_PAIR\" /\u003e\n    \u003cmap name = \"PUB\"  value = \"ZMQ_PUB\" /\u003e\n    \u003cmap name = \"SUB\"  value = \"ZMQ_SUB\" /\u003e\n\u003c/argument\u003e\n```\n\nThe value should be a constant that the binding code has access to.\n\nThe following attributes are supported for arguments:\n\n- `polymorphic` - indicates that the passed class instance is a `sockish` type. For an example see CZMQ's zsock class.\n\n### API Types\n\nThis is an incomplete list of API types:\n\n* \"nothing\" -- for return only, means \"void\" in C.\n\n* \"anything\" -- means \"void *\" in C.\n\n* \"size\" -- long size (64 bits), \"size_t\" in C.\n\n* \"time\" -- long time (64 bits), \"time_t\" in C.\n\n* \"msecs\" -- long number of msecs, \"int64_t\" in C.\n\n* \"file_size\" -- long file size (64 bits).\n\n* \"boolean\" -- Boolean.\n\n* \"byte\" -- single octet.\n\n* \"char\" -- single character (possibly multibyte, do we care?)\n\n* \"integer\" -- 32-bit signed integer.\n\n* \"number\" -- unsigned number, with 'size = \"1|2|4|8\"'.\n\n* \"real\" -- single-precision floating point with 'size = \"4\"' (default) or double-precision with 'size = \"8\"'.\n\n* \"buffer\" -- byte array. When passing a buffer argument, if the next argument has type 'size', the binding may fill the size automatically. To return a buffer, you should specify 'size' attribute that defines how to set the buffer size. This can be a constant, 'size = \"ZUUID_LEN\"', or a dot followed by method name in the same class, e.g. 'size = \".size\"'.\n\n* \"string\" -- character array.\n\n* \"sockish\" -- a variant socket type, may be a zsock_t, libzmq void *, or an actor handle.\n\n* \"format\" -- printf format, followed by zero or more arguments.\n\n* \"FILE\", \"va_list\", \"zmq_pollitem\", \"socket\" -- literally that, in C. (Not sure if it is wise to use raw C types.)\n\n* callbacks - tbd.\n\n* Names of classes, e.g. zmsg.\n\n### Tips\n\nAt any time, you can examine a resolved model as an XML string with all of its children and attributes using the appropriate GSL functions:\n\n```gsl\n # if the `method` variable is a \u003cmethod/\u003e entity:\necho method.string()  # will print the model as an XML string.\nmethod.save(filename) # will save the model as an XML string to the given file.\n```\n\nYou can save a snapshot of the entire resolved project model using this syntax:\n\n```\ngsl -save:1 project.xml\n```\n\n### Generate API model from C header files\n\nWriting API model for bigger project with a lot of classes can be tedious job. There mkapi.py, which automates most of the task.\n\nIn order to use it, you must install zproject itself and then pycparser. For most of real world code, you must have fake_libc_includes available too.\n```sh\nvirtualenv/venv mkapi\nsource mkapi/bin/activate\npip install pycparser\ngit clone https://github.com/eliben/pycparser.git\n```\n\nThen from root directory of your project (for example czmq), type following\n```sh\nmkapi.py -I /path/to/your/pycparser/utils/fake_libc_include include/czmq.h\n```\n\nNote you *must* use top-level include as pycparser fails if it does not know any definition.\n\nThe tool might expect `-DWITH_DRAFTS` parameter if the class is not marked as a stable.\n\n#### Known caveats\n\nThe tool can't distinguish methods which allocates new object. It does print a comment about adding fresh = \"1\" attribute to each method, which return non const pointer. However the final assigment must be done manually.\n\n## Language Binding Notes\n\n### Java Language Binding\n\n* Skips methods that it cannot handle properly.\n\n* To build, you need gradle (or equivalent). Run 'gradle build jar' in the bindings/jni directory.\n* To install, run 'gradle install'. This puts the files into $HOME/.m2/repository.\n\n## Draft API Support\n\nzproject lets you mark classes and methods as 'draft' so that they are not installed by default in stable builds. This lets you deliver draft APIs to your users, and change them later.\n\nBy default, all classes and methods are draft, unless you specify otherwise. To mark the state of a class or method, specify in the project.xml:\n\n```\n\u003cclass name = \"classname\" state = \"stable\" /\u003e\n```\n\nOr in the class API XML file:\n\n```\n\u003cclass name = \"classname\" state = \"stable\"\u003e\n    ...\n    \u003cmethod name = \"methodname\" state = \"stable\"\u003e\n        ...\n    \u003c/method\u003e\n\u003c/class\u003e\n```\n\nThe method will inherit the class state unless it has its own 'state' attribute.\n\nThe allowed states are:\n\n* draft - the class or method is not built/installed in stable releases.\n* stable - the class or method is always built and installed. A method may not be changed once marked as stable.\n* legacy - the class or method is always built and installed. It may carry a warning that support can be withdrawn at any time.\n\nUsing autotools or CMake, you can specify --with-drafts to enable draft APIs, and --without-drafts to disable them. By default, drafts are built and installed when you work in a git repository (if the directory \".git\" is present), and otherwise they are not. That means, if you build from a tarball, drafts are disabled by default.\n\n## Removal\n\n### autotools\n\n```sh\nmake uninstall\n```\n\n## Additional files\nInstallation of third party files is a *hard* problem. It is not platform\nindependent, became hard to maintain and impossible to use correctly. One of\nzproject's goals is a simplicity. There is a simple installation model\n\n### Design goals\n* KISS, less configuration options the better\n* no conditionals in the model, those SHALL be handled in background\n* each option solves a REAL problem, avoid extending it because you can\n\n### Example\n```\n    \u003cmain name = \"MAIN\"\u003e\n        \u003cinstall type = \"systemd-tmpfiles\" /\u003e\n        \u003cinstall type = \"config\" name = \"MAIN-ldap-integration.cfg.example\" /\u003e\n    \u003c/main\u003e\n```\n\n**systemd-tmpfiles**\nThis will add install information about systemd tmpfiles.d configuration files\nto autotools, packaging, and so. The resulting file\n/usr/lib/tmpfiles.d/MAIN.conf will be installed only if configure was called\nwith --with-systemd-units.\n\n**config**\nThis will install additional configuration files to\n$\\(sysconfdir)/$\\(project.name)/$\\(name).\n\n## Notes for Writing Targets\n\n### Snippets\n\nIf you write a new target or extend one you might be in the situation where you\nneed to put code fragments into files which are not specific to your target. For\nexample the `systemd` target has to extend files from the `autotools`, `debian`\nand `redhat` targets. In order to keep those files as maintainable as possible\nyou'll include a snippet which is pull from your targets file. To include\na snippet call:\n\n```\n    insert_snippet (target)\n```\n\nWhere target is the identifier for the insertion point i.e. the filename. To\nregister a snippet to be inserted simply call.\n\n```\n    register_snippet (target, name)\n```\n\nTarget is must match the one in `insert_snippet` and the name identifies your\nsnippet. Then you can create a function or macro with the following form\n(without the brackets):\n\n```\n    function snippet_\u003ctarget\u003e_\u003cname\u003e\n\n    .macro snippet_\u003ctarget\u003e_\u003cname\u003e\n```\n\nThis function will be called by the `insert_snippet` function. You can have an\narbitrary amount of registered snippets per insertion point which will be\ninserted in arbitrary order so don't make any assumption on the order of the\nsnippets per insertion point.\n\n## Notes for Writing Language Targets\n\nThis is the general form of a target:\n\n```\nregister_target (\"somename\", \"Decription of target\")\n\nfunction target_somename\n\n\\.macro generate_something\n    ...\n\\.endmacro\n\n    project.topdir = \"someplace/somename\"\n    directory.create (project.topdir)\n    generate_something ()\nendfunction\n```\n\n### Schema/Architecture Overview\n\n* All `class`es SHALL be in the project model (`project.xml`).\n* Each `class` MAY have a corresponding API model (`api/{class name}.api`).\n* A binding generator SHOULD consider only `class`es with an API model (`where defined (class.api)`).\n* Each API model SHALL consist of both explicit information (written in the XML file) and implicit information (inferred by the [`zproject_class_api`](zproject_class_api.gsl) script). Both kinds of information will already be resolved (and indistinguishable) when each language binding generator is invoked.\n* Each API model SHALL have exactly one `class` entity at the top level.\n* Each `class` SHALL have a `name` attribute.\n* Each `class` MAY have one or more `method` entities.\n* Each `class` MAY have one or more `constructor` entities.\n* Each `class` MAY have one or more `destructor` entities.\n* Each `method`, `constructor`, and `destructor` MAY have one or more `argument` entities.\n* Each `method`, `constructor`, and `destructor` SHALL at least one `return` entity, and if more than one `return` entity exist, only the first SHOULD be considered. The `return` entity MAY be ignored if it has `type = \"nothing\"` (the default when no `type` is given).\n* Each entity SHALL have its semantic attributes fully resolved before reaching the language binding generators.\n* Each language binding generator SHALL NOT modify values of semantic attributes of entities.\n* Each language binding generator MAY assign values to language-specific implementation attributes of entities.\n* Each language binding generator SHOULD use a unique prefix for names of language-specific implementation attributes of entities.\n\n### Informal Summary\n\nA `class` is always the top-level entity in an API model, and it will be merged with the corresponding `class` entity defined in the project model. A class contains `method`s, `constructor`s, and `destructor`s (collectively, \"method\"s), and methods contain `argument`s and `return`s (collectively, \"container\"s). Each entity will contain both *semantic attributes* and *language-specific implementation attributes*.\n\n### Semantic Attributes\n\nSemantic attributes describe something intrinsic about the container.\n\nFor example, arguments may be described as passed `by_reference` to indicate that ownership is transferred from the caller. Similarly, return values may be described as `fresh` to indicate that ownership is transferred to the caller, which must destroy the object when it is finished with it. It's important to remember that these attributes are primarily meant to be an abstraction that describes conceptual information, leaving the details of how code generators interpret (or ignore) each attribute up to the authors.\n\nSemantic attributes may be implicit (not given a value in the written model). In this case, it is up to the [`zproject_class_api`](zproject_class_api.gsl) script to fully resolve default values for all attributes. Downstream code generators should *never* resolve or alter semantic attributes, as this could change the behavior of any code generator that is run after the errant code generator.\n\nThese are the semantic attributes for each kind of entity that will be resolved before language bindings generators are invoked:\n\n```gsl\nclass.name        # string (as given in the API model)\nclass.description # string (comment in the API model, or empty string)\n```\n```gsl\nmethod.name           # string (as given in the API model, or a default value)\nmethod.description    # string (comment in the API model, or a default value)\nmethod.singleton      # 0/1 (default: 0, but 1 for constructors/destructors)\nmethod.is_constructor # 0/1 (default: 0, but 1 for constructors)\nmethod.is_destructor  # 0/1 (default: 0, but 1 for destructors)\nmethod.has_va_list_sibling # 0/1 (default: 0)\n```\n```gsl\ncontainer.name         # string (as given in the API model, or \"_\")\ncontainer.type         # string (as given, or \"nothing\")\ncontainer.mutable      # 0/1 (default: 0)\ncontainer.by_reference # 0/1 (default: 0)\ncontainer.callback     # 0/1 (default: 0)\ncontainer.fresh        # 0/1 (default: 0)\ncontainer.variadic     # 0/1 (default: 0)\ncontainer.va_start     # string - that holds the argment name for va_start ()\ncontainer.optional     # 0/1 (default: 0), up to binding generator to use\n```\n\n## Ownership and License\n\nThe contributors are listed in AUTHORS. This project uses the MPL v2 license, see LICENSE.\n\nzproject uses the [C4.1 (Collective Code Construction Contract)](http://rfc.zeromq.org/spec:22) process for contributions.\n\nTo report an issue, use the [zproject issue tracker](https://github.com/zeromq/zproject/issues) at github.com.\n\n### Ownership and License of generated sources\n\nThe copyright of the output of zproject is by default property of the users. The license.xml file must be set up by the users to specify a license of their choosing.\n\n### Hints to Contributors\n\nMake sure that the project model hides all details of backend scripts. For example don't make a user enter a header file because autoconf needs it.\n\nDo read your code after you write it and ask, \"Can I make this simpler?\" We do use a nice minimalist and yet readable style. Learn it, adopt it, use it.\n\nBefore opening a pull request read our [contribution guidelines](https://github.com/zeromq/zproject/blob/master/CONTRIBUTING.md). Thanks!\n\n### This Document\n\n_This documentation was generated from zproject/README.txt using [Gitdown](https://github.com/zeromq/gitdown)_\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzeromq%2Fzproject","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzeromq%2Fzproject","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzeromq%2Fzproject/lists"}