Skip to content

Build-time constants with BuildInfo.mqh

In this guide you will learn how to:

  • Configure defines in knitpkg.yaml
  • Use kp compile --define / -D or kp build --define / -D to inject compile-time constants
  • Work with the generated knitpkg/build/BuildInfo.mqh header in your MQL code
  • Produce different builds (debug, beta, production) from the same source tree
  • Keep EA metadata (version, author, description) in sync with your manifest

This section assumes you have already read the Concepts › BuildInfo page and are familiar with the basic idea.


1. What BuildInfo.mqh does

Every time you run kp compile or kp build KnitPkg will, before invoking the compiler:

  1. Load your project manifest (knitpkg.yaml)
  2. Collect constants from:
    • defines.from_manifest
    • defines.extra
    • CLI flags --define / -D
  3. Generate (or update) the file:
    • knitpkg/build/BuildInfo.mqh

This file is a pure MQL header containing #define directives, which you can then #include in your .mq5 / .mqh code.

You never edit BuildInfo.mqh manually — it is always generated by KnitPkg.


2. Declaring constants in knitpkg.yaml

Let’s start with a concrete example manifest:

'expertdemo' manifest with 'defines' section
target: mql5
type: expert

organization: douglasrechia
name: expertdemo
version: 2.0.2
version_description: Dependencies version update

description: KnitPkg for Metatrader - Expert Demo
keywords: ["showcase", "bars", "calc", "new-bar", "bar-watcher", "sma"]
author: Douglas Rechia
license: MIT

include_mode: flat

defines:
  from_manifest:
    MANIFEST_ORG:         organization
    MANIFEST_AUTHOR:      author
    MANIFEST_DESCRIPTION: description
    MANIFEST_VERSION:     version
  extra:
    MQL_STORE_VERSION:    '2.0'
    FEATURE_X_ENABLED:    null

entrypoints:
  - src/KnitPkgExpertDemo.mqh

compile:
  - src/KnitPkgExpertDemo.mq5

dependencies:
  '@douglasrechia/bar': ^1.0.0
  '@douglasrechia/barhelper': ^1.0.0

2.1 from_manifest

The from_manifest section maps:

  • key → the constant name you want in MQL (MANIFEST_VERSION)
  • value → the manifest field that should provide the value (version)

In the example:

  • MANIFEST_VERSION: version
  • MANIFEST_ORG: organization
  • MANIFEST_AUTHOR: author
  • MANIFEST_DESCRIPTION: description

All of these will end up as #defines in BuildInfo.mqh.

2.2 extra

The extra section is a simple map of:

  • constant name → value (or no value)

In the example:

  • MQL_STORE_VERSION: '2.0'
    "2.0" will be emitted as a string
  • FEATURE_X_ENABLED: null
    → null value → emitted as a flag without value

You can mix strings, numbers and flags:

defines:
  extra:
    MQL_STORE_VERSION: '2.0'   # → #define MQL_STORE_VERSION "2.0"
    MAX_BARS:          500     # → #define MAX_BARS 500
    ENABLE_DEBUG:      null    # → #define ENABLE_DEBUG

3. Running kp compile and inspecting BuildInfo.mqh

From the project root (where knitpkg.yaml lives), run:

kp compile

After a successful run you should see:

  • knitpkg/build/BuildInfo.mqh

Open that file; for the manifest above it will look similar to:

// ======================================================================
// AUTO-GENERATED BY KNITPKG — DO NOT EDIT MANUALLY
// Project  : douglasrechia/expertdemo
// Version  : 2.0.1
// Generated: 2026-03-05T14:11:41Z
// ======================================================================

#ifndef __KNITPKG_DOUGLASRECHIA_EXPERTDEMO_BUILDINFO__
#define __KNITPKG_DOUGLASRECHIA_EXPERTDEMO_BUILDINFO__

#define MANIFEST_ORG                             "douglasrechia"
#define MANIFEST_AUTHOR                          "Douglas Rechia"
#define MANIFEST_DESCRIPTION                     "KnitPkg for Metatrader - Expert Demo"
#define MANIFEST_VERSION                         "2.0.1"
#define MQL_STORE_VERSION                        "2.1"
#define FEATURE_X_ENABLED

#endif // __KNITPKG_DOUGLASRECHIA_EXPERTDEMO_BUILDINFO__

You now have a single header you can include anywhere in your project to access all of these values at compile time.


4. Using BuildInfo.mqh in your EA

A common pattern is to include the header at the top of your main EA file.

For the expertdemo project above, assuming your main entrypoint is src/KnitPkgExpertDemo.mq5, you can do:

#include "../knitpkg/build/BuildInfo.mqh"

// Your existing includes and code...

int OnInit()
  {
   Print("Expert: ", MANIFEST_DESCRIPTION);
   Print("Version: ", MANIFEST_VERSION, " (store ", MQL_STORE_VERSION, ")");

   #ifdef FEATURE_X_ENABLED
      Print("Feature X is enabled for this build");
   #else
      Print("Feature X is disabled for this build");
   #endif

   return(INIT_SUCCEEDED);
  }

Note:

  • The #include path is relative to the .mq5 file location.
  • You can safely include BuildInfo.mqh in multiple source files; it is protected by an include guard.

5. Wiring EA "Common" tab properties

One of the most powerful uses of BuildInfo.mqh is to keep your EA metadata in sync with the manifest.

