跳到主要內容

Windows 編譯 OpenSSL 1.1.0

Windows 編譯 OpenSSL 1.1.0

OpenSSL 的編譯方式在原始碼中的文件 NOTES.WIM 提到詳細的介紹在 INSTALL 文件中。

需要使用

  1. Visual Studio IDE
  2. OpenSSL 原始碼
  3. ActivePerl 或其他 Perl 執行環境

本文使用

  1. Windows 10 版本1703 組建 15063.413
  2. Visual Studio 2017 Community
  3. OpenSSL 1.1.0f
  4. ActivePerl 5.24.1.2402-MSWin32-x64-401627

32位元與64位元要分開編譯,release與debug也要分開

因為 openssl 的 Makefile 沒有自動處理四種版本,若不各自編譯會出錯,
複製四分 openssl 原始碼,分為 32 位元與 64 位元及 release 與 debug,例: c:\openssl-x86c:\openssl-x86-dbgc:\openssl-x64c:\openssl-x64-dbg

x86

  1. 以系統管理員權限執行 x86 Native Tools Command Prompt for VS 2017
    ,通常安裝 Visual Studio IDE 時會新增捷徑到開始列表
    ,而 2017 Community 版本的檔案位置為 C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars32.bat
    ,不能直接執行 vcvars32.bat, 應該以命令提示字元(cmd.exe)執行
  2. cd 到解壓縮的openssl資料夾內,例: cd c:\openssl-x86
  3. 執行以下
    perl Configure VC-WIN32 no-asm --prefix=C:\openssl-msvc2017-x86
    mkdir C:\openssl-msvc2017-x86
    nmake
    nmake test
    nmake install
    
這樣會輸出在 C:\openssl-msvc2017-x86

x86-debug

  1. 以系統管理員權限執行 x86 Native Tools Command Prompt for VS 2017
    ,通常安裝 Visual Studio IDE 時會新增捷徑到開始列表
    ,而 2017 Community 版本的檔案位置為 C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars32.bat
    ,不能直接執行 vcvars32.bat, 應該以命令提示字元(cmd.exe)執行
  2. cd 到解壓縮的openssl-debug資料夾內,例: cd c:\openssl-x86-dbg
  3. 執行以下
    perl Configure VC-WIN32 no-asm --prefix=C:\openssl-msvc2017-x86-dbg --debug
    mkdir C:\openssl-msvc2017-x86-dbg
    nmake
    nmake test
    nmake install
    

x64

  1. 以系統管理員權限執行 x64 Native Tools Command Prompt for VS 2017
    ,通常安裝 Visual Studio IDE 時會新增捷徑到開始列表
    ,而 2017 Community 版本的檔案位置為 C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat
    ,不能直接執行 vcvars64.bat, 應該以命令提示字元(cmd.exe)執行
  2. cd 到為64位元準備的的openssl-x64資料夾內,例: cd c:\openssl-x64
  3. 執行以下
    perl Configure VC-WIN64A no-asm --prefix=C:\openssl-msvc2017-x64
    mkdir C:\openssl-msvc2017-x64
    nmake
    nmake test
    nmake install
    

x64-debug

  1. 以系統管理員權限執行 x64 Native Tools Command Prompt for VS 2017
    ,通常安裝 Visual Studio IDE 時會新增捷徑到開始列表
    ,而 2017 Community 版本的檔案位置為 C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat
    ,不能直接執行 vcvars64.bat, 應該以命令提示字元(cmd.exe)執行
  2. cd 到為64位元準備的的openssl-x64-debug資料夾內,例: cd c:\openssl-x64-dbg
  3. 執行以下
    perl Configure VC-WIN64A no-asm --prefix=C:\openssl-msvc2017-x64-dbg --debug
    mkdir C:\openssl-msvc2017-x64-dbg
    nmake
    nmake test
    nmake install
    

環境設定

編譯輸出內有四個資料夾,分別是
  • bin - 動態庫
  • html - 文件
  • include - 標頭檔
  • lib - 靜態庫
