Skip to content

C and C++ dependencies in Pascal projects

Keep Pascal as your application language while using native libraries written in C or C++. Nexus Build can build those dependencies in the same project graph, publish their output directories, and make those resources available to a Pascal consumer. You still describe the interface and select the native inputs to link.

This integrates dependency construction with application development. It does not automatically translate C/C++ headers or expose arbitrary C++ classes to Pascal.

From native source to Pascal application

  1. Describe the native producer as a project. Use LLVM for direct Clang C/C++ operations, or CMake, MSBuild, or MSVC for the appropriate existing build.
  2. Publish the source, header, object, and library directories the producer owns.
  3. Reference that project from a catalog and add it to the consumer's Requires.
  4. Declare the Pascal interface and explicit object/library linkage.
  5. Build the consuming project. Required producers execute first; shared dependencies execute once per invocation.

A CMake project continues to own its internal dependency graph. Nexus Build coordinates the declared operation and its published outputs; it does not import every upstream build rule or acquire source repositories implicitly. Nexus Forge can prepare dependencies before invoking the build.

What publications provide

Published paths resolve in the producer's context and propagate through required projects, including intermediate projects that perform no compilation themselves.

Publication Pascal consumer (NXPC) Native consumer (LLVM)
Sources Unit lookup (-Fu) Retained in the resolved project environment
Headers Include lookup (-Fi, -I) Include lookup (-I)
Objects Object lookup (-Fo) Name object inputs explicitly
Libraries Library lookup (-Fl) Library lookup when linking (-L)

A search directory is not a linker input. Publishing Objects or Libraries does not link every file in that directory. Pascal link directives, library declarations, operation inputs, or explicit linker settings select what is used. Headers likewise do not become Pascal declarations automatically.

See dependencies and publications for catalog syntax and the operation reference for the full contract.

Example: Abbrevia-derived NXArchive and native codecs

NXArchive combines Pascal archive code derived from Abbrevia with native C codec sources. Its producer project compiles NXSevenZip.c and the retained LZMA SDK, PPMd, and WavPack C sources with an LLVM object operation. A separate LLVM shared-library operation builds bzip2 with target-specific configuration.

The following is the publication block from that project. SourceRoot and OutputRoot are values declared by the complete descriptor, not built-in paths:

Publishes Directories {
    Sources: [@NXArchive.SourceRoot + "/src"];
    Headers: [@NXArchive.SourceRoot + "/src"];
    Objects: [@NXArchive.OutputRoot + "/native/" + @Tools.Native.ObjectDirectory, @NXArchive.OutputRoot + "/native"];
    Libraries: [@NXArchive.OutputRoot + "/libraries"];
}

The producer selects its C compiler, target triple, include directories, codec defines, and output directory explicitly. Pascal consumers require its catalog entry, @Projects.NXArchive, alongside their other dependencies. The published Pascal units and native object lookup paths reach the consumer together.

The SevenZip Pascal unit links named C objects and declares C entry points. Two excerpts illustrate the boundary; the complete unit lists the other required objects and declarations:

{$L NXSevenZip.o}
function NXSevenZipCount(AHandle: Pointer): Cardinal; cdecl; external;

NXSevenZip.c adapts the LZMA SDK to stream callbacks and handles that the Pascal unit can consume. This makes 7z reading available through Pascal stream APIs without requiring a 7-Zip installation or a decoder DLL. It is explicit native integration, rather than a rewrite of the decoder in Pascal.

For a configured source checkout, inspect the producer from the Nexus root:

nxbuild /action=plan /project=packages/nexus-packages/nxarchive/NXArchive.nxproject /targetos=win64 /targetcpu=x86_64 /buildconfiguration=Debug

Use linux for the corresponding Linux selection. The source-development environment must point at the intended Clang, compiler, system libraries, and external worktree. plan inspects operations without compiling them. Build the consuming application's descriptor to compile its required producers and link the application; building this provider alone does not create a Pascal program.

See compression and hashing for supported archive formats, stream lifetime rules, and the distinction between the source provider and the separate compiler-native runtime package.

Example: Nexus Gear's native engine and Pascal plugins

Nexus Gear is the public name for nexus-mobile. Its native foundation includes C/C++ engine code and third-party technology inherited from Solar2D/Corona.

  • On Linux, Nexus2DEngine.nxproject builds Lua tools, generates embedded resources, compiles C and C++ object groups, and links the simulator with explicitly named native libraries.
  • On Windows, Nexus2D.Dependencies.nxproject uses CMake for shaderc, SPIRV-Cross, and libevent, plus MSVC operations for a DNS-SD library. The Forge workflow acquires pinned dependencies and orchestrates these builds and the engine's MSBuild solution through Nexus Build.
  • Pascal plugins use the separate Lua and Solar2D integration packages. The sample plugin project declares those dependencies and explicit platform link settings. The Lua 5.1 ABI and Solar2D Native declarations form the interoperability boundary.

These are complementary examples: building the C/C++ engine and linking a Pascal plugin through its native interface are distinct operations. They are not evidence that Pascal can directly instantiate arbitrary C++ engine classes.

See Pascal plugins for the bridge API and its limits, and source builds for engine prerequisites.

ABI, toolchain, and deployment responsibilities

Use matching CPU/OS targets, object formats, calling conventions, structure layouts, and native runtimes. Supply the destination SDKs and system libraries; a compiler backend or RTL does not supply every native dependency.

C++ libraries commonly need a C-compatible wrapper or an existing binding that defines ownership, allocation, exceptions, and data representation across the boundary. Direct consumption of arbitrary C++ classes/interfaces without those declarations or bindings is not currently supported. Automatic binding generation is not part of this workflow.

Shared-library deployment is separate from link-time discovery. Arrange DLL/ shared-object availability and loader paths for the application you ship. Static objects avoid that particular deployment dependency, but do not remove all platform/runtime dependencies or component license obligations.

Project publications are also distinct from Nexus Pascal compiler-native runtime packages. Choose the source/native provider or an explicit runtime-package model deliberately, using matching toolchains and SDKs.

Configure the tool environment and retain the original component notices described in the attribution information.