Search code examples
makefilegnu-makegnuautomakelibtool

GNU autotool:No rule to make target


my first question in stack overflow!

Quick overview of my question: I use autotool to generate a C program. When I use make command, I meet the error:

No rule to make target `../lib_foo/libfoo.a', needed by `mistery_foo'.  Stop.

Something detail of my questions:

I am doing an assignment of my teacher, in which I should use GNU autotool to generate a very simple C program.

File structure: /project: main, lib_foo, Makefile.am, configure.ac

/project/main: main.c, main.h, Makefile.am

/project/lib_foo: foo.c, foo.h, Makefile.am

Following is what I write for configure.ac and makefile.am:

I. "project/configure.ac":

AC_PREREQ([2.67])
AC_INIT([project1],[0.01],[cwentai01@gmail.com])
AM_INIT_AUTOMAKE([1.9 foreign])
AC_CONFIG_SRCDIR([./lib_foo/foo.c])
AC_CONFIG_HEADERS([config.h])
AC_PROG_CC
AC_PROG_RANLIB
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <mistery.h>]],\
                [[ mistery_value(1);]])],\
                [AC_DEFINE([MISTERY_VALUE_ONEPARAM], [],[CONSTANT])],[])
AC_SEARCH_LIBS([mistery_value],[magic vadoo mistery],[],[AC_MSG_ERROR([Libraries (mistery, magic, vadoo) not found])])
AC_CONFIG_FILES([Makefile  lib_foo/Makefile main/Makefile])
AC_OUTPUT 

P.S. the AC_COMPLIE_IFELSE is used to judge the number of the parameters in function mistery_value(). I think it has nothing to do with the error.

II. project/Makefile.am:

SUBDIRS = main lib_foo 

III. project/main/Makefile.am

LDADD = ../lib_foo/libfoo.a
mydir = ../uselessbin
my_PROGRAMS = mistery_foo
mistery_foo_SOURCES = main.c main.h
mistery_foo_LDADD = ../lib_foo/libfoo.a

IV. project/lib_foo/Makefile.am

noinst_LIBRARIES = libfoo.a
libfoo_a_SOURCES = foo.c foo.h

Then I run with the order of commands:

>cd project
> aclocal
> autoheader
> automake -a
> autoconf
> ./configure
> make
> make install
> ./uselessbin/mistery_foo

When I run make command, I got the error:

No rule to make target `../lib_foo/libfoo.a', needed by `mistery_foo'.  Stop.

I suppose the problem may be that I don't have libfoo.a properly installed. But the library libfoo.a should not be installed but only compiled so I have to use 'noinst_' in lib_foo/Makefile.am. That's why I get stucked here.

Any answers will be appreciated. Thanks for your help!


Solution

  • The problem is that you're using recursive automake, and in this case, dependencies crossing directory paths will just not resolve to extra rules: main/Makefile.am does not know how to make targets in lib_foo.

    The quick fix up is to change your SUBDIRS declaration in the top-level Makefile.am to:

    SUBDIRS = lib_foo main
    

    This way main/mystery_foo will only be built after lib_foo and its targets are built. Of course this does not allow you to just make in main/ and have it work.

    The other suggestion from the previous post, to use non-recursive automake is a more proper solution, because then all the dependencies can be resolved from a single Makefile.am.