[Vala] Command-line options, input files, and header generation



Hello,
I couldn't find any good documentation on how Vala generates code in
response to the different input files and command-line options, so I
did some experiments and came up with the following results. This
information might be useful for others, so I though I'd share it.
Please correct me if I make any mistakes:

--header & --vapi options
 Vala produces a single .h or .vapi file with declarations for
everything maked "public" in the .vala input files.

--internal-header option
 Vala produces a single .h file with declarations for everything in
the .vala input files, including private class members.

--internal-vapi option
 Vala produces a single .vapi file with declarations for everything in
the .vala input files except private class members.

.vala input files
 Vala produces one .c file for every .vala input file. Each C file
begins with a section similar to --internal-header's output, but
limited to the symbols needed in that specific file. This makes each C
source file self-contained. After the header block, Vala generates
implementations for everything defined in the file. Vala does not
generate implementations for things marked "external."

.vapi input files
 Vala never produces any code for .vapi files, either in the generated
C files or in the --header, --vapi, --internal-header, or
--internal-vapi outputs. The only code Vala will generate from .vapi
files are #include statements corresponding to [CCode
(cheader_filename="file.h")] attributes. These #include statements
appear in the --internal-header ouput and in the generated C files.

Based on these facts, it looks like --header and --vala options are
designed to generate the external interface for a library written in
Vala. I am not completely sure what the --internal-header and
--internal-vapi options are for, but it seems like they allow large
Vala projects to be complied in smaller chunks rather than
all-at-once.

== Mixing C and Vala ==

Mixing C and Vala in a single module is possible, but not easy. The
obvious approach is to write the C normally and interface it with Vala
using a .vapi file. This does not work well. The first problem is that
Vala uses <> quotes in its #include statements rather than "" quotes,
causing the C compiler to search everywhere except the current
directory. Passing "-I." to the C compiler fixes this, so it is a
managable problem. The bigger issue is that Vala's --header and --vapi
options completely ignore .vapi files. Thus, if you are writing a
library with a mix of C and Vala, the automatically-generated
interface doesn't cover the whole thing. It seems that .vapi files are
only designed for interfacing with external libraries.

Another approach for interfacing C with Vala is to describe the C code
in a regular .vala file using the "extern" keyword. Because the
inteface description lives in a regular .vala file, the various header
generation options like --header, --vapi, and --internal-header work
correctly. Then, because the extern keyword prevents Vala from
generating implementations, the functions themselves can exist in a
separate C file. This approach is limited because Vala always
generates implementations for classes declared in .vala files, even
when they are marked extern. This limits the options for interfacing
Vala with legacy C code in a single library. It would be nice if
"extern class" prevented Vala from generating class implementations
and instead caused it to generate #include "c-header-name.h"
statements wherever that class is used (note the "" quote style
instead of <> here). This would allow Vala to interface seamlessly
with legacy C code in the same module.

Maybe there is some way of interfacing C with Vala that doesn't have
these problems, but I can't find it. If anybody knows of one, please
elighten me. :)

Anyhow, I hope these findings are helpful to others.

-William Swanson



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]