C3: Library packaging
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.