| 1 | cmake_minimum_required(VERSION 3.5) |
| 2 | project(lightrec LANGUAGES C VERSION 0.9) |
| 3 | |
| 4 | list(APPEND LIGHTREC_SOURCES |
| 5 | blockcache.c |
| 6 | constprop.c |
| 7 | emitter.c |
| 8 | interpreter.c |
| 9 | lightrec.c |
| 10 | memmanager.c |
| 11 | optimizer.c |
| 12 | regcache.c |
| 13 | ) |
| 14 | list(APPEND LIGHTREC_HEADERS |
| 15 | blockcache.h |
| 16 | constprop.h |
| 17 | debug.h |
| 18 | disassembler.h |
| 19 | emitter.h |
| 20 | interpreter.h |
| 21 | lightrec-private.h |
| 22 | lightrec.h |
| 23 | memmanager.h |
| 24 | optimizer.h |
| 25 | recompiler.h |
| 26 | regcache.h |
| 27 | ) |
| 28 | |
| 29 | add_library(lightrec ${LIGHTREC_SOURCES} ${LIGHTREC_HEADERS}) |
| 30 | set_target_properties(lightrec PROPERTIES |
| 31 | VERSION ${PROJECT_VERSION} |
| 32 | SOVERSION ${PROJECT_VERSION_MAJOR} |
| 33 | PUBLIC_HEADER lightrec.h |
| 34 | C_STANDARD 11 |
| 35 | C_STANDARD_REQUIRED ON |
| 36 | C_EXTENSIONS OFF |
| 37 | ) |
| 38 | |
| 39 | set(BUILD_SHARED_LIBS ON CACHE BOOL "Build shared libraries") |
| 40 | if (NOT BUILD_SHARED_LIBS) |
| 41 | target_compile_definitions(lightrec PRIVATE LIGHTREC_STATIC) |
| 42 | endif (NOT BUILD_SHARED_LIBS) |
| 43 | |
| 44 | if (NOT LOG_LEVEL) |
| 45 | set(LOG_LEVEL Info CACHE STRING "Log level" FORCE) |
| 46 | set_property(CACHE LOG_LEVEL PROPERTY STRINGS NoLog Error Warning Info Debug) |
| 47 | endif() |
| 48 | |
| 49 | if (NOT CMAKE_BUILD_TYPE) |
| 50 | set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING |
| 51 | "Choose the type of build, options are: None(CMAKE_CXX_FLAGS or CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel." |
| 52 | FORCE) |
| 53 | set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS None Debug Release RelWithDebInfo MinSizeRel) |
| 54 | endif() |
| 55 | |
| 56 | string(TOUPPER ${LOG_LEVEL} LIGHTREC_LOG_LEVEL) |
| 57 | target_compile_definitions(lightrec PRIVATE LOG_LEVEL=${LIGHTREC_LOG_LEVEL}_L) |
| 58 | |
| 59 | if (CMAKE_COMPILER_IS_GNUCC) |
| 60 | target_compile_options(lightrec PRIVATE -fvisibility=hidden) |
| 61 | endif() |
| 62 | |
| 63 | set(HAS_DEFAULT_ELM ${CMAKE_COMPILER_IS_GNUCC}) |
| 64 | |
| 65 | option(ENABLE_FIRST_PASS "Run the interpreter as first-pass optimization" ON) |
| 66 | |
| 67 | option(ENABLE_THREADED_COMPILER "Enable threaded compiler" ON) |
| 68 | if (ENABLE_THREADED_COMPILER) |
| 69 | target_sources(lightrec PRIVATE recompiler.c reaper.c) |
| 70 | |
| 71 | if (NOT ENABLE_FIRST_PASS) |
| 72 | message(SEND_ERROR "Threaded compiler requires first-pass optimization") |
| 73 | endif (NOT ENABLE_FIRST_PASS) |
| 74 | endif (ENABLE_THREADED_COMPILER) |
| 75 | |
| 76 | option(OPT_REMOVE_DIV_BY_ZERO_SEQ "(optimization) Remove div-by-zero check sequence" ON) |
| 77 | option(OPT_REPLACE_MEMSET "(optimization) Detect and replace memset with host variant" ON) |
| 78 | option(OPT_DETECT_IMPOSSIBLE_BRANCHES "(optimization) Detect impossible branches" ON) |
| 79 | option(OPT_HANDLE_LOAD_DELAYS "(optimization) Detect load delays" ON) |
| 80 | option(OPT_TRANSFORM_OPS "(optimization) Transform opcodes" ON) |
| 81 | option(OPT_LOCAL_BRANCHES "(optimization) Detect local branches" ON) |
| 82 | option(OPT_SWITCH_DELAY_SLOTS "(optimization) Switch delay slots" ON) |
| 83 | option(OPT_FLAG_IO "(optimization) Flag I/O opcodes when the target can be detected" ON) |
| 84 | option(OPT_FLAG_MULT_DIV "(optimization) Flag MULT/DIV that only use one of HI/LO" ON) |
| 85 | option(OPT_EARLY_UNLOAD "(optimization) Unload registers early" ON) |
| 86 | option(OPT_PRELOAD_PC "(optimization) Preload PC value into register" ON) |
| 87 | |
| 88 | target_include_directories(lightrec PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) |
| 89 | |
| 90 | if (CMAKE_C_COMPILER_ID MATCHES "GNU|Clang") |
| 91 | target_compile_options(lightrec PRIVATE -Wall) |
| 92 | endif() |
| 93 | if (CMAKE_C_COMPILER_ID STREQUAL "Clang") |
| 94 | target_compile_options(lightrec PRIVATE -Wno-initializer-overrides) |
| 95 | endif() |
| 96 | |
| 97 | if (ENABLE_THREADED_COMPILER) |
| 98 | include(FindThreads) |
| 99 | |
| 100 | if (NOT CMAKE_USE_PTHREADS_INIT) |
| 101 | message(SEND_ERROR "Could not find compatible threads library") |
| 102 | endif() |
| 103 | |
| 104 | target_link_libraries(lightrec PUBLIC Threads::Threads) |
| 105 | endif (ENABLE_THREADED_COMPILER) |
| 106 | |
| 107 | option(ENABLE_CODE_BUFFER "Enable external code buffer" ON) |
| 108 | if (ENABLE_CODE_BUFFER) |
| 109 | target_sources(lightrec PRIVATE tlsf/tlsf.c) |
| 110 | target_include_directories(lightrec PRIVATE tlsf) |
| 111 | endif (ENABLE_CODE_BUFFER) |
| 112 | |
| 113 | find_library(LIBLIGHTNING lightning REQUIRED) |
| 114 | find_path(LIBLIGHTNING_INCLUDE_DIR lightning.h REQUIRED) |
| 115 | |
| 116 | target_include_directories(lightrec PUBLIC ${LIBLIGHTNING_INCLUDE_DIR}) |
| 117 | target_link_libraries(lightrec PUBLIC ${LIBLIGHTNING}) |
| 118 | |
| 119 | if (LOG_LEVEL STREQUAL Debug) |
| 120 | set(ENABLE_DISASSEMBLER ON) |
| 121 | target_sources(lightrec PRIVATE disassembler.c) |
| 122 | endif() |
| 123 | |
| 124 | configure_file(lightrec-config.h.cmakein lightrec-config.h @ONLY) |
| 125 | |
| 126 | include(GNUInstallDirs) |
| 127 | install(TARGETS lightrec |
| 128 | ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} |
| 129 | LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} |
| 130 | RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} |
| 131 | PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} |
| 132 | ) |