Skip to content

Commit

Permalink
CMake conversion of OE, step 2
Browse files Browse the repository at this point in the history
The fudamentals are in place:
- build & install of 3rd-party projects
- build & install of libs & tools
- build & execute tests
  + manual HW/sim distinction
- std build configs (none, debug/release/relwithdebug)

Not yet:
- config-script (thereby sample intregration)
  + review prereqs
  + cmake packaging...
- docs/ are POD makefile for Linux only
- review scripts
- enable & doc valgrind usage
- polishing
  + libunwind: pass build config through configure/automake
  + misc bits here and there
  • Loading branch information
jorkl committed Nov 18, 2017
1 parent ee17ba5 commit 9bf881b
Show file tree
Hide file tree
Showing 94 changed files with 1,202 additions and 37 deletions.
7 changes: 7 additions & 0 deletions 3rdparty/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Note: order does matter

add_subdirectory(libcxx)
add_subdirectory(libcxxrt)
add_subdirectory(libunwind)
add_subdirectory(musl)
add_subdirectory(mbedtls) # after musl
85 changes: 85 additions & 0 deletions 3rdparty/libcxx/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Copy headers to collector-dir, patch, compile libcxx into intermittent library
# place install rule

# Use an external project to place the headers in the collector-dir
include (ExternalProject)
ExternalProject_Add(oelibcxx_cxx_includes
DOWNLOAD_COMMAND ""
CONFIGURE_COMMAND ""
BUILD_COMMAND ${CMAKE_COMMAND} -E copy_directory
${CMAKE_CURRENT_LIST_DIR}/libcxx/include ${OE_INCDIR}/openenclave/libcxx
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_LIST_DIR}/libcxx/include/__config ${OE_INCDIR}/openenclave/libcxx/__config_original
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_LIST_DIR}/__config ${OE_INCDIR}/openenclave/libcxx/__config
INSTALL_COMMAND ""
)
install (DIRECTORY ${OE_INCDIR}/openenclave/libcxx DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/openenclave)

# build sources

add_library(oelibcxx_cxx STATIC
__dso_handle.cpp

libcxx/src/algorithm.cpp
libcxx/src/any.cpp
libcxx/src/bind.cpp
libcxx/src/chrono.cpp
libcxx/src/condition_variable.cpp
libcxx/src/debug.cpp
libcxx/src/exception.cpp
libcxx/src/functional.cpp
libcxx/src/future.cpp
libcxx/src/hash.cpp
libcxx/src/ios.cpp
libcxx/src/iostream.cpp
libcxx/src/locale.cpp
libcxx/src/memory.cpp
libcxx/src/mutex.cpp
libcxx/src/new.cpp
libcxx/src/optional.cpp
libcxx/src/random.cpp
libcxx/src/regex.cpp
libcxx/src/shared_mutex.cpp
libcxx/src/stdexcept.cpp
libcxx/src/string.cpp
libcxx/src/strstream.cpp
libcxx/src/system_error.cpp
libcxx/src/thread.cpp
libcxx/src/typeinfo.cpp
libcxx/src/utility.cpp
libcxx/src/valarray.cpp
libcxx/src/variant.cpp
libcxx/src/vector.cpp
)

target_compile_options(oelibcxx_cxx PRIVATE
-nostdinc
-nostdinc++

-w

-std=c++14
-fPIC
)

target_compile_definitions(oelibcxx_cxx PRIVATE
-DLIBCXXRT
-D_LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE
-D_LIBCPP_BUILDING_LIBRARY
)

# need the LIBCXX_CXX headers placed
add_dependencies(oelibcxx_cxx oelibcxx_cxx_includes)
# this project and its dependents require include/libcxx in the include path
target_include_directories(oelibcxx_cxx PUBLIC ${OE_INCDIR}/openenclave/libcxx)

# this project (and is dependents) require the LIBC includes
target_link_libraries(oelibcxx_cxx PUBLIC oelibc)
# If we built an OBJECT library, we would want to do the following, though CMake does not allow
# using target_link_libraries on an OBJECT lib (yet?):
#add_dependencies(oelibcxx_cxx oelibc)
#target_include_directories(oelibcxx_cxx PUBLIC ${OE_INCDIR}/libc)

# when building this project, we also need a number of internal includes
target_include_directories(oelibcxx_cxx PRIVATE libcxx/src)
target_include_directories(oelibcxx_cxx PRIVATE ${CMAKE_SOURCE_DIR}/3rdparty/libcxxrt/libcxxrt/src)

12 changes: 12 additions & 0 deletions 3rdparty/libcxxrt/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Compile CXXRT

