godot-cpp icon indicating copy to clipboard operation
godot-cpp copied to clipboard

[DRAFT] Add CMake support for XML documentation

Open dsnopek opened this issue 1 year ago • 1 comments

I forgot to add CMake support in PR https://github.com/godotengine/godot-cpp/pull/1374

So far this PR is just refactoring the scons code so that CMake can generate the code via the doc_source_generator.py script. However, I haven't yet figured out how to add that to CMake yet. If anyone who knows CMake can help out, that'd be great! Otherwise, I will work something eventually. :-)

dsnopek avatar Jun 19 '24 20:06 dsnopek

Hi @dsnopek so this is what I did to hack this for cmake:

  1. Defined a simple godot-docs-generator.cmake file with this content. The paths could be arguments passed into the function from the main CMAKE file to allow maximum configuration, I just didn't go that far due to this being a PoC.
FUNCTION( GENERATE_GODOT_DOCUMENTATION )
    # Grab all documentation XML files
    FILE(GLOB XML_FILES "${CMAKE_CURRENT_SOURCE_DIR}/doc_classes/*.xml")
    STRING(JOIN "," XML_FILES_STR ${XML_FILES})
    # Generate the target file
    SET(DOC_DATA_CPP_FILE "${CMAKE_BINARY_DIR}/_generated/doc_data.cpp")
    STRING(JOIN "," DOC_DATA_CPP_STR ${DOC_DATA_CPP_FILE})
    # Run python to generate the doc_data.cpp file
    EXECUTE_PROCESS(
            COMMAND cmd /c py ${CMAKE_CURRENT_SOURCE_DIR}/cmake/generate_godot_docs.py ${DOC_DATA_CPP_STR} ${XML_FILES_STR}
            WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
    )
ENDFUNCTION()
  1. In the generate_godot_docs.py, it contained your make_doc_source function verbatim, with this added to the bottom. I'm not a huge python guy, so might be a better way to do it:
def main():
    if len(sys.argv) > 2:
        target_str = sys.argv[1]
        target_list = target_str.split(",")
        source_str = sys.argv[2]
        source_list = source_str.split(",")
        make_doc_source(target_list, source_list)

if __name__ == "__main__":
    main()
  1. In the main cmake, include the generate-godot-documentation.cmake and call the function, i.e.:
INCLUDE(godot-docs-generator)
GENERATE_GODOT_DOCUMENTATION()

Now CMAKE will use python to run the script and generate the ${CMAKE_BINARY_DIR}/_generated/doc_data.cpp file. All the CMAKE then needs to do is to add that generated file to the list of sources, i.e.:

# Library sources
FILE(GLOB_RECURSE gdext_sources
        CONFIGURE_DEPENDS
        "${CMAKE_CURRENT_SOURCE_DIR}/src/*.[hc]"
        "${CMAKE_CURRENT_SOURCE_DIR}/src/*.[hc]pp"
        # Includes the generated doc data from /doc_classes
        "${CMAKE_BINARY_DIR}/_generated/*.cpp"
)

And that's it. It should be pretty straight forward to augment this for the current godot-cpp cmake, but likely with a few extra things since I did this in my downstream extension cmake.

Naros avatar Jun 20 '24 11:06 Naros

I have an implementation of this that requires no changes to the python and looks similar to the scons usage. My branch is here But I'd like to refine it after some other PR's i have get commited as they will clash slightly.

Edit: Tested with my standalone test project and it works fine, just requires python.

I have to test it in downstream projects to see if the function can be used as is, or whether it needs to be placed in a separate file.

# Usage of helper function in consumer projects
file( GLOB_RECURSE XML_SOURCES LIST_DIRECTORIES NO CONFIGURE_DEPENDS
    ${CMAKE_CURRENT_SOURCE_DIR}/doc_classes/*.xml )

# Generate doc_data.gen.cpp
generate_doc_source( DOC_DATA "${XML_SOURCES}" )

add_library( gdexample SHARED
        src/example.cpp
        ${DOC_DATA} )
# Helper function defined in godot-cpp which is to be used by consuming projects
#[[ Generate doc_data.gen.cpp]]
function( generate_doc_source OUT_VAR_NAME XML_SOURCES )

    set( OUTPUT_FILE "${CMAKE_CURRENT_BINARY_DIR}/gen/doc_data.gen.cpp" )

    # quote and join to form the interior of a python array.
    list( TRANSFORM XML_SOURCES REPLACE "(.*\.xml)" "'\\1'" )
    list( JOIN XML_SOURCES "," XML_SOURCES )

    # Lists in CMake are delimited by ';', so this works.
    set( PYTHON_SCRIPT "from doc_source_generator import generate_doc_source"
            "generate_doc_source( '${OUTPUT_FILE}', [${XML_SOURCES}] )" )

    add_custom_command( OUTPUT ${OUTPUT_FILE}
            COMMAND "${Python3_EXECUTABLE}" "-c" "${PYTHON_SCRIPT}"
            VERBATIM
            WORKING_DIRECTORY ${godot-cpp_SOURCE_DIR}
            DEPENDS ${godot-cpp_SOURCE_DIR}/doc_source_generator.py
            COMMENT "Generating Doc Data"
    )

    # Propagate generated file to caller scope
    set( ${OUT_VAR_NAME} ${OUTPUT_FILE} PARENT_SCOPE )
endfunction()

enetheru avatar Dec 28 '24 08:12 enetheru

I have submitted my implementation #1682

enetheru avatar Jan 12 '25 00:01 enetheru

Superseded by https://github.com/godotengine/godot-cpp/pull/1682

dsnopek avatar Jan 12 '25 10:01 dsnopek