Procházet zdrojové kódy

Add macro to exclude sgx wasi/pthread ocalls if not needed (#384)

Xu Jun před 5 roky
rodič
revize
547298d4e7

+ 5 - 0
core/shared/platform/linux-sgx/sgx_file.c

@@ -7,6 +7,8 @@
 #include "sgx_error.h"
 #include "sgx_file.h"
 
+#ifndef SGX_DISABLE_WASI
+
 #define TRACE_FUNC() os_printf("undefined %s\n", __FUNCTION__)
 #define TRACE_OCALL_FAIL() os_printf("ocall %s failed!\n", __FUNCTION__)
 
@@ -830,3 +832,6 @@ int get_errno(void)
     }
     return ret;
 }
+
+#endif
+

+ 4 - 0
core/shared/platform/linux-sgx/sgx_pthread.c

@@ -7,6 +7,8 @@
 #include "sgx_pthread.h"
 #include "sgx_error.h"
 
+#ifndef SGX_DISABLE_WASI
+
 #define TRACE_FUNC() os_printf("undefined %s\n", __FUNCTION__)
 #define TRACE_OCALL_FAIL() os_printf("ocall %s failed!\n", __FUNCTION__)
 
@@ -73,3 +75,5 @@ int pthread_rwlock_unlock(pthread_rwlock_t *rwlock)
     return ret;
 }
 
+#endif
+

+ 4 - 0
core/shared/platform/linux-sgx/sgx_signal.c

@@ -5,6 +5,8 @@
 
 #include "platform_api_vmcore.h"
 
+#ifndef SGX_DISABLE_WASI
+
 #define TRACE_OCALL_FAIL() os_printf("ocall %s failed!\n", __FUNCTION__)
 
 int ocall_raise(int *p_ret, int sig);
@@ -24,3 +26,5 @@ int raise(int sig)
     return ret;
 }
 
+#endif
+

+ 5 - 1
core/shared/platform/linux-sgx/sgx_socket.c

@@ -5,8 +5,9 @@
 
 #include "platform_api_vmcore.h"
 
-#define TRACE_OCALL_FAIL() os_printf("ocall %s failed!\n", __FUNCTION__)
+#ifndef SGX_DISABLE_WASI
 
+#define TRACE_OCALL_FAIL() os_printf("ocall %s failed!\n", __FUNCTION__)
 
 int ocall_socket(int *p_ret, int domain, int type, int protocol);
 int ocall_getsockopt(int *p_ret, int sockfd, int level, int optname,
@@ -216,3 +217,6 @@ int shutdown(int sockfd, int how)
 
     return ret;
 }
+
+#endif
+

+ 35 - 1
core/shared/platform/linux-sgx/sgx_thread.c

@@ -6,6 +6,7 @@
 #include "platform_api_vmcore.h"
 #include "platform_api_extension.h"
 
