CMake: автоматически генерирует файл c-wrapper из cpp-файла

По некоторым причинам у меня есть довольно много функций разделяемой библиотеки, написанной на C ++, которые должны быть «обернуты» C-функцией для правильного вызова. Теперь мне интересно, смогу ли я автоматизировать этот процесс (в лучшем случае хорошо интегрированный в мой CMake-build-process)

Пример: предположим, у меня есть определение функции

extern "C" void foo(Somestruct myinfo, char const * const data, char const * const data2)

в моем .hpp-файле. Теперь я бы изменил это определение, скажем,

C_WRAPPER void foo(Somestruct myinfo, ARG(1) data, ARG(3) data2)

Используя некоторые макросы, это можно без проблем преобразовать в исходную форму — таким образом, оставив hpp-файл нетронутым с функциональной точки зрения.

Некоторый парсер теперь должен прочитать этот файл и создать новый c-файл, который содержит (например)

extern void foo(Somestruct myinfo, char const * const, char const*const);
void foo_wrapper(Array everything) {
char * data1 = fromArray(array, 1);
char * data3 = fromArray(arary, 3);
foo(fromArray(0), data1, data3);
}

Граничные условия: общая схема всегда выглядит одинаково. Разница лишь в том, что количество ARGs обязательно постоянен. Аргументы ARG укажите позицию в массиве, в котором находятся данные.

В настоящее время файл оболочки написан вручную, что привело к некоторым трудоемким ошибкам из-за изменений интерфейса в прошлом. Вот почему я хотел бы автоматизировать этот шаг.

Вы знаете способ архивировать что-то подобное без необходимости создавать парсер самостоятельно? Как уже было сказано, желательно то, что хорошо вписывается в мой процесс сборки с использованием CMake.

0

Решение

Я имею честь ответить на свой вопрос.
Это можно сделать полностью в CMake.

Вот только скрипт CMake, который заполняет переменную funcstring который содержит все функции оболочки. Используя типичный файл конфигурации, эти строки могут быть записаны в функции оболочки.

set(sources a.cpp)

foreach(source ${sources})
file(READ ${source} contents)

foreach(var IN ITEMS ${contents})
string(REGEX MATCH "C_WRAPPER[ ]+[a-zA-Z0-9]+[(].*[)]" wrapperfun ${var})

if(wrapperfun)
string(REGEX REPLACE "C_WRAPPER[ ]+\([a-zA-Z0-9]+\)[(].*[)]" "\\1" function_name ${wrapperfun})

string(REGEX MATCHALL "ARG[(][0-9]+[)]" args ${wrapperfun})

set(lines "")
set(funcargs "")
foreach(arg ${args})
string(REGEX MATCH "[0-9]+" num ${arg})
set(lines "${lines}
char * data${num} = fromArray(array, ${num})\;")
set(funcargs "${funcargs}, arg${num})")
endforeach(arg)

set(funcstring "${wrapperfun}\;
Datum ${function_name}_wrapper(Array everything) {
${lines}
return ${function_name}(fromArray(0), ${funcargs})\;
}

")

endif()

endforeach(var)
endforeach(source)

Макросы не были заменены — это можно сделать в CMake, но это более короткий и простой способ включить адекватные определения макросов в окончательный C-файл.

1

Другие решения

Других решений пока нет …