<feed xmlns='http://www.w3.org/2005/Atom'>
<title>tazel, branch feature/action-level-incremental</title>
<subtitle>A build system and package manager for C, C++, Objective-C, Objective-C++ and Zig, with Kotlin project files.</subtitle>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/tazel/'/>
<entry>
<title>Make builds incremental per action, by content</title>
<updated>2026-11-12T19:40:35+00:00</updated>
<author>
<name>Leitwolf11</name>
</author>
<published>2026-11-12T19:40:35+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/tazel/commit/?id=d73260a011d463f492448bc2e29aa46fba657326'/>
<id>d73260a011d463f492448bc2e29aa46fba657326</id>
<content type='text'>
Every compile, archive, link and Zig build is now an action: a command
line with its directory and environment, the files it reads and the
files it writes. ActionCache keeps a record beside the first output of
each action, with the digest of the action and the SHA-256 of every
input and output. An action runs again only when:

- its command line, directory or environment changed,
- a file it read has other content: the declared inputs, and what the
  compiler included, from the depfile it wrote,
- or an output is gone or no longer what the action wrote.

Files are compared by content, not by time. Touching a file reruns
nothing; a translation unit recompiled to the same object (a comment in
a header, say) reruns neither the archive nor the program that use it.
Digests are kept per build by size and modification time, so each file
is read once.

- Zig writes no depfile, so every .zig file beside and below the root
  file, and the libraries it links, are the inputs of a Zig build. It
  no longer runs on every build.
- Staged headers and data files are copied only when their bytes
  differ.
- The .cmd records and the time comparisons of UpToDate are gone.

Tests: the action cache (command, environment, touched, changed and
restored inputs, altered outputs, forgotten records) and, with the C
compiler of the machine, a touch that runs nothing, a comment in a
header that recompiles two units but does not archive or link, and a
change of code that recompiles, archives and relinks.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Every compile, archive, link and Zig build is now an action: a command
line with its directory and environment, the files it reads and the
files it writes. ActionCache keeps a record beside the first output of
each action, with the digest of the action and the SHA-256 of every
input and output. An action runs again only when:

- its command line, directory or environment changed,
- a file it read has other content: the declared inputs, and what the
  compiler included, from the depfile it wrote,
- or an output is gone or no longer what the action wrote.

Files are compared by content, not by time. Touching a file reruns
nothing; a translation unit recompiled to the same object (a comment in
a header, say) reruns neither the archive nor the program that use it.
Digests are kept per build by size and modification time, so each file
is read once.

- Zig writes no depfile, so every .zig file beside and below the root
  file, and the libraries it links, are the inputs of a Zig build. It
  no longer runs on every build.
- Staged headers and data files are copied only when their bytes
  differ.
- The .cmd records and the time comparisons of UpToDate are gone.

Tests: the action cache (command, environment, touched, changed and
restored inputs, altered outputs, forgotten records) and, with the C
compiler of the machine, a touch that runs nothing, a comment in a
header that recompiles two units but does not archive or link, and a
change of code that recompiles, archives and relinks.
</pre>
</div>
</content>
</entry>
<entry>
<title>Merge pull request #5 from Progmasoft/feature/build-c-family</title>
<updated>2026-11-12T19:36:11+00:00</updated>
<author>
<name>Leitwolf</name>
</author>
<published>2026-11-12T19:36:11+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/tazel/commit/?id=86214c96285f73d352f934b0da33d231150898f0'/>
<id>86214c96285f73d352f934b0da33d231150898f0</id>
<content type='text'>
Build and run C, C++, Objective-C, Objective-C++ and Zig targets</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Build and run C, C++, Objective-C, Objective-C++ and Zig targets</pre>
</div>
</content>
</entry>
<entry>
<title>Build and run C, C++, Objective-C, Objective-C++ and Zig targets</title>
<updated>2026-11-12T19:19:46+00:00</updated>
<author>
<name>Leitwolf11</name>
</author>
<published>2026-11-12T19:19:46+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/tazel/commit/?id=7cb809c6560fc4ed29f41e4e4199cd91af6cbed1'/>
<id>7cb809c6560fc4ed29f41e4e4199cd91af6cbed1</id>
<content type='text'>
Tazel gets its first build commands:

  tazel build [--release] [--triple &lt;LLVM triple&gt;] [labels...]
  tazel run   [--release] [--triple &lt;LLVM triple&gt;] [label] [-- program arguments]

