一、问题
openssl库是一个安全库,包含摘要、加密等算法的实现,许多程序都会依赖它,但是当程序迁移时(编译和运行环境不一样时),就会报出类似的错误:error while loading shared libraries: libcrypto.so.1.0.0: cannot open shared object file: No such file or directory,这是一个很恶心的问题。
二、解决办法
解决办法有很多,将openssl库编译成静态库被程序所依赖就是一种方法,这样程序链接时会从静态库中找到要依赖的openssl。
三、操作
3.1 源码下载、解压
下载openssl源码,官网:https://www.openssl.org/ ; 下载地址:https://www.openssl.org/source/
下载自己需要的版本,一般来说下载最新的稳定版,更加安全。
解压 tar -zxvf openssl-1.1.0j.tar.gz
3.2 配置和编译
cd openssl-1.1.0j //切换目录
.
/config
-fPIC no-shared //配置静态编译
make //编译
ls *.a //查看生成的库文件,可以看到libssl.a和libcrypto.a两个库文件
3.3 打成bazel包
假设你的项目如下所示,在你的项目中的第三方库中创建如下openssl目录。其中libs下是刚刚编译生成的两个.a库文件,openssl-1.1.0j/include/openssl目录拷贝到third_part/openssl/include/下。编写openssl的BUILD文件,编译BUILD即可生成bazel的包。
目录结构:
--myproject
--mytest
--ssl_test.h
--ssl_test.cc
--BUILD
--third_part
--openssl
--include
--openssl
--libs
--libssl.a
--libcrypto.a
--BUILD
openssl/BUILD:
licenses(["notice"])
package(default_visibility = ["//visibility:public"])
cc_library(
name = "libssl",
srcs = [
"libs/libcrypto.a",
"libs/libssl.a",
],
hdrs = glob([
"include/**/*.h",
"include/**/*.hpp",
]),
includes = [
"include",
],
)
四、使用openssl静态库(bazel包)
如上面的目录结构,mytest是使用openssl库的一个示例程序。在BUILD中明确依赖静态openssl后,就可在源文件中使用
#include <openssl/***.h>来使用openssl。例子是MD5
ssl_test.h
#ifndef WEBSEARCH_SSL_TEST_H
#define WEBSEARCH_SSL_TEST_H
#include <string>
class SslTest {
public:
std::string get_md5(std::string &str);
};
#endif //WEBSEARCH_SSL_TEST_H
ssl_test.cc
#include "ssl_test.h"
#include <openssl/md5.h>
#include <iostream>
std::string SslTest::get_md5(std::string &str) {
unsigned char mdStr[33]={0};
MD5((const unsigned char *)str.c_str(),str.length(),mdStr);
std::string restr((const char * )mdStr);
return restr;
}
int main(){
std::cout<<"helloworld!"<<std::endl;
SslTest ssl;
std::string str="helloworld!";
std::string md5str = ssl.get_md5(str);
std::cout<<md5str<<std::endl;
return 0;
}
mytest/BUILD
cc_library(
name = "ssl_test",
srcs = ["ssl_test.cc"],
hdrs = ["ssl_test.h"],
deps = ["//third_party/openssl:libssl"], //依赖静态openssl库
)
cc_binary(
name = "ssl_test_main",
srcs = ["ssl_test.cc"],
deps = [":ssl_test"],
)