# build cxxrt sources passing additional options
add_subdirectory(libcxxrt/src)
target_compile_options(cxxrt-static PRIVATE
-include ${CMAKE_CURRENT_SOURCE_DIR}/stubs.h
-fPIC
# cannot use add_link_libraries on out-of-dir target
-nostdinc
-I${OE_INCDIR}/openenclave/libc
)
add_dependencies(cxxrt-static oelibc_includes)
25 changes: 25 additions & 0 deletions 3rdparty/libunwind/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Copy libunwind sources and build out-of-tree

set (OELIBCXX_UNWIND_OPTS
--enable-shared=no
--disable-block-signals
--enable-debug=no
--enable-debug-frame==no
--enable-cxx-exceptions
)

set (OELIBCXX_UNWIND_CFLAGS
"-DUNW_LOCAL_ONLY -DWSIZE=8 -fno-builtin -fPIC -DOPEN_ENCLAVE -include ${CMAKE_CURRENT_SOURCE_DIR}/stubs.h"
)

include (ExternalProject)
ExternalProject_Add(oelibcxx_unwind
DOWNLOAD_COMMAND ${CMAKE_COMMAND} -E copy_directory
${CMAKE_CURRENT_LIST_DIR}/libunwind ${CMAKE_CURRENT_BINARY_DIR}/libunwind
CONFIGURE_COMMAND cd ${CMAKE_CURRENT_BINARY_DIR}/libunwind &&
./autogen.sh
COMMAND cd ${CMAKE_CURRENT_BINARY_DIR}/libunwind &&
./configure "${OELIBCXX_UNWIND_OPTS}" "CFLAGS=${OELIBCXX_UNWIND_CFLAGS}"
BUILD_COMMAND $(MAKE) -C ${CMAKE_CURRENT_BINARY_DIR}/libunwind/src
INSTALL_COMMAND ""
)
40 changes: 40 additions & 0 deletions 3rdparty/mbedtls/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Copy mbedtls sources to replace config.h and build w/ own flags

set(MBEDTLS_WRAP_CFLAGS "-nostdinc -I${OE_INCDIR}/openenclave/libc -fPIC -fno-builtin-udivti3")

include (ExternalProject)
ExternalProject_Add(mbedtls-wrap
DEPENDS oelibc_includes

DOWNLOAD_COMMAND ${CMAKE_COMMAND} -E copy_directory
${CMAKE_CURRENT_LIST_DIR}/mbedtls <SOURCE_DIR>
PATCH_COMMAND ${CMAKE_COMMAND} -E copy_if_different
${CMAKE_CURRENT_SOURCE_DIR}/config.h <SOURCE_DIR>/include/mbedtls/config.h

# Addl args for compiler
CMAKE_ARGS
-DCMAKE_C_FLAGS=${MBEDTLS_WRAP_CFLAGS}
-DENABLE_PROGRAMS=OFF
-DENABLE_TESTING=OFF
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}

# copy headers/libs
INSTALL_COMMAND ${CMAKE_COMMAND} -E copy_directory
<SOURCE_DIR>/include/mbedtls ${OE_INCDIR}/openenclave/oe-mbedtls/mbedtls
COMMAND ${CMAKE_COMMAND} -E copy
<BINARY_DIR>/library/libmbedcrypto.a ${OE_LIBDIR}/openenclave/enclave/
)
install (DIRECTORY ${OE_INCDIR}/openenclave/oe-mbedtls DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/openenclave)
install (FILES ${OE_LIBDIR}/openenclave/enclave/libmbedcrypto.a DESTINATION ${CMAKE_INSTALL_LIBDIR}/openenclave/enclave)

# Convenience lib for use in target_link_libraries
add_library(mbedcrypto INTERFACE)
add_dependencies(mbedcrypto mbedtls-wrap)
target_include_directories(mbedcrypto INTERFACE ${OE_INCDIR}/openenclave/oe-mbedtls)
target_link_libraries(mbedcrypto INTERFACE ${OE_LIBDIR}/openenclave/enclave/libmbedcrypto.a)
# For the libc dependency, We would just want to use "oelibc". However, we need
# an actual lib-dependency between crypto an libc, which is not expressable
# with CMake. If using the target "oelibc", CMake reorders the libs, resulting
# in undefined LIBC symbols from crypto. Using the explicit lib-name preserves
# order.
target_link_libraries(mbedcrypto INTERFACE ${OE_LIBDIR}/openenclave/enclave/liboelibc.a)
49 changes: 49 additions & 0 deletions 3rdparty/musl/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Copy MUSL headers to collector dir and wrap
# actual compilation and lib-generation happens in <ROOT>/libc/

