G ++无法解析的标识符,找不到链接器错误

时间:2018-10-03 19:30:02

标签: c++ makefile g++

我不确定这是我的makefile,标头或源文件中的错误,但是看起来所有相关代码段应该都可以很好地链接起来,因此我可以使用另一个C ++文件中的函数,但是我正在撞墙。这是我正在使用的东西的简化版本:

common.h:

//common.h
#ifndef COMMON_H
#define COMMON_H

int foo();
#endif

common.cc:

//common.cc
#include "common.h"

int main(){
    int z = foo();
    return 0;
}//main

int foo(){
    int x = 5;
    int y = 7;
    return x + y;
}//foo

test.cc:

//test.cc

#include "common.h"

int main(){
    return foo();
}

和生成文件(抱歉,它有点复杂,以更好地反映我的整个项目的运行方式):

TARGETS = common test
FLAGS = -lpthread
DEPS = common.h

all: $(TARGETS)

common: common.cc $(DEPS)
    g++ $^ $(FLAGS) -g -o $@

test: test.cc $(DEPS)
    g++ $(FLAGS) $^ -g -o $@

clean::
    rm -fv $(TARGETS) *~

编译器似乎很高兴编译common.cc,但在test.cc上遇到无法解析的标识符错误:

  

g ++ -lpthread test.cc common.h -g -o test

     

/tmp/ccMwBGAj.o:在函数“ main”中:

     

/ home /...../ test.cc:6:对foo()的未定义引用

我在这里想念东西吗?

谢谢!

1 个答案:

答案 0 :(得分:2)

首先,请注意,当您尝试构建test时,使用的唯一文件是test.cccommon.htest.cc中的代码调用函数foo(),但是在任何一个文件中均未定义该函数。它是在common.cc中定义的,没有被邀请。而且,如果您尝试通过在配方中添加common.cccommon.o来解决此问题,则会遇到更多麻烦,因为common.cc包含main()的定义,依此类推test.cc,并且只能有一个。

如果要将foo()与其他版本的main()一起使用,则不应在main()中放置common.cc

现在制作makefile配方:

test: test.cc $(DEPS)
    g++ $(FLAGS) $^ -g -o $@

这扩展为:

test: test.cc common.h
    g++ -lpthread test.cc common.h -g -o test

如@NeilButterworth所指出的,这是不正确的。您可以这样做:

test: test.cc common.cc
    g++ test.cc common.cc -lpthread -g -o test

可以写为:

test: test.cc common.cc
    g++ $^ $(FLAGS) -g -o $@

但是如果更改common.h,那将无法重建,并且当它重建时,它可以重新编译未更改的源。更好的方法是:

common.o: common.cc $(DEPS)
    g++ -c $< -g -o $@

test.o: test.cc $(DEPS)
    g++ -c $< -g -o $@

common: common.o
    g++ $^ $(FLAGS) -o $@

test: test.o common.o
    g++ $^ $(FLAGS) -o $@

一旦您做了这么多的工作,就有可能进一步改善。