# Generating the FFI library

We have installed gir, set up our repo and have all the `.gir` files we need. Now let’s work on the unsafe bindings of the -sys crate. Let’s change into the directory of the sys crate.

    cd pango/pango-sys

## The Gir.toml file

The first step is to let gir know what to generate. This is what the `Gir.toml` file that we created inside the `pango-sys` folder is for. This file will not be replaced when we run gir again. The file is currently empty so let’s add the following to it:

    [options]
    library = "Pango"
    version = "1.0"
    min_cfg_version = "1.0"
    target_path = "."
    girs_directories = ["../../gir-files/"]
    work_mode = "sys"
    single_version_file = true

- `library` stands for the name of the library we want to generate.
- `version` stands for the version of the library to be used.
- `min_cfg_version` will be the minimum version supported by the generated bindings.
- `target_path` stands for the location where the files will be generated.
- `girs_directories` stands for the location of the `.gir` files.
- `work_mode` stands for the mode gir is using. The options here are `sys` and `normal`.
- `single_version_file` is a very useful option when you have a lot of generated files (like we’ll have). Instead of generating the gir hash commit used for the generation in the header of all generated files, it’ll just write it inside one file, removing `git diff` noise a lot.

You can find out the values for `library` and `version` by looking at the name of the .gir file of your library. In our case it is called Pango-1.0.gir. This tells us that the `library` is Pango and the `version` is 1.0. If you don’t know what value to use for `min_cfg_version`, use the same as you use for `version`. If not all needed `.gir` files reside in `../../gir-files/`, you can add the path to the other files by changing `girs_directories`. If for example you also have `.gir` files in the root of your project folder, change it to `girs_directories = ["../../gir-files/", "../.."]`. Because we are generating the unsafe bindings, we use the `sys` work mode.

Let’s generate the `sys` crate now:

    gir -o .

You should now see new files and a new folder.

- `build.rs`
- `Cargo.toml`
- `Gir.toml`
- `src/lib.rs`
- `tests/`

Now let’s try to build it:

    cargo build

Surprise. It doesn’t build at all and you should see a lot of errors. Well, that was expected. We need to add some dependencies in order to make it work. Have a look at the errors of the compiler to find out which are missing. In our example, the compiler throws the following errors:

    use of undeclared crate or module `glib`
    use of undeclared crate or module `gobject`

The dependencies need to be added to the `external_libraries` part. The names of the dependencies are the same as in the .gir files and not what the packages to install the libraries might be called. The compiler told us that the `GLib` and the `GObject` dependencies are missing. Let’s update our `Gir.toml` file to fix it:

    [options]
    library = "Pango"
    version = "1.0"
    min_cfg_version = "1.0"
    target_path = "."
    girs_directories = ["../../gir-files/"]
    work_mode = "sys"

    external_libraries = [
        "GLib",
        "GObject",
    ]

If one of your .gir files changed or you want to use an updated version of gir to generate the code, there is no need to delete the Cargo.toml or the Cargo.lock files before you regenerate the code. Because we made some changes to the Gir.toml file, we have to run gir again. Changing the content of the external_libraries array means that additional dependencies have to be added. gir does this automatically for you, but only if there is no Cargo.toml and no Cargo.lock file present. Just remove the `Cargo.*` files and run gir again and the additional dependencies will be added. If you made any manual changes to the file, you would have to do these changes again. After regenerating the code, we build the crate to see if the errors are gone.

    rm Cargo.*
    gir -o .
    cargo build

When executing the above commands, there should not be any errors and everything should work fine. Just to be sure everything was correctly generated, we can run some tests (graciously generated by gir as well):

    cargo test

Normally, all tests passed. If you get an error when running those tests, it’s very likely that the `sys` generation is invalid and/or incomplete.

## The Gir.toml file

This file was automatically generated but it will not be replaced when we run gir again. Make sure to look at your Cargo.toml to optionally add more information to it. If there are any `[features]`, you should try building and testing with these features activated as well. If you’d like, you can also set the default features. This can be useful for example if you want to always activate the newest version unless the user of the crate specifies an older version.

For our example, we now have a working `sys` crate containing all functions and objects definition. We are done here and can go back to the folder of the wrapper crate:

    cd ..

Time to generate the high-level Rust API!