00d104e519
run-test262 required pthreads, so let's add that. In addition, in MinGW, clock_gettime is implemented in the pthreads library, so we want to link it too. This doesn't get us anywhere closer to building with ClangCL on Windows, but hey, another target that required some tweaking...
330 lines
9.5 KiB
CMake
330 lines
9.5 KiB
CMake
cmake_minimum_required(VERSION 3.9)
|
|
|
|
project(quickjs LANGUAGES C)
|
|
|
|
include(CheckCCompilerFlag)
|
|
include(GNUInstallDirs)
|
|
|
|
# TODO:
|
|
# - Support cross-compilation
|
|
|
|
set(CMAKE_C_VISIBILITY_PRESET hidden)
|
|
set(CMAKE_C_STANDARD_REQUIRED ON)
|
|
set(CMAKE_C_EXTENSIONS ON)
|
|
set(CMAKE_C_STANDARD 11)
|
|
|
|
if(NOT CMAKE_BUILD_TYPE)
|
|
message(STATUS "No build type selected, default to Release")
|
|
set(CMAKE_BUILD_TYPE "Release")
|
|
endif()
|
|
|
|
message(STATUS "Building in ${CMAKE_BUILD_TYPE} mode")
|
|
message(STATUS "Building with ${CMAKE_C_COMPILER_ID} ${CMAKE_C_COMPILER_VERSION} on ${CMAKE_SYSTEM}")
|
|
|
|
macro(xcheck_add_c_compiler_flag FLAG)
|
|
string(REPLACE "-" "" FLAG_NO_HYPHEN ${FLAG})
|
|
check_c_compiler_flag(${FLAG} COMPILER_SUPPORTS_${FLAG_NO_HYPHEN})
|
|
if(COMPILER_SUPPORTS_${FLAG_NO_HYPHEN})
|
|
add_compile_options(${FLAG})
|
|
endif()
|
|
endmacro()
|
|
|
|
xcheck_add_c_compiler_flag(-Wall)
|
|
xcheck_add_c_compiler_flag(-Werror)
|
|
xcheck_add_c_compiler_flag(-Wextra)
|
|
xcheck_add_c_compiler_flag(-Wno-implicit-fallthrough)
|
|
xcheck_add_c_compiler_flag(-Wno-sign-compare)
|
|
xcheck_add_c_compiler_flag(-Wno-missing-field-initializers)
|
|
xcheck_add_c_compiler_flag(-Wno-unused-parameter)
|
|
xcheck_add_c_compiler_flag(-Wno-unused-variable)
|
|
xcheck_add_c_compiler_flag(-Wno-unused-but-set-variable)
|
|
xcheck_add_c_compiler_flag(-Wno-array-bounds)
|
|
xcheck_add_c_compiler_flag(-Wno-format-truncation)
|
|
xcheck_add_c_compiler_flag(-funsigned-char)
|
|
|
|
if(CMAKE_BUILD_TYPE MATCHES "Debug")
|
|
add_compile_options(-O0)
|
|
xcheck_add_c_compiler_flag(-ggdb)
|
|
xcheck_add_c_compiler_flag(-fno-omit-frame-pointer)
|
|
endif()
|
|
|
|
macro(xoption OPTION_NAME OPTION_TEXT OPTION_DEFAULT)
|
|
option(${OPTION_NAME} ${OPTION_TEXT} ${OPTION_DEFAULT})
|
|
if(DEFINED ENV{${OPTION_NAME}})
|
|
# Allow setting the option through an environment variable.
|
|
set(${OPTION_NAME} $ENV{${OPTION_NAME}})
|
|
endif()
|
|
if(${OPTION_NAME})
|
|
add_definitions(-D${OPTION_NAME})
|
|
endif()
|
|
message(STATUS " ${OPTION_NAME}: ${${OPTION_NAME}}")
|
|
endmacro()
|
|
|
|
xoption(BUILD_SHARED_LIBS "Build a shared library" OFF)
|
|
if(BUILD_SHARED_LIBS)
|
|
message(STATUS "Building a shared library")
|
|
endif()
|
|
|
|
xoption(BUILD_EXAMPLES "Build examples" OFF)
|
|
xoption(BUILD_STATIC_QJS_EXE "Build a static qjs executable" OFF)
|
|
xoption(CONFIG_ASAN "Enable AddressSanitizer (ASan)" OFF)
|
|
xoption(CONFIG_MSAN "Enable MemorySanitizer (MSan)" OFF)
|
|
xoption(CONFIG_UBSAN "Enable UndefinedBehaviorSanitizer (UBSan)" OFF)
|
|
|
|
if(CONFIG_ASAN)
|
|
message(STATUS "Building with ASan")
|
|
add_compile_definitions(
|
|
__ASAN__=1
|
|
)
|
|
add_compile_options(
|
|
-fsanitize=address
|
|
-fno-sanitize-recover=all
|
|
-fno-omit-frame-pointer
|
|
)
|
|
add_link_options(
|
|
-fsanitize=address
|
|
-fno-sanitize-recover=all
|
|
-fno-omit-frame-pointer
|
|
)
|
|
elseif(CONFIG_MSAN)
|
|
message(STATUS "Building with MSan")
|
|
add_compile_options(
|
|
-fsanitize=memory
|
|
-fno-sanitize-recover=all
|
|
-fno-omit-frame-pointer
|
|
)
|
|
add_link_options(
|
|
-fsanitize=memory
|
|
-fno-sanitize-recover=all
|
|
-fno-omit-frame-pointer
|
|
)
|
|
elseif(CONFIG_UBSAN)
|
|
message(STATUS "Building with UBSan")
|
|
add_compile_options(
|
|
-fsanitize=undefined
|
|
-fno-sanitize-recover=all
|
|
-fno-omit-frame-pointer
|
|
)
|
|
add_link_options(
|
|
-fsanitize=undefined
|
|
-fno-sanitize-recover=all
|
|
-fno-omit-frame-pointer
|
|
)
|
|
endif()
|
|
|
|
|
|
# QuickJS library
|
|
#
|
|
|
|
xoption(BUILD_QJS_LIBC "Build standard library modules as part of the library" OFF)
|
|
|
|
set(qjs_sources
|
|
cutils.c
|
|
libbf.c
|
|
libregexp.c
|
|
libunicode.c
|
|
quickjs.c
|
|
)
|
|
|
|
if(BUILD_QJS_LIBC)
|
|
list(APPEND qjs_sources quickjs-libc.c)
|
|
endif()
|
|
list(APPEND qjs_defines _GNU_SOURCE)
|
|
list(APPEND qjs_libs qjs m)
|
|
if(NOT WIN32)
|
|
list(APPEND qjs_libs dl)
|
|
endif()
|
|
if(NOT MSVC)
|
|
list(APPEND qjs_libs pthread)
|
|
endif()
|
|
|
|
add_library(qjs ${qjs_sources})
|
|
target_compile_definitions(qjs PRIVATE ${qjs_defines})
|
|
if (CMAKE_BUILD_TYPE MATCHES Debug)
|
|
target_compile_definitions(qjs PRIVATE
|
|
DUMP_LEAKS
|
|
)
|
|
endif()
|
|
target_include_directories(qjs PUBLIC
|
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
|
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
|
|
)
|
|
|
|
|
|
# QuickJS bytecode compiler
|
|
#
|
|
|
|
add_executable(qjsc
|
|
qjsc.c
|
|
quickjs-libc.c
|
|
)
|
|
target_compile_definitions(qjsc PRIVATE ${qjs_defines})
|
|
target_link_libraries(qjsc ${qjs_libs})
|
|
|
|
|
|
# QuickJS CLI
|
|
#
|
|
|
|
add_custom_command(
|
|
OUTPUT repl.c
|
|
COMMAND "${CMAKE_CURRENT_BINARY_DIR}/qjsc" -o ./repl.c -m ${CMAKE_CURRENT_SOURCE_DIR}/repl.js
|
|
DEPENDS qjsc
|
|
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
|
COMMENT "Compile repl.js to bytecode"
|
|
SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/repl.js
|
|
)
|
|
|
|
add_executable(qjs_exe
|
|
qjs.c
|
|
quickjs-libc.c
|
|
${CMAKE_CURRENT_BINARY_DIR}/repl.c
|
|
)
|
|
set_target_properties(qjs_exe PROPERTIES
|
|
OUTPUT_NAME "qjs"
|
|
)
|
|
target_compile_definitions(qjs_exe PRIVATE ${qjs_defines})
|
|
target_link_libraries(qjs_exe ${qjs_libs})
|
|
if(BUILD_STATIC_QJS_EXE OR MINGW)
|
|
target_link_options(qjs_exe PRIVATE -static)
|
|
if(MINGW)
|
|
target_link_options(qjs_exe PRIVATE -static-libgcc)
|
|
endif()
|
|
endif()
|
|
if(NOT MINGW)
|
|
set_target_properties(qjs_exe PROPERTIES ENABLE_EXPORTS TRUE)
|
|
endif()
|
|
|
|
|
|
# Test262 runner
|
|
#
|
|
|
|
add_executable(run-test262
|
|
quickjs-libc.c
|
|
run-test262.c
|
|
)
|
|
target_compile_definitions(run-test262 PRIVATE ${qjs_defines})
|
|
target_link_libraries(run-test262 ${qjs_libs})
|
|
|
|
|
|
# Unicode generator
|
|
#
|
|
|
|
add_executable(unicode_gen EXCLUDE_FROM_ALL
|
|
cutils.c
|
|
libunicode.c
|
|
unicode_gen.c
|
|
)
|
|
target_compile_definitions(unicode_gen PRIVATE ${qjs_defines})
|
|
|
|
|
|
# Examples
|
|
#
|
|
|
|
if(BUILD_EXAMPLES AND NOT MINGW)
|
|
add_custom_command(
|
|
OUTPUT hello.c
|
|
COMMAND "${CMAKE_CURRENT_BINARY_DIR}/qjsc" -e -o hello.c ${CMAKE_CURRENT_SOURCE_DIR}/examples/hello.js
|
|
DEPENDS qjsc
|
|
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
|
COMMENT "Compile hello.js to a C file with bytecode embeddee"
|
|
SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/examples/hello.js
|
|
)
|
|
add_executable(hello
|
|
${CMAKE_CURRENT_BINARY_DIR}/hello.c
|
|
quickjs-libc.c
|
|
)
|
|
target_include_directories(hello PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
|
target_compile_definitions(hello PRIVATE ${qjs_defines})
|
|
target_link_libraries(hello ${qjs_libs})
|
|
|
|
add_custom_command(
|
|
OUTPUT hello_module.c
|
|
COMMAND "${CMAKE_CURRENT_BINARY_DIR}/qjsc" -e -o hello_module.c -m ${CMAKE_CURRENT_SOURCE_DIR}/examples/hello_module.js
|
|
DEPENDS qjsc
|
|
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
|
COMMENT "Compile hello_module.js to a C file with bytecode embeddee"
|
|
SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/examples/hello_module.js
|
|
)
|
|
add_executable(hello_module
|
|
${CMAKE_CURRENT_BINARY_DIR}/hello_module.c
|
|
quickjs-libc.c
|
|
)
|
|
target_include_directories(hello_module PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
|
target_compile_definitions(hello_module PRIVATE ${qjs_defines})
|
|
target_link_libraries(hello_module ${qjs_libs})
|
|
|
|
if(NOT MINGW)
|
|
add_library(fib MODULE examples/fib.c)
|
|
set_target_properties(fib PROPERTIES
|
|
PREFIX ""
|
|
C_VISIBILITY_PRESET default
|
|
)
|
|
target_compile_definitions(fib PRIVATE JS_SHARED_LIBRARY)
|
|
if(APPLE)
|
|
target_link_options(fib PRIVATE -undefined dynamic_lookup)
|
|
endif()
|
|
|
|
add_library(point MODULE examples/point.c)
|
|
set_target_properties(point PROPERTIES
|
|
PREFIX ""
|
|
C_VISIBILITY_PRESET default
|
|
)
|
|
target_compile_definitions(point PRIVATE JS_SHARED_LIBRARY)
|
|
if(APPLE)
|
|
target_link_options(point PRIVATE -undefined dynamic_lookup)
|
|
endif()
|
|
|
|
add_library(bjson MODULE tests/bjson.c)
|
|
set_target_properties(bjson PROPERTIES
|
|
PREFIX ""
|
|
C_VISIBILITY_PRESET default
|
|
)
|
|
target_compile_definitions(bjson PRIVATE JS_SHARED_LIBRARY)
|
|
if(APPLE)
|
|
target_link_options(bjson PRIVATE -undefined dynamic_lookup)
|
|
endif()
|
|
endif()
|
|
|
|
add_custom_command(
|
|
OUTPUT test_fib.c
|
|
COMMAND "${CMAKE_CURRENT_BINARY_DIR}/qjsc" -e -o test_fib.c -M ${CMAKE_CURRENT_SOURCE_DIR}/examples/fib.so,fib -m ${CMAKE_CURRENT_SOURCE_DIR}/examples/test_fib.js
|
|
DEPENDS qjsc
|
|
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
|
COMMENT "Compile test_fib.js to a C file with bytecode embedded"
|
|
SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/examples/test_fib.js
|
|
)
|
|
add_executable(test_fib
|
|
${CMAKE_CURRENT_BINARY_DIR}/test_fib.c
|
|
examples/fib.c
|
|
quickjs-libc.c
|
|
)
|
|
target_include_directories(test_fib PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
|
target_compile_definitions(test_fib PRIVATE ${qjs_defines})
|
|
target_link_libraries(test_fib ${qjs_libs})
|
|
endif()
|
|
|
|
|
|
# Install target
|
|
#
|
|
|
|
file(STRINGS quickjs.h quickjs_h REGEX QJS_VERSION)
|
|
string(REGEX MATCHALL "([0-9])" QJS_VERSION "${quickjs_h}")
|
|
list(GET QJS_VERSION 0 QJS_VERSION_MAJOR)
|
|
list(GET QJS_VERSION 1 QJS_VERSION_MINOR)
|
|
list(GET QJS_VERSION 2 QJS_VERSION_PATCH)
|
|
set_target_properties(qjs PROPERTIES
|
|
VERSION ${QJS_VERSION_MAJOR}.${QJS_VERSION_MINOR}.${QJS_VERSION_PATCH}
|
|
SOVERSION ${QJS_VERSION_MAJOR}
|
|
)
|
|
install(FILES quickjs.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
|
if(BUILD_QJS_LIBC)
|
|
install(FILES quickjs-libc.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
|
endif()
|
|
install(TARGETS qjs_exe RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
|
install(TARGETS qjs EXPORT qjsConfig
|
|
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
|
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
|
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
|
install(EXPORT qjsConfig DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/quickjs)
|
|
install(FILES LICENSE DESTINATION ${CMAKE_INSTALL_DOCDIR})
|
|
install(DIRECTORY examples DESTINATION ${CMAKE_INSTALL_DOCDIR})
|