1

I am new to C++ and am trying to figure out where in the compiling process my error is. Apologies, if this question is unclear, I'm not sure what information to provide.

Reference information: The directory "mbedtls/lib/" contains two .a (archive) files, "libmbedtls_SGX_t.a" and "libmbedtls_SGX_u.a".

I am using a Makefile, which runs the following commands in order. The commands seem to run error free:

cc -m64 -O2 -fPIC -Wno-attributes -IApp -I/opt/intel/sgxsdk/include -Imbedtls/include -DNDEBUG -UEDEBUG -UDEBUG -c App/Enclave_u.c -o App/Enclave_u.o
g++ -m64 -O2 -fPIC -Wno-attributes -IApp -I/opt/intel/sgxsdk/include -Imbedtls/include -DNDEBUG -UEDEBUG -UDEBUG -std=c++11 -c App/App.cpp -o App/App.o
g++ -m64 -O2 -fPIC -Wno-attributes -IApp -I/opt/intel/sgxsdk/include -Imbedtls/include -DNDEBUG -UEDEBUG -UDEBUG -std=c++11 -c App/sgx_utils/sgx_utils.cpp -o App/sgx_utils/sgx_utils.o

After running those commands, it runs this command:

g++ App/Enclave_u.o App/App.o App/sgx_utils/sgx_utils.o -o app -m64 -O2 -L/opt/intel/sgxsdk/lib64 -lsgx_urts_sim -lpthread -Lmbedtls/lib/ -lsgx_uae_service_sim

However, this command produces an error:

App/Enclave_u.o: In function `Enclave_ocall_print_string':
Enclave_u.c:(.text+0x9): undefined reference to `ocall_print_string'
App/Enclave_u.o: In function `Enclave_ocall_mbedtls_net_free':
Enclave_u.c:(.text+0x28): undefined reference to `ocall_mbedtls_net_free'
App/Enclave_u.o: In function `Enclave_ocall_mbedtls_net_recv_timeout':
Enclave_u.c:(.text+0x54): undefined reference to `ocall_mbedtls_net_recv_timeout'
App/Enclave_u.o: In function `Enclave_ocall_mbedtls_net_send':
Enclave_u.c:(.text+0x71): undefined reference to `ocall_mbedtls_net_send'
App/Enclave_u.o: In function `Enclave_ocall_mbedtls_net_recv':
Enclave_u.c:(.text+0x91): undefined reference to `ocall_mbedtls_net_recv'
App/Enclave_u.o: In function `Enclave_ocall_mbedtls_net_usleep':
Enclave_u.c:(.text+0xa8): undefined reference to `ocall_mbedtls_net_usleep'
App/Enclave_u.o: In function `Enclave_ocall_mbedtls_net_set_nonblock':
Enclave_u.c:(.text+0xc9): undefined reference to `ocall_mbedtls_net_set_nonblock'
App/Enclave_u.o: In function `Enclave_ocall_mbedtls_net_set_block':
Enclave_u.c:(.text+0xe9): undefined reference to `ocall_mbedtls_net_set_block'
App/Enclave_u.o: In function `Enclave_ocall_mbedtls_net_accept':
Enclave_u.c:(.text+0x119): undefined reference to `ocall_mbedtls_net_accept'
App/Enclave_u.o: In function `Enclave_ocall_mbedtls_net_bind':
Enclave_u.c:(.text+0x144): undefined reference to `ocall_mbedtls_net_bind'
App/Enclave_u.o: In function `Enclave_ocall_mbedtls_net_connect':
Enclave_u.c:(.text+0x164): undefined reference to `ocall_mbedtls_net_connect'
collect2: error: ld returned 1 exit status
Makefile:184: recipe for target 'app' failed

I don't know why this error is being produced. My last command includes the flag -Lmbedtls/lib/ which should resolve these undefined references by linking the archive files (specifically - libmbedtls_SGX_u.a) to the executable. However, clearly this is not happening.

