-1

Im trying to create a Makefile which compiles some files and creates some outputs but first I want it to execute the configuration only one time and the next time I type make it wont re-execute the configuration unless I change the parameters for example the prefix.

I tried using touch , FORCE and if, after searching a bit in other posts but Im newbie in gcc and Makefiles so I cant make it work.

My code now is (did not include the other rules because they dont affect the configuration):

XLEN := 32
RISCV_PREFIX := riscv$(XLEN)-unknown-elf-
RISCV_GCC := $(RISCV_PREFIX)gcc
CFLAGS := -O2
WORKING_DIR:= $(shell pwd)
LIBRARY_DIR:= $(abspath $(dir $(lastword $(MAKEFILE_LIST)))/..)
B := $(shell echo $(LIBRARY_DIR))
$(info $(B))

--->(execute this only once)---> CONFIGURATION := configure --prefix=$(LIBRARY_DIR) --with-arch=rv32if --with-abi=ilp32d

RISCV_TEST_DIR:=$(shell pwd)
SCRIPTDIR:=$(RISCV_TEST_DIR)/../../tools

RISCV_OPTIONS = -o  
RISCV_LINK = $(RISCV_GCC) $(PROGRAMS) $(RISCV_OPTIONS) $@ $(CFLAGS) #produces .elf file!
RISCV_OBJDUMP = $(RISCV_PREFIX)objdump -D                           #produces a dump file to see the assembly code!
RISCV_OBJCOPY = $(RISCV_PREFIX)objcopy -O binary                    #produces a bin file!

%.elf: %.c
    $(info Generating .elf file from files: $(PROGRAMS_NO_EX))
    $(RISCV_LINK)
    $(info Success!)
    $(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~)
%.dump: %.elf
    $(info Copying assembly to dump file $(PROGRAMS_NO_EX).dump)
    @$(RISCV_OBJDUMP) $< > $@
    $(info Success!)
    $(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~)
%.bin: %.elf
    $(info Generating bin file)
    @$(RISCV_OBJCOPY) $< $@
    $(info Success!)
    $(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~)
%.hex: %.bin 
    $(info Generating hex file)
    echo cd $(SCRIPTDIR)
    $(info Running binary to hex >>>)
    python $(SCRIPTDIR)/bin2hex.py $< -a 0x0 > $@ || exit -1
    $(info Hex Generation Successful!)
    $(info ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~)

all: $(PROGRAMS_TO_CREATE); if [ -a $(LIBRARY_DIR)/config.status ]; then cd $(LIBRARY_DIR) && $(CONFIGURATION); fi;

configure: config.status
    touch configure

config.status:
    cd $(LIBRARY_DIR) && $(CONFIGURATION);

.PHONY: all clean
clean:
    $(info Cleaning files...)
    @rm -rf *.elf *.hex *.map *.objdump *.i *.s *.bin *.dump
    $(info Done cleaning!)

Thank you in advance!

John Liko
  • 17
  • 5
  • you can't have two functions with the same name. simple. no exceptions. make sure that you have only one. (I am abstracting from the weak linkage but I do not think it the case here) – 0___________ May 24 '20 at 10:12
  • @P__J__: You can have multiple functions with the same name, including `main`, in separate programs. Note the name `ALL_PROGRAMS` rather than `ALL_SOURCE_FILES`. And OP says they want `make` to “[create] some outputs”, plural. OP is confused about using `make`, not asking how to build one C program. – Eric Postpischil May 24 '20 at 10:32
  • Your question does not show the rules that cause the source files to be compiled and linked. It also does not show the definition of `PROGRAMS_TO_CREATE ` or the command used to execute `make`. (Is it `make all` or something else?) Edit the question to show a [mre]. – Eric Postpischil May 24 '20 at 10:39
  • @EricPostpischil comment is just hilarious. Of course you can have same function names is different programs. Otherwise we would have a special function names register to avoid duplication and FNS (similar to DNS) – 0___________ May 24 '20 at 10:40
  • @P__J__: The point is you misinterpreted the question and thus wrote an irrelevant comment. OP is attempting to build multiple programs and is getting that error message because their make file is linking incorrectly everything together, not because they are trying to use multiple functions with the same name in one program. – Eric Postpischil May 24 '20 at 10:43
  • Most makefile problems can be tackled when you take a sheet of paper (or the electronic equivalent) and draw the tree of dependencies between your files and their output files. This is mainly what you teach make by the makefile. If you got that right, translate it to your makefile, and you're done. -- For example, to let the configuration only run once (for any given input dependency), think about some file that will be produced by it. – the busybee May 24 '20 at 11:13
  • @EricPostpischil Hello thank you for your answer. I updated the file so you can see it more clearly. – John Liko May 24 '20 at 16:38
  • @P__J__ Hello PJ. Thank you for your answer. Can you help me on how to compile all .c files together? – John Liko May 24 '20 at 16:39

2 Answers2

0

I believe the only problem with your configuration statements are incorrect paths in rules for config.status and configure, since they really will be located within $(LIBRARY_DIR). When the paths are correct, it will correctly run configuration only once:

$ cat Makefile
LIBRARY_DIR := library

all: $(LIBRARY_DIR)/config.status
        $(info Making $@)

$(LIBRARY_DIR)/config.status: $(LIBRARY_DIR)/configure
        cd $(<D) && ./$(<F)

Output:

$ make
cd library && ./configure
Making all

$ make            # <--- Invoking second time, no configure step
Making all
make: 'all' is up to date.
raspy
  • 3,995
  • 1
  • 14
  • 18
  • thank you for your answer! Seems I cant make it to work thought. Maybe Im still doing something wrong. This is what I have tried: all: $(PROGRAMS_TO_CREATE); $(LIBRARY_DIR)/config.status configure: config.status touch configure $(LIBRARY_DIR)/config.status: $(LIBRARY_DIR)/$(CONFIGURATION) cd $( – John Liko May 26 '20 at 13:57
  • Try to drop `;` from `all` target. Semicolon ends up dependency list and starts recipe. Probably your library would be needed before the programs are built, so it should say: `all: $(PROGRAMS_TO_CREATE)` and separately `$(PROGRAMS_TO_CREATE): $(LIBRARY_DIR)/config.status`. – raspy May 26 '20 at 14:01
  • now it says no rule to target library/configure needed by config.status. Hm.. will have to experiment a lot on this I guess or just execute the configuration on another Makefile? – John Liko May 26 '20 at 14:17
  • `LIBRARY_DIR` needs to be adjusted to your own library location, where your `configure` script resides. Above example is, well, an example. – raspy May 26 '20 at 14:19
  • The configure script is set on my PATH variable and it executes everywhere. I need to specify with --prefix the location where this library will be installed. AKA (LIBRARY_DIR) – John Liko May 26 '20 at 15:36
  • I managed to get it to work like this but it keeps executing on the wrong folder. Like it does not accept the cd command: all: $(PROGRAMS_TO_CREATE) $(PROGRAMS_TO_CREATE):$(LIBRARY_DIR)/config.status $(LIBRARY_DIR)/config.status: configure cd $( – John Liko May 26 '20 at 16:14
  • I solved it like this: Somehow the $( – John Liko May 26 '20 at 16:40
0

With @raspy's help managed to solve the problem like this:

all: $(PROGRAMS_TO_CREATE)
$(PROGRAMS_TO_CREATE):$(LIBRARY_DIR)/config.status

$(LIBRARY_DIR)/config.status: 
    cd $(LIBRARY_DIR) && $(CONFIGURATION)
John Liko
  • 17
  • 5