Ctrl K
ComunidadGuías…

CMakeLists.txt

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
cmake_minimum_required(VERSION 3.10)
project(zc C)
include(GNUInstallDirs)

# Set C standard. Override with: cmake -DCMAKE_C_STANDARD=11
set(CMAKE_C_STANDARD 23 CACHE STRING "C standard to use")
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_C_EXTENSIONS ON)

# Derive ZEN_VERSION from git (similar to Makefile)
set(ZEN_VERSION "dev")
execute_process(
    COMMAND git describe --tags --always --dirty
    WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
    RESULT_VARIABLE GIT_DESCRIBE_RESULT
    OUTPUT_VARIABLE GIT_DESCRIBE_OUTPUT
    OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(GIT_DESCRIBE_RESULT EQUAL 0 AND NOT "${GIT_DESCRIBE_OUTPUT}" STREQUAL "")
    set(ZEN_VERSION "${GIT_DESCRIBE_OUTPUT}")
else()
    # Fallback: read .version file, then "unknown"
    set(ZEN_VERSION "unknown")
    if(EXISTS "${CMAKE_SOURCE_DIR}/.version")
        file(READ "${CMAKE_SOURCE_DIR}/.version" VERSION_FILE)
        string(STRIP "${VERSION_FILE}" ZEN_VERSION)
    endif()
endif()

# Set ZEN_SHARE_DIR for runtime file lookups (similar intent as Makefile)
if(NOT DEFINED CMAKE_INSTALL_FULL_DATADIR)
    set(CMAKE_INSTALL_FULL_DATADIR "${CMAKE_INSTALL_PREFIX}/share")
endif()
set(ZEN_SHARE_DIR "${CMAKE_INSTALL_FULL_DATADIR}/zenc")

# Provide these as compile definitions for all targets
add_compile_definitions(
    ZEN_VERSION="${ZEN_VERSION}"
    ZC_ALLOW_INTERNAL
    ZEN_SHARE_DIR="${ZEN_SHARE_DIR}"
)
# --- Compiler flags (set per compiler) ---
set(ZC_COMPILE_FLAGS "")
set(ZC_BASE_FLAGS -Wall -Wcast-align -Wconversion -Wdangling-else -Wdisabled-optimization -Wdouble-promotion -Wextra -Wfloat-equal -Wformat=2 -Wimplicit-fallthrough -Wmissing-field-initializers -Wmissing-prototypes -Wnull-dereference -Wpacked -Wredundant-decls -Wreturn-local-addr -Wshadow -Wshift-negative-value -Wsign-compare -Wstrict-prototypes -Wswitch-default -Wtautological-compare -Wtype-limits -Wundef -Wuninitialized -Wvla -g)
if(WIN32)
    if(MSVC)
        set(ZC_COMPILE_FLAGS "/W4 /Zi /D_CRT_SECURE_NO_WARNINGS")
    elseif(CMAKE_C_COMPILER_ID MATCHES "Clang|AppleClang")
        set(ZC_COMPILE_FLAGS ${ZC_BASE_FLAGS})
    elseif(CMAKE_C_COMPILER_ID STREQUAL "GNU")
        set(ZC_COMPILE_FLAGS ${ZC_BASE_FLAGS} -Wduplicated-cond -Wformat-signedness -Wlogical-op -Wsuggest-attribute=const -Wsuggest-attribute=noreturn -Wunsafe-loop-optimizations)
    elseif(CMAKE_C_COMPILER_ID STREQUAL "TinyCC")
        set(ZC_COMPILE_FLAGS -Wall -g)
    endif()
else()
    if(CMAKE_C_COMPILER_ID MATCHES "Clang|AppleClang")
        set(ZC_COMPILE_FLAGS ${ZC_BASE_FLAGS} -Wno-format-nonliteral -Wassign-enum -Wcomma -Wsometimes-uninitialized -Wloop-analysis -Wsizeof-array-div)
    elseif(CMAKE_C_COMPILER_ID STREQUAL "GNU")
        set(ZC_COMPILE_FLAGS ${ZC_BASE_FLAGS} -Wduplicated-cond -Wformat-signedness -Wlogical-op -Wsuggest-attribute=const -Wsuggest-attribute=noreturn -Wunsafe-loop-optimizations)
    elseif(CMAKE_C_COMPILER_ID STREQUAL "TinyCC")
        set(ZC_COMPILE_FLAGS -Wall -g)
    endif()
endif()

# --- Find Required Packages (Modern CMake Way) ---
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)

