Skip to content

Instantly share code, notes, and snippets.

@xuhdev xuhdev/Makefile
Last active Oct 29, 2019

Embed
What would you like to do?
# Makefile template for a shared library in C
# https://www.topbug.net/blog/2019/10/28/makefile-template-for-a-shared-library-in-c-with-explanations/
CC = gcc # C compiler
CFLAGS = -fPIC -Wall -Wextra -O2 -g # C flags
LDFLAGS = -shared # linking flags
RM = rm -f # rm command
TARGET_LIB = libtarget.so # target lib
SRCS = main.c src1.c src2.c # source files
OBJS = $(SRCS:.c=.o)
.PHONY: all
all: ${TARGET_LIB}
$(TARGET_LIB): $(OBJS)
$(CC) ${LDFLAGS} -o $@ $^
$(SRCS:.c=.d):%.d:%.c
$(CC) $(CFLAGS) -MM $< >$@
include $(SRCS:.c=.d)
.PHONY: clean
clean:
-${RM} ${TARGET_LIB} ${OBJS} $(SRCS:.c=.d)
@DevNaga

This comment has been minimized.

Copy link

DevNaga commented May 8, 2015

does -O2 and -g can co exist?

@0x4C4A

This comment has been minimized.

Copy link

0x4C4A commented Jul 27, 2015

@DevNaga

does -O2 and -g can co exist?

From man gcc:

Unlike most other C compilers, GCC allows you to use -g' with-O'. The shortcuts taken by optimized code may occasionally produce surprising results: some variables you declared may not exist at all; flow of control may briefly move where you did not expect it; some statements may not be executed because they compute constant results or their values were already at hand; some statements may execute in different places because they were moved out of loops.

Nevertheless it proves possible to debug optimized output. This makes it reasonable to use the optimizer for programs that might have bugs.

tl;dr - yes it can.

@saqib-ahmed

This comment has been minimized.

Copy link

saqib-ahmed commented Feb 27, 2017

Can you please explain its working. I mean I can see that you have generated .o files and linked em together to make the .so. I want to know like step by step execution of this makefile. (I'm new to makefiles and bash, so you might want to elaborate $^, $< etc).

@Tibalt

This comment has been minimized.

Copy link

Tibalt commented Apr 16, 2017

There are tons information on google about Makefile. Please google by yourself. @saqibahmed515

@behnejad

This comment has been minimized.

Copy link

behnejad commented Aug 20, 2017

could you tell me how can i build static library with your Makefile? and how can i specify a special directory for .d and .o files.

@nnop

This comment has been minimized.

Copy link

nnop commented Aug 17, 2018

Better using -MMD -MP for dependencies auto-generation.

@InspectorConstructor

This comment has been minimized.

Copy link

InspectorConstructor commented Dec 17, 2018

much appreciated! needed this in a pinch.

@nainesh1311

This comment has been minimized.

Copy link

nainesh1311 commented Jul 30, 2019

What about header file ?

@xuhdev

This comment has been minimized.

Copy link
Owner Author

xuhdev commented Aug 1, 2019

@nainesh1311 You don't need to add them to the Makefile, because we should only send source files directly to the compiler and the compiler will find header files automatically.

@dr-begemot

This comment has been minimized.

Copy link

dr-begemot commented Oct 2, 2019

Fix
$(SRCS:.c=.d):%.d:%.c
to
$(SRCS:.c=.o):%.o:%.c

And...
Why do you use the -MM option if you don’t have an entry point in `$(SRCS:.c=.d)? Where you using .d file?
https://renenyffenegger.ch/notes/development/languages/C-C-plus-plus/GCC/options/MM

$(CC) $(CFLAGS) -MM $< >$@ create some .d files

@xuhdev

This comment has been minimized.

Copy link
Owner Author

xuhdev commented Oct 2, 2019

@dr-begemot $(SRCS:.c=.d):%.d:%.c is correct. The *.d files are used in the include line. $(SRCS:.c=.o):%.o:%.c is not needed because they are subsumed by the content of *.d files. In your link, there is an example that states main.d contains:

main.o: main.c hello-world.h print-line.h

which is exactly what your "correction" tries to add (with header files also taken care of).

@dr-begemot

This comment has been minimized.

Copy link

dr-begemot commented Oct 3, 2019

@xuhdev
okay, then where entry point to
$(SRCS:.c=.d):%.d:%.c
?

You wrote: $(TARGET_LIB): $(OBJS)
where OBJS is $(SRCS:.c=.o), .c=.o, not .c=.d

I really want to understand)

@xuhdev

This comment has been minimized.

Copy link
Owner Author

xuhdev commented Oct 3, 2019

$(SRCS:.c=.d):%.d:%.c is used to generate *.d files.

$(SRCS:.c=.o) are expressed in the generated *.d files. (Try to use this template in a minimum project and inspect the generated *.d files yourself.) I can write a post explaining this template, but I will not be able to do it until weekend.

@dr-begemot

This comment has been minimized.

Copy link

dr-begemot commented Oct 3, 2019

How to force your way accept include path -I?

@xuhdev

This comment has been minimized.

Copy link
Owner Author

xuhdev commented Oct 28, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.