6

I'm trying to link statically OpenSSL library to my Swift framework, using XCode. Most approaches mentioned online are not correct, because they suggest using Import path (SWIFT_INCLUDE_PATHS). As a result, the framework binary is locked to a specific location in the file system and the binary itself is not portable. While this is not end of the world, I'd still like to be able to distribute the binary via Carthage for example and following above-mentioned approach doesn't enable that.

I have attempted to create my own module map with an umbrella header file for the framework and including OpenSSL library as an explicit module, following approaches described in articles like these: https://badootech.badoo.com/bundling-c-library-in-swift-framework-3d9dae950774

This is my modulemap file, path of which I inserted into MODULEMAP_FILE build config variable.

framework module MyFramework {
    umbrella header "MyFramework.h"
    requires objc

    export *
    module * { export * }

    module COpenSSL [system] {
        header "shim.h"
        link "ssl"
        link "crypto"
        export *
    }
}

where shim.h file is a header file that looks like this:

#ifndef __COPENSSL_SHIM_H__
#define __COPENSSL_SHIM_H__

#include <openssl/conf.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <openssl/bio.h>
#include <openssl/ssl.h>
#include <openssl/md4.h>
#include <openssl/md5.h>
#include <openssl/sha.h>
#include <openssl/hmac.h>
#include <openssl/rand.h>
#include <openssl/ripemd.h>
#include <openssl/pkcs12.h>
#include <openssl/x509v3.h>

__attribute__((swift_name("SSL_set_tlsext_host_name(_:_:)")))
static inline int shim_SSL_set_tlsext_host_name(const SSL *s, const char *name) {
    return SSL_set_tlsext_host_name(s, name);
};

#endif

The problem here is, that I get errors when trying to compile the project about including non-modular headers.

I've attempted to include all the header files to the XCode project as public header files (conf.h, evp.h, etc, all of them). But the problem still persists, presumably because it's unable to work with the syntax of the header inclusion #include <openssl/conf.h>. Changing inclusions to #include "conf.h" etc. works, but then the same style of header inclusion is used with conf.h and all the other header files that come from the Open SSL library, so that doesn't really help.

I really don't want to modify every single header file from the OpenSSL library just to make it work, it seems like there must be some easier way out of this.

Is there any way to not have to include these headers to the XCode project so that they still work with the original syntax of #include <openssl/conf.h>?

I've tried setting HEADER_SEARCH_PATHS to a path from which the relative path to each header is openssl/conf.h etc., but that it didn't help at all.

Thanks.

Lukas1
  • 582
  • 1
  • 5
  • 28
  • Did you find a solution for this? I tried declaring all header files in the ModuleMap, but it still does not solve the import issue – Sn0wfreeze Jul 23 '20 at 13:54
  • 1
    It boils down to the problem with header inclusion syntax -> `#include `. I've changed it for `#include "conf.h"` etc for every single file in the library, just as I described in the question above. I used this script to change the headers: `sed -E -i '' 's/#[[:space:]]*include /#include \"\1\.h"/' $SCRIPT_DIR/../Libraries/openssl/include/openssl/*.h ` – Lukas1 Jul 23 '20 at 19:13
  • Woah that was it. I thought there must be a better solution, but your script is really helpful here. You could add this as a correct answer I guess. – Sn0wfreeze Jul 24 '20 at 08:24
  • 1
    I guess so. Glad that it helped. – Lukas1 Jul 24 '20 at 13:43

1 Answers1

1

In the end I couldn't find any better solution than listing all necessary headers into module map and rewriting include macros of the SSL library files from <> syntax to just plain include. I used this little shell script to help me with that:

sed -E -i '' 's/#[[:space:]]*include <openssl\/(.*).h>/#include \"\1\.h"/' $SCRIPT_DIR/../Libraries/openssl/include/openssl/*.h
Lukas1
  • 582
  • 1
  • 5
  • 28