Fsu0413 / openssl-externalCMake

A totally external CMake project for building OpenSSL.
http://openssl.org
The Unlicense
9 stars 2 forks source link

mkdef #3

Closed Fsu0413 closed 7 months ago

Fsu0413 commented 1 year ago

To implement a library a common practice is to mark public symbols using XXXX_EXPORT, and use macros to conditionally compile the related code:

#ifndef XXXX_STATIC
  #ifdef _WIN32
    // works on both MSVC and MinGW
    #ifdef BUILDING_XXXX
      #define XXXX_EXPORT __declspec(dllexport)
    #else
      #define XXXX_EXPORT __declspec(dllimport)
    #endif
  #else
    #ifdef BUILDING_XXXX
      // compile using GCC or Clang with -fvisibility=hidden
      #define XXXX_EXPORT __attribute__((visibility("default")))
    #endif
  #endif
#endif
#ifndef XXXX_EXPORT
  #define XXXX_EXPORT
#endif

This is just common practice but OpenSSL does not use it. So all of the symbols from OpenSSL are not exported by default on Windows. On other platforms it is exported provided -fvisibility=hidden is not set (I am not doing this).

For resolving this problem OpenSSL team chooses to maintain a list (util/libeay.num / util/ssleay.num on 1.0.2, util/libcrypto.num / util/libssl.num on 1.1.1 onwards), from which it generates a .def file using mkdef.pl. To link the DLL using this .def file makes the symbols listed in it are exported.

I just feel this extremely complicated so I use following to export all symbols by default on Windows:

set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS YES)

However on OpenSSL 3.0 onwards the source code of libcrypto is splitted into crypto and provider, the provider is built as static library then link to libcrypto. According to the documentation WINDOWS_EXPORT_ALL_SYMBOLS does not affect static library, so the link error occurs on Windows.

Currently I switched the providers to object library to workaround this issue but I don't think it is a perfect workaround since the static library is gone. ( 4a0fc04da0a87e310e4aa23d76088fbf016b48f4 )

So I think it is needed for mkdef.pl alternative. Since mkdef.pl reads data output from Configure I don't think using it directly is a solution. Probably generating a cmake script during configure and run it during build will be the final solution.

Fsu0413 commented 1 year ago

mkdef is also used for generating version script for Linux. I have no knowledge about version script before, I think it may be a kind of assembly code or linker script.

Fsu0413 commented 7 months ago

OpenSSL 1.1.1 and before use a more complicated version than 3.0.0 and later of mkdef.pl. It seems like that the mkdef.pl on 1.1.1 and before is a combination of mkdef.pl and mknum.pl.