include (ExternalProject)
ExternalProject_Add(oelibc_includes
DOWNLOAD_COMMAND ${CMAKE_COMMAND} -E copy_directory
${CMAKE_CURRENT_LIST_DIR}/musl ${CMAKE_CURRENT_BINARY_DIR}/musl
CONFIGURE_COMMAND ${CMAKE_COMMAND} -E chdir ${CMAKE_CURRENT_BINARY_DIR}/musl
./configure --includedir=${OE_INCDIR}/openenclave/libc CFLAGS=-fPIC
BUILD_COMMAND ${CMAKE_COMMAND} -E chdir ${CMAKE_CURRENT_BINARY_DIR}/musl
make install-headers
COMMAND $(CMAKE_COMMAND)
-DWRAP_DST=${OE_INCDIR}/openenclave/libc/endian.h
-DWRAP_SRC=${CMAKE_CURRENT_LIST_DIR}/musl/include/endian.h
-DWRAP_PRE=${CMAKE_CURRENT_LIST_DIR}/endian.h.prefix
-DWRAP_SUF=${CMAKE_CURRENT_LIST_DIR}/endian.h.suffix
-P ${CMAKE_SOURCE_DIR}/cmake/wrap.cmake
BUILD_BYPRODUCTS ${OE_INCDIR}/openenclave/libc ${CMAKE_CURRENT_BINARY_DIR}/musl
INSTALL_COMMAND ""
)

# install-rule can be generated here, usage requirements defined in <ROOT>/libc/.
install (DIRECTORY ${OE_INCDIR}/openenclave/libc DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/openenclave)

#
# genearl tidbits follow - find a better home
#
# To get it to build on Windows - bypassing configure - we could:
#
#BUILD_COMMAND ${CMAKE_COMMAND} -E copy_directory
# ${CMAKE_CURRENT_SOURCE_DIR}/musl/include ${OE_INCDIR}/openenclave/libc
# COMMAND ${CMAKE_COMMAND} -E copy_directory
# ${CMAKE_CURRENT_SOURCE_DIR}/musl/arch/x86_64/bits ${OE_INCDIR}/openenclave/libc/bits
#
# still required creation of alltypes.h. Wrap as per above.

# This does not work with an ExternalProject_Add'ed project
#target_include_directories(oelibc_includes_copy INTERFACE ${OE_INCDIR}/openenclave/libc)
# use an interface library instead

# alternative to wrapping with newer CMake (3.10+) - use patch instead of wrap:
#find_package(Patch)
#if(!Patch_FOUND)
# message(FATAL_ERROR "Patch command not found")
#endif()

#add_custom_command(TARGET oe_libc_includes PRE_BUILD
# COMMAND ${CMAKE_COMMAND} -E chdir ${OE_INCDIR}/openenclave/libc ${Patch_EXECUTABLE} -p1 < ${CMAKE_SOURCE_DIR}/endian.h.patch
# )
21 changes: 16 additions & 5 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,27 @@
#
cmake_minimum_required(VERSION 3.5.1)

include(GNUInstallDirs)
# allow simpler include() of our scripts
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")

# sanitize build type
string(TOUPPER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE)

enable_language(C ASM)
enable_testing()
enable_language(ASM C CXX)

set(OE_OUTPUT_DIR ${CMAKE_BINARY_DIR}/output CACHE PATH "Path to the intermittent output tree")
include(GNUInstallDirs)
set(OE_OUTPUT_DIR ${CMAKE_BINARY_DIR}/output CACHE PATH "Path to the intermittent collector tree")
set(OE_BINDIR ${OE_OUTPUT_DIR}/bin CACHE PATH "Binary collector")
set(OE_INCDIR ${OE_OUTPUT_DIR}/include CACHE PATH "Include collector")
set(OE_LIBDIR ${OE_OUTPUT_DIR}/lib CACHE PATH "Library collector")

add_subdirectory(3rdparty)
add_subdirectory(enclave)
add_subdirectory(host)
add_subdirectory(include)
add_subdirectory(host) # convertable to Windows
add_subdirectory(idl)
add_subdirectory(include) # convertable to Windows
add_subdirectory(libc)
add_subdirectory(libcxx)
add_subdirectory(tests)
add_subdirectory(tools)
52 changes: 52 additions & 0 deletions cmake/add_enclave_executable.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@

# Helper function to create enclave binary
#
# Generates a target for an enclave binary
#
# Usage:
#
# add_enclave_executable(
# <name> <signconffile> <signkeyfile>
# source1 [source2...]
#
# Target properties can be set on <name>, see add_executable for details.
#
# Restrictions: A number of subtleties are not handled, such as
# - RUNTIME_OUTPUT_DIRECTORY property is not handled correctly
# - the resulting binary name is not reflected by the target
# (complicating install rules)
#
function(add_enclave_executable BIN SIGNCONF KEYFILE)
add_executable(${BIN} ${ARGN})

