Call the AL compiler from the command line

In this video, I take a look at how to use the Microsoft Dynamics 365 Business Central AL compiler from the command line. If you want to build your own pipeline/build service the very first step is to be able to control the compiler.

https://youtu.be/uGYYXlCGoWw

In this video, Erik demonstrates how to call the AL compiler directly from the command line in Business Central, taking it out of Visual Studio Code and into a workflow you can script and automate. This is the foundation for building your own build pipelines, build scripts, and CI/CD processes for AL projects.

Finding the AL Compiler

When you press Ctrl+Shift+B in Visual Studio Code with the AL Language extension installed, you see familiar output: the AL compiler version, a compilation started message, and (hopefully) a success message. But that’s not a command line — it’s all happening inside VS Code. So where is the actual compiler?

The compiler lives inside the AL Language extension folder. Navigate to your user profile’s VS Code extensions directory:

C:\Users\erik\.vscode\extensions\

Inside that folder, you’ll find a subfolder for each installed extension. The one we’re looking for is the ms-dynamics-smb.al-* folder. Inside it, there’s a bin directory containing a collection of DLL files (some even with debug symbols — nice of Microsoft!) and a couple of executables.

The executable we care about is alc.exe — following the long command line tradition where the C compiler is called cc, the AL compiler is called alc.

Making the Compiler Accessible

To use alc.exe from anywhere on the command line, you have a few options:

  • Copy the bin folder to a convenient location
  • Specify the full path every time you call it
  • Add the bin folder to your system’s PATH environment variable

Erik adds the folder to his PATH, which means he can type alc from any directory and the compiler is available. The one caveat is that Microsoft frequently updates the VS Code extension, which changes the folder name. In his build scripts, Erik has a routine that dynamically locates the folder containing alc.exe and uses that path.

Compiling from the Command Line

Running alc with no arguments gives you an error: “A project without a manifest must have the out option specified.” To compile successfully, you need to provide three key parameters:

  1. /project — The root folder where your app.json is located
  2. /packagecachepath — The folder where your symbols (.alpackages) are located
  3. /out — The output file name for the compiled .app file

Here’s an example of a successful compile command:

alc /project:"." /packagecachepath:"./.alpackages/" /out:"youtube1.app"

This produces a compiled .app file that is essentially identical to the one compiled from within Visual Studio Code — Erik notes the file sizes differ by only one byte, likely due to the different output file name.

Creating a Simple Build Script

Once you have a working compile command, you can put it into a batch file to make it repeatable. Here’s a minimal example:

@echo off
del youtube1.app
alc /project:"." /packagecachepath:"./.alpackages/" /out:"youtube1.app"
xcopy youtube1.app .. /Y

This script deletes any previous output, compiles the project, and copies the resulting .app file to the parent folder. Simple and rudimentary, but it illustrates the core concept: take the steps you want, put them into a structured file, and run them the same way every time.

Available Compiler Parameters

Running alc without arguments displays all available parameters. Beyond the three we used, there are several more:

  • /assemblyProbingPath — Required if your project references .NET assemblies
  • /ruleset — Control code analysis rule sets
  • /features — Override feature flags from app.json
  • /log — Specify how detailed the compiler log should be (useful for troubleshooting; you can send verbose logs to Microsoft for investigation)
  • /errorlog — Output errors in a structured format
  • /nowarn — Suppress warnings
  • /warnaserror — Treat warnings as errors

These are essentially the same parameters that Visual Studio Code uses behind the scenes — you have the exact same feature set and control over your build process from the command line.

Scaling Up: A Real Build System

Erik hints at where this journey leads. He has built a custom build tool called ALBuild that orchestrates full build pipelines using a JSON configuration file. Here’s a glimpse at how it’s invoked:

@echo off
c:\projects\albuild\video\ALBuild.exe pos.json

And here’s the kind of pipeline configuration it supports:

{
  "Project": "Point of Sale",
  "Report" : "Email",
  "ReportDestination" : "erik@hougaard.com",
  "Tasks": [
    {
      "Type": "DeployBasicDocker",
      "Settings": {
        "AppFile": "c:\\projects\\albuild\\testrunner\\Hougaard_ALBuild TestRunner_1.0.0.0.app",
        "BaseURL": "http://bc20:7049/BC/",
        "User": "demo",
        "Password": "demo",
        "SchemaUpdateMode": "forcesync"
      }
    },
    {
      "Type": "Git",
      "Settings": {
        "Path": "c:\\projects\\youtube\\point of sale",
        "Command": "pull"
      }
    },
    {
      "Type": "UpdateVersion",
      "Settings": {
        "AppPath": "c:\\projects\\youtube\\point of sale",
        "VersionPartToIncrement": 4,
        "Increment": 1,
        "DateInVersionPartNo": 3
      }
    },
    {
      "Type": "Remember",
      "Settings": {
        "AppPath": "c:\\projects\\youtube\\point of sale"
      }
    },
    {
      "Type": "DownloadSymbolsDocker",
      "Settings": {
        "AppPath": "%APPPATH%",
        "BaseURL": "http://bc20:7049/BC/",
        "User": "demo",
        "Password": "demo"
      }
    },
    {
      "Type": "Compile",
      "Settings": {
        "AppPath": "%APPPATH%"
      }
    },
    {
      "Type": "Translate",
      "Settings": {
        "XLFPath": "%APPPATH%\\Translations\\%NAME%.g.xlf",
        "ProductName": "%NAME%"
      }
    },
    {
      "Type": "Compile",
      "Settings": {
        "AppPath": "%APPPATH%"
      }
    },
    {
      "Type": "Copy",
      "Settings": {
        "From": "%APPPATH%\\%PUBLISHER%_%NAME%_%VERSION%.app",
        "To": "C:\\Projects\\youtube\\ALbuild\\Release\\%PUBLISHER%_%NAME%_%VERSION%.app"
      }
    },
    {
      "Type": "Git",
      "Settings": {
        "Path": "%APPPATH%",
        "Command": "add *"
      }
    },
    {
      "Type": "Git",
      "Settings": {
        "Path": "%APPPATH%",
        "Command": "commit -a -m \"ALBuild Version %VERSION%\""
      }
    },
    {
      "Type": "Git",
      "Settings": {
        "Path": "%APPPATH%",
        "Command": "push"
      }
    }
  ]
}

This configuration demonstrates a full build pipeline that:

  • Deploys a test runner app to a Docker-based BC environment
  • Pulls the latest source code from Git
  • Automatically increments the version number (with a date-based component)
  • Downloads symbols from the BC server
  • Compiles the project
  • Handles translations
  • Compiles again (after translations are applied)
  • Copies the output artifact to a release folder
  • Commits the changes back to Git and pushes

Notice the use of variables like %APPPATH%, %NAME%, %PUBLISHER%, and %VERSION% — the Remember task reads the app.json and makes these values available to subsequent tasks. This is the kind of sophisticated automation you can build once you understand the fundamentals of calling the compiler from the command line.

Conclusion

Calling the AL compiler from the command line is not rocket science — it’s simply a matter of locating alc.exe in your VS Code extensions folder, understanding the key parameters (/project, /packagecachepath, and /out), and putting those calls into repeatable scripts. This is the foundation for everything from simple compile scripts to full build pipelines that handle version management, translations, signing for AppSource, and Git integration. The compiler gives you the exact same feature set from the command line as you get inside Visual Studio Code — the only difference is that now you’re in control of the process.