Do I need to link the archive files earlier in the compile process? I.e - instead of using the flag -Lmbedtls/lib/ in the final g++ command, should I be using it in both of the previous g++ commands?

Update: Adding the flag -Lmbedtls/lib/ to the previous 2 g++ commands (the ones that generated App.o and sgx_utils.o) did not change anything. The error remains.

Foobar
  • 7,458
  • 16
  • 81
  • 161
  • 3
    `-L` tells g++ where to look for `.a` files, not to actually link them, you have to specify `-llibmbedtls_SGX_u` – orhtej2 Nov 12 '18 at 22:14
  • 1
    In general you should mention files referencing a symbol *before* the file providing the symbol. Many (not all, but most) linkers will discard any symbol that they have not seen a previous reference to. – Jesper Juhl Nov 12 '18 at 22:14
  • @JesperJuhl Can you explain what the implications of your statement are in terms of the commands I should be executing? – Foobar Nov 12 '18 at 22:16
  • The implication is that whenever you tell your toolchain to link something you have to name the object files/libraries in an order where the ones that come first are the ones that consume/use symbols and the ones that *provide* the implementation come after. – Jesper Juhl Nov 12 '18 at 22:20
  • I think -pthread (not -lpthread). – 2785528 Nov 12 '18 at 23:03

1 Answers1

2

As has been mentioned in the comment, only specifying a directory with -L without specifying the name of a library in that directory is useless.

So you have to additionally specify the library names with -l.

So instead of:

g++ App/Enclave_u.o App/App.o App/sgx_utils/sgx_utils.o -o app -m64 -O2 \
   -L/opt/intel/sgxsdk/lib64 -lsgx_urts_sim -lpthread \
   -Lmbedtls/lib/ \
   -lsgx_uae_service_sim

Use:

g++ App/Enclave_u.o App/App.o App/sgx_utils/sgx_utils.o -o app -m64 -O2 \
   -L/opt/intel/sgxsdk/lib64 -lsgx_urts_sim -lpthread \
   -Lmbedtls/lib/ -lmbedtls_SGX_t -lmbedtls_SGX_u \
   -lsgx_uae_service_sim
Codo
  • 75,595
  • 17
  • 168
  • 206
  • I ran the command `g++ App/Enclave_u.o App/App.o App/sgx_utils/sgx_utils.o -o app -m64 -O2 -L/opt/intel/sgxsdk/lib64 -lsgx_urts_sim -lpthread -Lmbedtls/lib/ -llibmbedtls_SGX_u -lsgx_uae_service_sim` because I only wanted to link `libmbedtls_SGX_u.a`. However, suprisingly, I am getting the error: "cannot find -llibmbedtls_SGX_u" even though I am very sure that "libmbedtls_SGX_u.a" is inside of the "mbedtls/lib" directory. – Foobar Nov 12 '18 at 22:28
  • 3
    The command `-l` is peculiar. You have to specify the library name without the leading `lib`. So it's just `-lmbedtls_SGX_u` instead of `-llibmbedtls_SGX_u`. My initial answer was partially incorrect in that respect and you have probably been very quick in copying it. – Codo Nov 12 '18 at 22:32
  • Oh whoops, I thought you made a mistake by omitting the lib, so I left it in. – Foobar Nov 12 '18 at 22:34
  • Where can I go to learn more about how to use the g++ compiler, so I can avoid making these mistakes in the future? – Foobar Nov 12 '18 at 22:49
  • I don't think so. It's a library as well. Try `ls -l /usr/lib/*pthread*` if you have Linux, Unix or macOS as the operation system. – Codo Nov 12 '18 at 23:11
  • I once removed every -lpthread, because I read the recommendation with a convincing rationale (but can't remember it). I have no linking problems for threads (in all 78 makefiles), so maybe either is ok. See also: https://stackoverflow.com/a/37118591/2785528 – 2785528 Nov 12 '18 at 23:21
  • On lubuntu 18.04, "man pthreads" has no mention of -lpthread. and one mention of -pthread. – 2785528 Nov 12 '18 at 23:35