Skip to content

Instantly share code, notes, and snippets.

@xuhdev
Last active December 5, 2025 14:13
Show Gist options
  • Select an option

  • Save xuhdev/1873316 to your computer and use it in GitHub Desktop.

Select an option

Save xuhdev/1873316 to your computer and use it in GitHub Desktop.
# 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)
@nnop

nnop commented Aug 17, 2018

Copy link
Copy Markdown

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

@InspectorConstructor

Copy link
Copy Markdown

much appreciated! needed this in a pinch.

@nainesh1311

Copy link
Copy Markdown

What about header file ?

@xuhdev

xuhdev commented Aug 1, 2019

Copy link
Copy Markdown
Author

@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

dr-begemot commented Oct 2, 2019

Copy link
Copy Markdown

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

xuhdev commented Oct 2, 2019

Copy link
Copy Markdown
Author

@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

Copy link
Copy Markdown

@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

xuhdev commented Oct 3, 2019

Copy link
Copy Markdown
Author

$(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

Copy link
Copy Markdown

How to force your way accept include path -I?

@xuhdev

xuhdev commented Oct 28, 2019

Copy link
Copy Markdown
Author

ghost commented Jan 13, 2021

Copy link
Copy Markdown

can any one tell me how to add shared library in my main project make file

@dr-begemot

Copy link
Copy Markdown

can any one tell me how to add shared library in my main project make file

-l

for example:
gcc -w -Wall -g $(SRCS) -o test.exe $(FLAGS) -lsqlite3 -lcrypto -lconfig -lprotobuf-c -lcurl $(INCLUDE)

ghost commented Jan 19, 2021

Copy link
Copy Markdown

thanks for response

but one think i am not understanding actually i install embedded eclipse for windows when i create shared library output fill generated lib.so file as for my knowladge lib.so file generate base on linux system . why its happen like that

if i successfully generated library then where i add the this line

gcc -w -Wall -g $(SRCS) -o test.exe $(FLAGS) -lsqlite3 -lcrypto -lconfig -lprotobuf-c -lcurl $(INCLUDE)

in make
please consider the my attachment of make file

##########################################################################################################################
# File automatically-generated by tool: [projectgenerator] version: [2.27.0] date: [Sat Apr 28 17:58:48 IST 2018]
##########################################################################################################################

# ------------------------------------------------
# Generic Makefile (based on gcc)
#
# ChangeLog :
#	2017-02-10 - Several enhancements + project update mode
#   2015-07-22 - first version
# ------------------------------------------------

######################################
# target
######################################
TARGET = InfaLoraNodeRev1


######################################
# building variables
######################################
# debug build?
DEBUG = 1
# optimization
OPT = -Og


#######################################
# paths
#######################################
# source path
SOURCES_DIR =  \
Drivers/CMSIS \
Drivers/STM32L1xx_HAL_Driver \
Drivers \
InfaLibrary \
Application/User \
Application \

# firmware library path
PERIFLIB_PATH = 

# Build path
BUILD_DIR = build

######################################
# source
######################################
# C sources
C_SOURCES =  \


# ASM sources
ASM_SOURCES =  \
startup_stm32l152xe.s


######################################
# firmware library
######################################
PERIFLIB_SOURCES = 


#######################################
# binaries
#######################################
#BINPATH = usr/bin
#PREFIX = arm-none-eabi-
#CC = $(BINPATH)/$(PREFIX)gcc
#AS = $(BINPATH)/$(PREFIX)gcc -x assembler-with-cpp
#CP = $(BINPATH)/$(PREFIX)objcopy
#AR = $(BINPATH)/$(PREFIX)ar
#SZ = $(BINPATH)/$(PREFIX)size
#HEX = $(CP) -O ihex
#BIN = $(CP) -O binary -S

#BINPATH = E:\Rakesh.KS\ECLIPSE\GNU Tools ARM Embedded\7 2017-q4-major\bin
PREFIX = arm-none-eabi-
CC = $(PREFIX)gcc
AS = $(PREFIX)gcc -x assembler-with-cpp
CP = $(PREFIX)objcopy
AR = $(PREFIX)ar
SZ = $(PREFIX)size
HEX = $(CP) -O ihex
BIN = $(CP) -O binary -S
 
#######################################
# CFLAGS
#######################################
# cpu
CPU = -mcpu=cortex-m3

# fpu
# NONE for Cortex-M0/M0+/M3

# float-abi


# mcu
MCU = $(CPU) -mthumb $(FPU) $(FLOAT-ABI)

# macros for gcc
# AS defines
AS_DEFS = 

# C defines
C_DEFS =  \


# AS includes
AS_INCLUDES = 

# C includes
C_INCLUDES =  \
-IInc \

# compile gcc flags
ASFLAGS = $(MCU) $(AS_DEFS) $(AS_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections -mdivide-enabled

CFLAGS = $(MCU) $(C_DEFS) $(C_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections

ifeq ($(DEBUG), 1)
CFLAGS += -g -gdwarf-2
endif


# Generate dependency information
CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)"


#######################################
# LDFLAGS
#######################################
# link script
LDSCRIPT = STM32L152RETx_FLASH.ld

# libraries
LIBS = -lc -lm -lnosys 
LIBDIR = 
LDFLAGS = $(MCU) -specs=nano.specs -u _printf_float -T$(LDSCRIPT) $(LIBDIR) $(LIBS) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections

# default action: build all
all: $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).bin


#######################################
# build the application
#######################################
# list of objects
OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o)))
vpath %.c $(sort $(dir $(C_SOURCES)))
# list of ASM program objects
OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASM_SOURCES:.s=.o)))
vpath %.s $(sort $(dir $(ASM_SOURCES)))

$(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR) 
	$(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@

$(BUILD_DIR)/%.o: %.s Makefile | $(BUILD_DIR)
	$(AS) -c $(CFLAGS) $< -o $@

$(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) Makefile
	$(CC) $(OBJECTS) $(LDFLAGS) -o $@
	$(SZ) $@

$(BUILD_DIR)/%.hex: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
	$(HEX) $< $@
	
$(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
	$(BIN) $< $@	
	
$(BUILD_DIR):
	mkdir $@		

#######################################
# clean up
#######################################
clean:
	-rm -fR .dep $(BUILD_DIR)
  
#######################################
# dependencies
#######################################
-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)

# *** EOF ***

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment