Skip to content

Instantly share code, notes, and snippets.

@xuhdev
Last active Aug 15, 2021
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)
@madmax440

This comment has been minimized.

Copy link

@madmax440 madmax440 commented May 8, 2015

does -O2 and -g can co exist?

@0x4C4A

This comment has been minimized.

Copy link

@0x4C4A 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 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 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 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 nnop commented Aug 17, 2018

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

@InspectorConstructor

This comment has been minimized.

Copy link

@InspectorConstructor InspectorConstructor commented Dec 17, 2018

much appreciated! needed this in a pinch.

@nainesh1311

This comment has been minimized.

Copy link

@nainesh1311 nainesh1311 commented Jul 30, 2019

What about header file ?

@xuhdev

This comment has been minimized.

Copy link
Owner Author

@xuhdev 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 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 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 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 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 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 xuhdev commented Oct 28, 2019

@singh667

This comment has been minimized.

Copy link

@singh667 singh667 commented Jan 13, 2021

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

@dr-begemot

This comment has been minimized.

Copy link

@dr-begemot dr-begemot commented Jan 13, 2021

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)

@singh667

This comment has been minimized.

Copy link

@singh667 singh667 commented Jan 19, 2021

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