Merge pull request #628 from lemmaa/lemmaa-build-for-osx-with-clang-new

Enable build on Mac OS X with clang - resolve merge conflicts
This commit is contained in:
Sung-Jae Lee 2015-09-16 19:39:16 +09:00
commit 034ecf78f8
7 changed files with 903 additions and 53 deletions

View File

@ -15,28 +15,35 @@
cmake_minimum_required (VERSION 2.8.12)
project (Jerry CXX C ASM)
# Require g++ of version >= 4.7.0
if(NOT CMAKE_COMPILER_IS_GNUCXX)
message(FATAL_ERROR "g++ compiler is required")
else()
execute_process(COMMAND ${CMAKE_CXX_COMPILER} -dumpversion
OUTPUT_VARIABLE GNU_CXX_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE)
# Determining platform
set(PLATFORM "${CMAKE_SYSTEM_NAME}")
string(TOUPPER "${PLATFORM}" PLATFORM)
if(${GNU_CXX_VERSION} VERSION_LESS 4.7.0)
message(FATAL_ERROR "g++ compiler version 4.7.0 or higher required")
endif()
# Compiler configuration
if(NOT ("${PLATFORM}" STREQUAL "DARWIN"))
# Require g++ of version >= 4.7.0
if(NOT CMAKE_COMPILER_IS_GNUCXX)
message(FATAL_ERROR "g++ compiler is required")
else()
execute_process(COMMAND ${CMAKE_CXX_COMPILER} -dumpversion
OUTPUT_VARIABLE GNU_CXX_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(${GNU_CXX_VERSION} VERSION_LESS 4.7.0)
message(FATAL_ERROR "g++ compiler version 4.7.0 or higher required")
endif()
endif()
# Use gcc-ar and gcc-ranlib to support LTO
get_filename_component(PATH_TO_GCC ${CMAKE_C_COMPILER} REALPATH)
get_filename_component(DIRECTORY_GCC ${PATH_TO_GCC} DIRECTORY)
get_filename_component(FILE_NAME_GCC ${PATH_TO_GCC} NAME)
string(REPLACE "gcc" "gcc-ar" CMAKE_AR ${FILE_NAME_GCC})
string(REPLACE "gcc" "gcc-ranlib" CMAKE_RANLIB ${FILE_NAME_GCC})
set(CMAKE_AR ${DIRECTORY_GCC}/${CMAKE_AR})
set(CMAKE_RANLIB ${DIRECTORY_GCC}/${CMAKE_RANLIB})
endif()
# Use gcc-ar and gcc-ranlib to support LTO
get_filename_component(PATH_TO_GCC ${CMAKE_C_COMPILER} REALPATH)
get_filename_component(DIRECTORY_GCC ${PATH_TO_GCC} DIRECTORY)
get_filename_component(FILE_NAME_GCC ${PATH_TO_GCC} NAME)
string(REPLACE "gcc" "gcc-ar" CMAKE_AR ${FILE_NAME_GCC})
string(REPLACE "gcc" "gcc-ranlib" CMAKE_RANLIB ${FILE_NAME_GCC})
set(CMAKE_AR ${DIRECTORY_GCC}/${CMAKE_AR})
set(CMAKE_RANLIB ${DIRECTORY_GCC}/${CMAKE_RANLIB})
# Imported and third-party targets prefix
set(PREFIX_IMPORTED_LIB imported_)
set(SUFFIX_THIRD_PARTY_LIB .third_party.lib)
@ -58,18 +65,20 @@ project (Jerry CXX C ASM)
set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS )
set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS )
# Determining platform and defining options
# Defining options
option(ENABLE_VALGRIND "Enable valgrind helpers in memory allocators" OFF)
option(ENABLE_LTO "Enable LTO build" ON)
option(ENABLE_LOG "Enable LOG build" OFF)
set(PLATFORM "${CMAKE_SYSTEM_NAME}")
string(TOUPPER "${PLATFORM}" PLATFORM)
if("${PLATFORM}" STREQUAL "LINUX")
set(PLATFORM_EXT "LINUX")
set(EXTERNAL_BUILD FALSE)
option(STRIP_RELEASE_BINARY "Strip symbols from release binaries" ON)
elseif("${PLATFORM}" STREQUAL "DARWIN")
set(PLATFORM_EXT "DARWIN")
set(EXTERNAL_BUILD FALSE)
option(STRIP_RELEASE_BINARY "Strip symbols from release binaries" ON)
elseif("${PLATFORM}" STREQUAL "MCU")
set(PLATFORM_EXT "MCU_${CMAKE_SYSTEM_VERSION}")
@ -167,6 +176,15 @@ project (Jerry CXX C ASM)
"FULL_PROFILE MEMORY_STATISTICS"
"COMPACT_PROFILE_MINIMAL MEMORY_STATISTICS")
# Darwin
set(MODIFIERS_LISTS_DARWIN
"FULL_PROFILE"
"FULL_PROFILE MEM_STRESS_TEST"
"COMPACT_PROFILE"
"COMPACT_PROFILE_MINIMAL"
"FULL_PROFILE MEMORY_STATISTICS"
"COMPACT_PROFILE_MINIMAL MEMORY_STATISTICS")
# MCU
# stm32f3
set(MODIFIERS_LISTS_MCU_STM32F3
@ -190,7 +208,10 @@ project (Jerry CXX C ASM)
# Compiler / Linker flags
set(COMPILE_FLAGS_JERRY "-fno-builtin")
set(LINKER_FLAGS_COMMON "-Wl,-z,noexecstack")
if(NOT ("${PLATFORM}" STREQUAL "DARWIN"))
set(LINKER_FLAGS_COMMON "-Wl,-z,noexecstack")
endif()
set(LINKER_FLAGS_COMMON_DARWIN "-lSystem")
# Turn off linking to compiler's default libc, in case jerry-libc is used
if(${USE_JERRY_LIBC})
@ -199,7 +220,10 @@ project (Jerry CXX C ASM)
# LTO
if("${ENABLE_LTO}" STREQUAL "ON")
set(COMPILE_FLAGS_JERRY "${COMPILE_FLAGS_JERRY} -flto -fno-fat-lto-objects")
set(COMPILE_FLAGS_JERRY "${COMPILE_FLAGS_JERRY} -flto")
if(NOT ("${PLATFORM}" STREQUAL "DARWIN"))
set(COMPILE_FLAGS_JERRY "${COMPILE_FLAGS_JERRY} -fno-fat-lto-objects")
endif()
set(LINKER_FLAGS_COMMON "${LINKER_FLAGS_COMMON} -flto")
endif()
@ -210,20 +234,28 @@ project (Jerry CXX C ASM)
set(COMPILE_FLAGS_JERRY "${COMPILE_FLAGS_JERRY} -g -gdwarf-4")
# Warnings
set(COMPILE_FLAGS_JERRY "${COMPILE_FLAGS_JERRY} -Wall -Wextra -pedantic -Wlogical-op")
set(COMPILE_FLAGS_JERRY "${COMPILE_FLAGS_JERRY} -Wall -Wextra -pedantic")
set(COMPILE_FLAGS_JERRY "${COMPILE_FLAGS_JERRY} -Wformat-nonliteral -Winit-self -Wno-stack-protector")
set(COMPILE_FLAGS_JERRY "${COMPILE_FLAGS_JERRY} -Wconversion -Wsign-conversion -Wformat-security")
set(COMPILE_FLAGS_JERRY "${COMPILE_FLAGS_JERRY} -Wmissing-declarations -Wno-attributes")
set(COMPILE_FLAGS_JERRY "${COMPILE_FLAGS_JERRY} -Werror -Wfatal-errors")
set(COMPILE_FLAGS_JERRY "${COMPILE_FLAGS_JERRY} -Wfatal-errors")
if(CMAKE_COMPILER_IS_GNUCXX)
set(COMPILE_FLAGS_JERRY "${COMPILE_FLAGS_JERRY} -Werror -Wlogical-op")
else()
set(COMPILE_FLAGS_JERRY "${COMPILE_FLAGS_JERRY} -Wno-nested-anon-types")
endif()
# Static build
set(LINKER_FLAGS_STATIC "-static")
if(NOT ("${PLATFORM}" STREQUAL "DARWIN"))
set(LINKER_FLAGS_STATIC "-static")
endif()
# C++
set(CXX_FLAGS_JERRY "-std=c++11 -fno-exceptions -fno-rtti")
# Turn off implicit template instantiation
set(CXX_FLAGS_JERRY "${CXX_FLAGS_JERRY} -fno-implicit-templates -fno-implicit-inline-templates")
if(CMAKE_COMPILER_IS_GNUCXX)
set(CXX_FLAGS_JERRY "${CXX_FLAGS_JERRY} -fno-implicit-templates -fno-implicit-inline-templates")
endif()
# C
set(C_FLAGS_JERRY "-std=c99")
@ -255,6 +287,9 @@ project (Jerry CXX C ASM)
# Linux
set(SOURCE_JERRY_STANDALONE_MAIN_LINUX main-linux.cpp)
# Darwin
set(SOURCE_JERRY_STANDALONE_MAIN_DARWIN main-darwin.cpp)
# MCU
# stm32f3
set(SOURCE_JERRY_STANDALONE_MAIN_MCU_STM32F3 main-mcu.cpp)
@ -266,6 +301,16 @@ project (Jerry CXX C ASM)
file(GLOB SOURCE_UNIT_TEST_MAIN_MODULES tests/unit/*.cpp)
# Imported libraries
if(("${PLATFORM}" STREQUAL "DARWIN") AND (NOT CMAKE_COMPILER_IS_GNUCXX))
# libclang_rt.osx
add_library(${PREFIX_IMPORTED_LIB}libclang_rt.osx STATIC IMPORTED)
execute_process(COMMAND ${CMAKE_C_COMPILER} ${FLAGS_COMMON_ARCH} -print-file-name=
OUTPUT_VARIABLE IMPORTED_LIBCLANG_RT_LOCATION
OUTPUT_STRIP_TRAILING_WHITESPACE)
set(IMPORTED_LIBCLANG_RT_LOCATION "${IMPORTED_LIBCLANG_RT_LOCATION}/lib/darwin/libclang_rt.osx.a")
set_property(TARGET ${PREFIX_IMPORTED_LIB}libclang_rt.osx
PROPERTY IMPORTED_LOCATION ${IMPORTED_LIBCLANG_RT_LOCATION})
else()
# libgcc
add_library(${PREFIX_IMPORTED_LIB}libgcc STATIC IMPORTED)
execute_process(COMMAND ${CMAKE_C_COMPILER} ${FLAGS_COMMON_ARCH} -print-file-name=libgcc.a
@ -286,6 +331,7 @@ project (Jerry CXX C ASM)
set_property(TARGET ${PREFIX_IMPORTED_LIB}libgcc_eh
PROPERTY IMPORTED_LOCATION ${IMPORTED_LIBGCC_LOCATION})
endif()
endif()
# Platform-specific configuration
set(MODIFIERS_LISTS ${MODIFIERS_LISTS_${PLATFORM_EXT}})
@ -335,7 +381,7 @@ project (Jerry CXX C ASM)
WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
add_custom_target(mcu_header_with_script_to_run.${TARGET_NAME} DEPENDS ${MCU_SCRIPT_GENERATED_HEADER})
set(DEFINES_JERRY ${DEFINES_JERRY} JERRY_MCU_SCRIPT_HEADER="${MCU_SCRIPT_GENERATED_HEADER}")
elseif("${PLATFORM}" STREQUAL "LINUX")
elseif(("${PLATFORM}" STREQUAL "LINUX") OR ("${PLATFORM}" STREQUAL "DARWIN"))
if("${ENABLE_LOG}" STREQUAL "ON")
set(DEFINES_JERRY ${DEFINES_JERRY} JERRY_ENABLE_LOG)
endif()
@ -349,8 +395,13 @@ project (Jerry CXX C ASM)
target_include_directories(${TARGET_NAME} PRIVATE ${INCLUDE_CORE_INTERFACE})
target_include_directories(${TARGET_NAME} SYSTEM PRIVATE ${INCLUDE_LIBC_INTERFACE})
target_include_directories(${TARGET_NAME} SYSTEM PRIVATE ${INCLUDE_EXTERNAL_LIBS_INTERFACE})
target_link_libraries(${TARGET_NAME} ${CORE_TARGET_NAME} ${LIBC_TARGET_NAME}
${FDLIBM_TARGET_NAME} ${PREFIX_IMPORTED_LIB}libgcc ${PREFIX_IMPORTED_LIB}libgcc_eh)
if(("${PLATFORM}" STREQUAL "DARWIN") AND (NOT CMAKE_COMPILER_IS_GNUCXX))
target_link_libraries(${TARGET_NAME} ${CORE_TARGET_NAME} ${LIBC_TARGET_NAME}
${FDLIBM_TARGET_NAME} ${PREFIX_IMPORTED_LIB}libclang_rt.osx)
else()
target_link_libraries(${TARGET_NAME} ${CORE_TARGET_NAME} ${LIBC_TARGET_NAME}
${FDLIBM_TARGET_NAME} ${PREFIX_IMPORTED_LIB}libgcc ${PREFIX_IMPORTED_LIB}libgcc_eh)
endif()
add_cppcheck_target(${TARGET_NAME})
@ -403,7 +454,7 @@ project (Jerry CXX C ASM)
declare_targets_for_build_mode(RELEASE)
# Unit tests declaration
if("${PLATFORM}" STREQUAL "LINUX")
if(("${PLATFORM}" STREQUAL "LINUX") OR ("${PLATFORM}" STREQUAL "DARWIN"))
add_custom_target(unittests)
add_custom_target(cppcheck.unittests)
@ -424,8 +475,14 @@ project (Jerry CXX C ASM)
PROPERTY LINK_FLAGS "${COMPILE_FLAGS_JERRY} ${CXX_FLAGS_JERRY} ${FLAGS_COMMON_UNITTESTS} ${LINKER_FLAGS_COMMON}")
target_include_directories(${TARGET_NAME} PRIVATE ${INCLUDE_CORE_INTERFACE})
target_include_directories(${TARGET_NAME} SYSTEM PRIVATE ${INCLUDE_LIBC_INTERFACE})
target_link_libraries(${TARGET_NAME} ${CORE_TARGET_NAME} ${LIBC_TARGET_NAME} ${FDLIBM_TARGET_NAME}
${PREFIX_IMPORTED_LIB}libgcc ${PREFIX_IMPORTED_LIB}libgcc_eh)
if(("${PLATFORM}" STREQUAL "DARWIN") AND (NOT CMAKE_COMPILER_IS_GNUCXX))
target_link_libraries(${TARGET_NAME} ${CORE_TARGET_NAME} ${LIBC_TARGET_NAME} ${FDLIBM_TARGET_NAME}
${PREFIX_IMPORTED_LIB}libclang_rt.osx)
else()
target_link_libraries(${TARGET_NAME} ${CORE_TARGET_NAME} ${LIBC_TARGET_NAME} ${FDLIBM_TARGET_NAME}
${PREFIX_IMPORTED_LIB}libgcc ${PREFIX_IMPORTED_LIB}libgcc_eh)
endif()
add_cppcheck_target(${TARGET_NAME})

View File

@ -15,7 +15,7 @@
#
# Target naming scheme
#
# Main targets: {debug,release}.{linux,stm32f{4}}[.flash]
# Main targets: {debug,release}.{linux,darwin,stm32f{4}}[.flash]
#
# Target mode part (before dot):
# debug: - JERRY_NDEBUG; - optimizations; + debug symbols; + -Werror | debug build
@ -23,10 +23,11 @@
#
# Target system and modifiers part (after first dot):
# linux - target system is linux
# darwin - target system is Mac OS X
# mcu_stm32f{3,4} - target is STM32F{3,4} board
#
# Modifiers can be added after '-' sign.
# For list of modifiers for PC target - see TARGET_PC_MODS, for MCU target - TARGET_MCU_MODS.
# For list of modifiers for NATIVE target - see TARGET_NATIVE_MODS, for MCU target - TARGET_MCU_MODS.
#
# Target action part (optional, after second dot):
# flash - flash specified mcu target binary
@ -77,6 +78,8 @@
QLOG := >/dev/null
endif
export TARGET_NATIVE_SYSTEMS = $(shell uname -s | tr [:upper:] [:lower:])
# External build configuration
# Flag, indicating whether to use compiler's default libc (YES / NO)
USE_COMPILER_DEFAULT_LIBC ?= NO
@ -95,30 +98,28 @@
export TARGET_DEBUG_MODES = debug
export TARGET_RELEASE_MODES = release
export TARGET_PC_SYSTEMS = linux
export TARGET_PC_MODS = cp cp_minimal mem_stats mem_stress_test
export TARGET_NATIVE_MODS = cp cp_minimal mem_stats mem_stress_test
export TARGET_MCU_MODS = cp cp_minimal
export TARGET_PC_SYSTEMS_MODS = $(TARGET_PC_SYSTEMS) \
$(foreach __MOD,$(TARGET_PC_MODS),$(foreach __SYSTEM,$(TARGET_PC_SYSTEMS),$(__SYSTEM)-$(__MOD)))
export TARGET_NATIVE_SYSTEMS_MODS = $(TARGET_NATIVE_SYSTEMS) \
$(foreach __MOD,$(TARGET_NATIVE_MODS),$(foreach __SYSTEM,$(TARGET_NATIVE_SYSTEMS),$(__SYSTEM)-$(__MOD)))
export TARGET_STM32F3_MODS = $(foreach __MOD,$(TARGET_MCU_MODS),mcu_stm32f3-$(__MOD))
export TARGET_STM32F4_MODS = $(foreach __MOD,$(TARGET_MCU_MODS),mcu_stm32f4-$(__MOD))
# Target list
export JERRY_LINUX_TARGETS = $(foreach __MODE,$(TARGET_DEBUG_MODES),$(foreach __SYSTEM,$(TARGET_PC_SYSTEMS_MODS),$(__MODE).$(__SYSTEM))) \
$(foreach __MODE,$(TARGET_RELEASE_MODES),$(foreach __SYSTEM,$(TARGET_PC_SYSTEMS_MODS),$(__MODE).$(__SYSTEM)))
export JERRY_NATIVE_TARGETS = $(foreach __MODE,$(TARGET_DEBUG_MODES),$(foreach __SYSTEM,$(TARGET_NATIVE_SYSTEMS_MODS),$(__MODE).$(__SYSTEM))) \
$(foreach __MODE,$(TARGET_RELEASE_MODES),$(foreach __SYSTEM,$(TARGET_NATIVE_SYSTEMS_MODS),$(__MODE).$(__SYSTEM)))
export JERRY_STM32F3_TARGETS = $(foreach __MODE,$(TARGET_RELEASE_MODES),$(foreach __SYSTEM,$(TARGET_STM32F3_MODS),$(__MODE).$(__SYSTEM)))
export JERRY_STM32F4_TARGETS = $(foreach __MODE,$(TARGET_DEBUG_MODES),$(foreach __SYSTEM,$(TARGET_STM32F4_MODS),$(__MODE).$(__SYSTEM))) \
$(foreach __MODE,$(TARGET_RELEASE_MODES),$(foreach __SYSTEM,$(TARGET_STM32F4_MODS),$(__MODE).$(__SYSTEM)))
export JERRY_TARGETS = $(JERRY_LINUX_TARGETS) $(JERRY_STM32F3_TARGETS) $(JERRY_STM32F4_TARGETS) unittests
export JERRY_TARGETS = $(JERRY_NATIVE_TARGETS) $(JERRY_STM32F3_TARGETS) $(JERRY_STM32F4_TARGETS) unittests
export CHECK_TARGETS = $(foreach __TARGET,$(JERRY_LINUX_TARGETS),$(__TARGET).check)
export CHECK_TARGETS = $(foreach __TARGET,$(JERRY_NATIVE_TARGETS),$(__TARGET).check)
export FLASH_TARGETS = $(foreach __TARGET,$(JERRY_STM32F3_TARGETS) $(JERRY_STM32F4_TARGETS),$(__TARGET).flash)
export OUT_DIR = ./build/bin
@ -127,7 +128,7 @@ export PREREQUISITES_STATE_DIR = ./build/prerequisites
export SHELL=/bin/bash
# Precommit check targets
PRECOMMIT_CHECK_TARGETS_LIST := debug.linux release.linux
PRECOMMIT_CHECK_TARGETS_LIST := debug.$(TARGET_NATIVE_SYSTEMS) release.$(TARGET_NATIVE_SYSTEMS)
# Building all options combinations
OPTIONS_COMBINATIONS := $(foreach __OPTION,ON OFF,$(__COMBINATION)-VALGRIND-$(__OPTION))
@ -167,7 +168,7 @@ $(BUILD_DIRS_NATIVE):
then \
readelf -A /proc/self/exe | grep Tag_ABI_VFP_args && arch=$$arch"-hf" || arch=$$arch"-el"; \
fi; \
TOOLCHAIN="build/configs/toolchain_linux_$$arch.cmake"; \
TOOLCHAIN="build/configs/toolchain_$(TARGET_NATIVE_SYSTEMS)_$$arch.cmake"; \
fi; \
if [ -d "$@" ]; \
then \
@ -198,8 +199,8 @@ $(BUILD_DIRS_STM32F4): prerequisites
(cmake -DENABLE_VALGRIND=$(VALGRIND) -DENABLE_LTO=$(LTO) -DCMAKE_TOOLCHAIN_FILE=build/configs/toolchain_mcu_stm32f4.cmake ../../.. 2>&1 | tee cmake.log $(QLOG) ; ( exit $${PIPESTATUS[0]} ) ) || \
(echo "CMake run failed. See "`pwd`"/cmake.log for details."; exit 1;)
.PHONY: $(JERRY_LINUX_TARGETS)
$(JERRY_LINUX_TARGETS): $(BUILD_DIR)/native
.PHONY: $(JERRY_NATIVE_TARGETS)
$(JERRY_NATIVE_TARGETS): $(BUILD_DIR)/native
$(Q) mkdir -p $(OUT_DIR)/$@
$(Q) [ "$(STATIC_CHECK)" = "OFF" ] || ($(MAKE) -C $(BUILD_DIR)/native VERBOSE=1 cppcheck.$@ 2>&1 | tee $(OUT_DIR)/$@/cppcheck.log $(QLOG) ; ( exit $${PIPESTATUS[0]} ) ) || \
(echo "cppcheck run failed. See $(OUT_DIR)/$@/cppcheck.log for details."; exit 1;)
@ -219,11 +220,11 @@ unittests: $(BUILD_DIR)/native
.PHONY: $(BUILD_ALL)_native
$(BUILD_ALL)_native: $(BUILD_DIRS_NATIVE)
$(Q) mkdir -p $(OUT_DIR)/$@
$(Q) ($(MAKE) -C $(BUILD_DIR)/native jerry-libc-all VERBOSE=1 2>&1 | tee $(OUT_DIR)/$@/make.log $(QLOG) ; ( exit $${PIPESTATUS[0]} ) ) || \
$(Q) [ "$(USE_COMPILER_DEFAULT_LIBC)" = "YES" ] || ($(MAKE) -C $(BUILD_DIR)/native jerry-libc-all VERBOSE=1 2>&1 | tee $(OUT_DIR)/$@/make.log $(QLOG) ; ( exit $${PIPESTATUS[0]} ) ) || \
(echo "Build failed. See $(OUT_DIR)/$@/make.log for details."; exit 1;)
$(Q) ($(MAKE) -C $(BUILD_DIR)/native jerry-fdlibm-all VERBOSE=1 2>&1 | tee $(OUT_DIR)/$@/make.log $(QLOG) ; ( exit $${PIPESTATUS[0]} ) ) || \
(echo "Build failed. See $(OUT_DIR)/$@/make.log for details."; exit 1;)
$(Q) ($(MAKE) -C $(BUILD_DIR)/native $(JERRY_LINUX_TARGETS) unittests VERBOSE=1 2>&1 | tee $(OUT_DIR)/$@/make.log $(QLOG) ; ( exit $${PIPESTATUS[0]} ) ) || \
$(Q) ($(MAKE) -C $(BUILD_DIR)/native $(JERRY_NATIVE_TARGETS) unittests VERBOSE=1 2>&1 | tee $(OUT_DIR)/$@/make.log $(QLOG) ; ( exit $${PIPESTATUS[0]} ) ) || \
(echo "Build failed. See $(OUT_DIR)/$@/make.log for details."; exit 1;)
.PHONY: $(JERRY_STM32F3_TARGETS)

View File

@ -0,0 +1,23 @@
# Copyright 2015 Samsung Electronics Co., Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set(CMAKE_SYSTEM_NAME Darwin)
set(CMAKE_SYSTEM_PROCESSOR x86_64)
find_program(CMAKE_C_COMPILER NAMES cc)
find_program(CMAKE_CXX_COMPILER NAMES c++)
# FIXME: This could break cross compilation, when the strip is not for the target architecture
find_program(CMAKE_STRIP NAMES strip)
#set(FLAGS_COMMON_ARCH -ffixed-rbp)

View File

@ -40,6 +40,8 @@ set(COMPILE_FLAGS_LIBC "${COMPILE_FLAGS_JERRY} ${C_FLAGS_JERRY}")
# Platform-specific
# Linux
set(DEFINES_LIBC_LINUX __TARGET_HOST)
# Darwin
set(DEFINES_LIBC_DARWIN __TARGET_HOST)
# MCU
set(DEFINES_LIBC_MCU __TARGET_MCU)
# stm32f3
@ -57,6 +59,9 @@ set(COMPILE_FLAGS_LIBC "${COMPILE_FLAGS_JERRY} ${C_FLAGS_JERRY}")
# Linux
set(INCLUDE_THIRD_PARTY_LINUX )
# Darwin
set(INCLUDE_THIRD_PARTY_DARWIN )
# MCU
# STM32F3
set(INCLUDE_THIRD_PARTY_MCU_STM32F3
@ -74,6 +79,9 @@ set(COMPILE_FLAGS_LIBC "${COMPILE_FLAGS_JERRY} ${C_FLAGS_JERRY}")
# Linux
file(GLOB SOURCE_LIBC_LINUX target/linux/*.c target/linux/*.S)
# Darwin
file(GLOB SOURCE_LIBC_DARWIN target/darwin/*.c target/darwin/*.S)
# MCU
# stm32f3
file(GLOB SOURCE_LIBC_MCU_STM32F3 target/mcu-stubs/*.c target/mcu-stubs/*.S)

View File

@ -0,0 +1,56 @@
#ifdef __TARGET_HOST_x64
# include "arch/x86-64.h"
#elif defined (__TARGET_HOST_x86)
# include "arch/x86-32.h"
#elif defined (__TARGET_HOST_ARMv7)
# include "arch/arm-v7.h"
#else /* !__TARGET_HOST_x64 && !__TARGET_HOST_x86 && !__TARGET_HOST_ARMv7 */
# error "!__TARGET_HOST_x64 && !__TARGET_HOST_x86 && !__TARGET_HOST_ARMv7"
#endif /* !__TARGET_HOST_x64 && !__TARGET_HOST_x86 && !__TARGET_HOST_ARMv7 */
.global _start
_start:
_START
.global syscall_0_asm
syscall_0_asm:
SYSCALL_0
.global syscall_1_asm
syscall_1_asm:
SYSCALL_1
.global syscall_2_asm
syscall_2_asm:
SYSCALL_2
.global syscall_3_asm
syscall_3_asm:
SYSCALL_3
/**
* setjmp (jmp_buf env)
*
* See also:
* longjmp
*
* @return 0 - if returns from direct call,
* nonzero - if returns after longjmp.
*/
.global setjmp
setjmp:
_SETJMP
/**
* longjmp (jmp_buf env, int val)
*
* Note:
* if val is not 0, then it would be returned from setjmp,
* otherwise - 0 would be returned.
*
* See also:
* setjmp
*/
.global longjmp
longjmp:
_LONGJMP

View File

@ -0,0 +1,386 @@
/* Copyright 2014-2015 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Jerry libc platform-specific functions darwin implementation
*/
#include <ctype.h>
#include <fcntl.h>
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/syscall.h>
#include <sys/resource.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "jerry-libc-defs.h"
LIBC_UNREACHABLE_STUB_FOR (int raise (int sig_no __attr_unused___))
/**
* Exit program with ERR_SYSCALL if syscall_ret_val is negative
*/
#define LIBC_EXIT_ON_ERROR(syscall_ret_val) \
if ((syscall_ret_val) < 0) \
{ \
libc_fatal ("Syscall", __FILE__, __func__, __LINE__); \
}
static long int syscall_0 (long int syscall_no);
static long int syscall_1 (long int syscall_no, long int arg1);
static long int syscall_2 (long int syscall_no, long int arg1, long int arg2);
static long int syscall_3 (long int syscall_no, long int arg1, long int arg2, long int arg3);
extern long int syscall_0_asm (long int syscall_no);
extern long int syscall_1_asm (long int syscall_no, long int arg1);
extern long int syscall_2_asm (long int syscall_no, long int arg1, long int arg2);
extern long int syscall_3_asm (long int syscall_no, long int arg1, long int arg2, long int arg3);
/**
* System call with no argument.
*
* @return syscall's return value
*/
static __attr_noinline___ long int
syscall_0 (long int syscall_no) /**< syscall number */
{
long int ret = syscall_0_asm (syscall_no);
LIBC_EXIT_ON_ERROR (ret);
return ret;
} /* syscall_0 */
/**
* System call with one argument.
*
* @return syscall's return value
*/
static __attr_noinline___ long int
syscall_1 (long int syscall_no, /**< syscall number */
long int arg1) /**< argument */
{
long int ret = syscall_1_asm (syscall_no, arg1);
LIBC_EXIT_ON_ERROR (ret);
return ret;
} /* syscall_1 */
/**
* System call with two arguments.
*
* @return syscall's return value
*/
static __attr_noinline___ long int
syscall_2 (long int syscall_no, /**< syscall number */
long int arg1, /**< first argument */
long int arg2) /**< second argument */
{
long int ret = syscall_2_asm (syscall_no, arg1, arg2);
LIBC_EXIT_ON_ERROR (ret);
return ret;
} /* syscall_2 */
/**
* System call with three arguments.
*
* @return syscall's return value
*/
static __attr_noinline___ long int
syscall_3 (long int syscall_no, /**< syscall number */
long int arg1, /**< first argument */
long int arg2, /**< second argument */
long int arg3) /**< third argument */
{
long int ret = syscall_3_asm (syscall_no, arg1, arg2, arg3);
LIBC_EXIT_ON_ERROR (ret);
return ret;
} /* syscall_3 */
/** Output of character. Writes the character c, cast to an unsigned char, to stdout. */
int
putchar (int c)
{
fwrite (&c, 1, sizeof (char), stdout);
return c;
} /* putchar */
/**
* Output specified string
*/
int
puts (const char *s) /**< string to print */
{
while (*s)
{
putchar (*s);
s++;
}
return 0;
} /* puts */
/**
* Exit - cause normal process termination with specified status code
*/
void __attr_noreturn___ __attr_used___
exit (int status) /**< status code */
{
syscall_1 (SYS_close, (long int)stdin);
syscall_1 (SYS_close, (long int)stdout);
syscall_1 (SYS_close, (long int)stderr);
syscall_1 (SYS_exit, status);
while (true)
{
/* unreachable */
}
} /* exit */
/**
* Abort current process, producing an abnormal program termination.
* The function raises the SIGABRT signal.
*/
void __attr_noreturn___ __attr_used___
abort (void)
{
syscall_1 (SYS_close, (long int)stdin);
syscall_1 (SYS_close, (long int)stdout);
syscall_1 (SYS_close, (long int)stderr);
syscall_2 (SYS_kill, syscall_0 (SYS_getpid), SIGABRT);
while (true)
{
/* unreachable */
}
} /* abort */
/**
* fopen
*
* @return FILE pointer - upon successful completion,
* NULL - otherwise
*/
FILE*
fopen (const char *path, /**< file path */
const char *mode) /**< file open mode */
{
bool may_read = false;
bool may_write = false;
bool truncate = false;
bool create_if_not_exist = false;
bool position_at_end = false;
LIBC_ASSERT (path != NULL && mode != NULL);
LIBC_ASSERT (mode[1] == '+' || mode[1] == '\0');
switch (mode[0])
{
case 'r':
{
may_read = true;
may_write = (mode[1] == '+');
break;
}
case 'w':
{
may_write = true;
truncate = true;
create_if_not_exist = true;
may_read = (mode[1] == '+');
break;
}
case 'a':
{
may_write = true;
position_at_end = true;
create_if_not_exist = true;
if (mode[1] == '+')
{
/* Not supported */
LIBC_UNREACHABLE ();
}
break;
}
default:
{
LIBC_UNREACHABLE ();
}
}
int flags = 0;
int access = S_IRUSR | S_IWUSR;
if (may_read && !may_write)
{
flags = O_RDONLY;
}
else if (!may_read && may_write)
{
flags = O_WRONLY;
}
else
{
LIBC_ASSERT (may_read && may_write);
flags = O_RDWR;
}
if (truncate)
{
flags |= O_TRUNC;
}
if (create_if_not_exist)
{
flags |= O_CREAT;
}
if (position_at_end)
{
flags |= O_APPEND;
}
long int ret = syscall_3 (SYS_open, (long int) path, flags, access);
return (void*) (uintptr_t) (ret);
} /* fopen */
/**
* The rewind () function sets the file position indicator
* for the stream pointed to by STREAM to the beginning of the file.
*/
void
rewind (FILE *stream) /**< stream pointer */
{
syscall_3 (SYS_lseek, (long int) stream, 0, SEEK_SET);
} /* rewind */
/**
* fclose
*
* @return 0 - upon successful completion,
* non-zero value - otherwise.
*/
int
fclose (FILE *fp) /**< stream pointer */
{
syscall_2 (SYS_close, (long int)fp, 0);
return 0;
} /* fclose */
/**
* fseek
*/
int
fseek (FILE * fp, /**< stream pointer */
long offset, /**< offset */
int whence) /**< specifies position type
* to add offset to */
{
syscall_3 (SYS_lseek, (long int)fp, offset, whence);
return 0;
} /* fseek */
/**
* ftell
*/
long
ftell (FILE * fp) /**< stream pointer */
{
long int ret = syscall_3 (SYS_lseek, (long int)fp, 0, SEEK_CUR);
return ret;
} /* ftell */
/**
* fread
*
* @return number of elements read
*/
size_t
fread (void *ptr, /**< address of buffer to read to */
size_t size, /**< size of elements to read */
size_t nmemb, /**< number of elements to read */
FILE *stream) /**< stream pointer */
{
long int ret;
size_t bytes_read = 0;
if (size == 0)
{
return 0;
}
do
{
ret = syscall_3 (SYS_read,
(long int) stream,
(long int) ((uint8_t*) ptr + bytes_read),
(long int) (size * nmemb - bytes_read));
bytes_read += (size_t)ret;
}
while (bytes_read != size * nmemb && ret != 0);
return bytes_read / size;
} /* fread */
/**
* fwrite
*
* @return number of elements written
*/
size_t
fwrite (const void *ptr, /**< data to write */
size_t size, /**< size of elements to write */
size_t nmemb, /**< number of elements */
FILE *stream) /**< stream pointer */
{
size_t bytes_written = 0;
if (size == 0)
{
return 0;
}
do
{
long int ret = syscall_3 (SYS_write,
(long int) stream,
(long int) ((uint8_t*) ptr + bytes_written),
(long int) (size * nmemb - bytes_written));
bytes_written += (size_t)ret;
}
while (bytes_written != size * nmemb);
return bytes_written / size;
} /* fwrite */

319
main-darwin.cpp Normal file
View File

@ -0,0 +1,319 @@
/* Copyright 2014-2015 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "jerry.h"
#include "jrt/jrt.h"
/**
* Maximum command line arguments number
*/
#define JERRY_MAX_COMMAND_LINE_ARGS (64)
/**
* Maximum size of source code buffer
*/
#define JERRY_SOURCE_BUFFER_SIZE (1048576)
/**
* Standalone Jerry exit codes
*/
#define JERRY_STANDALONE_EXIT_CODE_OK (0)
#define JERRY_STANDALONE_EXIT_CODE_FAIL (1)
static uint8_t source_buffer[ JERRY_SOURCE_BUFFER_SIZE ];
static const jerry_api_char_t *
read_sources (const char *script_file_names[],
int files_count,
size_t *out_source_size_p)
{
int i;
uint8_t *source_buffer_tail = source_buffer;
for (i = 0; i < files_count; i++)
{
const char *script_file_name = script_file_names[i];
FILE *file = fopen (script_file_name, "r");
if (file == NULL)
{
break;
}
int fseek_status = fseek (file, 0, SEEK_END);
if (fseek_status != 0)
{
break;
}
long script_len = ftell (file);
if (script_len < 0)
{
fclose (file);
break;
}
rewind (file);
const size_t current_source_size = (size_t)script_len;
if (source_buffer_tail + current_source_size >= source_buffer + sizeof (source_buffer))
{
fclose (file);
break;
}
size_t bytes_read = fread (source_buffer_tail, 1, current_source_size, file);
if (bytes_read < current_source_size)
{
fclose (file);
break;
}
fclose (file);
source_buffer_tail += current_source_size;
}
if (i < files_count)
{
JERRY_ERROR_MSG ("Failed to read script N%d\n", i + 1);
return NULL;
}
else
{
const size_t source_size = (size_t) (source_buffer_tail - source_buffer);
*out_source_size_p = source_size;
return (const jerry_api_char_t *) source_buffer;
}
}
/**
* Provide the 'assert' implementation for the engine.
*
* @return true - if only one argument was passed and the argument is a boolean true.
*/
static bool
assert_handler (const jerry_api_object_t *function_obj_p __attr_unused___, /** < function object */
const jerry_api_value_t *this_p __attr_unused___, /** < this arg */
jerry_api_value_t *ret_val_p __attr_unused___, /** < return argument */
const jerry_api_value_t args_p[], /** < function arguments */
const jerry_api_length_t args_cnt) /** < number of function arguments */
{
if (args_cnt == 1
&& args_p[0].type == JERRY_API_DATA_TYPE_BOOLEAN
&& args_p[0].v_bool == true)
{
return true;
}
else
{
JERRY_ERROR_MSG ("Script assertion failed\n");
exit (JERRY_STANDALONE_EXIT_CODE_FAIL);
}
} /* assert_handler */
int
main (int argc,
char **argv)
{
if (argc >= JERRY_MAX_COMMAND_LINE_ARGS)
{
JERRY_ERROR_MSG ("Too many command line arguments. Current maximum is %d (JERRY_MAX_COMMAND_LINE_ARGS)\n", argc);
return JERRY_STANDALONE_EXIT_CODE_FAIL;
}
const char *file_names[JERRY_MAX_COMMAND_LINE_ARGS];
int i;
int files_counter = 0;
size_t max_data_bss_size, max_stack_size;
jerry_get_memory_limits (&max_data_bss_size, &max_stack_size);
// FIXME:
// jrt_set_mem_limits (max_data_bss_size, max_stack_size);
jerry_flag_t flags = JERRY_FLAG_EMPTY;
#ifdef JERRY_ENABLE_LOG
const char *log_file_name = NULL;
#endif /* JERRY_ENABLE_LOG */
for (i = 1; i < argc; i++)
{
if (!strcmp ("-v", argv[i]))
{
printf ("Build date: \t%s\n", jerry_build_date);
printf ("Commit hash:\t%s\n", jerry_commit_hash);
printf ("Branch name:\t%s\n", jerry_branch_name);
printf ("\n");
}
else if (!strcmp ("--mem-stats", argv[i]))
{
flags |= JERRY_FLAG_MEM_STATS;
}
else if (!strcmp ("--mem-stats-per-opcode", argv[i]))
{
flags |= JERRY_FLAG_MEM_STATS_PER_OPCODE;
}
else if (!strcmp ("--mem-stats-separate", argv[i]))
{
flags |= JERRY_FLAG_MEM_STATS_SEPARATE;
}
else if (!strcmp ("--parse-only", argv[i]))
{
flags |= JERRY_FLAG_PARSE_ONLY;
}
else if (!strcmp ("--show-opcodes", argv[i]))
{
flags |= JERRY_FLAG_SHOW_OPCODES;
}
else if (!strcmp ("--log-level", argv[i]))
{
flags |= JERRY_FLAG_ENABLE_LOG;
if (++i < argc && strlen (argv[i]) == 1 && argv[i][0] >='0' && argv[i][0] <= '3')
{
#ifdef JERRY_ENABLE_LOG
jerry_debug_level = argv[i][0] - '0';
#endif /* JERRY_ENABLE_LOG */
}
else
{
JERRY_ERROR_MSG ("Error: wrong format or invalid argument\n");
return JERRY_STANDALONE_EXIT_CODE_FAIL;
}
}
else if (!strcmp ("--log-file", argv[i]))
{
flags |= JERRY_FLAG_ENABLE_LOG;
if (++i < argc)
{
#ifdef JERRY_ENABLE_LOG
log_file_name = argv[i];
#endif /* JERRY_ENABLE_LOG */
}
else
{
JERRY_ERROR_MSG ("Error: wrong format of the arguments\n");
return JERRY_STANDALONE_EXIT_CODE_FAIL;
}
}
else if (!strcmp ("--abort-on-fail", argv[i]))
{
flags |= JERRY_FLAG_ABORT_ON_FAIL;
}
else
{
file_names[files_counter++] = argv[i];
}
}
if (files_counter == 0)
{
return JERRY_STANDALONE_EXIT_CODE_OK;
}
else
{
size_t source_size;
const jerry_api_char_t *source_p = read_sources (file_names, files_counter, &source_size);
if (source_p == NULL)
{
return JERRY_STANDALONE_EXIT_CODE_FAIL;
}
else
{
#ifdef JERRY_ENABLE_LOG
if (log_file_name)
{
jerry_log_file = fopen (log_file_name, "w");
if (jerry_log_file == NULL)
{
JERRY_ERROR_MSG ("Failed to open log file: %s\n", log_file_name);
return JERRY_STANDALONE_EXIT_CODE_FAIL;
}
}
else
{
jerry_log_file = stdout;
}
#endif /* JERRY_ENABLE_LOG */
jerry_init (flags);
jerry_api_object_t *global_obj_p = jerry_api_get_global ();
jerry_api_object_t *assert_func_p = jerry_api_create_external_function (assert_handler);
jerry_api_value_t assert_value;
assert_value.type = JERRY_API_DATA_TYPE_OBJECT;
assert_value.v_object = assert_func_p;
bool is_assert_added = jerry_api_set_object_field_value (global_obj_p,
(jerry_api_char_t *) "assert",
&assert_value);
jerry_api_release_value (&assert_value);
jerry_api_release_object (global_obj_p);
if (!is_assert_added)
{
JERRY_ERROR_MSG ("Failed to register 'assert' method.");
}
jerry_completion_code_t ret_code = JERRY_COMPLETION_CODE_OK;
if (!jerry_parse (source_p, source_size))
{
/* unhandled SyntaxError */
ret_code = JERRY_COMPLETION_CODE_UNHANDLED_EXCEPTION;
}
else
{
if ((flags & JERRY_FLAG_PARSE_ONLY) == 0)
{
ret_code = jerry_run ();
}
}
jerry_cleanup ();
#ifdef JERRY_ENABLE_LOG
if (jerry_log_file && jerry_log_file != stdout)
{
fclose (jerry_log_file);
jerry_log_file = NULL;
}
#endif /* JERRY_ENABLE_LOG */
if (ret_code == JERRY_COMPLETION_CODE_OK)
{
return JERRY_STANDALONE_EXIT_CODE_OK;
}
else
{
return JERRY_STANDALONE_EXIT_CODE_FAIL;
}
}
}
}