13-0-G
13-0-G

Reputation: 11

Makefile multiple definition error when adding extern variable

I'm having trouble with my makefile for a C project (I don't entirely know how to write makefiles...)

Here's a simple tree of my project folder:

_ Project
    |_ src
        |_ useful_func.c
        |_ useful_func.h
        |_ program_1.c 
        |_ program_1.h
        |_ program_2.c
        |_ program_2.h
        |_ main.c
        |_ main.h
        |_ ...
    |_ Makefile
    |_ ...

And we must have:

The Makefile I initially wrote worked quite well (added below in the end), until I added in useful_func.h a char* array as extern that both program_1 and program_2 need.

extern const char *foo[] = {..., ...};

Now, running make gives me this error:

/usr/bin/ld : 
   /tmp/ccChfBuI.o: path_to_project_folder/src/useful_func.h:7 : multiple definition of « foo »;
   /tmp/ccrNqPsJ.o: path_to_project_folder/src/useful_func.h:7 : defined the first time here 
collect2: error: ld returned 1 exit status
make: *** [Makefile:29 : program_1] Error 1

Despite making sure that each header file had:

#ifndef __HEADER_H__
#define __HEADER_H__
...
#endif

So I do not understand why this error occured, especially because all other #define seem to be okay, and how to fix this.

Here's my current Makefile (ain't optimal ofc):

CC := gcc
CFLAGS := -Wall
LDFLAGS := -lm -lpthread -g

USEFULE_FUNC = $(SRC_DIR)/useful_func.c
PROG_1 = $(SRC_DIR)/prog_1.c
PROG_2 = $(SRC_DIR)/prog_2.c
MAIN   = $(SRC_DIR)/main.c

SRC_DIR := src
TARGETS = prog_1 prog_2 main

.PHONY: all

all: $(TARGETS)

prog_1: $(USEFULE_FUNC) $(PROG_1)
    @$(CC) $(CFLAGS) -o $@ $(SRC_DIR)/[email protected] $(USEFULE_FUNC) $(LDFLAGS)

prog_2: $(USEFULE_FUNC) $(PROG_2)
    @$(CC) $(CFLAGS) -o $@ $(SRC_DIR)/[email protected] $(USEFULE_FUNC) $(LDFLAGS)

main: $(USEFULE_FUNC) $(PROG_1) $(PROG_2) $(MAIN) prog_1 prog_2
    @$(CC) $(CFLAGS) -o $@ $(SRC_DIR)/[email protected] $(USEFULE_FUNC) $(LDFLAGS)

clean:
    @$(RM) $(TARGETS)

Can someone help me please?

Upvotes: 0

Views: 204

Answers (1)

13-0-G
13-0-G

Reputation: 11

Question solved by Yeputons in comments:

extern const char *foo[] = {..., ...}; is a definition regardless of the extern keyword, not declaration. As you put it in a header, it's then copied to multiple .c files, hence multiple definition. You should remove the initialization in the header and initialize the variable in exactly one .c file.

You define it in useful_fun.c as const char *foo[] = {....}, and then declare it in useful_func.h as extern const char *foo[];

Upvotes: 1

Related Questions