# enclave-specific compile options
# these should perhaps go to oeenclave usage properties
target_compile_options(${BIN} PRIVATE
-m64 -nostdinc -fPIC -fno-stack-protector
$<$<COMPILE_LANGUAGE:CXX>:-std=c++14 -nostdinc++>
)
# enclave-specific link options
# these should perhaps go to oeenclave usage properties
target_link_libraries(${BIN}
-Wl,--no-undefined -nostdlib -nodefaultlibs -nostartfiles
-Wl,-Bstatic -Wl,-Bsymbolic -Wl,--export-dynamic -Wl,-pie -Wl,-eOE_Main
)

# enclaves depend on the oeenclave lib
target_link_libraries(${BIN} oeenclave)

# custom rule to symlink the the binary to a name oesign understands
add_custom_command(OUTPUT ${BIN}.so
COMMAND ln -sf ${BIN} $<TARGET_FILE:${BIN}>.so
)
# custom rule to sign the binary
add_custom_command(OUTPUT ${BIN}.signed.so
COMMAND oesign $<TARGET_FILE:${BIN}>.so ${SIGNCONF} ${KEYFILE}
DEPENDS oesign $<TARGET_FILE:${BIN}>.so ${BIN} ${SIGNCONF} ${KEYFILE}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
# signed binary is a default target
add_custom_target(${BIN}-signed ALL
DEPENDS ${BIN}.signed.so
)
endfunction(add_enclave_executable)
54 changes: 54 additions & 0 deletions cmake/oeidl_file.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#
# Helper function to handle IDL (gen) files
#
# Create custom-command to generate .c/.h-file for a given IDL-file
# into CMAKE_CURRENT_BINARY_DIR and set misc properties on files.
#
# Usage:
#
# oeidl_file(
# <idl_file> <type> <out_files_var>
#
# Arguments:
# idl_file - name of the IDL file
# type - type of files to genreate ("enclave" or "host")
# out_files_var - variable to get the generated files added to
#
function(oeidl_file IDL_FILE TYPE OUT_FILES_VAR)
if(${TYPE} STREQUAL "enclave")
set(type_id "t")
elseif(${TYPE} STREQUAL "host")
set(type_id "u")
else()
message(FATAL_ERROR "unknown IDL generation type ${TYPE} - must be \"enclave\" or \"host\"")
endif()

get_filename_component(idl_base ${IDL_FILE} NAME_WE)
get_filename_component(in_path ${IDL_FILE} PATH)

set(h_file ${CMAKE_CURRENT_BINARY_DIR}/${idl_base}_${type_id}.h)
set(c_file ${CMAKE_CURRENT_BINARY_DIR}/${idl_base}_${type_id}.c)

add_custom_command(
OUTPUT ${h_file} ${c_file}
DEPENDS ${IDL_FILE}
COMMAND oegen -${type_id} -d ${CMAKE_CURRENT_BINARY_DIR} ${IDL_FILE}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)

set_source_files_properties(
${h_file} ${c_file}
PROPERTIES GENERATED TRUE
)
set_source_files_properties(
${IDL_FILE}
PROPERTIES HEADER_FILE_ONLY TRUE
)

# append h_file,c_file to output var
list(APPEND ${OUT_FILES_VAR} ${h_file} ${c_file})
set(${OUT_FILES_VAR} ${${OUT_FILES_VAR}} PARENT_SCOPE)

#message("h_file=${h_file} c_file=${c_file} IDL_FILE=${IDL_FILE} OUT_FILES=${${OUT_FILES_VAR}}")
endfunction(oeidl_file)

21 changes: 21 additions & 0 deletions cmake/wrap.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# CMAKE-script to wrap sources with pre- and suffix (all files)
#
# Args:
# - WRAP_DST - Output file
# - WRAP_SRC - Input file
# - WRAP_PRE - Prefix file
# - WRAP_SUF - Suffix file
#
# Reulting file (WRAP_DST) will be the contents of WRAP_PRE, WRAP_SRC, WRAP_SUF

function(wrap output input pre post)
file(READ ${pre} pre_cont)
file(READ ${input} input_cont)
file(READ ${post} post_cont)

file(WRITE ${output} "${pre_cont}")
file(APPEND ${output} "${input_cont}")
file(APPEND ${output} "${post_cont}")
endfunction(wrap)

wrap(${WRAP_DST} ${WRAP_SRC} ${WRAP_PRE} ${WRAP_SUF})
2 changes: 2 additions & 0 deletions common/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Sources shared by both the Enclave and Host libraries.

Loading

0 comments on commit 9bf881b

Please sign in to comment.