Skip to content

Commit

Permalink
Build macOS framework and add CocoaPods podspec
Browse files Browse the repository at this point in the history
* On Apple platforms build a [dynamic] framework bundle when
  `HERMES_BUILD_APPLE_FRAMEWORK` is set. When set to `FALSE` it will
  produce a `dylib`, like previously. Defaults to `TRUE`.
* On Apple platforms create a debugging symbols bundle.
* Add `HERMES_ENABLE_FUZZING`, which is enabled by default.
* Add `HERMES_ENABLE_TEST_SUITE`, which is enabled by default.
* Add a CocoaPods podspec that can build from source or use a binary.
  • Loading branch information
alloy committed Jul 3, 2020
1 parent 58c4245 commit a7efccf
Show file tree
Hide file tree
Showing 17 changed files with 242 additions and 57 deletions.
68 changes: 66 additions & 2 deletions API/hermes/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ set(api_sources
DebuggerAPI.cpp
)

file(GLOB api_headers ${CMAKE_CURRENT_SOURCE_DIR}/*.h)
file(GLOB api_public_headers ${PROJECT_SOURCE_DIR}/public/hermes/Public/*.h)

if (HERMESVM_API_TRACE)
list(APPEND api_sources
hermes_tracing.cpp
Expand Down Expand Up @@ -63,12 +66,13 @@ add_hermes_library(compileJS STATIC CompileJS.cpp)
set(HERMES_ENABLE_EH ON)
set(HERMES_ENABLE_RTTI ON)

add_library(libhermes SHARED ${api_sources})
add_library(libhermes SHARED ${api_sources} ${api_headers} ${api_public_headers})
target_link_libraries(libhermes
jsi
hermesVMRuntime
${CORE_FOUNDATION}
)
hermes_link_icu(libhermes)

# Export the required header directory
target_include_directories(libhermes PUBLIC ..)
Expand Down Expand Up @@ -96,5 +100,65 @@ set_target_properties(libhermes PROPERTIES
CXX_STANDARD_REQUIRED 14
# Avoid becoming liblibhermes (and there's already a target called 'hermes')
OUTPUT_NAME hermes
)

if(APPLE AND HERMES_BUILD_APPLE_FRAMEWORK)
set_target_properties(libhermes PROPERTIES
FRAMEWORK TRUE
VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_VERSION}
FRAMEWORK_VERSION ${PROJECT_VERSION_MAJOR}
MACOSX_FRAMEWORK_SHORT_VERSION_STRING ${PROJECT_VERSION}
MACOSX_FRAMEWORK_BUNDLE_VERSION ${PROJECT_VERSION}
MACOSX_FRAMEWORK_IDENTIFIER dev.hermesengine.${CMAKE_SYSTEM_NAME}
)
hermes_link_icu(libhermes)
# Install headers into `Headers` while keeping required directory structure
set_source_files_properties(${api_headers} PROPERTIES
MACOSX_PACKAGE_LOCATION Headers
)
set_source_files_properties(${api_public_headers} PROPERTIES
MACOSX_PACKAGE_LOCATION Headers/Public
)
endif()

install(TARGETS libhermes
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
FRAMEWORK DESTINATION Library/Frameworks
)
# Install headers into `include` while keeping required directory structure
install(DIRECTORY "${PROJECT_SOURCE_DIR}/API/hermes" DESTINATION include
FILES_MATCHING PATTERN "*.h"
PATTERN "synthtest" EXCLUDE)

# Create debug symbols (dSYM) bundle for Apple platform dylibs/frameworks
# Largely inspired by https://github.com/llvm/llvm-project/blob/6701993027f8af172d7ba697884459261b00e3c6/llvm/cmake/modules/AddLLVM.cmake#L1934-L1986
if(APPLE AND CMAKE_CXX_FLAGS MATCHES "-gdwarf")
if(CMAKE_CXX_FLAGS MATCHES "-flto")
set(lto_object ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/libhermes-lto.o)
set_property(TARGET libhermes APPEND_STRING PROPERTY LINK_FLAGS " -Wl,-object_path_lto,${lto_object}")
endif()

get_target_property(DSYM_PATH libhermes LOCATION)
if(HERMES_BUILD_APPLE_FRAMEWORK)
get_filename_component(DSYM_PATH ${DSYM_PATH} DIRECTORY)
endif()
set(DSYM_PATH "${DSYM_PATH}.dSYM")

if(NOT CMAKE_DSYMUTIL)
set(CMAKE_DSYMUTIL xcrun dsymutil)
endif()
add_custom_command(TARGET libhermes POST_BUILD
COMMAND ${CMAKE_DSYMUTIL} $<TARGET_FILE:libhermes> --out ${DSYM_PATH}
BYPRODUCTS ${DSYM_PATH}
)

if(HERMES_BUILD_APPLE_FRAMEWORK)
install(DIRECTORY ${DSYM_PATH} DESTINATION Library/Frameworks)
else()
install(DIRECTORY ${DSYM_PATH} DESTINATION lib)
endif()
endif()

hermes_strip_debug_symbols(libhermes)
4 changes: 4 additions & 0 deletions API/jsi/jsi/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,7 @@ elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "MSVC")
list(APPEND jsi_compile_flags "/EHsc")
endif()
target_compile_options(jsi PUBLIC ${jsi_compile_flags})

install(DIRECTORY "${PROJECT_SOURCE_DIR}/API/jsi/" DESTINATION include
FILES_MATCHING PATTERN "*.h"
PATTERN "test" EXCLUDE)
140 changes: 88 additions & 52 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@ if (POLICY CMP0023)
cmake_policy(SET CMP0023 OLD)
endif()

# Allow reading the LOCATION property of a target to determine the eventual
# location of build targets. This is needed when building the debugging symbols
# bundles for Apple platforms.
if (POLICY CMP0026)
cmake_policy(SET CMP0026 OLD)
endif()

# This must be consistent with the release_version in
# android/build.gradle and npm/package.json
Expand Down Expand Up @@ -127,6 +133,9 @@ set(HERMES_ENABLE_ADDRESS_SANITIZER OFF CACHE BOOL
set(HERMES_ENABLE_UNDEFINED_BEHAVIOR_SANITIZER OFF CACHE BOOL
"Enable -fsanitize=undefined")

set(HERMES_ENABLE_FUZZING ON CACHE BOOL
"Enable fuzzing")

# Set linker flag for building the fuzzer
set(HERMES_FUZZING_FLAG "-fsanitize=fuzzer" CACHE STRING
"Linker argument to link fuzz targets against a given fuzzer.")
Expand Down Expand Up @@ -197,7 +206,17 @@ set(EMSCRIPTEN_FASTCOMP ON CACHE BOOL
set(HERMES_ENABLE_INTL OFF CACHE BOOL
"Enable JS Intl support (WIP)")

if (HERMES_IS_ANDROID)
set(HERMES_ENABLE_TEST_SUITE ON CACHE BOOL
"Enable the test suite")

set(HERMES_BUILD_APPLE_FRAMEWORK ON CACHE BOOL
"Whether to build a framework bundle or dylib on Apple platforms")

if (NOT HERMES_IS_MOBILE_BUILD AND APPLE)
# Always emit debugging symbols (in the DWARF) format, as these will be
# stripped out of each target post-build.
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -gdwarf")
elseif (HERMES_IS_ANDROID)
set(HERMES_IS_MOBILE_BUILD TRUE)

add_definitions(-DHERMES_PLATFORM_UNICODE=HERMES_PLATFORM_UNICODE_JAVA)
Expand All @@ -218,7 +237,6 @@ if (HERMES_IS_ANDROID)
# https://github.com/android-ndk/ndk/issues/242
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fuse-ld=gold")
endif()

endif()

if (HERMES_IS_MOBILE_BUILD)
Expand Down Expand Up @@ -486,6 +504,20 @@ function(hermes_link_icu target_name)
endif()
endfunction()

# Declare a function that strips debugging symbols from any target built for
# Apple platforms, which we do build initially so they can be extracted into a
# dSYM bundle.
function(hermes_strip_debug_symbols target_name)
if(APPLE)
if(NOT CMAKE_STRIP)
set(CMAKE_STRIP xcrun strip)
endif()
add_custom_command(TARGET ${target_name} POST_BUILD
COMMAND ${CMAKE_STRIP} -S $<TARGET_FILE:${target_name}>
)
endif()
endfunction()

if (APPLE)
find_library(CORE_FOUNDATION CoreFoundation)
else()
Expand Down Expand Up @@ -566,8 +598,8 @@ add_subdirectory(utils/hermes-lit)
add_subdirectory(tools)
add_subdirectory(include)
add_subdirectory(lib)
add_subdirectory(public)
add_subdirectory(external)
add_subdirectory(unittests)
add_subdirectory(API)
add_subdirectory(android/intltest/java/com/facebook/hermes/test)

Expand All @@ -583,55 +615,59 @@ endif()

# Configure the test suites
#
list(APPEND HERMES_TEST_DEPS
HermesUnitTests
hermes
hermesc
hvm
interp-dispatch-bench
hdb
hbcdump
hbc-attribute
hbc-deltaprep
hbc-diff
dependency-extractor
)

set(HERMES_LIT_TEST_PARAMS
test_exec_root=${HERMES_BINARY_DIR}/test
unittests_dir=${HERMES_BINARY_DIR}/unittests
debugger_enabled=${HERMES_ENABLE_DEBUGGER}
use_flowparser=${HERMES_USE_FLOWPARSER}
jit_enabled=${HERMESVM_JIT}
jit_disassembler_enabled=${HERMESVM_JIT_DISASSEMBLER}
hbc_deltaprep=${HERMES_TOOLS_OUTPUT_DIR}/hbc-deltaprep
dependency_extractor=${HERMES_TOOLS_OUTPUT_DIR}/dependency-extractor
FileCheck=${HERMES_TOOLS_OUTPUT_DIR}//FileCheck
hermes=${HERMES_TOOLS_OUTPUT_DIR}/hermes
hermesc=${HERMES_TOOLS_OUTPUT_DIR}/hermesc
hdb=${HERMES_TOOLS_OUTPUT_DIR}/hdb
hbcdump=${HERMES_TOOLS_OUTPUT_DIR}/hbcdump
hbc-deltaprep=${HERMES_TOOLS_OUTPUT_DIR}/hbc-deltaprep
hbc_diff=${HERMES_TOOLS_OUTPUT_DIR}/hbc-diff
build_mode=${HERMES_ASSUMED_BUILD_MODE_IN_LIT_TEST}
exception_on_oom_enabled=${HERMESVM_EXCEPTION_ON_OOM}
serialize_enabled=${HERMESVM_SERIALIZE}
profiler=${HERMES_PROFILER_MODE_IN_LIT_TEST}
use_js_library_implementation=${HERMESVM_USE_JS_LIBRARY_IMPLEMENTATION}
gc=${HERMESVM_GCKIND}
ubsan=${HERMES_ENABLE_UNDEFINED_BEHAVIOR_SANITIZER}
)

set(LLVH_LIT_ARGS "-sv")

add_lit_testsuite(check-hermes "Running the Hermes regression tests"
${HERMES_SOURCE_DIR}/test
${HERMES_SOURCE_DIR}/unittests
PARAMS ${HERMES_LIT_TEST_PARAMS}
DEPENDS ${HERMES_TEST_DEPS}
ARGS ${HERMES_TEST_EXTRA_ARGS}
)
set_target_properties(check-hermes PROPERTIES FOLDER "Hermes regression tests")
if(HERMES_ENABLE_TEST_SUITE)
add_subdirectory(unittests)

list(APPEND HERMES_TEST_DEPS
HermesUnitTests
hermes
hermesc
hvm
interp-dispatch-bench
hdb
hbcdump
hbc-attribute
hbc-deltaprep
hbc-diff
dependency-extractor
)

set(HERMES_LIT_TEST_PARAMS
test_exec_root=${HERMES_BINARY_DIR}/test
unittests_dir=${HERMES_BINARY_DIR}/unittests
debugger_enabled=${HERMES_ENABLE_DEBUGGER}
use_flowparser=${HERMES_USE_FLOWPARSER}
jit_enabled=${HERMESVM_JIT}
jit_disassembler_enabled=${HERMESVM_JIT_DISASSEMBLER}
hbc_deltaprep=${HERMES_TOOLS_OUTPUT_DIR}/hbc-deltaprep
dependency_extractor=${HERMES_TOOLS_OUTPUT_DIR}/dependency-extractor
FileCheck=${HERMES_TOOLS_OUTPUT_DIR}//FileCheck
hermes=${HERMES_TOOLS_OUTPUT_DIR}/hermes
hermesc=${HERMES_TOOLS_OUTPUT_DIR}/hermesc
hdb=${HERMES_TOOLS_OUTPUT_DIR}/hdb
hbcdump=${HERMES_TOOLS_OUTPUT_DIR}/hbcdump
hbc-deltaprep=${HERMES_TOOLS_OUTPUT_DIR}/hbc-deltaprep
hbc_diff=${HERMES_TOOLS_OUTPUT_DIR}/hbc-diff
build_mode=${HERMES_ASSUMED_BUILD_MODE_IN_LIT_TEST}
exception_on_oom_enabled=${HERMESVM_EXCEPTION_ON_OOM}
serialize_enabled=${HERMESVM_SERIALIZE}
profiler=${HERMES_PROFILER_MODE_IN_LIT_TEST}
use_js_library_implementation=${HERMESVM_USE_JS_LIBRARY_IMPLEMENTATION}
gc=${HERMESVM_GCKIND}
ubsan=${HERMES_ENABLE_UNDEFINED_BEHAVIOR_SANITIZER}
)

set(LLVH_LIT_ARGS "-sv")

add_lit_testsuite(check-hermes "Running the Hermes regression tests"
${HERMES_SOURCE_DIR}/test
${HERMES_SOURCE_DIR}/unittests
PARAMS ${HERMES_LIT_TEST_PARAMS}
DEPENDS ${HERMES_TEST_DEPS}
ARGS ${HERMES_TEST_EXTRA_ARGS}
)
set_target_properties(check-hermes PROPERTIES FOLDER "Hermes regression tests")
endif()

# This is how github release files are built.

Expand Down
45 changes: 45 additions & 0 deletions hermes.podspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
module HermesHelper
# BUILD_TYPE = :debug
BUILD_TYPE = :release

def self.command_exists?(bin)
"command -v #{bin} > /dev/null 2>&1"
end

def self.configure_command
"./utils/build/configure.py #{BUILD_TYPE == :release ? "--distribute" : "--build-type=Debug"} --cmake-flags='-DHERMES_ENABLE_DEBUGGER:BOOLEAN=true -DHERMES_ENABLE_FUZZING:BOOLEAN=false -DHERMES_ENABLE_TEST_SUITE:BOOLEAN=false -DCMAKE_INSTALL_PREFIX:PATH=../destroot' build"
end
end

Pod::Spec.new do |spec|
spec.name = "hermes"
spec.version = "0.5.0"
spec.summary = "Hermes is a small and lightweight JavaScript engine optimized for running React Native."
spec.description = "Hermes is a JavaScript engine optimized for fast start-up of React Native apps. It features ahead-of-time static optimization and compact bytecode."
spec.homepage = "https://hermesengine.dev"
spec.license = { type: "MIT", file: "LICENSE" }
spec.author = "Facebook"
spec.source = { git: "https://github.com/facebook/hermes.git", tag: "v#{spec.version}" }
spec.platforms = { :osx => "10.14" }

spec.preserve_paths = ["destroot/bin/*"].concat(HermesHelper::BUILD_TYPE == :debug ? ["**/*.{h,c,cpp}"] : [])
spec.source_files = "destroot/include/**/*.h"
spec.header_mappings_dir = "destroot/include"
spec.vendored_frameworks = "destroot/Library/Frameworks/hermes.framework"
spec.xcconfig = { "CLANG_CXX_LANGUAGE_STANDARD" => "c++14", "CLANG_CXX_LIBRARY" => "compiler-default", "GCC_PREPROCESSOR_DEFINITIONS" => "HERMES_ENABLE_DEBUGGER=1" }

spec.prepare_command = <<-EOS
if [ ! -d destroot/Library/Frameworks/hermes.framework ]; then
if #{HermesHelper.command_exists?("cmake")}; then
if #{HermesHelper.command_exists?("ninja")}; then
#{HermesHelper.configure_command} --build-system='Ninja' && cd build && ninja install
else
#{HermesHelper.configure_command} --build-system='Unix Makefiles' && cd build && make install
fi
else
echo >&2 'CMake is required to install Hermes, install it with: brew install cmake'
exit 1
fi
fi
EOS
end
2 changes: 1 addition & 1 deletion public/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.

add_subdirectory(hermes)
add_subdirectory(hermes/Public)
7 changes: 7 additions & 0 deletions public/hermes/Public/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Copyright (c) Facebook, Inc. and its affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.

install(DIRECTORY "${PROJECT_SOURCE_DIR}/public/hermes/Public" DESTINATION include/hermes
FILES_MATCHING PATTERN "*.h")
2 changes: 1 addition & 1 deletion tools/fuzzers/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.

if("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
if(HERMES_ENABLE_FUZZING AND "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(HERMES_ENABLE_EH ON)
Expand Down
1 change: 1 addition & 0 deletions tools/hbc-attribute/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ target_link_libraries(hbc-attribute
)

hermes_link_icu(hbc-attribute)
hermes_strip_debug_symbols(hbc-attribute)
1 change: 1 addition & 0 deletions tools/hbc-deltaprep/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ target_link_libraries(hbc-deltaprep
)

hermes_link_icu(hbc-deltaprep)
hermes_strip_debug_symbols(hbc-deltaprep)
1 change: 1 addition & 0 deletions tools/hbc-diff/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@ target_link_libraries(hbc-diff
)

hermes_link_icu(hbc-diff)
hermes_strip_debug_symbols(hbc-diff)
5 changes: 5 additions & 0 deletions tools/hbcdump/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,8 @@ target_link_libraries(hbcdump
)

hermes_link_icu(hbcdump)
hermes_strip_debug_symbols(hbcdump)

install(TARGETS hbcdump
RUNTIME DESTINATION bin
)
6 changes: 6 additions & 0 deletions tools/hdb/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,9 @@ set_target_properties(hdb PROPERTIES
target_link_libraries(hdb
hermesapi
)

hermes_strip_debug_symbols(hdb)

install(TARGETS hdb
RUNTIME DESTINATION bin
)
Loading

0 comments on commit a7efccf

Please sign in to comment.