+#ifndef SGX_DISABLE_PTHREAD
 typedef struct {
     thread_start_routine_t start;
     void *arg;
@@ -52,56 +53,79 @@ int os_thread_create(korp_tid *tid, thread_start_routine_t start, void *arg,
     return os_thread_create_with_prio(tid, start, arg, stack_size,
                                       BH_THREAD_DEFAULT_PRIORITY);
 }
+#endif
 
 korp_tid os_self_thread()
 {
+#ifndef SGX_DISABLE_PTHREAD
     return pthread_self();
+#else
+    return 0;
+#endif
 }
 
 int os_mutex_init(korp_mutex *mutex)
 {
+#ifndef SGX_DISABLE_PTHREAD
     pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
     *mutex = m;
+#endif
     return BHT_OK;
 }
 
 int os_mutex_destroy(korp_mutex *mutex)
 {
+#ifndef SGX_DISABLE_PTHREAD
     pthread_mutex_destroy(mutex);
+#endif
     return BHT_OK;
 }
 
 int os_mutex_lock(korp_mutex *mutex)
 {
+#ifndef SGX_DISABLE_PTHREAD
     return pthread_mutex_lock(mutex);
+#else
+    return 0;
+#endif
 }
 
 int os_mutex_unlock(korp_mutex *mutex)
 {
+#ifndef SGX_DISABLE_PTHREAD
     return pthread_mutex_unlock(mutex);
+#else
+    return 0;
+#endif
 }
 
 int os_cond_init(korp_cond *cond)
 {
+#ifndef SGX_DISABLE_PTHREAD
     pthread_cond_t c = PTHREAD_COND_INITIALIZER;
     *cond = c;
+#endif
     return BHT_OK;
 }
 
 int os_cond_destroy(korp_cond *cond)
 {
+#ifndef SGX_DISABLE_PTHREAD
     pthread_cond_destroy(cond);
+#endif
     return BHT_OK;
 }
 
 int os_cond_wait(korp_cond *cond, korp_mutex *mutex)
 {
+#ifndef SGX_DISABLE_PTHREAD
     assert(cond);
     assert(mutex);
 
     if (pthread_cond_wait(cond, mutex) != BHT_OK)
         return BHT_ERROR;
 
+#endif
     return BHT_OK;
 }
 
@@ -114,17 +138,23 @@ int os_cond_reltimedwait(korp_cond *cond, korp_mutex *mutex, int useconds)
 
 int os_cond_signal(korp_cond *cond)
 {
+#ifndef SGX_DISABLE_PTHREAD
     assert(cond);
 
     if (pthread_cond_signal(cond) != BHT_OK)
         return BHT_ERROR;
 
+#endif
     return BHT_OK;
 }
 
 int os_thread_join(korp_tid thread, void **value_ptr)
 {
+#ifndef SGX_DISABLE_PTHREAD
     return pthread_join(thread, value_ptr);
+#else
+    return 0;
+#endif
 }
 
 int os_thread_detach(korp_tid thread)
@@ -135,7 +165,11 @@ int os_thread_detach(korp_tid thread)
 
 void os_thread_exit(void *retval)
 {
-    return pthread_exit(retval);
+#ifndef SGX_DISABLE_PTHREAD
+    pthread_exit(retval);
+#else
+    return;
+#endif
 }
 
 uint8 *os_thread_get_stack_boundary()

+ 5 - 0
core/shared/platform/linux-sgx/sgx_time.c

@@ -28,6 +28,8 @@ os_time_get_boot_microsecond()
     return 0;
 }
 
+#ifndef SGX_DISABLE_WASI
+
 int clock_getres(int clock_id, struct timespec *res)
 {
     int ret;
@@ -113,3 +115,6 @@ int clock_nanosleep(clockid_t clock_id, int flags,
 
     return ret;
 }
+
+#endif
+

+ 8 - 0
core/shared/platform/linux-sgx/shared_platform.cmake

@@ -20,6 +20,14 @@ if (NOT BUILD_UNTRUST_PART EQUAL 1)
                        ${SGX_SDK_DIR}/include/libcxx)
 endif ()
 