# Include directories
include_directories(
    ${PROJECT_SOURCE_DIR}/src
    ${PROJECT_SOURCE_DIR}/src/ast
    ${PROJECT_SOURCE_DIR}/src/parser
    ${PROJECT_SOURCE_DIR}/src/codegen
    ${PROJECT_SOURCE_DIR}/plugins
    ${PROJECT_SOURCE_DIR}/src/zen
    ${PROJECT_SOURCE_DIR}/src/utils
    ${PROJECT_SOURCE_DIR}/src/lexer
    ${PROJECT_SOURCE_DIR}/src/analysis
    ${PROJECT_SOURCE_DIR}/src/lsp
    ${PROJECT_SOURCE_DIR}/src/diagnostics
)

# Source files
# Source files read from src-sources.txt (single manifest shared by Makefile, CMakeLists.txt, build.bat)
file(STRINGS src-sources.txt SRCS)

# --- Find JIT Backend (LibTCC) ---
option(ZC_USE_JIT "Enable JIT support in REPL using LibTCC" ON)

if(ZC_USE_JIT)
    find_library(TCC_LIBRARY NAMES tcc libtcc)
    if(TCC_LIBRARY)
        add_compile_definitions(ZC_HAS_JIT)
        message(STATUS "LibTCC found: ${TCC_LIBRARY}. JIT enabled.")
    else()
        message(WARNING "libtcc not found. JIT support will be disabled. Fallback will be used.")
        set(ZC_USE_JIT OFF)
    endif()
endif()

# --- Feature Flags ---
option(ZC_NO_PLUGINS "Disable the plugin system entirely" OFF)
option(ZC_NO_LSP "Disable LSP server" OFF)
option(ZC_NO_REPL "Disable interactive REPL" OFF)
option(ZC_NO_BACKENDS "Disable non-C backends" OFF)

add_compile_definitions(ZC_HAS_LSP=$<NOT:$<BOOL:${ZC_NO_LSP}>>)
add_compile_definitions(ZC_HAS_REPL=$<NOT:$<BOOL:${ZC_NO_REPL}>>)
add_compile_definitions(ZC_HAS_PLUGINS=$<NOT:$<BOOL:${ZC_NO_PLUGINS}>>)
add_compile_definitions(ZC_HAS_CPP_BACKEND=$<NOT:$<BOOL:${ZC_NO_BACKENDS}>>)
add_compile_definitions(ZC_HAS_CUDA_BACKEND=$<NOT:$<BOOL:${ZC_NO_BACKENDS}>>)
add_compile_definitions(ZC_HAS_OBJC_BACKEND=$<NOT:$<BOOL:${ZC_NO_BACKENDS}>>)
add_compile_definitions(ZC_HAS_JSON_BACKEND=$<NOT:$<BOOL:${ZC_NO_BACKENDS}>>)
add_compile_definitions(ZC_HAS_LISP_BACKEND=$<NOT:$<BOOL:${ZC_NO_BACKENDS}>>)
add_compile_definitions(ZC_HAS_DOT_BACKEND=$<NOT:$<BOOL:${ZC_NO_BACKENDS}>>)
add_compile_definitions(ZC_HAS_ASTDUMP_BACKEND=$<NOT:$<BOOL:${ZC_NO_BACKENDS}>>)

if(ZC_NO_PLUGINS)
    add_compile_definitions(ZC_NO_PLUGINS)
    message(STATUS "Plugin system disabled.")
endif()

# Platform-specific library logic
set(PLATFORM_LIBS Threads::Threads)
if(ZC_USE_JIT)
    list(APPEND PLATFORM_LIBS ${TCC_LIBRARY})
endif()
if(WIN32)
    # Winsock 2 for Networking, ws2_32 is required for our socket abstraction
    list(APPEND PLATFORM_LIBS ws2_32)
    set(PLUGIN_EXT ".dll")
    set(BINARY_EXT ".exe")
    set(SHARED_FLAGS "")
