Search code examples
cvala

How to use Vala objects/methods from C?


My application is entirely written in C at this point but I'd like to start adding objects in Vala for use in the various C files. I'm aware that I can generate the .c/.h files using valac and include those, but it would be preferable to include them into my automake setup as a source file.

This is trivial to go the other way, just write a vapi file for any of the .c/.h files and add that as a --pkg. Unfortunately it seems to be not as trivial for the way that I want to use.

The relevant additions that I've made nonetheless.

configure.ac:

AM_PROG_VALAC([0.12.0])

dnl Only adding these to test the package include in vala
OFS_PACKAGES="--pkg gee-1.0"
AC_SUBST(OFS_PACKAGES)

Makefile.am:

VALAFLAGS = \
    @OFS_PACKAGES@

src_ofs_SOURCES = \
    src/main.c \
    src/test.vala

src/main.c

#include "test.h"

...

FooTest *object = foo_test_new ();

src/test.vala:

using Gee;

namespace Foo {

    public class Test : Object {

        public Test () {
            stdout.printf ("Test construction\n");
        }
    }
}

When I run make I get the error

src/main.c:10:18: fatal error: test.h: No such file or directory

which is no surprise given that the call to valac didn't happen prior to the one to gcc. So the question is really whether or not there's a way to tell automake/make to have valac run first to generate the required files to include?

UPD:

Managed to get it to work using the following changes:

Makefile.am:

VALAFLAGS = \
    -H ofs.h -C -c
    @OFS_PACKAGES@

src_ofs_SOURCES = \
    src/test.vala \
    src/main.c

Solution

  • See http://www.gnu.org/software/automake/manual/automake.html#Built-Sources-Example.

    The easiest fix is to add test.h to BUILT_SOURCES:

    BUILT_SOURCES += src/test.h
    CLEANFILES += $(BUILT_SOURCES)
    

    You can get this expanded by putting your vala files in their own variable:

    src_ofs_VALASOURCES = $(filter %.valam,$(src_ofs_SOURCES))
    BUILT_SOURCES += $(src_ofs_VALASOURCES:.vala=.h)
    

    The alternative is to add it to nodist_ofs_SOURCES and to the dependencies of src/main.$(OBJEXT).