+if (NOT WAMR_BUILD_LIBC_WASI EQUAL 1)
+  add_definitions(-DSGX_DISABLE_WASI)
+endif ()
+
+if (NOT WAMR_BUILD_THREAD_MGR EQUAL 1)
+  add_definitions(-DSGX_DISABLE_PTHREAD)
+endif ()
+
 file (GLOB source_all ${PLATFORM_SHARED_DIR}/*.c)
 
 file (GLOB source_all_untrusted ${PLATFORM_SHARED_DIR}/untrusted/*.c)

+ 15 - 0
doc/linux_sgx.md

@@ -39,12 +39,25 @@ or:
 iwasm [-options] aot_file [args...]
 ```
 
+### Minimal build
+The libc-WASI and lib-pthread features require a lot of ocalls, if you don't need so much ocalls in your application, you can use the `minimal` version
+
+``` Bash
+# replace the build files with minimal version
+cd product-mini/platforms/linux-sgx/
+cp CMakeLists_minimal.txt CMakeLists.txt
+cp enclave-sample/Makefile_minimal enclave-sample/Makefile
+cp enclave-sample/Enclave/Enclave_minimal.edl enclave-sample/Enclave/Enclave.edl
+# follow the building process above
+```
+
 Port WAMR vmcore for Linux SGX
 ------------------------------
 
 The enclave-sample creates a sample to embed wamr vmlib of Enclave part and App part to an SGX application. To port WAMR vmcore lib to SGX application, there are some steps to do:
 
 **Step 1: Add "sgx_wamr.edl" and "sgx_pthread.edl" into EDL file, e.g. Enclave.edl:**
+> This step is not required in minimal version
 
 ```bash
 from "sgx_pthread.edl" import *;
@@ -68,6 +81,7 @@ The sgx_wamr.edl is under ${WAMR_ROOT}/core/shared/platform/linux-sgx, so please
 ```
 
 **Step 2: Link libvmlib.a to Enclave part and link libvmlib_untrusted.a to App part:**
+> libvmlib_untrusted.a is not required in minimal version
 
 ```makefile
 Enclave_Link_Flags := ... libvmlib.a ...
@@ -78,6 +92,7 @@ App_Link_Flags := ... libvmlib_untrusted.a ...
 ```
 
 **And link SGX pthread lib to Enclave part:**
+> SGX pthread lib is not required in minimal version
 
 ```makefile
 Enclave_Link_Flags := ... -lsgx_pthread ...

+ 90 - 0
product-mini/platforms/linux-sgx/CMakeLists_minimal.txt

@@ -0,0 +1,90 @@
+# Copyright (C) 2019 Intel Corporation.  All rights reserved.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+cmake_minimum_required (VERSION 2.8)
+
+project (iwasm)
+
+set (WAMR_BUILD_PLATFORM "linux-sgx")
+
+# Reset default linker flags
+set (CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
+set (CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "")
+
+# Set WAMR_BUILD_TARGET
+if (NOT DEFINED WAMR_BUILD_TARGET)
+  if (CMAKE_SIZEOF_VOID_P EQUAL 8)
+    # Build as X86_64 by default in 64-bit platform
+    set (WAMR_BUILD_TARGET "X86_64")
+  else ()
+    # Build as X86_32 by default in 32-bit platform
+    set (WAMR_BUILD_TARGET "X86_32")
+  endif ()
+endif ()
+
+if (NOT CMAKE_BUILD_TYPE)
+  set(CMAKE_BUILD_TYPE Release)
+endif ()
+
+if (NOT DEFINED WAMR_BUILD_INTERP)
+  # Enable Interpreter by default
+  set (WAMR_BUILD_INTERP 1)
+endif ()
+
+if (NOT DEFINED WAMR_BUILD_AOT)
+  # Enable AOT by default
+  # Please install Intel SGX SDKv2.8 or later.
+  set (WAMR_BUILD_AOT 1)
+endif ()
+
+if (NOT DEFINED WAMR_BUILD_JIT)
+  # Disable JIT by default.
+  set (WAMR_BUILD_JIT 0)
+endif ()
+
+if (NOT DEFINED WAMR_BUILD_LIBC_BUILTIN)
+  # Enable libc builtin support by default
+  set (WAMR_BUILD_LIBC_BUILTIN 1)
+endif ()
+
+if (NOT DEFINED WAMR_BUILD_LIBC_WASI)
+  # Enable libc wasi support by default
+  set (WAMR_BUILD_LIBC_WASI 0)
+endif ()
+
+if (NOT DEFINED WAMR_BUILD_FAST_INTERP)
+  # Enable fast interpreter
+  set (WAMR_BUILD_FAST_INTERP 1)
+endif ()
+
+if (NOT DEFINED WAMR_BUILD_MULTI_MODULE)
+  # Enable multiple modules
+  set (WAMR_BUILD_MULTI_MODULE 0)
+endif ()
+
+if (NOT DEFINED WAMR_BUILD_LIB_PTHREAD)
+  # Enable pthread library by default
+  set (WAMR_BUILD_LIB_PTHREAD 0)
+endif ()
+
+if (COLLECT_CODE_COVERAGE EQUAL 1)
+  set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage")
+endif ()
+
+set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections")
+set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99 -ffunction-sections -fdata-sections \
+                                     -Wall -Wno-unused-parameter -Wno-pedantic \
+                                     -nostdinc -fvisibility=hidden -fpie" )
+
+set (WAMR_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../..)
+
+include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake)
+add_library(vmlib ${WAMR_RUNTIME_LIB_SOURCE})
+
+add_custom_command (
+             OUTPUT libvmlib_untrusted.a
+             COMMAND mkdir -p untrusted && cd untrusted &&
+                     ${CMAKE_C_COMPILER} -c ${PLATFORM_SHARED_SOURCE_UNTRUSTED}
+             COMMAND ${CMAKE_AR} rc libvmlib_untrusted.a untrusted/*.o)
+
+add_custom_target (vmlib_untrusted ALL DEPENDS libvmlib_untrusted.a)

+ 8 - 0
product-mini/platforms/linux-sgx/enclave-sample/Enclave/Enclave.cpp

@@ -300,6 +300,7 @@ handle_cmd_set_log_level(uint64 *args, uint32 argc)
 #endif
 }
 
+#ifndef SGX_DISABLE_WASI
 static void
 handle_cmd_set_wasi_args(uint64 *args, int32 argc)
 {
@@ -391,6 +392,13 @@ handle_cmd_set_wasi_args(uint64 *args, int32 argc)
 
     *args_org = true;
 }
+#else
+static void
+handle_cmd_set_wasi_args(uint64 *args, int32 argc)
+{
+    *args = true;
+}
+#endif /* end of SGX_DISABLE_WASI */
 
 void
 ecall_handle_command(unsigned cmd,

+ 0 - 1
product-mini/platforms/linux-sgx/enclave-sample/Enclave/Enclave.edl

@@ -15,7 +15,6 @@ enclave {
                                          unsigned cmd_buf_size);
         public void ecall_iwasm_main([user_check]uint8_t *wasm_file_buf,
                                      uint32_t wasm_file_size);
-        public void ecall_iwasm_test();
     };
 
     untrusted {

+ 22 - 0
product-mini/platforms/linux-sgx/enclave-sample/Enclave/Enclave_minimal.edl

@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2019 Intel Corporation.  All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ */
+
+enclave {
+    from "sgx_tstdc.edl" import *;
+
+    trusted {
+        /* define ECALLs here. */
+        public void ecall_handle_command(unsigned cmd,
+                                         [in, out, size=cmd_buf_size]uint8_t *cmd_buf,
+                                         unsigned cmd_buf_size);
+        public void ecall_iwasm_main([user_check]uint8_t *wasm_file_buf,
+                                     uint32_t wasm_file_size);
+    };
+
+    untrusted {
+        /* define OCALLs here. */
+        void ocall_print([in, string]const char* str);
+    };
+};

+ 1 - 1
product-mini/platforms/linux-sgx/enclave-sample/Makefile

@@ -90,7 +90,7 @@ Crypto_Library_Name := sgx_tcrypto
 
 WAMR_ROOT := $(CURDIR)/../../../../
 
-Enclave_Cpp_Files := Enclave/Enclave.cpp Enclave/Enclave_test.cpp
+Enclave_Cpp_Files := Enclave/Enclave.cpp
 
 Enclave_Include_Paths := -IEnclave -I$(WAMR_ROOT)/core/iwasm/include \
                          -I$(WAMR_ROOT)/core/shared/utils \

+ 210 - 0
product-mini/platforms/linux-sgx/enclave-sample/Makefile_minimal

@@ -0,0 +1,210 @@
+# Copyright (C) 2019 Intel Corporation.  All rights reserved.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+######## SGX SDK Settings ########
+
+SGX_SDK ?= /opt/intel/sgxsdk
+SGX_MODE ?= SIM
+SGX_ARCH ?= x64
+SGX_DEBUG ?= 0
+SPEC_TEST ?= 0
+
+ifeq ($(shell getconf LONG_BIT), 32)
+	SGX_ARCH := x86
+else ifeq ($(findstring -m32, $(CXXFLAGS)), -m32)
+	SGX_ARCH := x86
+endif
+
+ifeq ($(SGX_ARCH), x86)
+	SGX_COMMON_CFLAGS := -m32
+	SGX_LIBRARY_PATH := $(SGX_SDK)/lib
+	SGX_ENCLAVE_SIGNER := $(SGX_SDK)/bin/x86/sgx_sign
+	SGX_EDGER8R := $(SGX_SDK)/bin/x86/sgx_edger8r
+else
+	SGX_COMMON_CFLAGS := -m64
+	SGX_LIBRARY_PATH := $(SGX_SDK)/lib64
+	SGX_ENCLAVE_SIGNER := $(SGX_SDK)/bin/x64/sgx_sign
+	SGX_EDGER8R := $(SGX_SDK)/bin/x64/sgx_edger8r
+endif
+
+ifeq ($(SGX_DEBUG), 1)
+ifeq ($(SGX_PRERELEASE), 1)
+$(error Cannot set SGX_DEBUG and SGX_PRERELEASE at the same time!!)
+endif
+endif
+
+ifeq ($(SGX_DEBUG), 1)
+	SGX_COMMON_CFLAGS += -O0 -g
+else
+	SGX_COMMON_CFLAGS += -O2
+endif
+
+######## App Settings ########
+
+ifneq ($(SGX_MODE), HW)
+	Urts_Library_Name := sgx_urts_sim
+else
+	Urts_Library_Name := sgx_urts
+endif
+
+App_Cpp_Files := App/App.cpp
+App_Include_Paths := -IApp -I$(SGX_SDK)/include
+
+App_C_Flags := $(SGX_COMMON_CFLAGS) -fPIC -Wno-attributes $(App_Include_Paths)
+
+# Three configuration modes - Debug, prerelease, release
+#   Debug - Macro DEBUG enabled.
+#   Prerelease - Macro NDEBUG and EDEBUG enabled.
+#   Release - Macro NDEBUG enabled.
+ifeq ($(SGX_DEBUG), 1)
+	App_C_Flags += -DDEBUG -UNDEBUG -UEDEBUG
+else ifeq ($(SGX_PRERELEASE), 1)
+	App_C_Flags += -DNDEBUG -DEDEBUG -UDEBUG
+else
+	App_C_Flags += -DNDEBUG -UEDEBUG -UDEBUG
+endif
+
+App_Cpp_Flags := $(App_C_Flags) -std=c++11
+App_Link_Flags := $(SGX_COMMON_CFLAGS) -L$(SGX_LIBRARY_PATH) -l$(Urts_Library_Name) -lpthread
+
+ifneq ($(SGX_MODE), HW)
+	App_Link_Flags += -lsgx_uae_service_sim
+else
+	App_Link_Flags += -lsgx_uae_service
+endif
+
+App_Cpp_Objects := $(App_Cpp_Files:.cpp=.o)
+
+App_Name := iwasm
+
+######## Enclave Settings ########
+
+ifneq ($(SGX_MODE), HW)
+	Trts_Library_Name := sgx_trts_sim
+	Service_Library_Name := sgx_tservice_sim
+else
+	Trts_Library_Name := sgx_trts
+	Service_Library_Name := sgx_tservice
+endif
+Crypto_Library_Name := sgx_tcrypto
+
+WAMR_ROOT := $(CURDIR)/../../../../
+
+Enclave_Cpp_Files := Enclave/Enclave.cpp
+
+Enclave_Include_Paths := -IEnclave -I$(WAMR_ROOT)/core/iwasm/include \
+                         -I$(WAMR_ROOT)/core/shared/utils \
+                         -I$(WAMR_ROOT)/core/shared/platform/linux-sgx \
+                         -I$(SGX_SDK)/include \
+                         -I$(SGX_SDK)/include/tlibc \
+                         -I$(SGX_SDK)/include/stlport
+
+Enclave_C_Flags := $(SGX_COMMON_CFLAGS) -nostdinc -fvisibility=hidden -fpie -fstack-protector $(Enclave_Include_Paths)
+
+# disable wasi
+Enclave_C_Flags += -DSGX_DISABLE_WASI
+
+ifeq ($(SPEC_TEST), 1)
+	Enclave_C_Flags += -DWASM_ENABLE_SPEC_TEST=1
+else
+	Enclave_C_Flags += -DWASM_ENABLE_SPEC_TEST=0
+endif
+Enclave_Cpp_Flags := $(Enclave_C_Flags) -std=c++03 -nostdinc++
+Enclave_Link_Flags := $(SGX_COMMON_CFLAGS) -Wl,--no-undefined -nostdlib -nodefaultlibs -nostartfiles -L$(SGX_LIBRARY_PATH) \
+	-Wl,--whole-archive -l$(Trts_Library_Name) -Wl,--no-whole-archive \
+    libvmlib.a \
+	-Wl,--start-group -lsgx_tstdc -lsgx_tcxx -l$(Crypto_Library_Name) -l$(Service_Library_Name) -Wl,--end-group \
+	-Wl,-Bstatic -Wl,-Bsymbolic -Wl,--no-undefined \
+	-Wl,-pie,-eenclave_entry -Wl,--export-dynamic  \
+	-Wl,--defsym,__ImageBase=0
+
+Enclave_Cpp_Objects := $(Enclave_Cpp_Files:.cpp=.o)
+
+Enclave_Name := enclave.so
+Signed_Enclave_Name := enclave.signed.so
+Enclave_Config_File := Enclave/Enclave.config.xml
+
+ifeq ($(SGX_MODE), HW)
+ifneq ($(SGX_DEBUG), 1)
+ifneq ($(SGX_PRERELEASE), 1)
+Build_Mode = HW_RELEASE
+endif
+endif
+endif
+
+
+.PHONY: all run
+
+ifeq ($(Build_Mode), HW_RELEASE)
+all: $(App_Name) $(Enclave_Name)
+	@echo "The project has been built in release hardware mode."
+	@echo "Please sign the $(Enclave_Name) first with your signing key before you run the $(App_Name) to launch and access the enclave."
+	@echo "To sign the enclave use the command:"
+	@echo "   $(SGX_ENCLAVE_SIGNER) sign -key <your key> -enclave $(Enclave_Name) -out <$(Signed_Enclave_Name)> -config $(Enclave_Config_File)"
+	@echo "You can also sign the enclave using an external signing tool. See User's Guide for more details."
+	@echo "To build the project in simulation mode set SGX_MODE=SIM. To build the project in prerelease mode set SGX_PRERELEASE=1 and SGX_MODE=HW."
+else
+all: $(App_Name) $(Signed_Enclave_Name)
+endif
+
+run: all
+ifneq ($(Build_Mode), HW_RELEASE)
+	@$(CURDIR)/$(App_Name)
+	@echo "RUN  =>  $(App_Name) [$(SGX_MODE)|$(SGX_ARCH), OK]"
+endif
+
+######## App Objects ########
+
+App/Enclave_u.c: $(SGX_EDGER8R) Enclave/Enclave.edl
+	@cd App && $(SGX_EDGER8R) --untrusted ../Enclave/Enclave.edl \
+		--search-path ../Enclave \
+		--search-path $(SGX_SDK)/include \
+		--search-path $(WAMR_ROOT)/core/shared/platform/linux-sgx
+	@echo "GEN  =>  $@"
+
+App/Enclave_u.o: App/Enclave_u.c
+	@$(CC) $(App_C_Flags) -c $< -o $@
+	@echo "CC   <=  $<"
+
+App/%.o: App/%.cpp
+	@$(CXX) $(App_Cpp_Flags) -c $< -o $@
+	@echo "CXX  <=  $<"
+
+$(App_Name): App/Enclave_u.o $(App_Cpp_Objects)
+	@$(CXX) $^ -o $@ $(App_Link_Flags)
+	@echo "LINK =>  $@"
+
+
+######## Enclave Objects ########
+
+Enclave/Enclave_t.c: $(SGX_EDGER8R) Enclave/Enclave.edl
+	@cd Enclave && $(SGX_EDGER8R) --trusted ../Enclave/Enclave.edl \
+		--search-path ../Enclave \
+		--search-path $(SGX_SDK)/include \
+		--search-path $(WAMR_ROOT)/core/shared/platform/linux-sgx
+	@echo "GEN  =>  $@"
+
+Enclave/Enclave_t.o: Enclave/Enclave_t.c
+	@$(CC) $(Enclave_C_Flags) -c $< -o $@
+	@echo "CC   <=  $<"
+
+Enclave/%.o: Enclave/%.cpp
+	@$(CXX) $(Enclave_Cpp_Flags) -c $< -o $@
+	@echo "CXX  <=  $<"
+
+libvmlib.a: ../build/libvmlib.a
+	@cp $< $@
+	@echo "CP $@  <=  $<"
+
+$(Enclave_Name): Enclave/Enclave_t.o $(Enclave_Cpp_Objects) libvmlib.a
+	@$(CXX) $^ -o $@ $(Enclave_Link_Flags)
+	@echo "LINK =>  $@"
+
+$(Signed_Enclave_Name): $(Enclave_Name)
+	@$(SGX_ENCLAVE_SIGNER) sign -key Enclave/Enclave_private.pem -enclave $(Enclave_Name) -out $@ -config $(Enclave_Config_File)
+	@echo "SIGN =>  $@"
+
+.PHONY: clean
+
+clean:
+	@rm -f $(App_Name) $(Enclave_Name) $(Signed_Enclave_Name) $(App_Cpp_Objects) App/Enclave_u.* $(Enclave_Cpp_Objects) Enclave/Enclave_t.* libvmlib.a