chore: baseline usable version

This commit is contained in:
dela
2026-06-10 11:17:51 +08:00
commit a2f82a86b6
932 changed files with 172551 additions and 0 deletions

View File

@@ -0,0 +1,141 @@
include_guard(DIRECTORY)
#[[
Add rules for creating Google Protobuf source files.
qm_create_protobuf(<OUT>
INPUT <files...>
[OUTPUT_DIR <dir>]
[TARGET <target>]
[INCLUDE_DIRECTORIES <dirs...>]
[OPTIONS <options...>]
[DEPENDS <deps...>]
[CREATE_ONCE]
)
INPUT: source files
OUTPUT_DIR: output directory
TARGET: add a custom target to run the generating command
INCLUDE_DIRECTORIES: extra include directories
OPTIONS: extra options passed to protobuf compiler
DEPENDS: dependencies
CREATE_ONCE: create proto code files at configure phase if not exist
OUT: output source file paths
#]]
function(qm_create_protobuf _out)
set(options CREATE_ONCE)
set(oneValueArgs OUTPUT_DIR TARGET)
set(multiValueArgs INPUT INCLUDE_DIRECTORIES OPTIONS DEPENDS)
cmake_parse_arguments(FUNC "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
# Find `protoc`
if(NOT PROTOC_EXECUTABLE)
if(NOT TARGET protobuf::protoc)
message(FATAL_ERROR "qm_create_protobuf: protobuf compiler not found. Add find_package(Protobuf) to CMake to enable.")
endif()
get_target_property(PROTOC_EXECUTABLE protobuf::protoc LOCATION)
if(NOT PROTOC_EXECUTABLE)
message(FATAL_ERROR "qm_create_protobuf: failed to get the location of `protoc`, you could set PROTOC_EXECUTABLE manually.")
endif()
# Cache value
set(PROTOC_EXECUTABLE ${PROTOC_EXECUTABLE} PARENT_SCOPE)
endif()
if(NOT FUNC_INPUT)
message(FATAL_ERROR "qm_create_protobuf: INPUT not specified.")
endif()
if(FUNC_OUTPUT_DIR)
get_filename_component(_out_dir ${FUNC_OUTPUT_DIR} ABSOLUTE)
file(MAKE_DIRECTORY ${_out_dir})
else()
set(_out_dir ${CMAKE_CURRENT_BINARY_DIR})
endif()
# Collect include paths and out files
set(_include_options)
set(_out_files)
set(_input_names)
foreach(_item IN LISTS FUNC_INCLUDE_DIRECTORIES)
get_filename_component(_abs_path ${_item} ABSOLUTE)
list(APPEND _include_options -I${_abs_path})
endforeach()
foreach(_item IN LISTS FUNC_INPUT)
get_filename_component(_item ${_item} ABSOLUTE)
get_filename_component(_abs_path ${_item} DIRECTORY)
list(APPEND _include_options -I${_abs_path})
endforeach()
list(REMOVE_DUPLICATES _include_options)
set(_create_once_warning)
set(_create_once_warning_printed off)
# Prepare for create once
if(FUNC_CREATE_ONCE)
# Check if options contain generator expressions
foreach(_opt IN LISTS _include_options LISTS FUNC_OPTIONS)
string(GENEX_STRIP "${_opt}" _no_genex)
if(NOT _no_genex STREQUAL _opt)
set(_create_once_warning "options contain generator expressions, skip generating source file now")
break()
endif()
endforeach()
endif()
foreach(_item IN LISTS FUNC_INPUT)
get_filename_component(_basename ${_item} NAME_WLE)
list(APPEND _out_files ${_out_dir}/${_basename}.pb.h ${_out_dir}/${_basename}.pb.cc)
get_filename_component(_name ${_item} NAME)
list(APPEND _input_names ${_name})
if(FUNC_CREATE_ONCE AND(NOT EXISTS ${_out_dir}/${_basename}.pb.h OR NOT EXISTS ${_out_dir}/${_basename}.pb.cc))
if(_create_once_warning)
if(NOT _create_once_warning_printed)
message(WARNING "qm_create_protobuf: ${_create_once_warning}")
set(_create_once_warning_printed on)
endif()
else()
get_filename_component(_abs_file ${_item} ABSOLUTE)
if(NOT EXISTS ${_abs_file})
message(WARNING "qm_create_protobuf: input file \"${_name}\" is not available, skip generating source file now")
else()
message(STATUS "Protoc: Generating ${_basename}.pb.h, ${_basename}.pb.cc")
execute_process(COMMAND
${PROTOC_EXECUTABLE} --cpp_out=${_out_dir} ${_include_options} ${FUNC_OPTIONS} ${_name}
)
endif()
endif()
endif()
add_custom_command(
OUTPUT ${_out_dir}/${_basename}.pb.h ${_out_dir}/${_basename}.pb.cc
COMMAND ${PROTOC_EXECUTABLE} --cpp_out=${_out_dir} ${_include_options} ${FUNC_OPTIONS} ${_name}
DEPENDS ${_item} ${FUNC_DEPENDS}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
VERBATIM
)
endforeach()
if(FUNC_TARGET)
if(NOT TARGET ${FUNC_TARGET})
add_custom_target(${FUNC_TARGET})
endif()
add_dependencies(${FUNC_TARGET} ${_out_files})
endif()
set(${_out} ${_out_files} PARENT_SCOPE)
endfunction()