Makefile - move object files

前端 未结 2 536
清酒与你
清酒与你 2021-01-06 14:45

After a bit of searching, I\'ve managed to throw together the following Makefile:

CC = gcc
CFLAGS = -c -Wall
LDFLAGS = 
SOURCEFILES = main.c
SOURCES = src/$(         


        
相关标签:
2条回答
  • 2021-01-06 15:29

    Something like this?

    SOURCES = src/main.c
    OBJECTS = obj/main.o
    
    ...
    
    obj/%.o: src/%.c
        $(CC) $(CFLAGS) $< -o $@
    

    Once that's working, you can add further tricks, like this:

    OBJECTS = $(patsubst src/%.c, obj/%.o, $(SOURCES)
    
    0 讨论(0)
  • 2021-01-06 15:31

    The trick is to not move your objects.
    You should build it and use it from where they are built.

    For example you have the following directory structure:

    $ tree .
    ├── Makefile
    ├── include
    │   └── common_head.h
    ├── obj
    └── src
        ├── foo.c
        └── main.c
    

    Manual execution:

    $ gcc -o ./obj/foo.o  -c ./src/foo.c  -I ./include  # Build Object #
    $ gcc -o ./obj/main.o -c ./src/main.c -I ./include
    $ gcc -o exe ./obj/foo.o ./obj/main.o               # Build Executable #
    

    Makefile to simulate the above

    C_FLAGS := -g -Wall -Wextra
    CC := gcc
    RM := rm
    LINKFLAGS := -lanylibrary
    
    .PHONY: $(TARGET)
    .PHONY: clean
    
    VPATH:= ./src/ ./obj/ ./include/
    
    # Path for .c , .h and .o Files 
    SRC_PATH := ./src/
    OBJ_PATH := ./obj/
    INC_PATH := -I ./include
    
    # Executable Name 
    TARGET := exe
    
    # Files to compile
    OBJ1 := foo.o \
            main.o
    
    OBJ := $(patsubst %,$(OBJ_PATH)%,$(OBJ1))
    
    # Build .o first
    $(OBJ_PATH)%.o: $(SRC_PATH)%.c
                    @echo [CC] $<
                    @$(CC) $(C_FLAGS) -o $@ -c $< $(INC_PATH)                  
    
    # Build final Binary
    $(TARGET):      $(OBJ)
                    @echo [INFO] Creating Binary Executable [$(TARGET)]
                    @$(CC) -o $@ $^ $(LINKFLAGS)
    
    # Clean all the object files and the binary
    clean:   
                    @echo "[Cleaning]"
                    @$(RM) -rfv $(OBJ_PATH)*
                    @$(RM) -rfv $(TARGET)
    

    So when you do a Make

    $ make -B
    [CC] src/foo.c
    [CC] src/main.c
    [INFO] Creating Binary Executable [exe]
    

    To see a dry-run use make -n

    $ make clean ; make -n
    g++ -g -Wall -Wextra -o obj/foo.o  -c src/foo.c  -I ./include
    g++ -g -Wall -Wextra -o obj/main.o -c src/main.c -I ./include
    g++ -o  exe  obj/foo.o obj/main.o -lanylibrary
    

    So after building your directory structure should look like this.

    $ tree .
    ├── Makefile
    ├── exe
    ├── include
    │   └── common_head.h
    ├── obj
    │   ├── foo.o
    │   └── main.o
    └── src
        ├── foo.c
        └── main.c
    

    So from my previous answer.
    You don't have to use any PHONY move and also no objects are recreated unnecessarily.

    0 讨论(0)
提交回复
热议问题