After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 572536 - Rework header file generation
Rework header file generation
Status: RESOLVED FIXED
Product: vala
Classification: Core
Component: Code Generator
0.5.x
Other All
: Normal major
: ---
Assigned To: Jürg Billeter
Vala maintainers
Depends on:
Blocks: 471244 472048 571037 572753 575629
 
 
Reported: 2009-02-20 10:04 UTC by Jürg Billeter
Modified: 2009-03-30 22:36 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Jürg Billeter 2009-02-20 10:04:02 UTC
From mailing list discussion http://mail.gnome.org/archives/vala-list/2009-January/msg00058.html

I want to finally solve issues we're having related to generation of C
header files. The current situation is that valac generates a .h file in
addition to a .c file for each .vala source file. The .h files describe
both, the public and the internal, C API.

There are various issues with the current approach:

 * Header file interdependencies
   Header files often depend on other header files and sometimes these
   dependencies form cycles. These cycles are currently detected by the
   compiler and resolved as far as possible - for example, by moving
   typedefs to other header files and reordering includes.

   While this works in many cases, there are situations that cannot be
   solved with the current approach, depending on what type you declare
   in what .vala file. There are also situations that could be solved
   with the current approach but are not implemented yet; it would
   complicate the code even further.

 * Internal API
   The whole point of an internal API is that it is internal, and we
   should therefore aim to separate public from internal header files.

 * Build performance
   As the internal API is in the header file as well, small changes can
   lead to a rebuild of the whole library or application. As the C
   compilation takes more time than the Vala compilation for larger
   projects, developers could profit from a vastly increased rebuild
   performance if we can solve this issue.

 * No single header file for users
   The trend in GLib-based libraries is to only provide a single header
   file per library for public use. The advantage is that it is easier
   to provide a stable include mechanism and provides more flexibility
   to the internal header organization of libraries.

   This is currently not directly supported by the Vala compiler,
   leading to extra work for people that want to provide that.

It is important that we find a permanent solution as changes to this can
lead to broken build systems, and I intend to finish upstream automake
integration as soon as we have a stable solution.

Possible solution steps and their issues:

 * Centralize type declarations
   Interdependencies only occur among type declarations (typedefs and
   struct declarations). If we move type declarations to a central
   place and include that before any function and global variable
   declarations, we solve the dependency issues. However, this change
   might decrease build performance, especially if we also do this for
   internal types.

 * Generate two sets of header files
   For each source file foo.vala, we could generate foo-priv.h in
   addition to foo.c and foo.h and move the internal C API there. One
   issue with this approach is that it clutters the source directory
   with even more files. The compiler will always have to generate all
   three files, even if some are empty, to not break build system
   integration.

 * Generate one additional header file for the internal API
   We could avoid generating many -priv.h by just generating one big
   foo-priv.h file that contains the full internal. However, in some
   projects you have a large internal API, for example, in applications
   without plugin support. This means that rebuild performance would get
   a lot worse.

 * Minimize use of header files
   A more radical approach would be to not use header files where not
   necessary. The Vala compiler could insert required declarations at
   the top of each generated .c file and only use include directives for
   external libraries. This would lead to optimal rebuild performance at
   the cost of a bit larger .c files.

   We obviously still need to support generating header files to use
   libraries written in Vala. I would propose to add an option -H foo.h
   to valac to generate a single header file with the full public C API.

I'm leaning towards the last solution as this solves all of the issues
mentioned above and should also provide the simplest way to integrate
into build systems such as automake. I can understand that some people
might not like that solution as it deviates from the traditional way how
you would do it in C. However, Vala is about practical solutions, not
traditions.
Comment 1 Jürg Billeter 2009-03-30 22:36:23 UTC
commit 2d4a4a264677b42710914907f63e1624e25e560f
Author: Jürg Billeter <j@bitron.ch>
Date:   Tue Mar 31 00:31:07 2009 +0200

    Rework header file generation
    
    Generate single C header file for public API, do not use header
    files for internal API. Fixes bug 471244, bug 571037, bug 572536,
    and bug 575629.