Linux链接静态库与动态库并且打包程序
[toc]
链接静态库
1.自写
链接动态库
1 | gcc -o httpc httpc.c -lssl -lcrypto |
2.第三方
链接动态库
1.自写
链接静态库
1 | gcc -o LinClient LinClient.c -static -lssl -lcrypto |
2.第三方
打包程序
1.打包一个链接OpenSSl的程序
安装 OpenSSL
1
2sudo apt update
sudo apt install openssl libssl-dev编写代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156// LinClient.c
void send_request(SSL* ssl, const char* host, const char* path) {
char request[BUFFER_SIZE];
sprintf(request, "GET %s HTTP/1.1\r\n"
"Host: %s\r\n"
"Connection: close\r\n\r\n", path, host);
SSL_write(ssl, request, strlen(request));
}
int main() {
char response[BUFFER_SIZE];
int bytes_received;
// 初始化OpenSSL
SSL_library_init();
SSL_CTX* ctx = SSL_CTX_new(TLS_client_method());
SSL* ssl = NULL;
// 创建套接字
int sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
perror("Could not create socket");
return 1;
}
// 设置服务器信息
struct sockaddr_in server;
server.sin_family = AF_INET;
server.sin_port = htons(443); // HTTPS端口
// 将主机名转换为IP地址
struct hostent* host = gethostbyname("www.bilibili.com");
if (host == NULL) {
perror("Could not resolve hostname");
close(sock);
return 1;
}
memcpy(&server.sin_addr, host->h_addr, host->h_length);
// 连接到服务器
if (connect(sock, (struct sockaddr*)&server, sizeof(server)) < 0) {
perror("Connect failed");
close(sock);
return 1;
}
// 初始化SSL连接
ssl = SSL_new(ctx);
SSL_set_fd(ssl, sock);
// 建立SSL连接
if (SSL_connect(ssl) <= 0) {
printf("SSL connect failed. Error Code: %ld\n", ERR_get_error());
SSL_free(ssl);
SSL_CTX_free(ctx);
close(sock);
return 1;
}
// 发送初始请求
send_request(ssl, "www.bilibili.com", "/");
// 接收响应并处理重定向
while ((bytes_received = SSL_read(ssl, response, sizeof(response) - 1)) > 0) {
response[bytes_received] = '\0'; // 添加字符串结束符
printf("%s", response); // 打印响应
// 检查是否有重定向
if (strstr(response, "HTTP/1.1 301 Moved Permanently") ||
strstr(response, "HTTP/1.1 302 Found")) {
// 提取Location头
char* location = strstr(response, "Location: ");
if (location) {
location += strlen("Location: ");
char* end = strstr(location, "\r\n");
if (end) {
*end = '\0'; // 结束字符串
printf("\nRedirecting to: %s\n", location);
// 关闭当前SSL连接
SSL_shutdown(ssl);
SSL_free(ssl);
close(sock);
// 重新连接到新的URL
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
perror("Could not create socket");
SSL_CTX_free(ctx);
return 1;
}
// 解析新的主机名
char* new_host = location; // 这里假设Location是完整的URL
char* path = strchr(new_host, '/'); // 找到路径
if (path) {
*path = '\0'; // 分离主机名
path++; // 跳过'/'
}
// 连接到新的主机
host = gethostbyname(new_host);
if (host == NULL) {
perror("Could not resolve hostname");
close(sock);
SSL_CTX_free(ctx);
return 1;
}
memcpy(&server.sin_addr, host->h_addr, host->h_length);
server.sin_port = htons(443); // HTTPS端口
// 连接到新的服务器
if (connect(sock, (struct sockaddr*)&server, sizeof(server)) < 0) {
perror("Connect failed");
close(sock);
SSL_CTX_free(ctx);
return 1;
}
// 初始化新的SSL连接
ssl = SSL_new(ctx);
SSL_set_fd(ssl, sock);
if (SSL_connect(ssl) <= 0) {
printf("SSL connect failed. Error Code: %ld\n", ERR_get_error());
SSL_free(ssl);
SSL_CTX_free(ctx);
close(sock);
return 1;
}
// 发送请求到新的URL
send_request(ssl, new_host, path);
}
}
break; // 处理完重定向后退出循环
}
}
// 关闭SSL连接和套接字
SSL_shutdown(ssl);
SSL_free(ssl);
SSL_CTX_free(ctx);
close(sock);
return 0;
}编译程序
1
gcc -o LinClient LinClient.c -lssl -lcrypto
查看程序依赖的动态库,手动复制到同一文件夹中
1
ldd LinClient
打包程序
2.使用make编译并且打包程序
编写
makefile文件1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45# 定义变量
CC = gcc
CFLAGS = -Wall -g
LDFLAGS = -lssl -lcrypto
TARGET = LinClient
SRC = LinClient.c
OPENSSL_LIBS = /usr/lib/x86_64-linux-gnu/libssl.so /usr/lib/x86_64-linux-gnu/libcrypto.so
PREFIX_BIN ?= /usr/local/bin# 可执行文件安装路径
PREFIX_LIB ?= /usr/local/lib/LinClient# 库文件安装路径
# 默认目标
all: $(TARGET)
# 编译目标
$(TARGET): $(SRC)
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
# 安装目标
install: $(TARGET)
mkdir -p $(PREFIX_BIN) # 创建可执行文件目录(如果不存在)
mkdir -p $(PREFIX_LIB) # 创建库文件目录(如果不存在)
cp $(TARGET) $(PREFIX_BIN) # 将可执行文件复制到安装目录
cp $(OPENSSL_LIBS) $(PREFIX_LIB) # 将库文件复制到安装目录
# 卸载目标
uninstall:
@echo "Removing $(PREFIX_BIN)/$(TARGET)"
rm -f "$(PREFIX_BIN)/$(TARGET)" # 从安装目录删除可执行文件
@echo "Removing $(PREFIX_LIB)"
rm -rf "$(PREFIX_LIB)" # 删除库文件夹与文件
# 打包目标
package: install
tar -czvf LinClientPackage.tar.gz $(TARGET) $(OPENSSL_LIBS)
# 清理目标
clean:
rm -f $(TARGET) LinClientPackage.tar.gz
# 强制重新编译
rebuild: clean all运行make命令编译
1
sudo make
运行命令打包程序与库
1
sudo make package
清理生成的文件
1
make clean
如果需要卸载程序
1
sudo make uninstall
如果需要将 LinClientPackage.tar.gz 文件复制到其他机器中
1
scp LinClientPackage.tar.gz kali@10.0.2.110:/home/kali/Downloads/
如果需要解压
1
mkdir -p LinClientPackage && tar -xzvf LinClientPackage.tar.gz -C LinClientPackage
3.使用cmake编译并打包程序
创建 CMakeLists.txt 文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45cmake_minimum_required(VERSION 3.10)
# 项目名称和版本
project(LinClient VERSION 1.0)
# 查找 OpenSSL 库
find_package(OpenSSL REQUIRED)
# 添加可执行文件
add_executable(LinClient LinClient.c)
# 链接 OpenSSL 库
target_link_libraries(LinClient OpenSSL::SSL OpenSSL::Crypto)
# 安装目标
install(TARGETS LinClient
DESTINATION bin)
# 安装动态库
install(FILES ${OPENSSL_SSL_LIBRARY} ${OPENSSL_CRYPTO_LIBRARY}
DESTINATION lib/LinClient)
# 卸载目标
if(NOT DEFINED CMAKE_INSTALL_PREFIX)
set(CMAKE_INSTALL_PREFIX "/usr/local")
endif()
# 添加卸载目标
set(UNINSTALL_SCRIPT "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
file(WRITE ${UNINSTALL_SCRIPT} "message(STATUS \"Uninstalling...\")\n")
file(APPEND ${UNINSTALL_SCRIPT} "file(REMOVE \"${CMAKE_INSTALL_PREFIX}/bin/LinClient\")\n")
file(APPEND ${UNINSTALL_SCRIPT} "file(REMOVE \"${CMAKE_INSTALL_PREFIX}/lib/LinClient/libssl.so\")\n")
file(APPEND ${UNINSTALL_SCRIPT} "file(REMOVE \"${CMAKE_INSTALL_PREFIX}/lib/LinClient/libcrypto.so\")\n")
file(APPEND ${UNINSTALL_SCRIPT} "file(REMOVE_RECURSE \"${CMAKE_INSTALL_PREFIX}/lib/LinClient\")\n") # 删除目录
# 移除自动执行卸载脚本的命令
# install(SCRIPT ${UNINSTALL_SCRIPT}) # 注释掉这一行
# 打包目标
set(CPACK_GENERATOR "TGZ")
set(CPACK_PACKAGE_NAME "LinClient")
set(CPACK_PACKAGE_VERSION "1.0")
set(CPACK_PACKAGE_CONTACT "Your Name <your.email@example.com>")
include(CPack)编译和安装
在终端中,执行以下命令来编译和安装程序:
1
2
3
4
5
6
7
8
9
10
11
12# 创建构建目录
mkdir build
cd build
# 运行 CMake
cmake ..
# 编译程序
make
# 安装程序
sudo make install打包
在构建目录中,运行以下命令来创建打包文件:
1
sudo cpack
这将生成一个名为 LinClient-1.0-Linux.tar.gz 的压缩包
如果需要卸载程序
1
sudo cmake -P cmake_uninstall.cmake
All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
