View previous topic :: View next topic |
Author |
Message |
pjp Administrator
Joined: 16 Apr 2002 Posts: 20395
|
Posted: Mon Sep 23, 2024 6:22 am Post subject: improving Makefile object handling |
|
|
First the general question with some details, then the specific question and the rest of the details.
What is a better way to compile with all of the object files given the current structure and Makefile's handling of foobarbaz and fib objects?
The releveant Makefile snippet (whole file at the end): Code: | # EXE is the target 'main'.
# FBB_OBJ and FIB_OBJ generate their respective object files.
${EXE}: ${FBB_OBJ} ${FIB_OBJ} ${SRC}
${CC} ${CFLAGS} ${INC} -o ${EXE} ${SRC} ${FBB_OBJ} ${FIB_OBJ}
$(FBB_OBJ): obj/%.o: foobarbaz/%.c
${CC} ${CFLAGS} ${INC} -c $^ -o $@
$(FIB_OBJ): obj/%.o: fib/%.c
${CC} ${CFLAGS} ${INC} -c $^ -o $@ |
The specific question is in handling target EXE compilation when adding more *_OBJ dependencies. Yes I can add A_OBJ, ... ZZ_OBJ, but at some point that seems like the wrong solution.
The real project is for learning, so I don't know how many I'll have. The purpose of breaking them out into their own directories is for code organization and readability.
This currently works. Here is the output for clarity: Code: | $ ./main
[foobarbaz]
Fibonacci:
1 2 3 5 8 13 21 34 55 89 |
Given this layout: Code: | .
├── fib Next number in fibonacci series, from 1.
│ └── fib.c Static variables retain previous results.
├── foobarbaz Combines multiple strings, returns a struct string.
│ ├── bar.c Returns "bar".
│ ├── bar.h Declares function bar() for foobarbaz().
│ ├── baz.c Returns "baz".
│ ├── baz.h Declares function baz() for foobarbaz().
│ └── foobarbaz.c Combines foo, bar, baz, into a struct string.
├── inc "Public" api.
│ ├── fib.h Declares function next_in_fib() for main().
│ └── foobarbaz.h Declares function foobarbaz() for main().
├── main Executable
├── Makefile
├── obj
│ ├── bar.o
│ ├── baz.o
│ ├── fib.o
│ └── foobarbaz.o
└── src
└── main.c Calls foobarbaz() and loops next_in_fib(). | The makefile: Code: | CC := /usr/lib/llvm/18/bin/clang
C_STANDARD := c11
CFLAGS := -Wall -Wextra -std=$(C_STANDARD) -pedantic
INC_PATHS := ./inc
INC := $(addprefix -I,${INC_PATHS})
EXE := main
SRC := src/${EXE}.c
FBB_SRC := $(wildcard foobarbaz/*.c)
FBB_OBJ := $(patsubst foobarbaz/%.c, obj/%.o, $(FBB_SRC))
FIB_SRC := $(wildcard fib/*.c)
FIB_OBJ := $(patsubst fib/%.c, obj/%.o, $(FIB_SRC))
${EXE}: ${FBB_OBJ} ${FIB_OBJ} ${SRC}
${CC} ${CFLAGS} ${INC} -o ${EXE} ${SRC} ${FBB_OBJ} ${FIB_OBJ}
$(FBB_OBJ): obj/%.o: foobarbaz/%.c
${CC} ${CFLAGS} ${INC} -c $^ -o $@
$(FIB_OBJ): obj/%.o: fib/%.c
${CC} ${CFLAGS} ${INC} -c $^ -o $@
.PHONY: clean showvar
clean:
ifneq (,$(wildcard obj/*.o ${EXE}))
rm $(wildcard obj/*.o ${EXE})
endif |
I've spent about a week to get this far, pretty much from close to zero knowledge of how to use a Makefile. Around half of that time was getting the Makefile to work with something in it's own directory separate from src/, so I'm a bit slow on thoughts about it right now.
My first thought is to simply find a way to combine all of the *_OBJ variables into one used for the compilation. Something like: Code: | ALL_OBJ := ${A_OBJ} ... ${ZZ_OBJ} | But before I try that, I'm wondering if I'm going down a wrong path and should be doing something very different (Makefile, directory structure, something else).
Hopefully that makes sense and I didn't omit something important.
Thanks! _________________ Quis separabit? Quo animo? |
|
Back to top |
|
|
eschwartz Developer
Joined: 29 Oct 2023 Posts: 160
|
|
Back to top |
|
|
Zucca Moderator
Joined: 14 Jun 2007 Posts: 3632 Location: Rasi, Finland
|
Posted: Mon Sep 23, 2024 8:10 pm Post subject: |
|
|
Very informative site. Thanks! _________________ ..: Zucca :..
Gentoo IRC channels reside on Libera.Chat.
--
Quote: | I am NaN! I am a man! |
|
|
Back to top |
|
|
eschwartz Developer
Joined: 29 Oct 2023 Posts: 160
|
Posted: Mon Sep 23, 2024 8:13 pm Post subject: |
|
|
Yeah, it's by the author of GNU Make so as you can imagine it knows all the tricks. |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|