4

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
baedert
  • 73
  • 1
  • 6

2 Answers2

4

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.

ptomato
  • 56,175
  • 13
  • 112
  • 165
2

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.

Community
  • 1
  • 1
ldav1s
  • 15,885
  • 2
  • 53
  • 56
  • Well, foo.txt gets generated whenever b gets built (as I said). ```a``` depends on foo.txt because I pass it to the compiler in a command line argument (but that shouldn't matter?). – baedert Apr 27 '14 at 05:44
  • Ha, that seems to work (even for parallel builds!). I modified your example to use all the files in my project - now it looks like the valac command gets executed one for all files in the current directory and then again once for every file in each subdirectory (e.g. it gets executed 20 times for all the 20 files in src/util/ (so ./util)). Is there a way to prevent that? – baedert Apr 30 '14 at 18:50
  • I worked around the previous issue by just creating different Makefile.am's for every subdirectory. Now the less important issues are that: I need to list every project file twice (once in its subdir, once in the src dir because of the .vapi file) and that valac gets executed a little bit often sometimes (esp. with -jX). – baedert Apr 30 '14 at 19:26