[ https://issues.apache.org/jira/browse/THRIFT-5477?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17440675#comment-17440675 ]
Max commented on THRIFT-5477: ----------------------------- Hi Csonkás Kristóf Gyula , I had to write a much, much more involved CMake helper for Thrift. It came out at about 1200 SLoC AFAIRC. If you go down this road, be prepared for the following. Thrift generator will output variable set of files, depending on whether the source IDL file has at least 1 service defined or not. Names of the output files will be variable, too (you got this). Thrift generator's {{-r}} recursive flag makes bad friends with CMake. If you use {{include}} in your IDLs — don't use -r; parse out the include's, walk them recursively and map each IDL file to cmake custom target, setting proper dependencies between targets. Otherwise, you'll lose incremental rebuilds, in one of two ways: # the entire project will get recompiled on every `make`/`ninja` call (or what have you); # make won't pick up changes in .thrift and their dependees, forcing the user to nuke CMAKE_BUILD_DIR and recompile from scratch on every change to .thrift IDL files. To do the parsing, I'd coded a ~150 SLoC Thrift AST parser in Python + arpeggio, it was easy. Then called it via execute_process() at CMake configure stage, using the output. That same parser did me triple-duty: 1) parse inter-IDL includes 2) parse whether there's at least 1 service definition 3) extract Golang namespacing info. (The same thrift.cmake had supported codegen for C++, Python, Golang and PHP in my case.) I highly recommend using the common cmake idiom of add_custom_command() wrapped in add_custom_target(). The former alone will give issues. As another trick, I had great success with packaging the compiled .o files from Thrift codegen into static library targets (one .a glue library per IDL file) — that worked really smoothly with CMake's target dependency tracking. Am very sorry to not provide the cmake module itself; it was developed commercially under a proprietary license and cannot be openly shared. > Thrift does not generate a well-defined set of files > ---------------------------------------------------- > > Key: THRIFT-5477 > URL: https://issues.apache.org/jira/browse/THRIFT-5477 > Project: Thrift > Issue Type: Bug > Components: C++ - Compiler > Affects Versions: 0.14.0, 0.15.0 > Reporter: Csonkás Kristóf Gyula > Priority: Major > > While upgrading the Thrift version that we use, I noticed that starting with > version 0.14.0 Thrift does not generate a well-defined set of output files > for C++, which makes it difficult to build generic build system tooling > around it. I tracked the issue down to THRIFT-5168. > Our current cmake helper function, where I prefixed the lines that were added > to workaround this issue with a {{{}+{}}}: > {code:none} > function(target_thrift_source _target) > set(_single_args > "THRIFT_FILE" > "BINARY_DIR" > ) > set(_multi_args > "SERVICES;CXX_OPTIONS" > ) > cmake_parse_arguments(tts "" "${_single_args}" "${_multi_args}" ${ARGN}) > foreach(_required_arg THRIFT_FILE) > if(NOT tts_${_required_arg}) > message(FATAL_ERROR "target_thrift_source called without > ${_required_arg}") > endif() > endforeach() > if(NOT tts_BINARY_DIR) > set(tts_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/thrift_generated") > endif() get_filename_component(_thriftfile_abs_path "${tts_THRIFT_FILE}" > ABSOLUTE) > get_filename_component(_working_directory "${_thriftfile_abs_path}" > DIRECTORY) > get_filename_component(_thriftfile_name "${tts_THRIFT_FILE}" NAME_WE) > set(_output_files > "${tts_BINARY_DIR}/${_thriftfile_name}_types.h" > "${tts_BINARY_DIR}/${_thriftfile_name}_types.cpp" > "${tts_BINARY_DIR}/${_thriftfile_name}_constants.h" > "${tts_BINARY_DIR}/${_thriftfile_name}_constants.cpp" > ) > foreach(_service IN LISTS tts_SERVICES) > list(APPEND _output_files > "${tts_BINARY_DIR}/${_service}.h" > "${tts_BINARY_DIR}/${_service}.cpp" > ) > endforeach() set(thrift_CXX_OPTIONS "moveable_types,no_skeleton") > foreach(_opt IN LISTS tts_CXX_OPTIONS) > string(APPEND thrift_CXX_OPTIONS ",${_opt}") > endforeach() > + set(_touch_commands) > + foreach(_file IN LISTS _output_files) > + list(APPEND _touch_commands COMMAND "${CMAKE_COMMAND}" -E touch > "${_file}") > + endforeach() > add_custom_command( > OUTPUT ${_output_files} > COMMAND "${CMAKE_COMMAND}" -E make_directory "${tts_BINARY_DIR}" > COMMAND Thrift::compiler -out "${tts_BINARY_DIR}" > --gen cpp:${thrift_CXX_OPTIONS} > "${_thriftfile_abs_path}" > + ${_touch_commands} > MAIN_DEPENDENCY "${_thriftfile_abs_path}" > DEPENDS "${_thriftfile_abs_path}" > WORKING_DIRECTORY "${_working_directory}" > ) > target_include_directories("${_target}" PRIVATE "${tts_BINARY_DIR}") > target_sources("${_target}" > PRIVATE ${_output_files} ${tts_THRIFT_FILE} > ) > endfunction() > {code} -- This message was sent by Atlassian Jira (v8.20.1#820001)