gcc не разрешает внешние глобальные переменные с параметром -c или без него

Итак, у меня есть эта проблема: я объявляю некоторые внешние глобальные переменные в своей программе C. Если я не использую параметр -c для gcc, я получаю ошибки неопределенных ссылок. Но с этой опцией -c связывание не выполняется, что означает, что у меня не сгенерирован исполняемый файл.

Итак, как мне решить эту проблему?

Вот мой makefile (спасибо Алексу)

CC = gcc                      # compiler/linker frontend
INCL = -I$(INCL_DIR)          # includes
DEFS = -D_DEBUG_              # defines
CFLAGS = -g $(INCL) $(DEFS)   # compiler flags
LFLAGS = -lpthread -lm -g     # linker flags

OBJ = approx.o producteur.o sequentialApproximation.o main.o
BIN = calculPi.exe
LINKOBJ  = approx.o producteur.o sequentialApproximation.o main.o
RM = rm -fv

all: $(BIN)

clean:
 ${RM} *\~ \#*\# $(OBJ)

clean_all: clean
 ${RM} $(BIN)

cleanall: clean
 ${RM} $(BIN)

$(BIN): $(OBJ)
 $(CC) $(LFLAGS) -o $@ $^

main.o: main.c
approx.o: approx.c approx.h
producteur.o: producteur.c producteur.h
sequentialApproximation.o : sequentialApproximation.c sequentialApproximation.h

.c.o:
 $(CC) $(CFLAGS) -c $<

А вот результат make: http://pastebin.com/NzsFetrn

Я объявлял внешние переменные в приблизительно.h (внешние и глобальные) и пытаюсь вызывать их в приблизительно.с, и там это не работает.


person MounirReg    schedule 08.05.2010    source источник
comment
Вы можете удалить переменную LINKOBJ, она избыточна. Вам нужно определить свои переменные, просто объявить их extern недостаточно.   -  person Alex Budovski    schedule 09.05.2010


Ответы (1)


Решение 1

Вы не можете передать -c на этапе компоновки, так как это скажет компилятору пропустить компоновку.

Ваша проблема

$(BIN): $(OBJ)
    $(CXX) $(LINKOBJ) -o "calculPi.exe"

с участием

CXX_FLAGS =-g -c -lpthread -lm

где $(CXX) расширяется до gcc -g -c -lpthread -lm ...

избавиться от -c там.

Передавайте -c только при компиляции из исходного кода в объектные модули.

Решение 2

Что касается второй проблемы, вы фактически нигде не определяете переменные. В вашем файле .c вам нужны строки:

Coord* production;
int indice_prod;
int indice_cons;

(Предполагая, что вам действительно нужны глобальные переменные). Это устранит неразрешенную внешнюю ошибку. Вы не можете писать им, пока они не будут выделены!

Примечания

Также обратите внимание, что вы можете указать, как создавать объектные файлы из исходного кода в одном правиле:

.c.o:
    $(CC) $(CFLAGS) -c $<

и указать зависимости без правил:

main.o: main.c
approx.o: approx.c approx.h
producteur.o: producteur.c producteur.h
sequentialApproximation.o : sequentialApproximation.c sequentialApproximation.h

и т.п.

Другие примечания.

Кроме того, как правило, CXX должно содержать только имя компилятора, а не флаги. Они должны идти в CXX_FLAGS. И почему вы называете его CXX, а не CC? Используйте g++, если вам нужен компилятор C++, или используйте CC. Поскольку у вас есть файлы .c, я предполагаю, что C. Итак, в вашем случае вы должны изменить:

CXX_FLAGS =-g -c -lpthread -lm
CXX = gcc $(CXX_FLAGS) $(INCL) $(DEFS)

to

CC = gcc
CFLAGS = -g -lpthread -lm $(INCL) $(DEFS)  # also removed -c

И вам не нужен отдельный LINK_CXX.

Пример Makefile

Таким образом, минимальный Makefile должен выглядеть так:

# Makefile
CC = gcc                      # compiler/linker frontend
INCL = -I$(INCL_DIR)          # includes
DEFS = -D_DEBUG_              # defines
CFLAGS = -g $(INCL) $(DEFS)   # compiler flags
LFLAGS = -lpthread -lm -g     # linker flags

OBJ = approx.o producteur.o sequentialApproximation.o main.o
BIN = calculPi.exe

all: $(BIN)

$(BIN): $(OBJ)
    $(CC) $(LFLAGS) -o$@ $^

main.o: main.c
approx.o: approx.c approx.h
producteur.o: producteur.c producteur.h
sequentialApproximation.o : sequentialApproximation.c sequentialApproximation.h

.c.o:
    $(CC) $(CFLAGS) -c $<

# clean and other stuff.
person Alex Budovski    schedule 08.05.2010
comment
Привет, Алекс, спасибо, что помог мне. О том, как построить объект по одному правилу: .c.o: $(CC) $(CFLAGS) -c это правильно? Он говорит, что отсутствует разделитель (опять же, извините, я очень плохо пишу make-файлы и не умею компилировать код на C). Кроме того, когда я избавляюсь от -c в правиле $(BIN), у меня все еще есть неопределенные ссылки назад! - person MounirReg; 08.05.2010
comment
Я не называл это CXX, как я уже сказал, я взял существующий make-файл, который я отредактировал, я попробую это и дам вам знать Еще раз спасибо - person MounirReg; 08.05.2010
comment
На самом деле я буду занят сегодня днем, поэтому я попробую это завтра :) Еще раз спасибо за вашу любезную помощь! - person MounirReg; 08.05.2010
comment
Итак, вот новый make-файл pastebin.com/u4pJKJKt Вот результат make: pastebin.com/NzsFetrn Неопределенные ссылки — это глобальные внешние переменные, которые я объявляю в приблизительно.h и которые я устанавливаю в приблизительно.c (и которые я придется использовать в producteur.c) - person MounirReg; 09.05.2010
comment
@Moons, где определяется indice_prod? И отредактируйте свой исходный вопрос в идеале. (И уберите переменную LINKOBJ, она вам не нужна) - person Alex Budovski; 09.05.2010
comment
@Moons, покажите, как indice_prod и др. определены. Их явно нет в approx.o - person Alex Budovski; 09.05.2010
comment
Вот примерно.c: pastebin.com/TZw5jHWj Вот примерно.h: pastebin.com/qjbRvH03 (я не могу выкладывать их в основной пост, моя репутация недостаточно высока :) ) - person MounirReg; 09.05.2010
comment
Когда я устанавливаю значение для indice_prod в прибл.ч, я получаю следующую ошибку: множественное определение indice_prod! Это странно! - person MounirReg; 09.05.2010
comment
@Moon, проблема в том, что ты не зарезервировал место для этих переменных. Вы должны определить переменную где-нибудь (не в заголовке!). Например. в прим.с напишите int indice_prod; и так же для остальных. (Предполагая, что вы действительно хотите, чтобы эти переменные были глобальными). Никогда не определяйте переменные в заголовке. Extern в порядке (поскольку он их не определяет). Я отредактирую свой ответ. - person Alex Budovski; 09.05.2010
comment
Спасибо за ответ, компилируется. Итак, теперь, когда я добавил строки в .c, я могу использовать их в любом другом .c ?? Я не знал, что мне нужно было написать эти 3 строки, но когда я включил .h, это справилось бы со своей задачей! Что ж, я рад, что снова могу работать над этой школьной работой, спасибо. - person MounirReg; 09.05.2010
comment
@Moon, да, вы можете использовать их в других файлах C. - person Alex Budovski; 09.05.2010