Without a label they take the package of the current directory. A
pattern skips targets not built for the triple; a label names one, or
it is an error. tazel run builds and runs one bin target with its args
and env from BUILD.kts, then the arguments after --.

- Plan (driver.BuildPlan): the selected targets and every library they
  depend on, configured once each for one triple and build mode, with
  link order (dependents before dependencies) and cycle detection.
  Dependencies from ViGet and local .vipkg files are refused with a
  message, since they are not built yet.
- Compilers (driver.CcToolchain): Clang, then GCC, then zig cc on PATH
  unless the target chooses one. Clang builds for other triples with
  --target, zig cc with its own triple spelling; GCC only for the host.
  MSVC and clang-cl are refused with a message for now.
- Commands (driver.CcCommands): standard, gnuExtensions, optimize and
  debugInfo with their mode defaults, warnings, warningsAsErrors,
  position-independent code (sharedlibs, and staticlibs a sharedlib
  links unless pic says otherwise), arc, sanitizers, LTO, public and
  private defines and headers with those of the libraries, headers
  staged under includePrefix/stripIncludePrefix, precompiledHeader as a
  forced include, flags; archives with llvm-ar or ar; links with
  alwaysLink as whole-archive, links, frameworks on macOS, rpath (and
  the directories of shared libraries), linkerScript, exports (version
  script or exported symbols), soVersion (soname and the unversioned
  name), defFile and subsystem on Windows, strip and linkFlags.
  Windows resource scripts are refused with a message for now.
- Zig targets run zig build-exe, build-lib (-dynamic) or test
  --test-no-exec on their root file, with the libraries they depend on.
- Incremental (driver.UpToDate): every compile writes a depfile (-MD
  -MF); an object is current while its command line is the same and no
  input in its depfile is newer. Archives and programs are remade when
  their command or an input changed. A failed command is redone.
- Jobs: the job pool and build graph of the legacy Tazel run the
  translation units in parallel (execution.jobs, keepGoing).
- data files are copied beside the output.

Tests: depfile reading, up-to-date decisions, globs and excludes, Zig
triples and output names, and a real build with the C compiler of the
machine: a first build, a build with nothing to do, a header change
that recompiles both units, tazel run with args, env and extra
arguments, and a compiler error.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Tazel gets its first build commands:

  tazel build [--release] [--triple &lt;LLVM triple&gt;] [labels...]
  tazel run   [--release] [--triple &lt;LLVM triple&gt;] [label] [-- program arguments]

Without a label they take the package of the current directory. A
pattern skips targets not built for the triple; a label names one, or
it is an error. tazel run builds and runs one bin target with its args
and env from BUILD.kts, then the arguments after --.

- Plan (driver.BuildPlan): the selected targets and every library they
  depend on, configured once each for one triple and build mode, with
  link order (dependents before dependencies) and cycle detection.
  Dependencies from ViGet and local .vipkg files are refused with a
  message, since they are not built yet.
- Compilers (driver.CcToolchain): Clang, then GCC, then zig cc on PATH
  unless the target chooses one. Clang builds for other triples with
  --target, zig cc with its own triple spelling; GCC only for the host.
  MSVC and clang-cl are refused with a message for now.
- Commands (driver.CcCommands): standard, gnuExtensions, optimize and
  debugInfo with their mode defaults, warnings, warningsAsErrors,
  position-independent code (sharedlibs, and staticlibs a sharedlib
  links unless pic says otherwise), arc, sanitizers, LTO, public and
  private defines and headers with those of the libraries, headers
  staged under includePrefix/stripIncludePrefix, precompiledHeader as a
  forced include, flags; archives with llvm-ar or ar; links with
  alwaysLink as whole-archive, links, frameworks on macOS, rpath (and
  the directories of shared libraries), linkerScript, exports (version
  script or exported symbols), soVersion (soname and the unversioned
  name), defFile and subsystem on Windows, strip and linkFlags.
  Windows resource scripts are refused with a message for now.
- Zig targets run zig build-exe, build-lib (-dynamic) or test
  --test-no-exec on their root file, with the libraries they depend on.
