3
votes

so I currently have this weird problem with autotools. I have a target A that I list in bin_PROGRAMS (it's my primary target). I've split up my application into a main file with just the main function (target A) and everything else which gets built into a .la file that target A then uses (and the unit tests, but those aren't interesting in this case).

Now the interesting part: when compiling target B (the .la file), another file, say foo.txt gets generated (not a source file so I can't just list it in a_SOURCES). Now I want to tell automake that target A has a dependency to foo.txt. The "normal" way to do this would be a: foo.txt but if I do that, automake tells me to replace it with a$(EXEEXT), but that doesn't matter since both versions don't work. The outcome in this case is that A just never gets compiled. So, my current status is something like this:

bin_PROGRAMS = a

b_la_SOURCES = bar.h bar.c

foo.txt: b.la

a_SOURCES: main.c
a_LDADD: b.la
#won't work:
a$(EXEEXT): foo.txt

I'm kinda lost here, so any help would be appreciated.

EDIT: The above code was not an example per so, but here's the src/Makefile.am from a minimal testcase I just cooked up that has the same behavior:

# We need a .vapi and .h file from the generated .la
libproject_la_LIBADD = @PROJ_LIBS@
libproject_la_SOURCES = project.vala
# Generates both project.vapi and project.h
libproject_la_VALAFLAGS = --vapi=project.vapi --header project.h @PROJ_VALA_FLAGS@

#THIS
project.vapi: libproject.la



project_exec_SOURCES = main.vala
project_exec_LDADD = libproject.la @PROJ_LIBS@
#THIS
project_exec$(EXEEXT): project.vapi

#project_exec 'depends' on project.vapi
project_exec_VALAFLAGS = project.vapi @PROJ_VALA_FLAGS@



CLEANFILES = *.c *.h libproject.la project_exec

I'm essentially testing this by executing make clean && ./autogen.sh && make && rm src/project.vapi && echo "//foo" >> src/main.vala && make.

EDIT2: I got it to "work" with following hack:

project.vapi: libproject.la
    touch project.vala

the problem before was that libproject.la was not rebuilt because none of its source files changed (I guess). But this approach brakes as soon as someone uses -j2, so I'd like to know the real answer to this.

So with ldav1s' help, it works but the following src/Makefile.am shows that when using the above long make command, the valac rule gets executed 4 times (where 1 would be enough):

AM_CPPFLAGS = $(PROJ_CFLAGS) AUTOMAKE_OPTIONS = subdir-objects

bin_PROGRAMS = project_exec
noinst_LTLIBRARIES = libproject.la



dir_sources = project.vala
dir_c = $(dir_sources:.vala=.c)

sub_sources = sub/dep.vala sub/dep2.vala
sub_c = $(sub_sources:.vala=.c)

all_files = $(dir_sources) $(sub_sources)
all_c = $(dir_c) $(sub_c)


project.vapi project_header.h $(all_c): $(all_files)
    $(VALAC) -C -H project_header.h --vapi=project.vapi $^ @PROJ_VALA_FLAGS@

libproject_la_LIBADD = @PROJ_LIBS@
nodist_libproject_la_SOURCES = $(all_c)


# project_exec setup {{{
project_exec_SOURCES = main.vala
project_exec_LDADD = libproject.la @PROJ_LIBS@
project_exec_VALAFLAGS = project.vapi @PROJ_VALA_FLAGS@
main.vala: project.vapi
# }}}

CLEANFILES = *.c project.vapi project_exec *.o *.lo
2

2 Answers

3
votes

According to this page of the manual:

EXTRA_a_DEPENDENCIES = foo.txt

or in your case EXTRA_project_exec_DEPENDENCIES = project.vapi, should do what you want.

2
votes

There's nothing saying how foo.txt gets made to make in your example.

Something like:

foo.txt : b.la
        touch $@

might get you past this, but it's probably not correct for your build either. I don't see why a should depend on foo.txt.

EDIT: OK, now that's much better context. Thank you. This might work:

# Split compilation to get dependency processing correct for project.vapi
project.vapi project.c project.h : project.vala
        $(VALAC) $< --vapi=project.vapi -C -H project.h $(VALAFLAGS) @PROJ_VALA_FLAGS@

# Compile generated project.c and project.h
libproject_la_LIBADD = @PROJ_LIBS@
nodist_libproject_la_SOURCES = project.c project.h

project_exec_SOURCES = main.vala
project_exec_LDADD = libproject.la @PROJ_LIBS@
project_exec_VALAFLAGS = project.vapi @PROJ_VALA_FLAGS@

# main.vala depends on project.vapi
main.vala : project.vapi

CLEANFILES += $(nodist_libproject_la_SOURCES) project.vapi

This way project.vapi (AKA foo.txt) has a build step for make to execute which was lacking.