Packaging libraries is fairly straight forward. A library package
can be either “packed” or “unpacked” e.g. just a directory
or an archive file named mylib.c3l
. When distributing
packages the latter option probably makes the most sense.
Let’s now look at how we can take the library from previous post and turn it into a package.
Creating a library project #
From the project root, navigate to lib
directory and initialize a new library package.
cd lib
c3c init-lib mylib
this will create a directory mylib.c3l
with the following contents.
/mylib.c3l
├── LICENSE
├── README.md
├── android-aarch64
├── freebsd-x64
├── linux-aarch64
├── linux-riscv32
├── linux-riscv64
├── linux-x64
├── linux-x86
├── macos-aarch64
├── macos-x64
├── manifest.json
├── mylib.c3i
├── netbsd-x64
├── openbsd-x64
├── scripts
├── wasm32
├── wasm64
├── windows-aarch64
└── windows-x64
Move or copy the static library from the previous post
into to the directory of your target platform. In my case that’s freebsd-x64
.
mv libmylib.a mylib.c3l/freebsd-x64/
Now we need edit the mylib.c3i
file so that it contains our
Point
struct and add_point
declaration from before.
module mylib;
struct Point
{
int x;
int y;
}
extern fn void point_add(Point* a, Point* b, Point* dest);
A .c3i
file is essentially like a .h
file from C.
Now we need to edit the manifest.json
file. Find your
target platform and edit the linked-libraries
field
to look like this.
"freebsd-x64" : {
"link-args" : [],
"dependencies" : [],
"linked-libraries" : [ "mylib", "c" ]
},
You should now have roughly the following project structure.
Where freebsd-x64
is replaced with whatever platform you are on.
myproject
├── LICENSE
├── README.md
├── docs
├── lib
│ └── mylib.c3l
│ ├── freebsd-x64
│ │ └── libmylib.a
│ ├── manifest.json
│ └── mylib.c3i
├── project.json
├── resources
├── scripts
└── src
└── main.c3
Using the package #
Edit the project.json
file and add "mylib"
to the list of dependencies and remove the
linked-libraries
and linker-search-paths
lines that we added previously.
{
"langrev": "1",
"warnings": [ "no-unused" ],
"dependency-search-paths": [ "lib" ],
"dependencies": [ "mylib" ],
"authors": [ "John Doe <john.doe@example.com>" ],
"version": "0.1.0",
"sources": [ "src/**" ],
"test-sources": [ "test/**" ],
"output": "build",
"targets": {
"c3_cinterop": {
"type": "executable",
},
},
"cpu": "generic",
"opt": "O0",
}
Import mylib
in main.c3
import std;
import mylib;
fn int main()
{
Point a = { 1, 1 };
Point b = { 1, 2 };
Point c = {};
mylib::point_add(&a, &b, &c);
io::printfn("x: %d, y: %d", c.x, c.y);
return 0;
}
Let’s run it!
c3c run
If all goes well you should get the following output
x: 2, y: 3
From here you could improve the library by adding a c3
source-file
with some wrapper functions if you wish. I’ll leave this as an exercise
for the reader :^)
Getting existing C3 libraries #
A repository of libraries can found at github.com/c3lang/vendor, to install any of these libraries in your project simply run
c3c vendor-fetch <library-name>
Note: The vendor libraries may or may not be in sync with the latest version of the compiler.