350 lines
10 KiB
CMake
350 lines
10 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)
|
|
if(NOT MSVC)
|
|
xcheck_add_c_compiler_flag(-Werror)
|
|
xcheck_add_c_compiler_flag(-Wextra)
|
|
endif()
|
|
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)
|
|
|
|
# ClangCL is command line compatible with MSVC, so 'MSVC' is set.
|
|
if(MSVC)
|
|
xcheck_add_c_compiler_flag(-Wno-unsafe-buffer-usage)
|
|
xcheck_add_c_compiler_flag(-Wno-sign-conversion)
|
|
xcheck_add_c_compiler_flag(-Wno-nonportable-system-include-path)
|
|
xcheck_add_c_compiler_flag(-Wno-implicit-int-conversion)
|
|
xcheck_add_c_compiler_flag(-Wno-shorten-64-to-32)
|
|
xcheck_add_c_compiler_flag(-Wno-reserved-macro-identifier)
|
|
xcheck_add_c_compiler_flag(-Wno-reserved-identifier)
|
|
xcheck_add_c_compiler_flag(-Wdeprecated-declarations)
|
|
add_compile_definitions(WIN32_LEAN_AND_MEAN)
|
|
endif()
|
|
|
|
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 ${CMAKE_DL_LIBS})
|
|
if(NOT MSVC)
|
|
list(APPEND qjs_libs m 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}>
|
|
)
|
|
|
|
if(EMSCRIPTEN)
|
|
add_executable(qjs_wasm ${qjs_sources})
|
|
target_compile_definitions(qjs_wasm PRIVATE ${qjs_defines})
|
|
target_link_libraries(qjs_wasm m)
|
|
endif()
|
|
|
|
|
|
# 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 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 WIN32)
|
|
set_target_properties(qjs_exe PROPERTIES ENABLE_EXPORTS TRUE)
|
|
endif()
|
|
|
|
|
|
# Test262 runner
|
|
#
|
|
|
|
# run-test262 uses pthreads.
|
|
if(NOT WIN32)
|
|
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})
|
|
endif()
|
|
|
|
# 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 WIN32)
|
|
add_custom_command(
|
|
OUTPUT hello.c
|
|
COMMAND 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 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 WIN32)
|
|
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 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})
|