Skip to content
/ vendored-v Public template

Vendor V, go from `cc` to `v *.v`.

Notifications You must be signed in to change notification settings

4KiB/vendored-v

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

26 Commits
 
 
 
 
 
 

Repository files navigation

Include V's source code with a project written in V.

On a new git clone, go from cc to v *.v. Call make to build tcc, libgc, and v without any downloads or prebuilt binaries.

The V compiler is written in V. It bootstraps by compiling the (standalone) .c output of an existing v binary, with the philosophy that C is the modern cross-platform assembly language.

Vendoring V also includes vlang's published translation to C (which is updated upstream by an automated process), the Tiny C Compiler, and the Boehm-Demers-Weiser garbage collector.

Vendoring tcc source addresses the TinyCC bootstrapping problem as well, assuming that cc is available on the host machine, a safe assumption for a language with a C/C++ audience, avoiding any method of prebuilt binary that excludes V's viability on non-prebuilt architectures that are supported by C.

While v is usable without tcc, V's sensibilities require it for faster compilation, which is especially important for the REPL and hot reloading.

With these tools in place, updating vendored V code can be more frequent than other vendored code, given that V rebuilds itself (with v self). It follows that the self-updating feature v up is disabled by a local patch, as suggested in V's doc on packaging v for OS distributions.

A .vendor file in the root of each src/vendor/ repository contains audit detail on the download of upstream files. This file is simple enough to update manually (or with git --git-dir=path/to/v/.git checkout .) and is simple enough for a small program to manage.* The format is the git remote URL at a given reference, followed by zero or more lines modifying the resulting clone.

https://github.com/{user}/{repo}.git@0c0ffee

-test
-tests
-*_test

+patch/

* As a result of vendoring, a tool to manage vendor files can be written in V.

Use # for comments. The ref is anything understood by git checkout. Lines beginning with - are to remove files and directories that match the given name. If the line contains a slash (/), then it is a relative path. Otherwise, it accepts simple * wildcards and is the equivalent of find|xargs where PATTERN is the line in .vendor without the leading -:

find . -name 'PATTERN' | xargs rm -r

When lines that begin with + contain a slash (/), they reference a relative path to copy into the project root. Otherwise, they reference a file or a directory of files:

patch/
  fix.patch
  build.sh
  path/to/override.txt
  another/path/0001.patch
  another/path/0002.patch

When referencing directories, the line can have an optional trailing slash for readability, i.e. +patch or +patch/. The directory layout mirrors that of the repository. Files ending in .patch apply within the listed directory, otherwise copy over as-is. If the reference is to a file and not a directory, then it is a relative path to copy into the project root.

Further, it's important to discard .git to (a) keep the resulting repository from getting too large and (b) avoid confusing git by nesting projects. The git-builtin feature of submodules does not achieve vendoring as it requires an internet connection and an online remote (with the repo still intact); git subtree remains relevant as an alternative.

Note that repositories have multiple .gitignore at various locations, and that git can track files that are otherwise ignored; such files need to be vendored.

The result of vendoring V is a repository that is 60MB, a factor of more than three less than upstream, having removed git history and project support files. This compresses down to a 9.7MB git archive, which is how much data is required on a git clone.

In this repository, V application code is at src/example/; v builds in place, resulting in example.v having its executable at src/example/example. Given that the executable is built in place, the src/example/.gitignore file contains the following, to ignore everything but .v files:

*
!*.v
!*/

The executable generated from .v code has dependencies typical to dynamically linked C, namely libc. Call make static to use V's -freestanding feature to build a binary that is less than 300kB, and leave the world behind.

This repository is laid out before introducing any of V's concepts of package management. A project using this template can add v.mod as needed.

Adhering to a vendor-everything policy allows for a project to build without external dependencies, which provides stability in any project but especially one built with a new programming language. A very significant (and profound) advantage is that the programming language implementation becomes transparent. Every feature is available for edit and rebuilds instantly. This allows for both local patches to v and patches intended for upstream.

Hacking the language is as natural as hacking the project that builds on it.

About

Vendor V, go from `cc` to `v *.v`.

Topics

Resources

Stars

Watchers

Forks