【问题标题】:Where to add the -lm flag within a makefile?在 makefile 中的何处添加 -lm 标志?
【发布时间】:2014-06-08 05:21:46
【问题描述】:

我正在尝试编译一个名为 COSI 的模拟程序: http://www.broadinstitute.org/~sfs/cosi/cosi_1.2.1.tar

使用tar xfp cosi_package.tar 解压缩后,我尝试按照新创建的目录cosi_1.2 中的自述文件中的说明运行make。不幸的是,我遇到了很多错误,例如

coalescent.a(historical.o): In function `historical_process_pop_event':
historical.c:(.text+0x5c7): undefined reference to `log'
coalescent.a(historical.o): In function `historical_next_exp':
historical.c:(.text+0x76a): undefined reference to `exp'
../cosi_rand/random.a(ranbinom.o):ranbinom.c:(.text+0x702): more undefined references to `log' follow
collect2: ld returned 1 exit status
make[1]: *** [coalescent] Error 1
make[1]: Leaving directory `/home/myname/Desktop/cosi_1.2/cosi'
make: *** [all] Error 2

有问题的子目录中的 MAKEFILE 如下所示:

PACKAGE := coalescent
BINFILES := coalescent.c
SKIPFILES := 
ARFILE := $(PACKAGE).a
BINS := $(BINFILES:.c=)
PREFILES := $(wildcard *.c)
CFILES := $(filter-out $(SKIPFILES),$(PREFILES))
LIBFILES := $(filter-out $(BINFILES),$(CFILES))
OFILES := $(LIBFILES:.c=.o)
DFILES := $(CFILES:.c=.d)
FOO := $(ARFILE)(
BAR := )
AFILES := $(addprefix $(FOO), $(OFILES))
AFILES := $(addsuffix $(BAR), $(AFILES))
CC := gcc
CFLAGS := $(DEBUG) -O3 -Wall -ansi

all : $(BINS)
#   rm *.d; rm *.o
install : $(BINS)
    rm *.d; rm *.o
.PHONY : cleaninstall
cleaninstall : 
    rm $(BINS)

$(ARFILE) : $(AFILES)
    $(AR) cr $(ARFILE) $(?:.c=.o)
    $(RM) $(?:.c=.o)

$(BINS) : % : %.o $(ARFILE)
    ranlib $(ARFILE)
    $(CC) $(CFLAGS) -lm -v -o $@ $@.o $(ARFILE) ../cosi_rand/random.a


%.d: %.c
    @$(SHELL) -ec '$(CC) -MM $(CPPFLAGS) $< \
                      | sed '\''s/\($*\)\.o[ :]*/coalescent.a(\1.o) $@ : /g'\'' > $@; \
                      [ -s $@ ] || rm -f $@'

-include $(DFILES)

显然,所有错误都缺少数学函数。因此,我尝试将-lm 添加到CFLAGS,但没有帮助。有什么建议吗?

【问题讨论】:

    标签: c gcc compiler-errors makefile


    【解决方案1】:

    -lm 是一个链接器标志。它应该出现在链接器命令的末尾:

    $(CC) -v -o $@ $@.o $(ARFILE) ../cosi_rand/random.a -lm
    

    显然一些编译器允许-l 出现在任何地方。我还没有发现哪些可以,但是我的 GCC 想要它们在最后,并且以相反的依赖顺序:如果 random.a 需要 libm,那么 libm 应该在 after 之后链接em>random.a.

    我还从链接器命令中删除了$(CFLAGS),因为在链接时您应该传递链接器选项,而不是编译器选项。

    【讨论】:

    • 非常感谢,它有效!也感谢您的解释,我想知道为什么在一个非常知名/经常使用的程序中出现问题......我在等待期后接受您的回答。
    【解决方案2】:

    链接器按照它们在命令行中的顺序搜索依赖项。因此,当您要求链接器与库链接(例如-lm)时,链接器将查看是否有任何依赖于库的内容。如果没有,则丢弃该库。

    为解决此问题,建议您始终将库放在所有源/目标文件之后。

    注意:这个依赖顺序也用在库之间,所以如果你有一个库 A 依赖于库 B,那么你需要在命令行中将 A 放在 B 之前。如果您有两个相互依赖的库,这当然会很困难。

    【讨论】:

      猜你喜欢
      • 2023-03-23
      • 1970-01-01
      • 1970-01-01
      • 2020-10-06
      • 2016-04-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-25
      相关资源
      最近更新 更多