- Incremental (driver.UpToDate): every compile writes a depfile (-MD
  -MF); an object is current while its command line is the same and no
  input in its depfile is newer. Archives and programs are remade when
  their command or an input changed. A failed command is redone.
- Jobs: the job pool and build graph of the legacy Tazel run the
  translation units in parallel (execution.jobs, keepGoing).
- data files are copied beside the output.

Tests: depfile reading, up-to-date decisions, globs and excludes, Zig
triples and output names, and a real build with the C compiler of the
machine: a first build, a build with nothing to do, a header change
that recompiles both units, tazel run with args, env and extra
arguments, and a compiler error.
</pre>
</div>
</content>
</entry>
<entry>
<title>Merge pull request #4 from Progmasoft/feature/plugin-api-and-gradle-plugin</title>
<updated>2026-11-12T19:06:58+00:00</updated>
<author>
<name>Leitwolf</name>
</author>
<published>2026-11-12T19:06:58+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/tazel/commit/?id=95cdafcf1aa01b5d32171c56e6a94137402643b9'/>
<id>95cdafcf1aa01b5d32171c56e6a94137402643b9</id>
<content type='text'>
Bring the plugin API and the Gradle plugin from the legacy Tazel</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Bring the plugin API and the Gradle plugin from the legacy Tazel</pre>
</div>
</content>
</entry>
<entry>
<title>Merge main into feature/plugin-api-and-gradle-plugin</title>
<updated>2026-11-12T15:54:01+00:00</updated>
<author>
<name>Leitwolf11</name>
</author>
<published>2026-11-12T15:54:01+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/tazel/commit/?id=9cff1e2b6a37959abc8a8b66946df61850a0aa47'/>
<id>9cff1e2b6a37959abc8a8b66946df61850a0aa47</id>
<content type='text'>
Keeps both changelog entries: Tazel Custom Commands and Options from
main, then the plugin API and the Gradle plugin.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Keeps both changelog entries: Tazel Custom Commands and Options from
main, then the plugin API and the Gradle plugin.
</pre>
</div>
</content>
</entry>
<entry>
<title>Merge pull request #3 from Progmasoft/feature/custom-commands-and-options</title>
<updated>2026-11-12T15:53:10+00:00</updated>
<author>
<name>Leitwolf</name>
</author>
<published>2026-11-12T15:53:10+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/tazel/commit/?id=01036658064b95c24c1136d2bba9403c81c3337d'/>
<id>01036658064b95c24c1136d2bba9403c81c3337d</id>
<content type='text'>
Bring Tazel Custom Commands and Tazel Options from the legacy Tazel</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Bring Tazel Custom Commands and Tazel Options from the legacy Tazel</pre>
</div>
</content>
</entry>
<entry>
<title>Bring the plugin API and the Gradle plugin from the legacy Tazel</title>
<updated>2026-11-12T15:52:50+00:00</updated>
<author>
<name>Leitwolf11</name>
</author>
<published>2026-11-12T15:52:50+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/tazel/commit/?id=6c7e9ad4e59c46da58a121d70caa17c01006273b'/>
<id>6c7e9ad4e59c46da58a121d70caa17c01006273b</id>
<content type='text'>
Tazel Plugins stay, built with Gradle and published to Tazel Portal.
The api/ (com.progmasoft.tazel:tazel-api) and gradle-plugin/
(com.progmasoft.tazel.plugin) projects come from Progmasoft/tazel-legacy
with their tests, with these changes:

- tazelPlugin { } holds group, name and version. The descriptor
  META-INF/tazel-plugin.properties records them first, so the JAR says
  who the plugin is; before, ViGet recorded the publisher, name and
  version at push time. The group must be a reversed domain of at least
  two parts (Tazel Portal checks the namespace by the Sonatype rules),
  the name letters, digits and _ . -, and the version a Semantic
  Version. The version of the Gradle project is not the plugin's.
- The API version starts again at 1, so plugins built for the legacy
  Tazel (API 3) are not loaded.
- Documentation no longer speaks of ViGet, Tala targets or
  tazel.tala.run; the site is tazel.net.
- Dependency locking of the legacy build is not carried over, like in
  the rest of this build.