elseif(APPLE)
    # macOS requires CoreFoundation for _NSGetExecutablePath
    find_library(COREFOUNDATION_FRAMEWORK CoreFoundation)
    list(APPEND PLATFORM_LIBS ${CMAKE_DL_LIBS} ${COREFOUNDATION_FRAMEWORK})
    set(SHARED_FLAGS "-fPIC")
    set(BINARY_EXT "")
    set(PLUGIN_EXT ".dylib")
else()
    # Linux/BSD: Link with libdl for zc_dlopen and libm for math
    if(NOT ZC_NO_PLUGINS)
        list(APPEND PLATFORM_LIBS ${CMAKE_DL_LIBS})
    endif()
    list(APPEND PLATFORM_LIBS m)
    set(SHARED_FLAGS "-fPIC")
    set(BINARY_EXT "")
    set(PLUGIN_EXT ".so")
endif()

# Add executable
add_executable(zc ${SRCS})
target_link_libraries(zc PRIVATE ${PLATFORM_LIBS})
if(NOT "${ZC_COMPILE_FLAGS}" STREQUAL "")
    target_compile_options(zc PRIVATE ${ZC_COMPILE_FLAGS})
endif()

# Build plugins using our newly built zc compiler
set(PLUGIN_NAMES befunge brainfuck forth lisp sql)
foreach(plugin ${PLUGIN_NAMES})
    set(PLUGIN_OUTPUT "${CMAKE_BINARY_DIR}/plugins/${plugin}${PLUGIN_EXT}")
    
    add_custom_command(
        OUTPUT "${PLUGIN_OUTPUT}"
        COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_BINARY_DIR}/plugins"
        COMMAND $<TARGET_FILE:zc> build "${PROJECT_SOURCE_DIR}/plugins/${plugin}.zc" -shared -o "${PLUGIN_OUTPUT}"
        DEPENDS zc "${PROJECT_SOURCE_DIR}/plugins/${plugin}.zc"
        COMMENT "Building native plugin ${plugin}"
        VERBATIM
    )
    
    add_custom_target(${plugin}_plugin ALL DEPENDS "${PLUGIN_OUTPUT}")
endforeach()

# --- Install Rules ---
install(TARGETS zc DESTINATION bin)
install(FILES std.zc DESTINATION share/zenc)
install(DIRECTORY std DESTINATION share/zenc)
install(FILES src/repl/docs.json DESTINATION share/zenc)
install(FILES plugins/zprep_plugin.h DESTINATION include/zenc)
install(DIRECTORY ${CMAKE_BINARY_DIR}/plugins/ DESTINATION lib/zenc/plugins 
        FILES_MATCHING PATTERN "*.${PLUGIN_EXT}")

if(UNIX AND NOT WIN32)
    install(FILES man/zc.1 DESTINATION share/man/man1)
    install(FILES man/zc.5 DESTINATION share/man/man5)
    install(FILES man/zc.7 DESTINATION share/man/man7)
endif()
# Test target (supports: cmake --build . --target test -- -DTEST_FILES="tests/std/test_hash.zc")
set(TEST_FILES "" CACHE STRING "Space-separated list of specific test files to run")
add_custom_target(test
    COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tests/scripts/run_tests.sh -- ${TEST_FILES}
    COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tests/scripts/run_codegen_tests.sh ${TEST_FILES}
    COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tests/scripts/run_example_transpile.sh ${TEST_FILES}
    DEPENDS zc
    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)

add_custom_target(test-misra
    COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tests/scripts/run_misra_tests.sh
    DEPENDS zc
    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)

add_custom_target(test-tcc
    COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tests/scripts/run_tests.sh --cc tcc
    DEPENDS zc
    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)

# Clean target
add_custom_target(distclean
    COMMAND ${CMAKE_COMMAND} --build . --target clean
    COMMAND ${CMAKE_COMMAND} -E rm -f out.c
    COMMAND ${CMAKE_COMMAND} -E rm -rf ${CMAKE_BINARY_DIR}/plugins
    WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
)