Using SWIG-generated files in another project

I am attempting to use SWIG to generate a C# wrapper for some C++ code, and then use that generated code in another C# project. Right now, I’m just trying to get things working in an example project. Starting with the CMake example on the SWIG website (http://www.swig.org/Doc3.0/Introduction.html#Introduction_build_system), I updated it a bit to try and match the latest CMake documentation (https://cmake.org/cmake/help/latest/module/UseSWIG.html), as well as removed the Python parts in favour of C# equivalents.

Now I’m looking at

cmake_minimum_required(VERSION 3.17)

project(example
    LANGUAGES CSharp
)

find_package(SWIG REQUIRED)
include(${SWIG_USE_FILE})

include_directories(${CMAKE_CURRENT_SOURCE_DIR})

set(CMAKE_SWIG_FLAGS "")
set(CMAKE_SWIG_OUTDIR ${CMAKE_CURRENT_BINARY_DIR}/example_out)

set_source_files_properties(example.i PROPERTIES CPLUSPLUS ON)
swig_add_library(example
    TYPE SHARED
    LANGUAGE csharp
    SOURCES example.i example.c
)

If anyone’s trying to get this to work locally, I also needed to change example.i from the SWIG website to directly #include "example.c", rather than use externs.

This does generate a C# wrapper, and outputs it to ${CMAKE_CURRENT_BINARY_DIR}/example_out. The problem then is, that I need to reference these output files from another project. One approach would be

get_property(EXAMPLE_OUT_DIR TARGET ${PROJECT_NAME} PROPERTY SWIG_SUPPORT_FILES_DIRECTORY)

file(GLOB OUT_SRC
    CONFIGURE_DEPENDS
    "${EXAMPLE_OUT_DIR}/*.cs"
)

add_library(newlib SHARED ${OUT_SRC} tmp.cs)
add_library(mylibs::newlib ALIAS newlib)
set_property(TARGET newlib PROPERTY DOTNET_TARGET_FRAMEWORK_VERSION "v4.6.1")
set_property(TARGET newlib PROPERTY VS_DOTNET_REFERENCES
    "Microsoft.CSharp"
)

The properties being there to force this project to be a C# project (which is necessary for setting it as a reference for another C# project), and tmp.cs being an empty file to get this to run before anything’s been generated (since the generation from SWIG happens at build time).

Even with CONFIGURE_DEPENDS, though, this still requires compiling twice, and then touching the CMakeLists to get a further C# project to recognise that the wrappers have been added to it.
Example C# project for consuming this:

cmake_minimum_required(VERSION 3.17)

project(thing_using_example
    LANGUAGES CSharp)
include(CSharpUtilities)

set(SOURCES
    ThingUsingExample.cs
)

add_executable(${PROJECT_NAME} ${SOURCES})
set_property(TARGET ${PROJECT_NAME} PROPERTY VS_DOTNET_TARGET_FRAMEWORK_VERSION "v4.6.1")
set_property(TARGET ${PROJECT_NAME} PROPERTY VS_GLOBAL_ROOTNAMESPACE "ThingUsingExample")
set_property(TARGET ${PROJECT_NAME} PROPERTY VS_GLOBAL_Prefer32Bit "false")
set(CMAKE_CSharp_FLAGS "${CMAKE_CSharp_FLAGS} /langversion:6")
add_dependencies(${PROJECT_NAME} mylibs::newlib)

My question is: what is the right way to create a library, consisting of files generated at build time, the names of which are not known in advance? Right now I’m leaning towards replacing the swig_add_library with a custom command, but I’m sure there’s a cleaner/nicer way.

In case anyone comes across this in the future, the solution I ended up going with was to follow the pattern given here: https://stackoverflow.com/a/52714922

Basically, to have SWIG run through execute_process; add the wrapped headers and the SWIG interface files as CMake dependencies, by adding them to CMAKE_CONFIGURE_DEPENDS; and then glob the output directory, and add the globbed files to a new C# project.

I don’t think swig_add_library is designed to be used in such a way, so this is probably about as clean of an answer as is out there (as of this post).