You can use the constants exported from defines.from_manifest and defines.extra directly in the #property declarations:

#include "../knitpkg/build/BuildInfo.mqh"

#property copyright   "Copyright © 2026 " + MANIFEST_AUTHOR + ". All rights reserved."
#property link        "https://knitpkg.dev"
#property version     (string)MQL_STORE_VERSION

#property description ""
#property description "Version: " + MANIFEST_VERSION
#property description ""
#property description "Description: " + MANIFEST_DESCRIPTION
#property description "Organization: " + MANIFEST_ORG
#property description "Author: " + MANIFEST_AUTHOR
#property description "License: MIT"
#property description ""
#property description "Powered by KnitPkg for MetaTrader"
#property description "https://knitpkg.dev"

With this setup:

  • When you bump version or description in knitpkg.yaml, your EA "Common" tab is automatically updated after the next kp compile or kp build.
  • You don’t have to manually synchronize strings in multiple places.
  • Store-specific versions (for example MQL_STORE_VERSION) can live in defines.extra without polluting the manifest with store-only details.

6. Overriding constants from the CLI

In addition to the manifest, you can define or override constants directly from the command line using --define or -D with both kp compile and kp build commands.

This is useful for:

  • Debug / test builds
  • Nightly / beta / production channels
  • Broker-specific parameters
  • CI pipelines that should not edit knitpkg.yaml

6.1 Basic usage

Run:

kp compile -D NIGHTLY
kp compile -D BUILD_TYPE=release
kp compile -D FEATURE_X_ENABLED -D MAX_BARS=500

kp build -D NIGHTLY
kp build -D BUILD_TYPE=release
kp build -D FEATURE_X_ENABLED -D MAX_BARS=500

Accepted formats:

  • -D NAME
    → emits #define NAME
  • -D NAME=value
    → emits #define NAME "value" if value is non-numeric
    → emits #define NAME 42 if value is numeric (42, 3.14, etc.)

These CLI-provided constants:

  • Are applied only for the current invocation
  • Are not written back into knitpkg.yaml
  • Override any constant with the same name defined in the manifest

6.2 Priority

If a constant name appears in more than one place, the resolution order is:

  1. CLI --define / -D (highest priority)
  2. defines.extra
  3. defines.from_manifest (lowest priority)

This means you can safely set defaults in the manifest and override them from CI or local scripts without touching the file.

Example:

defines:
  extra:
    BUILD_TYPE:         'dev'
    FEATURE_X_ENABLED:  null

Then:

kp compile -D BUILD_TYPE=release

BuildInfo.mqh will contain:

#define BUILD_TYPE "release"
#define FEATURE_X_ENABLED

7. Practical build variants

Here are a few practical patterns you can adopt using BuildInfo.mqh and kp compile -D.

7.1 Debug vs store builds

In knitpkg.yaml:

defines:
  extra:
    MQL_STORE_VERSION: '2.1'

In code:

#include "../knitpkg/build/BuildInfo.mqh"

#ifdef DEBUG_BUILD
  #define LOG_LEVEL 3
#else
  #define LOG_LEVEL 1
#endif

In your terminal:

# Local debug build
kp compile -D DEBUG_BUILD

# Store-ready build
kp compile -D BUILD_TYPE=store

You can then branch logic based on DEBUG_BUILD or BUILD_TYPE inside your code without changing any source file.

7.2 Broker or environment-specific builds

kp compile -D ENV=prod -D BROKER_CODE=ICMARKETS
kp compile -D ENV=staging -D BROKER_CODE=OANDA

In code:

#include "../knitpkg/build/BuildInfo.mqh"

void OnInit()
  {
   Print("Environment: ", ENV);
   Print("Broker code: ", BROKER_CODE);

   #ifdef ENV
     if(ENV == "prod")
       {
        // production parameters
       }
     else
       {
        // staging / sandbox parameters
       }
   #endif
  }

8. Troubleshooting

Here are some common issues you may run into while adopting BuildInfo.mqh.

8.1 File not found on include

If MetaEditor shows an error like:

  • '../knitpkg/build/BuildInfo.mqh' cannot be opened

Check:

  1. You have run kp compile at least once after adding defines.
  2. The #include path is correct relative to the .mq5 file.
  3. The folder knitpkg/build/ exists inside the project root.

If you are unsure about the path, open the project folder in your file explorer and adjust the #include line accordingly.

8.2 Constants missing in BuildInfo.mqh

If a constant you added in defines.from_manifest or defines.extra does not show up in BuildInfo.mqh:

  • Confirm that knitpkg.yaml is valid YAML (run kp validate if available).
  • Check for typos in the manifest field names used in from_manifest.
  • Make sure you re-ran kp compile after editing the manifest.
  • Confirm that no CLI -D is overriding the same constant name.

9. Summary

With a small amount of configuration in knitpkg.yaml, BuildInfo.mqh gives you:

  • Centralized metadata: version, author, description, organization
  • Compile-time feature flags: controlled via manifest or CLI
  • Consistent EA "Common" tab: always in sync with your manifest
  • Multiple build flavors (debug, store, beta, broker-specific) from the same codebase

This lets you treat your MQL projects much more like modern software projects: builds are reproducible, configuration is explicit, and you can automate everything in your scripts and CI pipelines without touching .mq5 files.