以 Visual Studio IDE 組態 Release 平台 x64 為例
  1. 專案 > 屬性 >> 組態屬性 > C/C++ > 一般 >> 其他 Include 目錄 新增目錄
    C:\openssl-msvc2017-x64\include
  2. 專案 > 屬性 >> 組態屬性 > 連結器 > 一般 >> 其他程式庫目錄 新增目錄
    C:\openssl-msvc2017-x64\lib
  3. 專案 > 屬性 >> 組態屬性 > 連結器 > 輸入 >> 其他相依性 新增兩個靜態庫
    libssl.lib
    libcrypto.lib
  4. 將對應組態的 dll 動態庫放到專案資料夾中
    libssl-1_1-x64.dll
    libcrypto-1_1-x64.dll
關於 dll 檔的位置,放在專案資料夾或是執行檔輸出目錄都可以,以方案 my-sln 專案 my-project 組態 Release 平台 x64 為例,專案路徑 C:\my-sln\my-project,那 dll 檔放在執行檔目錄 C:\my-sln\x64\Release 或是專案目錄 C:\my-sln\my-project 裡都可以,放在執行檔目錄是比較好的選擇,可以根據組態與平台取得正確的 dll 檔。

留言

這個網誌中的熱門文章

Dynamically loaded libraries 動態載入函式庫

Dynamically loaded libraries 動態載入庫 動態載入函式庫可以由程式控制在需要時才載入、釋放,在編譯連結時不需要相關的界面與函式庫,可以用來設計軟體插件之類的功能。 範例函式庫 mylib.h void hello(); void world(); hello.c #include "mylib.h" #include <stdio.h> void hello(){ printf("Hello"); } world.c #include "mylib.h" #include <stdio.h> void world(){ printf("World"); } 編譯 $ gcc -c -fPIC hello.c world.c $ gcc -shared -o libmylib.so hello.o world.o -fPIC 要編譯器產生 position-independent code -shared 編譯 Shared Library -o libmylib.so 函式庫檔案名稱為 libmylib.so 這裡沒使用 soname 等便於版本維護的參數 這樣會建立一個 libmylib.so 共享函式庫 使用方式 main.c #include <dlfcn.h> /* 動態載入要用的相關函式標頭 */ #include <stdio.h> int main() { /* 載入函式庫 libmylib.so */ void* handle = dlopen("./libmylib.so", RTLD_LAZY); /* 若有錯誤可以取得錯誤訊息 */ char* err = dlerror(); if (err) { printf(err); return 0; } /* 取得void hello()函式的指標 */ void (*f1)() = (void (*)()) dlsym(handle

Dynamically loaded libraries 動態載入庫 #3 C++ 類別載入

Dynamically loaded libraries 動態載入庫 #3 C++ 類別載入 繼上一篇 Dynamically loaded libraries 動態載入庫 #2 C++ 提到 libdl 是 C 函式庫,不包含類別的功能, 而 C++ 物件導向的特性之一 多形 可以用來達成動態載入類別的功能, 這樣唯一不足的點是, 在要使用動態類別庫的專案中需要加入類別介面標頭, 而不能在讓編譯器完全不知道類別介面的狀況下動態載入。 範例類別庫 以下程式為了節省版面沒有使用 #include 防範 HelloWorld.hpp (介面) class HelloWorld { public: HelloWorld() {} virtual ~HelloWorld() {} virtual void hello() {} }; extern "C"{ HelloWorld* create_object(); void destroy_object(HelloWorld* object); } 會直接實作 HelloWorld 的方法是為了使用上的方便, 不論是不實作或是讓它=0都會有些相對應的問題, 因此我還是將這個 HelloWorld 稱為介面。 create_object 和 destroy_object 兩個函式用於轉發建構子與解構子, 這下就有辦法呼叫其他類別庫中的 HelloWorld 子類別建構子、解構子, 也剛好有 HelloWorld 介面,如此就可以動態載入類別了。 MyHelloWorld.hpp (要被動態載入的類別) #include "HelloWorld.hpp" class MyHelloWorld: public HelloWorld { public: MyHelloWorld(); virtual ~MyHelloWorld(); virtual void hello(); }; MyHelloWorld.cpp #include "MyHelloWorld.hpp" #include <iostream> /* 轉發建構子*/ HelloWor