Home > Enterprise >  /tmp/ccPxME98.o: in function `main':
/tmp/ccPxME98.o: in function `main':

Time:11-13

I have just learn about makefile and I want to write a makefile to build both file c and c . But when I try to make, the error is occurs. I'm sure about my code is run exactly because when I change main.cpp to main.c and make, it's built successfully. I'm glad to see your answer, thanks very much.
My directory struct

inc
  |_linked_list.h
src
  |_linked_list.c
  |_main.cpp
Makefile
makefile.mk

main.cpp

#include <bits/stdc  .h>
#include "linked_list.h"
using namespace std;

int main(){
    printf("Makefile\n");
    LList_create();
    LList_add(5);
    LList_add(9);
    LList_add(6);
    LList_add(4);
    Data_t find_list = LList_search(5)->data;
    Data_t after_list = LList_search(5)->next->data;
    printf("%d after %d\n", find_list, after_list);
    printf("remove data 4\n");
    printf("print list: ");
    LList_remove(4);
    LList_add(7);
    LList_print();
    printf("\n");
    
    return 0;
}

linked_list.h

#ifndef _LINKED_LIST_H
#define _LINKED_LIST_H

#include <stdint.h>
#include <stdio.h>

#ifdef __cplusplus
extern "C" {
#endif

typedef int32_t Data_t;


struct LinkedList
{
    Data_t data;
    struct LinkedList * next;
};
typedef struct LinkedList LList_t;


extern void LList_create(void);
extern void LList_add(Data_t dataInsert);
extern LList_t * LList_search(Data_t dataSearch);
extern void LList_remove(Data_t dataRemove);
extern LList_t * LList_headInfo(void);
extern void LList_print(void);


#ifdef __cplusplus
}  //extern "C"
#endif

#endif /* _LINKED_LIST_H */

Makefile


PRO_DIR     := .
PROJ_NAME   := gnu_build_cxcpp
BUILD       :=  build
$(shell mkdir -p $(BUILD))

BUILD_DIR   := $(PRO_DIR)/$(BUILD)
INC_DIR     := $(PRO_DIR)/inc
SRC_DIR     := $(PRO_DIR)/src

CC          := gcc
C99         := -std=c99
CFLAGS           = $(GDB_OPT) -Wall -c

CXX         := g  
CXX11       := -std=c  11
CXXFLAGS         = $(GDB_OPT) -Wall

GDB_OPT     := -g

#include
-include makefile.mk

SOURCE_C         = $(notdir $(SRC_C_PATH))
SOURCE_CXX       = $(notdir $(SRC_CXX_PATH))
OBJ      = $(patsubst %.c, $(BUILD_DIR)/%.o, $(SOURCE_C))
OBJ      = $(patsubst %.cpp, $(BUILD_DIR)/%.o, $(SOURCE_CXX))

TARGET  := $(BUILD_DIR)/$(PROJ_NAME)


.PHONY: all
all: $(TARGET)
    file $<
    @echo "finished."

$(TARGET): $(OBJ)
#   $(CC) $(C99) $^ -o $@
    $(CXX) $(CXX11) $^ -o $@
$(BUILD_DIR)/%.o: %.c
    $(CC) $(CFLAGS) $< -o $@

$(BUILD_DIR)/%.o: %.cpp
    $(CXX) $(CXXFLAGS) $< -o $@

    
run:
    $(TARGET)
debug:
    gdb $(TARGET)

.PHONY: clean
clean:
    rm -rf $(BUILD_DIR) folder
    @echo "Clean done"
    
print-%:
    @echo $($(subst print-,,$@))

makefile.mk

CFLAGS       = -I./inc
CXXFLAGS     = -I./inc

VPATH    = src
VPATH    = inc

# FILE .c
SRC_C_PATH       = src/linked_list.c

# FILE .cpp
SRC_CXX_PATH     = src/main.cpp

erro occurs:

g   -g -Wall -I./inc src/main.cpp -o build/main.o
/usr/bin/ld: /tmp/ccOdDhI3.o: in function `main':
/home/hung/Documents/coding/src/main.cpp:26: undefined reference to `LList_create'
/usr/bin/ld: /home/hung/Documents/coding/src/main.cpp:27: undefined reference to `LList_add'
/usr/bin/ld: /home/hung/Documents/coding/src/main.cpp:28: undefined reference to `LList_add'
/usr/bin/ld: /home/hung/Documents/coding/src/main.cpp:29: undefined reference to `LList_add'
/usr/bin/ld: /home/hung/Documents/coding/src/main.cpp:30: undefined reference to `LList_add'
/usr/bin/ld: /home/hung/Documents/coding/src/main.cpp:31: undefined reference to `LList_search'
/usr/bin/ld: /home/hung/Documents/coding/src/main.cpp:32: undefined reference to `LList_search'
/usr/bin/ld: /home/hung/Documents/coding/src/main.cpp:36: undefined reference to `LList_remove'
/usr/bin/ld: /home/hung/Documents/coding/src/main.cpp:37: undefined reference to `LList_add'
/usr/bin/ld: /home/hung/Documents/coding/src/main.cpp:38: undefined reference to `LList_print'
collect2: error: ld returned 1 exit status
make: *** [Makefile:48: build/main.o] Error 1

CodePudding user response:

Add a -c flag (compile only) to your %.o: %.c and %.o: %.cpp rules. Without it, the compiler does linking as well which you intended to do in a separate step.

I see that for .c you already have it in CFLAGS so it's technically missing only in CXXFLAGS but it's probably better to have it in the rule:

$(BUILD_DIR)/%.o: %.cpp
    $(CXX) $(CXXFLAGS) -c $< -o $@

CodePudding user response:

When you're attempting to build your object files, you're actually telling gcc to create an executable, not an object file. You need to add the -c option for that:

$(BUILD_DIR)/%.o: %.c
    $(CC) $(CFLAGS) -c $< -o $@

$(BUILD_DIR)/%.o: %.cpp
    $(CXX) $(CXXFLAGS) -c $< -o $@
  • Related