Play Makefile | Enterprise Project Makefile Example

1 Introduction
This tutorial shows a relatively complete enterprise project-level Makefile, including: version number, dynamic library, macro definition, etc.

2. Program display
The program directory structure of this routine is often seen in enterprise projects, that is: all .c files are placed in a src directory, all .h files are placed in a .h directory, and the generated targets are placed in an output directory independently (Dynamic generation).

      The source code can be obtained from here .

The directory structure is as follows:
The source program is:
//fun1.h
void fun1();


//fun1.c
void fun1()
{
	printf("this is fun1\n");
}


//fun2.h
void fun2();


//fun2.c
void fun2()
{
	printf("this is fun2\n");
}


//dylib.h
void dynamic_lib_call();


//main.c
intmain()
{
	printf("hello world\n");
	fun1();
	fun2();

#ifdef _MACRO
	printf("macro test\n");
#endif
	dynamic_lib_call();
}
The Makefile is:
VERSION = 1.0.0 #Program version number

SOURCE = $(wildcard ./src/*.c) #Get all .c files
OBJ = $(patsubst %.c, %.o, $(SOURCE)) # Convert .c files to .o files
INCLUDES = -I./h #Header file path

LIBS = -ldylib #Library file name
LIB_PATH = -L./lib #Library file address

DEBUG = -D_MACRO #macro definition
CFLAGS = -Wall -c #Compile flags

TARGET = app
CC = gcc

$(TARGET): $(OBJ)	
	@mkdir -p output/ #Create a directory to store compiled targets
	$(CC) $(OBJ) $(LIB_PATH) $(LIBS) -o output/$(TARGET).$(VERSION)

%.o: %.c
	$(CC) $(INCLUDES) $(DEBUG) $(CFLAGS) $< -o $@

.PHONY: clean
clean:
	rm -rf $(OBJ) output/
Library file description:
The name of the library file is libdylib.so, and there is only one function in it: dynamic_lib_call(), which outputs a sentence: this is a function in dynamic library.

3. Contents of Makefile
3.1 Program version
In the process of software development, multiple versions of programs are generated, and a version number suffix is ​​usually added to the end of the program.
VERSION = 1.0.0 #define
$(CC) $(OBJ) $(LIB_PATH) $(LIBS) -o output/$(TARGET).$(VERSION)	#使用
3.2 Header files
Since the .c file is separated from the .h file in a different directory, the header file path should be specified.
INCLUDES = -I./h
3.3 Macro Definition
In the process of code debugging, we usually add a macro definition to control whether this code is compiled or not, for example:
#ifdef _MACRO
    printf("macro test\n");
#endif
We do not need to define specific macros in the code, but specify them in the Makefile, for example:
DEBUG=-D_MACRO #define
$(CC) $(INCLUDES) $(DEBUG) $(CFLAGS) $< -o $@	#使用
3.4 Compilation options
When there are many compilation options, we usually take it out separately, such as:
CFLAGS = -Wall -c #define
$(CC) $(INCLUDES) $(DEBUG) $(CFLAGS) $< -o $@	#使用
3.5 Libraries
If we want to use the library in the code, we can take out the library name and path separately, for example:
LIBS = -ldylib #Library file name
LIB_PATH = -L./lib      #库文件地址
$(CC) $(OBJ) $(LIB_PATH) $(LIBS) -o output/$(TARGET).$(VERSION)	#使用
3.6 output目录
如果不想把生成的程序与源文件混在一起,可将生成的程序单独放在一个output目录,比如:
$(TARGET): $(OBJ)
        @mkdir -p output/       #创建一个目录,用于存放已编译的目标
        $(CC) $(OBJ) $(LIB_PATH) $(LIBS) -o output/$(TARGET).$(VERSION)
4. 编译执行结果



Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324519635&siteId=291194637