119f2c1b4c
I want to do a Release build (so that assert is disabled), but still log leaks. This adds the option to enable that through CMake.
365 lines
11 KiB
CMake
365 lines
11 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 OR DUMP_LEAKS)
|
|
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})
|
|
|
|
add_custom_command(
|
|
OUTPUT function_source.c
|
|
COMMAND qjsc -e -o function_source.c ${CMAKE_CURRENT_SOURCE_DIR}/tests/function_source.js
|
|
DEPENDS qjsc ${CMAKE_CURRENT_SOURCE_DIR}/tests/function_source.js
|
|
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
|
COMMENT "Compile function_source.js to a C file with bytecode embedded"
|
|
SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/tests/function_source.js
|
|
)
|
|
add_executable(function_source
|
|
${CMAKE_CURRENT_BINARY_DIR}/function_source.c
|
|
quickjs-libc.c
|
|
)
|
|
target_include_directories(function_source PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
|
target_compile_definitions(function_source PRIVATE ${qjs_defines})
|
|
target_link_libraries(function_source ${qjs_libs})
|
|
|
|
# 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 embedded"
|
|
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 embedded"
|
|
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})
|