GNU autotool:没有规则来制定目标

Posted

技术标签:

【中文标题】GNU autotool:没有规则来制定目标【英文标题】:GNU autotool:No rule to make target 【发布时间】:2017-01-21 22:32:44 【问题描述】:

堆栈溢出我的第一个问题!

快速概述我的问题:我使用 autotool 生成 C 程序。当我使用 make 命令时,我遇到了错误:

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

一些细节我的问题:

我正在做老师的作业,我应该使用 GNU autotool 生成一个非常简单的 C 程序。

文件结构:/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

以下是我为 configure.ac 和 makefile.am 编写的内容:

我。 “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 

附: AC_COMPLIE_IFELSE 用于判断函数 misery_value() 中的参数个数。我认为这与错误无关。

二。 项目/Makefile.am

SUBDIRS = main lib_foo 

三。 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

四。 project/lib_foo/Makefile.am

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

然后我按照命令的顺序运行:

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

当我运行 make 命令时,我得到了错误:

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

我想问题可能是我没有正确安装 libfoo.a。但是库 libfoo.a 不应该安装,而只能编译,所以我必须在 lib_foo/Makefile.am 中使用“noinst_”。这就是我被困在这里的原因。

任何答案将不胜感激。 感谢您的帮助!

【问题讨论】:

【参考方案1】:

问题在于您使用的是递归自动生成,在这种情况下,跨目录路径的依赖项将无法解析为额外的规则:main/Makefile.am 不知道如何在lib_foo 中生成目标。

快速解决方法是将***Makefile.am 中的SUBDIRS 声明更改为:

SUBDIRS = lib_foo main

这样main/mystery_foo 将仅在lib_foo 及其目标构建后构建。当然,这不允许您只在 main/ 中使用 make 并让它工作。

上一篇文章的另一个建议是使用non-recursive automake 是一个更合适的解决方案,因为这样所有的依赖关系都可以从单个Makefile.am 解决。

【讨论】:

【参考方案2】:

您的程序看起来几乎完全正常。我刚刚发现了一些可能的错误

    您的 configure.ac 应该有 LT_INIT 指令 在 project/main/Makefile.am 中,我会将 ../lib_foo/libfoo.a 更改为 libfoo.a 如果前一个不起作用,我建议使用单个 Makefile.am 而不是递归 Makefile.am(递归 Makefile.am 可能更难编码,可能会损害编译性能)

【讨论】:

我想知道为什么我会被否决吗,留下反馈通常是一种习惯 :) 嘿 Vicente,我已经解决了这个问题。问题是在 project/src/Makefile.am 中,我在“lib_foo”之前设置了子目录“main”。所以make会在“lib_foo”之前处理“main”。但事情在 src/main/main.c 我需要使用由 src/lib_foo/foo.c 生成的“libfoo.a”。所以我像“SUBDIRS = lib_foo main”一样修改了project/src/Makefile.am,它可以工作。感谢您的帮助,顺便说一下,我不知道为什么这里有反对票,不是我:(

以上是关于GNU autotool:没有规则来制定目标的主要内容,如果未能解决你的问题,请参考以下文章

GNU Autotools:在没有版本信息的情况下重建

GNU make:规则专题

已经存在的“没有制定目标的规则”

GNU autotools自动生成Makefile 介绍

gnu autotools

gnu autotools