经过AI指导, 在C项目中引入第三方库的过程(zlib)
由于打算在特定的杰理MCU中引入第三方的库zlib实现deflate/inflate压缩和解压, 发现比较好的方式是单独选择核心文件进行编译.
zlib官网 https://www.zlib.net/
当前最新的zlib源码 : https://www.zlib.net/zlib-1.3.1.tar.gz
解压缩后, 让cursor生成了一个核心代码的makefile
替代原zlib目录下的makefile,使用杰理br25的编译器,自己根据杰理官方的项目中的makefile, 增加了complier flags
TOOL_DIR := C:/JL/pi32/bin
CC := $(TOOL_DIR)/clang.exe
CXX := $(TOOL_DIR)/clang.exe
LD := $(TOOL_DIR)/pi32v2-lto-wrapper.exe
AR := $(TOOL_DIR)/pi32v2-lto-ar.exe
MKDIR := mkdir_win -p
RM := rm -rf
# Compiler flags
CFLAGS = -O2 -Wall -DZ_SOLO \
-target pi32v2 \
-mcpu=r3 \
-integrated-as \
-flto \
-Wuninitialized \
-Wno-invalid-noreturn \
-fno-common \
-integrated-as \
-Oz \
-g \
-flto \
-fallow-pointer-null \
-fprefer-gnu-section \
-Wno-shift-negative-value \
-Wundef \
-fms-extensions \
-w \
LDFLAGS =
# Source files
# SRCS = adler32.c compress.c crc32.c deflate.c gzclose.c gzlib.c gzread.c \
# gzwrite.c infback.c inffast.c inflate.c inftrees.c trees.c uncompr.c zutil.c
SRCS = deflate.c inflate.c zutil.c
# Object files
OBJS = $(SRCS:.c=.o)
# Library name
LIBRARY = libz.a
# Default target
all: $(LIBRARY)
# Rule to build the library
$(LIBRARY): $(OBJS)
$(AR) rcs $@ $(OBJS)
# Rule to compile source files
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
# Clean target
clean:
$(RM) $(OBJS) $(LIBRARY)
.PHONY: all clean
zlib目录中运行make
, 成功生成libz.a
文件.
杰理的官方项目使用Code::Blocks
作为编码IDE, 在Code::Blocks
项目中添加libz.a
: 菜单 > Project > Build Options > Linker Settings > Link Libraries
中增加libz.a
.
PS: 不放心还可以在other options中增加-LD:\d3\_git\c_proj\SDK_ble\apps\soundbox\zlib
注意, 上面只编译了核心的一些函数, 部分函数如compress/decompress没有. 要检查zlib中有哪些函数: c:\jl\pi32\bin\llvm-nm libz.a
显示如下:
deflate.o:
U _dist_code
U _length_code
U _tr_align
U _tr_flush_bits
U _tr_flush_block
U _tr_init
U _tr_stored_block
U adler32
-------- d configuration_table
U crc32
-------- T deflate
-------- T deflateBound
-------- T deflateCopy
-------- T deflateEnd
-------- T deflateGetDictionary
-------- T deflateInit2_
-------- T deflateInit_
-------- T deflateParams
-------- T deflatePending
-------- T deflatePrime
-------- T deflateReset
-------- T deflateResetKeep
-------- T deflateSetDictionary
-------- T deflateSetHeader
-------- t deflateStateCheck
-------- T deflateTune
-------- D deflate_copyright
-------- t deflate_fast
-------- t deflate_slow
-------- t deflate_stored
-------- t fill_window
-------- t flush_pending
-------- t longest_match
-------- t putShortMSB
-------- t read_buf
-------- t slide_hash
U z_errmsg
U zmemcpy
U zmemzero
inflate.o:
U adler32
U crc32
-------- d fixedtables.distfix
-------- d fixedtables.lenfix
-------- T inflate
-------- d inflate.order
-------- T inflateCodesUsed
-------- T inflateCopy
-------- T inflateEnd
-------- T inflateGetDictionary
-------- T inflateGetHeader
-------- T inflateInit2_
-------- T inflateInit_
-------- T inflateMark
-------- T inflatePrime
-------- T inflateReset
-------- T inflateReset2
-------- T inflateResetKeep
-------- T inflateSetDictionary
-------- t inflateStateCheck
-------- T inflateSync
-------- T inflateSyncPoint
-------- T inflateUndermine
-------- T inflateValidate
U inflate_fast
U inflate_table
-------- t syncsearch
-------- t updatewindow
U zmemcpy
zutil.o:
-------- T zError
-------- D z_errmsg
-------- T zlibCompileFlags
-------- T zlibVersion
-------- T zmemcmp
-------- T zmemcpy
-------- T zmemzero
然后在项目的headers中增加zlib.h
文件.
示例:
#define CHUNK 16384
int compress_data(const char *src, size_t src_len, unsigned char *dest, size_t *dest_len) {
int ret;
z_stream strm;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
ret = deflateInit(&strm, Z_DEFAULT_COMPRESSION);
if (ret != Z_OK) return ret;
strm.avail_in = src_len;
strm.next_in = (unsigned char *)src;
strm.avail_out = CHUNK;
strm.next_out = dest;
ret = deflate(&strm, Z_FINISH);
if (ret != Z_STREAM_END) {
deflateEnd(&strm);
return ret;
}
*dest_len = CHUNK - strm.avail_out;
deflateEnd(&strm);
return Z_OK;
}
int decompress_data(const unsigned char *src, size_t src_len, char *dest, size_t *dest_len) {
int ret;
z_stream strm;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
ret = inflateInit(&strm);
if (ret != Z_OK) return ret;
strm.avail_in = src_len;
strm.next_in = (unsigned char *)src;
strm.avail_out = CHUNK;
strm.next_out = (unsigned char *)dest;
ret = inflate(&strm, Z_NO_FLUSH);
if (ret != Z_STREAM_END) {
inflateEnd(&strm);
return ret;
}
*dest_len = CHUNK - strm.avail_out;
inflateEnd(&strm);
return Z_OK;
}
int test_zlib() {
const char *original_data = "Hello, World! This is a test of the zlib compression library.";
size_t original_length = strlen(original_data) + 1; // +1 for null terminator
unsigned char compressed[CHUNK];
// Compress the data
size_t compressed_length;
if(compress_data(original_data, original_length, compressed, &compressed_length) != Z_OK){
printf("Failed to compress data\n");
return 1;
}
printf("Original length: %zu\n", original_length);
printf("Compressed length: %zu\n", compressed_length);
// Decompress the data
char decompressed[CHUNK];
size_t decompressed_length;
if(decompress_data(compressed, compressed_length, decompressed, &decompressed_length) != Z_OK){
printf("Failed to decompress data\n");
return 1;
}
printf("Decompressed length: %zu\n", decompressed_length);
printf("Decompressed data: %s\n", decompressed);
return 0;
}
在主函数中引用test_zlib()
就可以编译了. 实测编译通过.