# Copyright (c) Meta Platforms, Inc. and affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # Requirements: # Please provide the following two variables before using these macros: # ${THRIFT1} - path/to/bin/thrift1 # ${THRIFTCPP2} - path/to/lib/thriftcpp2 # # # thrift_object # This creates a object that will contain the source files and all the proper # dependencies to generate and compile thrift generated files # # Params: # @file_name - The name of the thrift file # @services - A list of services that are declared in the thrift file # @language - The generator to use (cpp or cpp2) # @options - Extra options to pass to the generator # @file_path - The directory where the thrift file lives # @output_path - The directory where the thrift objects will be built # @include_prefix - The last part of output_path, relative include prefix # # Output: # A object file named `${file-name}-${language}-obj` to include into your # project's library # # Notes: # If any of the fields is empty, it is still required to provide an empty string # # Usage: # thrift_object( # #file_name # #services # #language # #options # #file_path # #output_path # #include_prefix # ) # add_library(somelib $ ...) # macro(thrift_object file_name services language options file_path output_path include_prefix ) thrift_generate( "${file_name}" "${services}" "${language}" "${options}" "${file_path}" "${output_path}" "${include_prefix}" "${ARGN}" ) bypass_source_check(${${file_name}-${language}-SOURCES}) add_library( "${file_name}-${language}-obj" OBJECT ${${file_name}-${language}-SOURCES} ) add_dependencies( "${file_name}-${language}-obj" "${file_name}-${language}-target" ) message("Thrift will create the Object file : ${file_name}-${language}-obj") endmacro() # thrift_library # Same as thrift object in terms of usage but creates the library instead of # object so that you can use to link against your library instead of including # all symbols into your library # # Params: # @file_name - The name of the thrift file # @services - A list of services that are declared in the thrift file # @language - The generator to use (cpp or cpp2) # @options - Extra options to pass to the generator # @file_path - The directory where the thrift file lives # @output_path - The directory where the thrift objects will be built # @include_prefix - The last part of output_path, relative include prefix # # Output: # A library file named `${file-name}-${language}` to link against your # project's library # # Notes: # If any of the fields is empty, it is still required to provide an empty string # # Usage: # thrift_library( # #file_name # #services # #language # #options # #file_path # #output_path # #include_prefix # ) # add_library(somelib ...) # target_link_libraries(somelibe ${file_name}-${language} ...) # macro(thrift_library file_name services language options file_path output_path include_prefix ) thrift_object( "${file_name}" "${services}" "${language}" "${options}" "${file_path}" "${output_path}" "${include_prefix}" "${ARGN}" ) add_library( "${file_name}-${language}" $ ) target_link_libraries("${file_name}-${language}" ${THRIFTCPP2}) message("Thrift will create the Library file : ${file_name}-${language}") endmacro() # # bypass_source_check # This tells cmake to ignore if it doesn't see the following sources in # the library that will be installed. Thrift files are generated at compile # time so they do not exist at source check time # # Params: # @sources - The list of files to ignore in source check # macro(bypass_source_check sources) set_source_files_properties( ${sources} PROPERTIES GENERATED TRUE ) endmacro() # # thrift_generate # This is used to codegen thrift files using the thrift compiler # Params: # @file_name - The name of tge thrift file # @services - A list of services that are declared in the thrift file # @language - The generator to use (cpp, cpp2 or py3) # @options - Extra options to pass to the generator # @output_path - The directory where the thrift file lives # # Output: # file-language-target - A custom target to add a dependenct # ${file-language-HEADERS} - The generated Header Files. # ${file-language-SOURCES} - The generated Source Files. # # Notes: # If any of the fields is empty, it is still required to provide an empty string # # When using file_language-SOURCES it should always call: # bypass_source_check(${file_language-SOURCES}) # This will prevent cmake from complaining about missing source files # macro(thrift_generate file_name services language options file_path output_path include_prefix ) cmake_parse_arguments(THRIFT_GENERATE # Prefix "" # Options "" # One Value args "THRIFT_INCLUDE_DIRECTORIES" # Multi-value args "${ARGN}") set(thrift_include_directories) foreach(dir ${THRIFT_GENERATE_THRIFT_INCLUDE_DIRECTORIES}) list(APPEND thrift_include_directories "-I" "${dir}") endforeach() set("${file_name}-${language}-HEADERS" ${output_path}/gen-${language}/${file_name}_constants.h ${output_path}/gen-${language}/${file_name}_data.h ${output_path}/gen-${language}/${file_name}_metadata.h ${output_path}/gen-${language}/${file_name}_types.h ${output_path}/gen-${language}/${file_name}_types.tcc ) set("${file_name}-${language}-SOURCES" ${output_path}/gen-${language}/${file_name}_constants.cpp ${output_path}/gen-${language}/${file_name}_data.cpp ${output_path}/gen-${language}/${file_name}_types.cpp ) if(NOT "${options}" MATCHES "no_metadata") set("${file_name}-${language}-SOURCES" ${${file_name}-${language}-SOURCES} ${output_path}/gen-${language}/${file_name}_metadata.cpp ) endif() foreach(service ${services}) set("${file_name}-${language}-HEADERS" ${${file_name}-${language}-HEADERS} ${output_path}/gen-${language}/${service}.h ${output_path}/gen-${language}/${service}.tcc ${output_path}/gen-${language}/${service}AsyncClient.h ${output_path}/gen-${language}/${service}_custom_protocol.h ) set("${file_name}-${language}-SOURCES" ${${file_name}-${language}-SOURCES} ${output_path}/gen-${language}/${service}.cpp ${output_path}/gen-${language}/${service}AsyncClient.cpp ) endforeach() if("${include_prefix}" STREQUAL "") set(include_prefix_text "") else() set(include_prefix_text "include_prefix=${include_prefix}") if(NOT "${options}" STREQUAL "") set(include_prefix_text ",${include_prefix_text}") endif() endif() set(gen_language ${language}) if("${language}" STREQUAL "cpp2") set(gen_language "mstch_cpp2") elseif("${language}" STREQUAL "py3") set(gen_language "mstch_py3") file(WRITE "${output_path}/gen-${language}/${file_name}/__init__.py") endif() add_custom_command( OUTPUT ${${file_name}-${language}-HEADERS} ${${file_name}-${language}-SOURCES} COMMAND ${THRIFT1} --gen "${gen_language}:${options}${include_prefix_text}" -o ${output_path} ${thrift_include_directories} "${file_path}/${file_name}.thrift" DEPENDS ${THRIFT1} "${file_path}/${file_name}.thrift" COMMENT "Generating ${file_name} files. Output: ${output_path}" ) add_custom_target( ${file_name}-${language}-target ALL DEPENDS ${${language}-${language}-HEADERS} ${${file_name}-${language}-SOURCES} ) install( DIRECTORY gen-${language} DESTINATION include/${include_prefix} FILES_MATCHING PATTERN "*.h") install( DIRECTORY gen-${language} DESTINATION include/${include_prefix} FILES_MATCHING PATTERN "*.tcc") endmacro()