Improve the linking of libraries (#1338)

Although both jerry-libc and jerry-libm have configuration options
that enable/disable their build, in practice, only jerry-libc can be
replaced with the system (compiler-default) libc. If jerry-libm is
disabled, the build of jerry-main fails, as there is no way to
instruct the linker to link the system libm to the binary. (The
build system does have a way to pass flags to the linker, but those
flags are listed before the linked objects. For the references to
get resolved correctly, the libraries to be linked have to be
specified _after_ the objects.)

This patch adds the EXTERNAL_LINK_LIBS configuration option to
CMakeLists, which ensures that the specified libraries get
correctly passed to the linker. (E.g, replacing jerry-libm with
system libm becomes possible with
`JERRY_LIBM=OFF EXTERNAL_LINK_LIBS='-lm'`.)

Additionally, the patch also makes the following related changes:

* Removes the COMPILER_DEFAULT_LIBC configuration option, as it is
  (almost) always the opposite of JERRY_LIBC. Moreover, its name is
  misleading: its only role is to add `-nostdlib` to the linker
  flags.

* Makes use of transitive library dependencies: if a library has
  another library as dependency, and it is linked to a binary, its
  dependency is linked as well. Thus, jerry-libc, jerry-libm, and
  any external libraries are added to jerry-core as dependency, and
  then only jerry-core is linked to executables (cmake will take
  care of the rest).

* build.py and run-tests.py follow up the changes, along with some
  minor syntax changes.

* Moves static linking option to global CMakeLists, as unit test
  binaries should be linked the same way as jerry-main.

* Adds EXTERNAL_COMPILER_FLAGS and EXTERNAL_LINKER_FLAGS as last to
  the flag list, to allow user override of (nearly) anything.

The patch speculatively follows up the build system changes in the
mbed, riot-stm32f4, and zephyr targets.

JerryScript-DCO-1.0-Signed-off-by: Akos Kiss akiss@inf.u-szeged.hu
This commit is contained in:
Akos Kiss 2016-09-15 13:07:01 +02:00 committed by GitHub
parent 86ac6445e8
commit d38ab71140
10 changed files with 42 additions and 72 deletions

View File

@ -31,10 +31,10 @@ set(UNITTESTS OFF CACHE BOOL "Build unit tests?")
# Optional build settings
set(PORT_DIR "${CMAKE_SOURCE_DIR}/targets/default" CACHE STRING "Use default or external port?")
set(COMPILER_DEFAULT_LIBC OFF CACHE BOOL "Use compiler default libc?")
set(ENABLE_LTO OFF CACHE BOOL "Enable LTO build?")
set(ENABLE_ALL_IN_ONE ON CACHE BOOL "Enable all-in-one build?")
set(ENABLE_STRIP ON CACHE BOOL "Enable stripping all symbols from release binary?")
set(ENABLE_STATIC_LINK ON CACHE BOOL "Enable static linking?")
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release")
@ -45,11 +45,7 @@ if("${PLATFORM}" STREQUAL "DARWIN")
set(ENABLE_ALL_IN_ONE "ON")
set(JERRY_LIBC "OFF")
set(JERRY_LIBM "OFF")
set(COMPILER_DEFAULT_LIBC "ON")
endif()
if(JERRY_LIBC AND COMPILER_DEFAULT_LIBC)
message(FATAL_ERROR "JERRY_LIBC and COMPILER_DEFAULT_LIBC cannot be enabled at the same time")
set(ENABLE_STATIC_LINK "OFF")
endif()
# Status messages
@ -61,10 +57,10 @@ message(STATUS "JERRY_LIBM " ${JERRY_LIBM})
message(STATUS "JERRY_CMDLINE " ${JERRY_CMDLINE})
message(STATUS "UNITTESTS " ${UNITTESTS})
message(STATUS "PORT_DIR " ${PORT_DIR})
message(STATUS "COMPILER_DEFAULT_LIBC " ${COMPILER_DEFAULT_LIBC})
message(STATUS "ENABLE_LTO " ${ENABLE_LTO})
message(STATUS "ENABLE_ALL_IN_ONE " ${ENABLE_ALL_IN_ONE})
message(STATUS "ENABLE_STRIP " ${ENABLE_STRIP})
message(STATUS "ENABLE_STATIC_LINK " ${ENABLE_STATIC_LINK})
# Setup directories
# Project binary dir
@ -111,6 +107,11 @@ set(CMAKE_C_FLAGS_RELEASE "-Os")
jerry_add_compile_flags(${FLAGS_COMMON_ARCH})
jerry_add_flags(CMAKE_EXE_LINKER_FLAGS ${FLAGS_COMMON_ARCH})
# Enable static build
if(ENABLE_STATIC_LINK)
jerry_add_link_flags("-static")
endif()
# LTO
if(ENABLE_LTO)
jerry_add_compile_flags(-flto)
@ -126,7 +127,7 @@ if(ENABLE_LTO)
endif()
# Define _BSD_SOURCE if we use default port and compiler default libc
if(${PORT_DIR} STREQUAL "${CMAKE_SOURCE_DIR}/targets/default" AND COMPILER_DEFAULT_LIBC)
if(${PORT_DIR} STREQUAL "${CMAKE_SOURCE_DIR}/targets/default" AND NOT JERRY_LIBC)
set(DEFINES_JERRY ${DEFINES_JERRY} _BSD_SOURCE)
endif()
@ -163,8 +164,8 @@ else()
jerry_add_link_flags(-Wl,-z,noexecstack)
endif()
# Turn off linking to compiler's default libc, in case jerry-libc or external is used
if(NOT COMPILER_DEFAULT_LIBC)
# Turn off linking to compiler's default libc, in case jerry-libc is used
if(JERRY_LIBC)
jerry_add_link_flags(-nostdlib)
endif()
@ -187,14 +188,6 @@ if(JERRY_LIBC)
jerry_add_compile_flags(-Werror)
endif()
if(DEFINED EXTERNAL_COMPILE_FLAGS)
jerry_add_compile_flags(${EXTERNAL_COMPILE_FLAGS})
endif()
if(DEFINED EXTERNAL_LINKER_FLAGS)
jerry_add_link_flags(${EXTERNAL_LINKER_FLAGS})
endif()
# C
jerry_add_compile_flags(-std=c99 -pedantic)
@ -203,6 +196,15 @@ if(ENABLE_STRIP AND NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
jerry_add_link_flags(-s)
endif()
# External compiler & linker flags
if(DEFINED EXTERNAL_COMPILE_FLAGS)
jerry_add_compile_flags(${EXTERNAL_COMPILE_FLAGS})
endif()
if(DEFINED EXTERNAL_LINKER_FLAGS)
jerry_add_link_flags(${EXTERNAL_LINKER_FLAGS})
endif()
# Jerry's libc
if(JERRY_LIBC)
add_subdirectory(jerry-libc)

View File

@ -58,13 +58,13 @@ The default libc is jerry-libc, but you can use compiler-default libc or an exte
- compiler-default libc:
```bash
python tools/build.py --jerry-libc=off --compiler-default-libc=on
python tools/build.py --jerry-libc=off
```
- external libc:
```bash
python tools/build.py --jerry-libc=off --compiler-default-libc=off --compile-flag="-I/path/to/libc/include"
python tools/build.py --jerry-libc=off --compile-flag="-nostdlib -I/path/to/ext-libc/include" --link-lib="-lext-c"
```
**Add toolchain file**

View File

@ -201,13 +201,19 @@ add_library(${JERRY_CORE_NAME} STATIC ${SOURCE_CORE})
target_compile_definitions(${JERRY_CORE_NAME} PUBLIC ${DEFINES_JERRY})
target_include_directories(${JERRY_CORE_NAME} PUBLIC ${INCLUDE_CORE})
if (JERRY_LIBC)
set(JERRY_LIBS )
if(JERRY_LIBC)
set(JERRY_LIBS ${JERRY_LIBS} jerry-libc)
target_include_directories(${JERRY_CORE_NAME} SYSTEM PRIVATE "${CMAKE_SOURCE_DIR}/jerry-libc/include")
endif()
if (JERRY_LIBM)
if(JERRY_LIBM)
set(JERRY_LIBS ${JERRY_LIBS} jerry-libm)
target_include_directories(${JERRY_CORE_NAME} SYSTEM PRIVATE "${CMAKE_SOURCE_DIR}/jerry-libm/include")
endif()
target_link_libraries(${JERRY_CORE_NAME} ${JERRY_LIBS} ${IMPORTED_LIB} ${EXTERNAL_LINK_LIBS})
install(TARGETS ${JERRY_CORE_NAME} DESTINATION lib)
install(FILES jerry-api.h jerry-port.h DESTINATION include)

View File

@ -18,16 +18,10 @@ set(JERRY_NAME jerry)
project (${JERRY_NAME} C)
# Optional build settings
set(ENABLE_LINK_MAP OFF CACHE BOOL "Enable generating a link map file?")
set(ENABLE_STATIC_LINK ON CACHE BOOL "Enable static linking?")
if("${PLATFORM}" STREQUAL "DARWIN")
set(ENABLE_STATIC_LINK "OFF")
endif()
set(ENABLE_LINK_MAP OFF CACHE BOOL "Enable generating a link map file?")
# Status messages
message(STATUS "ENABLE_LINK_MAP " ${ENABLE_LINK_MAP})
message(STATUS "ENABLE_STATIC_LINK " ${ENABLE_STATIC_LINK})
# Sources
# Jerry standalone
@ -42,11 +36,6 @@ if(ENABLE_LINK_MAP)
endif()
endif()
# Disable static build
if(ENABLE_STATIC_LINK)
set(LINKER_FLAGS_COMMON "-static ${LINKER_FLAGS_COMMON}")
endif()
# Get version information from git
if(IS_DIRECTORY "${CMAKE_SOURCE_DIR}/.git")
execute_process(COMMAND git rev-parse --short HEAD
@ -67,18 +56,6 @@ target_compile_definitions(${JERRY_NAME} PRIVATE ${DEFINES_JERRY})
target_include_directories(${JERRY_NAME} PRIVATE ${PORT_DIR})
link_directories(${CMAKE_BINARY_DIR})
set(JERRY_LIBS jerry-core)
if(JERRY_LIBM)
set(JERRY_LIBS ${JERRY_LIBS} jerry-libm)
endif()
if(JERRY_LIBC)
set(JERRY_LIBS ${JERRY_LIBS} jerry-libc)
endif()
set(JERRY_LIBS ${JERRY_LIBS} ${IMPORTED_LIB})
target_link_libraries(${JERRY_NAME} ${JERRY_LIBS})
target_link_libraries(${JERRY_NAME} jerry-core)
install(TARGETS ${JERRY_NAME} DESTINATION bin)

View File

@ -59,7 +59,6 @@ jerry:
-DCMAKE_TOOLCHAIN_FILE=cmake/toolchain_external.cmake \
-DJERRY_LIBC=OFF \
-DJERRY_CMDLINE=OFF \
-DCOMPILER_DEFAULT_LIBC=ON \
-DENABLE_ALL_IN_ONE=OFF \
-DEXTERNAL_CMAKE_SYSTEM_PROCESSOR=armv7l-hf \
-DEXTERNAL_CMAKE_C_COMPILER=arm-none-eabi-gcc \

View File

@ -35,7 +35,6 @@ libjerry:
-DCMAKE_TOOLCHAIN_FILE=cmake/toolchain_external.cmake \
-DJERRY_LIBC=OFF \
-DJERRY_CMDLINE=OFF \
-DCOMPILER_DEFAULT_LIBC=ON \
-DENABLE_ALL_IN_ONE=OFF \
-DEXTERNAL_CMAKE_SYSTEM_PROCESSOR=armv7l \
-DEXTERNAL_CMAKE_C_COMPILER=arm-none-eabi-gcc \

View File

@ -86,6 +86,7 @@ EXT_CFLAGS += -Werror=format -Werror=implicit-int -Wno-unused-but-set-variable
EXT_CFLAGS += -Wno-main -Wno-strict-aliasing -Wno-old-style-declaration
EXT_CFLAGS += -Wno-error=format=
EXT_CFLAGS += -D_XOPEN_SOURCE=700
EXT_CFLAGS += -nostdlib
# Pass2
-include $(ZEPHYR_BASE)/scripts/Makefile.toolchain.$(ZEPHYR_GCC_VARIANT)
@ -127,7 +128,6 @@ endif
-DEXTERNAL_CMAKE_C_COMPILER=$(CC) \
-DEXTERNAL_CMAKE_C_COMPILER_ID=GNU \
-DEXTERNAL_CMAKE_SYSTEM_PROCESSOR=$(CPU) \
-DCOMPILER_DEFAULT_LIBC=OFF \
-DJERRY_CMDLINE=OFF \
-DEXTERNAL_COMPILE_FLAGS="$(EXT_CFLAGS)" \
-DCMAKE_TOOLCHAIN_FILE=cmake/toolchain_external.cmake \

View File

@ -36,19 +36,7 @@ foreach(SOURCE_UNIT_TEST_MAIN ${SOURCE_UNIT_TEST_MAIN_MODULES})
link_directories(${CMAKE_BINARY_DIR})
set(JERRY_LIBS jerry-core)
if(JERRY_LIBM)
set(JERRY_LIBS ${JERRY_LIBS} jerry-libm)
endif()
if(JERRY_LIBC)
set(JERRY_LIBS ${JERRY_LIBS} jerry-libc)
endif()
set(JERRY_LIBS ${JERRY_LIBS} ${IMPORTED_LIB})
target_link_libraries(${TARGET_NAME} ${JERRY_LIBS})
target_link_libraries(${TARGET_NAME} jerry-core)
add_dependencies(unittests ${TARGET_NAME})
endforeach()

View File

@ -55,15 +55,15 @@ def get_arguments():
parser.add_argument('--snapshot-exec', metavar='X', choices=['on', 'off'], default='on', help='enable executing snapshot files (%(choices)s; default: %(default)s)')
parser.add_argument('--cpointer-32bit', metavar='X', choices=['on', 'off'], default='off', help='enable 32 bit compressed pointers (%(choices)s; default: %(default)s)')
parser.add_argument('--toolchain', metavar='FILE', action='store', default=default_toolchain(), help='add toolchain file (default: %(default)s)')
parser.add_argument('--cmake-param', metavar='OPTS', action='append', default=[], help='add custom arguments to CMake')
parser.add_argument('--compile-flag', metavar='OPTS', action='append', default=[], help='add custom compile flags')
parser.add_argument('--linker-flag', metavar='OPTS', action='append', default=[], help='add custom linker flags')
parser.add_argument('--cmake-param', metavar='OPT', action='append', default=[], help='add custom argument to CMake')
parser.add_argument('--compile-flag', metavar='OPT', action='append', default=[], help='add custom compile flag')
parser.add_argument('--linker-flag', metavar='OPT', action='append', default=[], help='add custom linker flag')
parser.add_argument('--link-lib', metavar='OPT', action='append', default=[], help='add custom library to be linked')
parser.add_argument('--jerry-libc', metavar='X', choices=['on', 'off'], default='on', help='build and use jerry-libc (%(choices)s; default: %(default)s)')
parser.add_argument('--compiler-default-libc', metavar='X', choices=['on', 'off'], default='off', help='use compiler-default libc (%(choices)s; default: %(default)s)')
parser.add_argument('--jerry-libm', metavar='X', choices=['on', 'off'], default='on', help='build and use jerry-libm (%(choices)s; default: %(default)s)')
parser.add_argument('--jerry-cmdline', metavar='X', choices=['on', 'off'], default='on', help='build jerry command line tool (%(choices)s; default: %(default)s)')
parser.add_argument('--static-link', metavar='X', choices=['on', 'off'], default='on', help='enable static linking of jerry command line tool (%(choices)s; default: %(default)s)')
parser.add_argument('--strip', metavar='X', choices=['on', 'off'], default='on', help='strip release binary (%(choices)s; default: %(default)s)')
parser.add_argument('--static-link', metavar='X', choices=['on', 'off'], default='on', help='enable static linking of binaries (%(choices)s; default: %(default)s)')
parser.add_argument('--strip', metavar='X', choices=['on', 'off'], default='on', help='strip release binaries (%(choices)s; default: %(default)s)')
parser.add_argument('--unittests', action='store_const', const='ON', default='OFF', help='build unittests')
devgroup = parser.add_argument_group('developer options')
@ -88,7 +88,6 @@ def generate_build_options(arguments):
build_options.append('-DJERRY_LIBC=%s' % arguments.jerry_libc.upper())
build_options.append('-DJERRY_LIBM=%s' % arguments.jerry_libm.upper())
build_options.append('-DJERRY_CMDLINE=%s' % arguments.jerry_cmdline.upper())
build_options.append('-DCOMPILER_DEFAULT_LIBC=%s' % arguments.compiler_default_libc.upper())
build_options.append('-DCMAKE_VERBOSE_MAKEFILE=%s' % arguments.verbose)
build_options.append('-DCMAKE_BUILD_TYPE=%s' % arguments.build_type)
build_options.append('-DFEATURE_PROFILE=%s' % arguments.profile)
@ -113,6 +112,7 @@ def generate_build_options(arguments):
build_options.append('-DEXTERNAL_COMPILE_FLAGS=' + ' '.join(arguments.compile_flag))
build_options.append('-DEXTERNAL_LINKER_FLAGS=' + ' '.join(arguments.linker_flag))
build_options.append('-DEXTERNAL_LINK_LIBS=' + ' '.join(arguments.link_lib))
if arguments.toolchain:
build_options.append('-DCMAKE_TOOLCHAIN_FILE=%s' % arguments.toolchain)

View File

@ -91,8 +91,7 @@ jerry_buildoptions = [
Options('buildoption_test-mem_stats', ['--mem-stats=on']),
Options('buildoption_test-show_opcodes', ['--show-opcodes=on']),
Options('buildoption_test-show_regexp_opcodes', ['--show-regexp-opcodes=on']),
Options('buildoption_test-jerry_libc', ['--jerry-libc=on', '--compiler-default-libc=off']),
Options('buildoption_test-compiler_default_libc', ['--compiler-default-libc=on', '--jerry-libc=off']),
Options('buildoption_test-compiler_default_libc', ['--jerry-libc=off']),
]
def get_bin_dir_path(out_dir):