1

I'm making once which compiles some sort algorithms that i made.

I have a structure like this:

    |/sorting_algorithms  
    |----/bin  
    |----/build  
    |----/include  
    |--------tiempo.h
    |----/src  
    |--------bubble_sort.c  
    |--------enhanced_bubble_sort.c  
    |--------selection_sort.c  
    |--------insertion_sort.c  
    |--------shellsort.c  
    |--------heapsort.c  
    |--------tiempo.c
    |----makefile

And my makefile is like this:

    CC := gcc
    CFLAGS := -g -Wall
    SRCDIR := src
    BUILDDIR := build
    TARGETDIR := bin
    SRCEXT := c
    INC := -I include
    # need to create rhis object code,before binding code with objects to make the binaries
    TIME_CODE = tiempo.$(SRCEXT)
    TIME_OBJECT = $(BUILDDIR)/tiempo.o
    # get source list
    SOURCES := $(shell find $(SRCDIR) -type f -name *.$(SRCEXT))
    # create object list
    OBJECTS := $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%,$(SOURCES:.$(SRCEXT)=.o))
    # create target list
    TARGETS := $(patsubst $(BUILDDIR)/%,$(TARGETDIR)/%,$(OBJECTS:%.o=%))
    # it this is necesary?
    ALL: $(TIME_OBJECT) $(TARGETS)

    $(TIME_OBJECT):
        @mkdir -p $(BUILDDIR)
        $(CC) $(CFLAGS) $(SRCDIR)/$(TIME_CODE) -c $(INC) -o $(TIME_OBJECT)

    $(TARGETS): $(OBJECTS)
        @echo "$(CC) -o $@ $< $(TIME_OBJECT)"
        @$(CC) -o $@ $< $(TIME_OBJECT)

    $(BUILDDIR)/%.o: $(SRCDIR)/%.$(SRCEXT)
        @echo "$(CC) $(CFLAGS) $(INC) -c $< -o $@"
        @$(CC) $(CFLAGS) $(INC) -c $< -o $@

    clean:
        @echo "$(RM) -r $(BUILDDIR) $(TARGETDIR)/*"
        @$(RM) -r $(BUILDDIR) $(TARGETDIR)/*

    .PHONY: clean

[I use the tiempo.h library to measure time, thats why i use it with all]

So, when i compile with this, it is create correctly the object code, but at the time of creating the binaries, the automatic variable '$<' brings me only one value that is "build/bubble_sort.o", so it creates the same binary file but with diferent names, here is the output:

    gcc -g -Wall src/tiempo.c -c -I include -o build/tiempo.o
    gcc -g -Wall -I include -c src/bubble_sort.c -o build/bubble_sort.o
    gcc -g -Wall -I include -c src/enhanced_bubble_sort.c -o build/enhanced_bubble_sort.o
    gcc -g -Wall -I include -c src/heapsort.c -o build/heapsort.o
    gcc -g -Wall -I include -c src/insertion_sort.c -o build/insertion_sort.o
    gcc -g -Wall -I include -c src/selection_sort.c -o build/selection_sort.o
    gcc -g -Wall -I include -c src/shellsort.c -o build/shellsort.o
    gcc -o bin/bubble_sort build/bubble_sort.o build/tiempo.o
    gcc -o bin/enhanced_bubble_sort build/bubble_sort.o build/tiempo.o
    gcc -o bin/heapsort build/bubble_sort.o build/tiempo.o
    gcc -o bin/insertion_sort build/bubble_sort.o build/tiempo.o
    gcc -o bin/selection_sort build/bubble_sort.o build/tiempo.o
    gcc -o bin/shellsort build/bubble_sort.o build/tiempo.o
    gcc -o bin/tiempo build/bubble_sort.o build/tiempo.o

Also, if you could give me some tips to build the makefile, good practices or tell me what I could do to increase performance, I would be grateful.

Craig S. Anderson
  • 6,966
  • 4
  • 33
  • 46
Alejandro
  • 15
  • 6

1 Answers1

0

The rules for the binary targets are not specified correctly. It tells that all the binaries depend on all the objects, which is not right.

Also, $< is the first dependency. That's why the first object file gets included in the command to build every binary.

You can use $^, which stands for all the dependencies.

Instead of:

$(TARGETS): $(OBJECTS)
    @echo "$(CC) -o $@ $< $(TIME_OBJECT)"
    @$(CC) -o $@ $< $(TIME_OBJECT)

Use:

${TARGETDIR}/% : ${BUILDDIR}/%.o ${TIME_OBJECT}
    @$(CC) -o $@ $^
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • Oh, but how can i tell "ALL" target that it depends of ${TARGETDIR}/% ? – Alejandro May 10 '15 at 06:24
  • `$^` stands for all the prerequisites; `$?` stands for all of the prerequisites that are newer than the target. – Beta May 10 '15 at 17:10
  • Thanks, i have done it and it worked. But i have a doubt, why when i use "@$(CC) $(CFLAGS) $(INC) -c $< -o $@" to build the object code, the '$<' give me all the values of the list, so why when I create the binaries doesn't work? – Alejandro May 10 '15 at 21:47
  • @Alejandro, when you are compiling one file to build object code, the list of dependencies is just one file. It works by lucky coincidence. – R Sahu May 11 '15 at 02:50
  • Oh!, it works too, but thanks to everybody. Greetings. – Alejandro May 11 '15 at 04:28