问题
Building OpenSSL using its default configuration gives you a dynamic version of the library. According to OpenSSL Compilation and Installation document on its Wiki, there is a configuration option named no-shared which disables shared objects and only creates a static library.
Visual C++ compiler links a binary (library or application) either to libcmt(d).lib (Statically links the native CRT startup into your code using /MT(d)) or msvcrt(d).lib (Static library for the native CRT startup for use with DLL UCRT and vcruntime using /MD(d)).
Linking binaries which themselves have linked to CRT differently, results in conflicts. Unfortunately, OpenSSL did not give us the option of setting this compiler switch. It always build its dynamic version using /MD and its static version using /MT. So what should we do when we want to link a static version of it to our application when we have other static libraries which have linked using /MD such as Qt?
回答1:
There are some pre-built binaries available online which have linked this way but there is always a good reason for building OpenSSL yourself. The most important reason might be security considerations or sometimes you find that these pre-built binaries did not compile with your desired version of Visual C++ or your desired configurations. I have searched around the Web but could not find a simple method of building a static version of OpenSSL using /MD compiler switch without extra complicated building scripts. Some of them are working just with the older version of library (i.e. 1.0.x). So I decided to share my way.
NOTE: In the following steps, do not place anything in a directory with space in its name.
Step 1. OpenSSL building scripts are written using Perl. So if do not have Perl, install it first. I have used the portable version of Strawberry Perl.
Step 2. You need a 32 and/or 64 bit version of nasm assembler according to which platforms you decide to build OpenSSL for. You can download a copy here. Add the desired version to your system path.
Step 3. Download the latest stable version of OpenSSL source from its web site and extract it. It's a good idea to build OpenSSL from a clean download. So keep a copy of it for later builds (perhaps with different configurations).
Step 4. Open the Strawberry Perl portable shell and go to OpenSSL source directory.
Step 5. Create OpenSSL make files using the following command:
perl Configure platform [options] [--debug] --prefix=absolute_path --openssldir=same_path
platform can be VC-WIN32, VC-WIN64A, etc.
Some interesting options for me:
- no-shared: Disables shared objects (only a static library is created)
- no-stdio: Don't use anything from the C header file "stdio.h" that makes use of the "FILE" type. Using this option release you from linking your final binary to crypt32.lib.
- no-sock: Don't build support for socket BIOs. Using this option release you from linking your final binary to Ws2_32.lib.
According to OpenSSL Compilation and Installation document, when you want something that "just works" for all recent versions of OpenSSL, including OpenSSL 1.0.2 and 1.1.0, specify both --prefix and --openssldir and set both to the same location.
Step 6. Under OpenSSL source directory, open makefile and find LIB_CFLAGS. Change /MT to /MD or /MDd according to whether you compile a release version or not. You can link debug information (the contents of pdb file) to your library. For this remove /Fdossl_static and change /Zl compiler switch to /Z7.
Step 7. Run Visual Studio x86/x64 Native Tools Command (according to which platforms you decide to build OpenSSL for) and go to OpenSSL source directory. Then and finally run the following commands consequently:
nmake
nmake install
Enjoy your time. With special thanks to my friend Afshin.
回答2:
Look at files ending with *_static.lib when build "shared" version. For OpenSSL 1.1 this are libcrypto_static.lib and libssl_static.lib.
来源:https://stackoverflow.com/questions/50365513/building-a-static-version-of-openssl-library-using-md-switch