2

I'm planning on using a c++ library for a web application and web assembly seemed like a good tool for this. I am using emscripten for compiling it.

I got the source code of this open source c++ library and made it using emmake make and emmake make install

After those two calls I had .a libraries in my /usr/local/<name of open source>/lib as well as header files in my /usr/local/<name of open source>/include

I also had an example cpp code that uses this open source library.

The question is: how do I create a html file for this cpp file? The name of such file is "test.cpp" and I tried this command, but it cause a lot of "unresolved symbols"

em++ -I/usr/local/<name of open source>/include -L/usr/local/<name of open source>/lib test.cpp -s WASM=1 -o final.html

Then I called emrun to run a web server on my local, but final.html was not displaying what I expected it to display.

Can you please help me?

unresolved symbol warnings in the console

3
  • This doesn't seem specific to WebAssembly. Can you follow Emscripten's regular asm.js instructions and see if you get the same errors? If so, what are these errors? Further, can you not use /usr/local? Emscripten has its own C and C++ standard libraries. Commented Jan 13, 2017 at 2:42
  • 1
    Hi it's not a standard library that I am trying to use it's an open source project developed by developers to do some intense computation for scientific research. Also, I tried following Emscripten's regular asm.js instructions, but it also did not seem to work. Commented Jan 13, 2017 at 7:52
  • JF Bastien: You mention "Emscripten has its own C and C++ standard libraries". Could you expand on this? Tnx Commented Jan 19, 2017 at 22:32

4 Answers 4

1

The warnings (errors, actually) show that you have not compiled the included library's cpp files via emscripten. Besides the file test.cpp, you will need to provide every file that your project requires to the em++ command. Read here for more information on this.

Now coming to the other part of your question, emscripten will only create a JS function for those C++ functions that you "expose". (Obviously the functions called by these exposed functions will also be compiled, rest are stripped off).

A small tutorial on achieving this can be found here

Once your functions are exposed, you call them from your own JS code(example: binding them on JS events)

Sign up to request clarification or add additional context in comments.

1 Comment

Just wanted to point out that you are a genius. I don't know why I thought I could just add the .a (lib) and the includes and it would all just work like magic.
0

It looks like your library may have dependencies that are not met (the unresolved symbols). An emscripten build is a cross build, meaning it cannot use your installed system libraries; instead you have to build all the dependencies with the emscripten compiler. Emscripten has the unfortunate behavior that the unresolved symbols are warnings (other linkers consider these as errors) but your program is unlikely to work if you have them.

Comments

0

Emscripten does not treat unresolved symbols as compile errors for various reasons.

When compiling your project, you also need to link the generated .a library. The -I and -L options you used specify where to look for libraries that you want linked with your program, but it does not specify which libraries you want to link.

You need to add the option -l<name of your library> to your compile command to specify that you want the lib to be linked with your program.

Comments

0

First your open source library needs to be compiled in LLVM bitcode.

In my example I use Botan library. It previously was compiled in LLVM bitcode.

libbotan-2.a is in LLVM bitcode.

My file tree