The root build includes both projects, so ./gradlew check runs the
Gradle TestKit tests of the plugin as well.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Tazel Plugins stay, built with Gradle and published to Tazel Portal.
The api/ (com.progmasoft.tazel:tazel-api) and gradle-plugin/
(com.progmasoft.tazel.plugin) projects come from Progmasoft/tazel-legacy
with their tests, with these changes:

- tazelPlugin { } holds group, name and version. The descriptor
  META-INF/tazel-plugin.properties records them first, so the JAR says
  who the plugin is; before, ViGet recorded the publisher, name and
  version at push time. The group must be a reversed domain of at least
  two parts (Tazel Portal checks the namespace by the Sonatype rules),
  the name letters, digits and _ . -, and the version a Semantic
  Version. The version of the Gradle project is not the plugin's.
- The API version starts again at 1, so plugins built for the legacy
  Tazel (API 3) are not loaded.
- Documentation no longer speaks of ViGet, Tala targets or
  tazel.tala.run; the site is tazel.net.
- Dependency locking of the legacy build is not carried over, like in
  the rest of this build.

The root build includes both projects, so ./gradlew check runs the
Gradle TestKit tests of the plugin as well.
</pre>
</div>
</content>
</entry>
<entry>
<title>Bring Tazel Custom Commands and Tazel Options from the legacy Tazel</title>
<updated>2026-11-12T13:05:54+00:00</updated>
<author>
<name>Leitwolf11</name>
</author>
<published>2026-11-12T13:05:54+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/tazel/commit/?id=74c6d3b2e85cc51e5dde1bcccae581e23eae20df'/>
<id>74c6d3b2e85cc51e5dde1bcccae581e23eae20df</id>
<content type='text'>
The code and tests come from Progmasoft/tazel-legacy, with the packages
renamed so that the shared lexer sits beside both users:

- com.progmasoft.tazel.custom.commands        -&gt; com.progmasoft.tazel.dsl.custom
- com.progmasoft.tazel.custom.commands.lexer  -&gt; com.progmasoft.tazel.dsl.custom.lexer
- com.progmasoft.tazel.custom.commands.parser -&gt; com.progmasoft.tazel.dsl.custom.parser
- com.progmasoft.tazel.options                -&gt; com.progmasoft.tazel.dsl.options

tazel custom runs a command of the nearest tazel_custom.txt in the
directory of that file, or lists the commands; the name matching, &lt;N&gt;
and &lt;*&gt; arguments, the -- separator, s(...) shell steps (CMD on Windows,
sh elsewhere) and the strict-process check are those of the legacy
Tazel. tazel_options.txt is read as before: a sandbox asked for in any
file at or above the directory stops the command, since Tazel has no
MicroVM to start yet.

The process interface (driver.Processes) and the suggestions under
errors come along; program lookup on PATH is driver.Programs, the part
of the legacy Toolchain that is not about Tala tools. OperatingSystem
becomes the Os of the project files. An unknown command now gets a
"did you mean" hint.

The 33 legacy tests of these parts pass against a smaller fixture.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The code and tests come from Progmasoft/tazel-legacy, with the packages
renamed so that the shared lexer sits beside both users:

- com.progmasoft.tazel.custom.commands        -&gt; com.progmasoft.tazel.dsl.custom
- com.progmasoft.tazel.custom.commands.lexer  -&gt; com.progmasoft.tazel.dsl.custom.lexer
- com.progmasoft.tazel.custom.commands.parser -&gt; com.progmasoft.tazel.dsl.custom.parser
- com.progmasoft.tazel.options                -&gt; com.progmasoft.tazel.dsl.options

tazel custom runs a command of the nearest tazel_custom.txt in the
directory of that file, or lists the commands; the name matching, &lt;N&gt;
and &lt;*&gt; arguments, the -- separator, s(...) shell steps (CMD on Windows,
sh elsewhere) and the strict-process check are those of the legacy
Tazel. tazel_options.txt is read as before: a sandbox asked for in any
file at or above the directory stops the command, since Tazel has no
MicroVM to start yet.

The process interface (driver.Processes) and the suggestions under
errors come along; program lookup on PATH is driver.Programs, the part
of the legacy Toolchain that is not about Tala tools. OperatingSystem
becomes the Os of the project files. An unknown command now gets a
"did you mean" hint.

