message(STATUS "CMAKE_CXX_COMPILER_ID: ${CMAKE_CXX_COMPILER_ID}") message(STATUS "CMAKE_SYSTEM_NAME: ${CMAKE_SYSTEM_NAME}") message(STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}") if(DEFINED CMAKE_TOOLCHAIN_FILE) message(STATUS ">>> CMAKE_TOOLCHAIN_FILE: ${CMAKE_TOOLCHAIN_FILE}") endif() # 统一使用 Clang 编译器,避免 GCC 对 C++ Modules 的兼容性问题 if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") message(STATUS "Building with Clang modules support") elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") message(STATUS "Building with GCC; C++ modules support is experimental for this project") else() message(WARNING "Unsupported compiler for modules: ${CMAKE_CXX_COMPILER_ID}. Build may fail.") endif() if(WIN32) set(CMAKE_FIND_LIBRARY_SUFFIXES ".a" ".lib" ".dll.a") else() set(CMAKE_FIND_LIBRARY_SUFFIXES ".a" ".so") endif() find_package(glaze CONFIG REQUIRED) find_package(spdlog CONFIG REQUIRED) find_package(fmt CONFIG REQUIRED) find_package(Taskflow CONFIG REQUIRED) find_package(tree-sitter CONFIG REQUIRED) if(UNIX AND NOT APPLE) find_package(Threads REQUIRED) endif() if(NOT TARGET spdlog::spdlog_header_only) message(WARNING "spdlog header-only target not found, using shared library") endif() if(NOT TARGET fmt::fmt-header-only) message(WARNING "fmt header-only target not found, using shared library") endif() set(CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP 1) set(SOURCES cli/launcher.cppm main.cc utils/args_parser.cppm utils/text_coordinates.cppm core/dispacther.cppm core/server.cppm scheduler/async_executor.cppm language/symbol/internal/builder.cppm language/symbol/index/location.cppm language/symbol/index/coordinator.cppm language/symbol/index/scope.cppm language/symbol/internal/store.cppm language/symbol/internal/table.cppm manager/bootstrap.cppm manager/document.cppm manager/parser.cppm manager/symbol.cppm manager/detail/text_document.cppm manager/manager_hub.cppm language/semantic/graph/types.cppm language/semantic/graph/call.cppm language/semantic/graph/inheritance.cppm language/semantic/graph/reference.cppm language/semantic/interface.cppm language/semantic/type_system.types.cppm language/semantic/type_system.cppm language/semantic/name_resolver.cppm language/semantic/semantic_model.cppm language/semantic/analyzer.cppm language/semantic/token_collector.cppm tree-sitter/parser.c tree-sitter/scanner.c) file(GLOB_RECURSE PROVIDER_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/provider/*.cppm") file(GLOB_RECURSE MANAGER_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/manager/*.cppm") add_executable(${PROJECT_NAME} ${SOURCES}) if(TARGET std_module) add_dependencies(${PROJECT_NAME} std_module) endif() target_sources( ${PROJECT_NAME} PRIVATE FILE_SET cxx_modules TYPE CXX_MODULES FILES bridge/glaze.cppm bridge/spdlog.cppm bridge/taskflow.cppm bridge/tree_sitter.cppm cli/launcher.cppm language/ast/ast.cppm language/ast/types.cppm language/ast/deserializer.cppm language/ast/deserializer_impl.cppm language/ast/ts_utils.cppm language/ast/detail.cppm utils/string.cppm utils/args_parser.cppm utils/text_coordinates.cppm protocol/common/basic_types.cppm protocol/common/message.cppm protocol/common/registration.cppm protocol/window/progress.cppm protocol/initialize/configuration.cppm protocol/initialize/capabilities.cppm protocol/workspace/workspace.cppm protocol/workspace/file_operations.cppm protocol/workspace/notebook.cppm protocol/text_document/document_sync.cppm protocol/text_document/completion.cppm protocol/text_document/code_actions.cppm protocol/text_document/diagnostics.cppm protocol/text_document/document_features.cppm protocol/text_document/formatting.cppm protocol/text_document/inline_features.cppm protocol/text_document/navigation.cppm protocol/text_document/rename.cppm protocol/text_document/semantic_tokens.cppm protocol/text_document/signature_help.cppm protocol/text_document/symbols.cppm codec/common.cppm codec/transformer.cppm codec/facade.cppm protocol/types.cppm protocol/protocol.cppm language/symbol/types.cppm language/symbol/internal/builder.cppm language/symbol/internal/store.cppm language/symbol/internal/table.cppm language/symbol/index/coordinator.cppm language/symbol/index/location.cppm language/symbol/index/scope.cppm language/symbol/symbol.cppm language/semantic/interface.cppm language/semantic/semantic.cppm language/semantic/type_system.types.cppm language/semantic/type_system.cppm language/semantic/name_resolver.cppm language/semantic/semantic_model.cppm language/semantic/analyzer.cppm language/semantic/token_collector.cppm language/semantic/graph/types.cppm language/semantic/graph/call.cppm language/semantic/graph/inheritance.cppm language/semantic/graph/reference.cppm language/keyword/repo.cppm scheduler/async_executor.cppm ${MANAGER_MODULES} core/dispacther.cppm core/server.cppm ${PROVIDER_MODULES}) target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) target_compile_definitions(${PROJECT_NAME} PRIVATE SPDLOG_HEADER_ONLY FMT_HEADER_ONLY) target_link_libraries( ${PROJECT_NAME} PRIVATE glaze::glaze Taskflow::Taskflow spdlog::spdlog_header_only fmt::fmt-header-only tree-sitter::tree-sitter $<$:Threads::Threads> # 使用生成器表达式 ) if(WIN32) # 静态链接 libunwind,避免运行时缺少 libunwind.dll set(_orig_suffixes ${CMAKE_FIND_LIBRARY_SUFFIXES}) set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") find_library(LIBUNWIND_STATIC NAMES unwind libunwind) set(CMAKE_FIND_LIBRARY_SUFFIXES ${_orig_suffixes}) if(NOT LIBUNWIND_STATIC) # Fallback to known llvm-mingw sysroot layout (used by windows-cross toolchain) set(_unwind_candidate "/opt/llvm-mingw/llvm-mingw-ucrt/${CMAKE_SYSTEM_PROCESSOR}-w64-mingw32/lib/libunwind.a" ) if(EXISTS "${_unwind_candidate}") set(LIBUNWIND_STATIC "${_unwind_candidate}") endif() endif() if(LIBUNWIND_STATIC) target_link_libraries(${PROJECT_NAME} PRIVATE ${LIBUNWIND_STATIC}) else() message(WARNING "libunwind static library not found; executable may require libunwind.dll at runtime") endif() endif() target_compile_options( ${PROJECT_NAME} PRIVATE -Wall -Wextra -Wpedantic -Wno-import-implementation-partition-unit-in-interface-unit $<$:-g -O0> $<$:-O3>)