HelloProject:.
│   hello.cpp
│   hello.js
│   hello.wasm
│   test.html
│
├───include
│   └───botan-2
│       └───botan
│               adler32.h
│               aead.h
│               aes.h
│               alg_id.h
│               argon2.h
│               aria.h
│               asn1_alt_name.h
│               asn1_attribute.h
│               asn1_obj.h
│               asn1_oid.h
│               asn1_print.h
│               asn1_str.h
│               asn1_time.h
│               assert.h
│               atomic.h
│               auto_rng.h
│               base32.h
│               base58.h
│               base64.h
│               basefilt.h
│               bcrypt.h
│               bcrypt_pbkdf.h
│               ber_dec.h
│               bigint.h
│               blake2b.h
│               blinding.h
│               block_cipher.h
│               blowfish.h
│               botan.h
│               bswap.h
│               buf_comp.h
│               buf_filt.h
│               build.h
│               calendar.h
│               camellia.h
│               cascade.h
│               cast128.h
│               cast256.h
│               cbc.h
│               cbc_mac.h
│               ccm.h
│               cecpq1.h
│               certstor.h
│               certstor_flatfile.h
│               certstor_sql.h
│               certstor_system.h
│               cert_status.h
│               cfb.h
│               chacha.h
│               chacha20poly1305.h
│               chacha_rng.h
│               charset.h
│               cipher_filter.h
│               cipher_mode.h
│               cmac.h
│               comb4p.h
│               compiler.h
│               comp_filter.h
│               cpuid.h
│               crc24.h
│               crc32.h
│               credentials_manager.h
│               crl_ent.h
│               cryptobox.h
│               ctr.h
│               curve25519.h
│               curve_gfp.h
│               curve_nistp.h
│               database.h
│               datastor.h
│               data_snk.h
│               data_src.h
│               der_enc.h
│               des.h
│               desx.h
│               dh.h
│               divide.h
│               dlies.h
│               dl_algo.h
│               dl_group.h
│               dsa.h
│               dyn_load.h
│               eax.h
│               ecc_key.h
│               ecdh.h
│               ecdsa.h
│               ecgdsa.h
│               ecies.h
│               eckcdsa.h
│               ec_group.h
│               ed25519.h
│               elgamal.h
│               eme.h
│               eme_pkcs.h
│               eme_raw.h
│               emsa.h
│               emsa1.h
│               emsa_pkcs1.h
│               emsa_raw.h
│               emsa_x931.h
│               entropy_src.h
│               exceptn.h
│               fd_unix.h
│               ffi.h
│               filter.h
│               filters.h
│               fpe_fe1.h
│               gcm.h
│               gf2m_small_m.h
│               ghash.h
│               gmac.h
│               gost_28147.h
│               gost_3410.h
│               gost_3411.h
│               hash.h
│               hash_id.h
│               hex.h
│               hkdf.h
│               hmac.h
│               hmac_drbg.h
│               hotp.h
│               http_util.h
│               idea.h
│               init.h
│               iso9796.h
│               kasumi.h
│               kdf.h
│               kdf1.h
│               kdf1_iso18033.h
│               kdf2.h
│               keccak.h
│               keypair.h
│               key_constraint.h
│               key_filt.h
│               key_spec.h
│               lion.h
│               loadstor.h
│               locking_allocator.h
│               lookup.h
│               mac.h
│               mceies.h
│               mceliece.h
│               md4.h
│               md5.h
│               mdx_hash.h
│               mem_ops.h
│               mgf1.h
│               misty1.h
│               mode_pad.h
│               monty.h
│               mul128.h
│               mutex.h
│               name_constraint.h
│               newhope.h
│               nist_keywrap.h
│               noekeon.h
│               numthry.h
│               oaep.h
│               ocb.h
│               ocsp.h
│               ocsp_types.h
│               ofb.h
│               oids.h
│               p11.h
│               p11_ecc_key.h
│               p11_ecdh.h
│               p11_ecdsa.h
│               p11_module.h
│               p11_object.h
│               p11_randomgenerator.h
│               p11_rsa.h
│               p11_session.h
│               p11_slot.h
│               p11_x509.h
│               package.h
│               parsing.h
│               par_hash.h
│               passhash9.h
│               pbes2.h
│               pbkdf.h
│               pbkdf1.h
│               pbkdf2.h
│               pem.h
│               pgp_s2k.h
│               pipe.h
│               pkcs10.h
│               pkcs11.h
│               pkcs11f.h
│               pkcs11t.h
│               pkcs8.h
│               pk_algs.h
│               pk_keys.h
│               pk_ops.h
│               pk_ops_fwd.h
│               point_gfp.h
│               poly1305.h
│               polyn_gf2m.h
│               pow_mod.h
│               prf_tls.h
│               prf_x942.h
│               psk_db.h
│               psk_db_sql.h
│               pssr.h
│               pubkey.h
│               pwdhash.h
│               rc4.h
│               reducer.h
│               rfc3394.h
│               rfc6979.h
│               rmd160.h
│               rng.h
│               rotate.h
│               rsa.h
│               salsa20.h
│               scan_name.h
│               scrypt.h
│               secmem.h
│               secqueue.h
│               seed.h
│               serpent.h
│               sha160.h
│               sha2_32.h
│               sha2_64.h
│               sha3.h
│               shacal2.h
│               shake.h
│               shake_cipher.h
│               siphash.h
│               siv.h
│               skein_512.h
│               sm2.h
│               sm2_enc.h
│               sm3.h
│               sm4.h
│               sodium.h
│               sp800_108.h
│               sp800_56a.h
│               sp800_56c.h
│               srp6.h
│               stateful_rng.h
│               stl_compatibility.h
│               stream_cipher.h
│               stream_mode.h
│               streebog.h
│               symkey.h
│               sym_algo.h
│               system_rng.h
│               threefish.h
│               threefish_512.h
│               tiger.h
│               tls_alert.h
│               tls_algos.h
│               tls_blocking.h
│               tls_callbacks.h
│               tls_channel.h
│               tls_ciphersuite.h
│               tls_client.h
│               tls_exceptn.h
│               tls_extensions.h
│               tls_handshake_msg.h
│               tls_magic.h
│               tls_messages.h
│               tls_policy.h
│               tls_server.h
│               tls_server_info.h
│               tls_session.h
│               tls_session_manager.h
│               tls_session_manager_sql.h
│               tls_version.h
│               totp.h
│               tss.h
│               twofish.h
│               types.h
│               uuid.h
│               version.h
│               whrlpool.h
│               workfactor.h
│               x509cert.h
│               x509path.h
│               x509self.h
│               x509_ca.h
│               x509_crl.h
│               x509_dn.h
│               x509_ext.h
│               x509_key.h
│               x509_obj.h
│               x919_mac.h
│               xmss.h
│               xmss_address.h
│               xmss_common_ops.h
│               xmss_hash.h
│               xmss_index_registry.h
│               xmss_key_pair.h
│               xmss_parameters.h
│               xmss_privatekey.h
│               xmss_publickey.h
│               xmss_tools.h
│               xmss_wots_parameters.h
│               xmss_wots_privatekey.h
│               xmss_wots_publickey.h
│               xtea.h
│               xts.h
│
└───libs
    └───Botan
            libbotan-2.a