The 33 legacy tests of these parts pass against a smaller fixture.
</pre>
</div>
</content>
</entry>
<entry>
<title>Merge pull request #2 from Progmasoft/feature/labels-and-project-files</title>
<updated>2026-11-12T13:01:45+00:00</updated>
<author>
<name>Leitwolf</name>
</author>
<published>2026-11-12T13:01:45+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/tazel/commit/?id=0a37512d10792996402c21051c6ad58e4f5f506e'/>
<id>0a37512d10792996402c21051c6ad58e4f5f506e</id>
<content type='text'>
Read MODULE.kts and BUILD.kts, and resolve labels</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Read MODULE.kts and BUILD.kts, and resolve labels</pre>
</div>
</content>
</entry>
<entry>
<title>Read MODULE.kts and BUILD.kts, and resolve labels</title>
<updated>2026-11-12T04:46:46+00:00</updated>
<author>
<name>Leitwolf11</name>
</author>
<published>2026-11-12T04:46:46+00:00</published>
<link rel='alternate' type='text/html' href='https://git.progmasoft.com/tazel/commit/?id=3bffdc1d747a73ff83fab83f1a51b53c0ab507d9'/>
<id>3bffdc1d747a73ff83fab83f1a51b53c0ab507d9</id>
<content type='text'>
Tazel now reads the project files of the accepted DSL:

- Labels: //:x for the root BUILD.kts, //dir/:x for dir/BUILD.kts, :x for
  the same file, @name//:x for a dependency, and the patterns //dir/... and
  //... . The //dir shorthand is refused with a hint.
- MODULE.kts: module (name, SemVer version, description, authors, license),
  dependencies (implementation, testImplementation, localImplementation,
  localTestImplementation, with alias), viget (push, pushTarget, exclude),
  cache and execution. Duplicate dependency names, a push without version,
  description or author, and a pushTarget in a private BUILD.kts are errors.
- BUILD.kts: isPublic per file and c, cpp, objc, objcpp and zig targets,
  each with bin, staticlib, sharedlib and test. The scopes carry type
  markers of their language and kind, so a setting that one does not have
  (exports on a bin, args on a staticlib, a C standard on C++, arc on C,
  compiler on Zig, test settings on a bin, bundle on C++) is a compile
  error at its line in the project file.
- A target block runs for each triple and build mode it is built for; OS
  and ARCH come from the LLVM triple, BUILD_MODE from the command. Its
  depends are resolved: libraries only, visibility through isPublic, test
  dependencies for test targets only, paths kept inside the module.
- Directories starting with a dot and nested modules are not packages;
  file names are compared case-sensitively.

The tests load a reference module that uses every setting of the DSL and
configure each of its eleven targets for each triple and mode.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Tazel now reads the project files of the accepted DSL:

- Labels: //:x for the root BUILD.kts, //dir/:x for dir/BUILD.kts, :x for
  the same file, @name//:x for a dependency, and the patterns //dir/... and
  //... . The //dir shorthand is refused with a hint.
- MODULE.kts: module (name, SemVer version, description, authors, license),
  dependencies (implementation, testImplementation, localImplementation,
  localTestImplementation, with alias), viget (push, pushTarget, exclude),
  cache and execution. Duplicate dependency names, a push without version,
  description or author, and a pushTarget in a private BUILD.kts are errors.
- BUILD.kts: isPublic per file and c, cpp, objc, objcpp and zig targets,
  each with bin, staticlib, sharedlib and test. The scopes carry type
  markers of their language and kind, so a setting that one does not have
  (exports on a bin, args on a staticlib, a C standard on C++, arc on C,
  compiler on Zig, test settings on a bin, bundle on C++) is a compile
  error at its line in the project file.
- A target block runs for each triple and build mode it is built for; OS
  and ARCH come from the LLVM triple, BUILD_MODE from the command. Its
  depends are resolved: libraries only, visibility through isPublic, test
  dependencies for test targets only, paths kept inside the module.
- Directories starting with a dot and nested modules are not packages;
  file names are compared case-sensitively.

The tests load a reference module that uses every setting of the DSL and
configure each of its eleven targets for each triple and mode.
</pre>
</div>
</content>
</entry>
</feed>
