Неразрешенный идентификатор G ++, не может найти ошибку компоновщика - PullRequest
0 голосов
/ 03 октября 2018

Я не уверен, является ли это ошибкой в ​​моем make-файле, заголовке или исходном коде, но похоже, что все соответствующие части кода должны красиво соединяться, чтобы я мог использовать функции из одного файла 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();
}

И make-файл (извините, он немного сложнее, чтобы лучше отразить, как работает мой общий проект):

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 голосов
/ 04 октября 2018

Во-первых, обратите внимание, что при попытке создать test используются только файлы test.cc и common.h.Код в test.cc вызывает функцию foo(), но эта функция не определена ни в одном из этих файлов;это определено в common.cc, который не был приглашен.И если вы попытаетесь исправить это, добавив common.cc или common.o к рецепту, у вас возникнут дополнительные проблемы, потому что common.cc содержит определение main(), как и test.cc, и можетбыть только одним.

Если вы хотите использовать foo() с другими версиями main(), вам не следует помещать main() в common.cc.

Теперь для рецепта make-файла:

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 $@

И дальнейшее улучшение возможно, как только у вас будет много работы.

...