Compiling
Run command

em++ hello.cpp libs/botan/libbotan-2.a -s WASM=1 -o hello.js -std=c++17 -s "EXTRA_EXPORTED_RUNTIME_METHODS=['ccall']" -O3 -I include/botan-2

C++ - hello.cpp

#include <iostream>
#include <vector>
#include <emscripten.h>
#include "botan/sha2_64.h"
#include "botan/base64.h"
#define EXTERNC extern "C"

int main(int argc, char ** argv) {
    std::cout<<u8"Hello World from main\n";
}

EXTERNC const char * EMSCRIPTEN_KEEPALIVE  GetSha512Hash(const char* data) {
    std::cout<< "Received from JS: "<<data << std::endl;
    Botan::SHA_512 sha;
    std::vector<uint8_t> buffer(data, data + strlen(data));
    //std::fread(&buffer[0], 1, buffer.size(), pFile);
    return Botan::base64_encode(sha.process(buffer)).c_str();
}

HTML/JS - Test.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script type="text/javascript" src="hello.js"></script>
    <button onclick="native()">click</button>

    <script type='text/javascript'>

      function native() {
        var result = Module.ccall(
                    'GetSha512Hash',    // name of C function 
                    "string",   // return type
                    ["string"], // argument types
                    ["Joma"]    // arguments
                );
        console.log("Returned from CPP: " + result);
      }

    </script>

</body>
</html>

Test WASM in browser
Run command

emrun --browser "C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" .\test.html

** Results in browser** enter image description here

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.