万物皆有因,存在即为真理!
缘起:写代码的过程中呢,为了避免源代码太裸露,能不能又让别人可以使用你的代码实现功能,又不给他源代码呢?
那么可以这样
下面是一些 cmake 的示例,可以生成.a 静态库文件,这样相当于加密代码了呢。
# 生成 o 文件
一个生成.o 文件的示例:
# 定义编译器、链接器 | |
CC = gcc | |
LD = gcc | |
# 通配符函数表示目录下所有.c 文件,相当于:SRCS = main.c a.c b.c | |
SRCS = $(wildcard *.c) | |
# 通配符函数把列表中的.c 全部替换为.o,相当于:OBJS = main.o a.o b.o | |
OBJS = $(patsubst %.c, %.o, $(SRCS)) | |
# 可执行文件的名字 | |
TARGET = Test | |
# .PHONE 伪目标 | |
.PHONY:all clean | |
# 要生成的目标文件 | |
all: $(TARGET) | |
# 依赖关系:冒号后面为依赖的文件,相当于 Test: main.o a.o b.o | |
# 规则:$@表示目标文件,$^ 表示所有依赖文件,$< 表示第一个依赖文件 | |
$(TARGET): $(OBJS) | |
$(LD) -o $@ $^ | |
# 上一句目标文件依赖一大堆.o 文件,这句表示所有.o 都由相应名字的.c 文件自动生成 | |
%.o:%.c | |
$(CC) -c $^ | |
# make clean 删除所有.o 和目标文件 | |
clean: | |
rm -f $(OBJS) $(TARGET) |
# 生成 a 文件
你可以使用 Makefile 来编译一些 .c
和 .h
文件,并最终生成一个静态库( .a
文件)。以下是一个简单的 Makefile 示例:
Copy CodeCC=gcc | |
CFLAGS=-Wall -g | |
AR=ar | |
ARFLAGS=-rcs | |
TARGET=mylib.a | |
SRCS=$(wildcard *.c) # 通过通配符获取所有.c 文件 | |
OBJS=$(patsubst %.c,%.o,$(SRCS)) # 将所有.c 文件转为对应的.o 文件 | |
.PHONY: all clean | |
all: $(TARGET) | |
$(TARGET): $(OBJS) | |
$(AR) $(ARFLAGS) $@ $^ | |
%.o: %.c %.h | |
$(CC) $(CFLAGS) -c $< -o $@ | |
clean: | |
rm -f $(OBJS) $(TARGET) |
在这个示例中,我们首先定义了几个变量:
CC
:编译器命令。CFLAGS
:编译器参数。AR
:静态库打包命令。ARFLAGS
:静态库打包参数。
然后,我们定义了目标文件 $(TARGET)
,即要生成的静态库文件。通过 $(wildcard *.c)
命令获取当前目录下的所有 .c
文件,然后通过 $(patsubst %.c,%.o,$(SRCS))
命令将所有 .c
文件转换为对应的 .o
文件。
接着,我们定义了两个规则:
$(TARGET): $(OBJS)
:表示要生成目标文件$(TARGET)
,依赖于所有的.o
文件。执行命令$(AR) $(ARFLAGS) $@ $^
来将所有的.o
文件打包成静态库。%.o: %.c %.h
:表示要编译生成每一个.o
目标文件,依赖于对应的.c
源文件和对应的.h
头文件。执行命令$(CC) $(CFLAGS) -c $< -o $@
进行编译操作。
最后,我们定义了两个动态规则:
.PHONY: all clean
:声明all
和clean
为伪目标,防止误判。all: $(TARGET)
和clean:
:表示all
和clean
是默认目标,使用命令make
时,会自动执行all
目标。
你可以根据需要修改编译器参数、头文件目录、源文件目录等。通过执行 make
命令,即可编译生成静态库文件( .a
文件)。执行 make clean
命令,可以清除编译过程中生成的中间文件和目标文件。
# 引入 a 文件
对于 C/C++ 语言,可以在代码中使用 #include
预处理指令来引入头文件,使用 -l
选项或 -L
选项来链接静态库。以下是一个示例:
#include <stdio.h> | |
#include "mylibrary.h" | |
int main() | |
{ | |
printf("Hello, World!\n"); | |
// 使用 mylibrary 中的函数 | |
int result = myfunction(10); | |
printf("Result: %d\n", result); | |
return 0; | |
} |
在上述示例中, #include
指令用于引入标准头文件 <stdio.h>
和自定义头文件 "mylibrary.h"
。 mylibrary.h
头文件中声明了一个名为 myfunction
的函数,该函数在静态库 libmylibrary.a
中实现。
在编译代码时,可以使用 -l
选项来指定静态库名称,例如:
gcc -o myprogram mysource.c -l mylibrary
如果静态库不在默认的库路径中,可以使用 -L
选项指定库路径,例如:
gcc -o myprogram mysource.c -L /path/to/library -l mylibrary
这样的操作好玩不,快试试吧😂