From acf0600ee4787644125823a1fed18e3073e7b387 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Grisez?= Date: Wed, 15 Mar 2017 15:01:42 +0100 Subject: [PATCH] Reworking of the C++ wrapper generator * generate the wrapper implementation in a single file * the CMakeLists.txt file that build the wrapper is now static --- wrappers/cpp/CMakeLists.txt | 53 +++++++++++++---- wrappers/cpp/LinphoneCxxConfig.cmake.in | 14 +++-- wrappers/cpp/c_make_lists.mustache.in | 76 ------------------------- wrappers/cpp/class_impl.mustache | 4 +- wrappers/cpp/genwrapper.py | 60 ++++++++----------- 5 files changed, 78 insertions(+), 129 deletions(-) delete mode 100644 wrappers/cpp/c_make_lists.mustache.in diff --git a/wrappers/cpp/CMakeLists.txt b/wrappers/cpp/CMakeLists.txt index f91070676..bb817038f 100644 --- a/wrappers/cpp/CMakeLists.txt +++ b/wrappers/cpp/CMakeLists.txt @@ -1,18 +1,49 @@ -configure_file(c_make_lists.mustache.in c_make_lists.mustache @ONLY) -configure_file(object.cc src/object.cc COPYONLY) -configure_file(object.hh include/object.hh COPYONLY) configure_file(LinphoneCxxConfig.cmake.in LinphoneCxxConfig.cmake @ONLY) -add_custom_command(OUTPUT CMakeLists.txt include/linphone.hh +add_custom_command(OUTPUT include/linphone++/linphone.hh src/linphone++.cc COMMAND ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/genwrapper.py" "${PROJECT_BINARY_DIR}/coreapi/help/doc/xml" DEPENDS abstractapi.py genwrapper.py class_header.mustache class_impl.mustache enums_header.mustache main_header.mustache linphone-doc "${PROJECT_BINARY_DIR}/coreapi/help/doc/xml/index.xml" - "${CMAKE_CURRENT_BINARY_DIR}/c_make_lists.mustache" ) -add_custom_target(make_cpp_wrapper ALL ${CMAKE_COMMAND} -E make_directory build/ - COMMAND ${CMAKE_COMMAND} -E chdir build/ ${CMAKE_COMMAND} .. -DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX} -DCMAKE_INSTALL_RPATH="${CMAKE_INSTALL_RPATH}" -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} - COMMAND ${CMAKE_COMMAND} --build build/ - DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/CMakeLists.txt - ${CMAKE_CURRENT_BINARY_DIR}/include/linphone.hh + +add_library(linphone++ SHARED + object.cc + ${CMAKE_CURRENT_BINARY_DIR}/src/linphone++.cc +) +target_link_libraries(linphone++ + PRIVATE ${BCTOOLBOX_CORE_LIBRARIES} ${BELLESIP_LIBRARIES} linphone +) +target_include_directories(linphone++ + PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/include + PRIVATE ${CMAKE_BINARY_DIR}/include + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${BCTOOLBOX_INCLUDE_DIRS} + PRIVATE ${BELLESIP_INCLUDE_DIRS} +) +set_target_properties(linphone++ PROPERTIES SOVERSION ${LINPHONE_SO_VERSION}) + +install(TARGETS linphone++ EXPORT LinphoneCxxTargets + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} +) +install(FILES object.hh + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/linphone++ +) +install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include/linphone++ + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} +) + +include(CMakePackageConfigHelpers) +write_basic_package_version_file( + "${CMAKE_CURRENT_BINARY_DIR}/LinphoneCxxVersion.cmake" + VERSION ${PROJECT_VERSION} + COMPATIBILITY AnyNewerVersion +) +export(EXPORT LinphoneCxxTargets + FILE "${CMAKE_CURRENT_BINARY_DIR}/LinphoneCxxTargets.cmake" +) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/LinphoneCxxVersion.cmake + ${CMAKE_CURRENT_BINARY_DIR}/LinphoneCxxTargets.cmake + ${CMAKE_CURRENT_BINARY_DIR}/LinphoneCxxConfig.cmake + DESTINATION ${CMAKE_INSTALL_DATADIR}/LinphoneCxx/cmake ) -install(CODE "execute_process(COMMAND \"${CMAKE_COMMAND}\" --build \"${CMAKE_CURRENT_BINARY_DIR}/build\" --config \"${CMAKE_BUILD_TYPE}\" --target install)") diff --git a/wrappers/cpp/LinphoneCxxConfig.cmake.in b/wrappers/cpp/LinphoneCxxConfig.cmake.in index 107edc651..6ed42d720 100644 --- a/wrappers/cpp/LinphoneCxxConfig.cmake.in +++ b/wrappers/cpp/LinphoneCxxConfig.cmake.in @@ -30,11 +30,15 @@ # LINPHONECXX_LIBRARIES - The libraries needed to use linphone++ # LINPHONECXX_LDFLAGS - The linking flags needed to use linphone++ -find_package(BelleSIP) -find_package(Linphone) include("${CMAKE_CURRENT_LIST_DIR}/LinphoneCxxTargets.cmake") -get_filename_component(LINPHONECXX_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) -set(LINPHONECXX_INCLUDE_DIRS "${LINPHONECXX_CMAKE_DIR}/../../../include" "${BELLESIP_INCLUDE_DIRS}" "${LINPHONE_INCLUDE_DIRS}") set(LINPHONECXX_LDFLAGS "") -set(LINPHONECXX_LIBRARIES linphone++ ${BELLESIP_LIBRARIES} ${LINPHONE_LIBRARIES}) +set(LINPHONECXX_CPPFLAGS "") +set(LINPHONECXX_LIBRARIES linphone++) + +#get_target_property(LINPHONECXX_INCLUDE_DIRS linphone++ INTERFACE_INCLUDE_DIRECTORIES) +#list(INSERT LINPHONECXX_INCLUDE_DIRS 0 "@CMAKE_INSTALL_FULL_INCLUDEDIR@") +set(LINPHONECXX_INCLUDE_DIRS "@CMAKE_INSTALL_FULL_INCLUDEDIR@") +list(REMOVE_DUPLICATES LINPHONECXX_INCLUDE_DIRS) + +set(LINPHONECXX_FOUND 1) diff --git a/wrappers/cpp/c_make_lists.mustache.in b/wrappers/cpp/c_make_lists.mustache.in deleted file mode 100644 index 66a8d4fc2..000000000 --- a/wrappers/cpp/c_make_lists.mustache.in +++ /dev/null @@ -1,76 +0,0 @@ -cmake_minimum_required(VERSION 3.0) - -project(LinphoneCxx VERSION @LINPHONE_VERSION@) - -include(GNUInstallDirs) - -find_package(BcToolbox REQUIRED) -find_package(BelleSIP REQUIRED) - -set(CMAKE_CXX_STANDARD 11) - -set(GENERATED_SOURCES - {{#classes}} - src/{{{source}}} - {{/classes}} -) -set(SOURCES - ${GENERATED_SOURCES} - src/object.cc -) -set(GENERATED_HEADERS - {{#classes}} - include/{{{header}}} - {{/classes}} - {{#interfaces}} - include/{{{header}}} - {{/interfaces}} - include/linphone.hh - include/enums.hh -) -set(HEADERS - ${GENERATED_HEADERS} - ${CMAKE_CURRENT_SOURCE_DIR}/include/object.hh -) - -add_definitions("-DLINPHONECXX_EXPORTS") -add_library(linphone++ SHARED ${SOURCES}) -if(WIN32) - target_link_libraries(linphone++ PRIVATE @PROJECT_BINARY_DIR@/coreapi/${CMAKE_BUILD_TYPE}/linphone.lib ${BCTOOLBOX_CORE_LIBRARIES} ${BELLESIP_LIBRARIES}) -elseif(APPLE) - target_link_libraries(linphone++ PRIVATE @PROJECT_BINARY_DIR@/coreapi/liblinphone.@LINPHONE_SO_VERSION@.dylib ${BCTOOLBOX_CORE_LIBRARIES} ${BELLESIP_LIBRARIES}) -else() - target_link_libraries(linphone++ PRIVATE @PROJECT_BINARY_DIR@/coreapi/liblinphone.so.@LINPHONE_SO_VERSION@ ${BCTOOLBOX_CORE_LIBRARIES} ${BELLESIP_LIBRARIES}) -endif() -target_include_directories(linphone++ - PRIVATE include - PRIVATE @PROJECT_SOURCE_DIR@/include - PRIVATE ${BCTOOLBOX_INCLUDE_DIRS} - PRIVATE ${BELLESIP_INCLUDE_DIRS} -) -set_target_properties(linphone++ - PROPERTIES SOVERSION @LINPHONE_SO_VERSION@ -) - -install(TARGETS linphone++ EXPORT LinphoneCxxTargets - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} -) -install(FILES ${HEADERS} - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/linphone++ -) - -include(CMakePackageConfigHelpers) -write_basic_package_version_file( - "${CMAKE_CURRENT_BINARY_DIR}/LinphoneCxxVersion.cmake" - VERSION ${PROJECT_VERSION} - COMPATIBILITY AnyNewerVersion -) -export(EXPORT LinphoneCxxTargets - FILE "${CMAKE_CURRENT_BINARY_DIR}/LinphoneCxxTargets.cmake" -) -install(FILES ${CMAKE_CURRENT_BINARY_DIR}/LinphoneCxxVersion.cmake - ${CMAKE_CURRENT_BINARY_DIR}/LinphoneCxxTargets.cmake - ${CMAKE_CURRENT_SOURCE_DIR}/LinphoneCxxConfig.cmake - DESTINATION ${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME}/cmake -) diff --git a/wrappers/cpp/class_impl.mustache b/wrappers/cpp/class_impl.mustache index 26615b5ed..aaa3cb004 100644 --- a/wrappers/cpp/class_impl.mustache +++ b/wrappers/cpp/class_impl.mustache @@ -20,7 +20,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. using namespace {{{namespace}}}; -{{#_class}} +{{#classes}} {{#isNotListener}} {{{namespace}}}::{{{className}}}::{{{className}}}(::belle_sip_object_t *ptr, bool takeRef): {{{parentClassName}}}(ptr, takeRef) { @@ -151,4 +151,4 @@ std::shared_ptr &Vcard::getVcard() { } {{/wrapperCbs}} -{{/_class}} +{{/classes}} diff --git a/wrappers/cpp/genwrapper.py b/wrappers/cpp/genwrapper.py index 70c186759..6be80023c 100755 --- a/wrappers/cpp/genwrapper.py +++ b/wrappers/cpp/genwrapper.py @@ -22,6 +22,7 @@ import re import argparse import os import sys +import errno sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..', 'tools')) print(sys.path) import genapixml as CApi @@ -625,21 +626,9 @@ class MainHeader(object): class ClassImpl(object): - def __init__(self, parsedClass, translatedClass): - self._class = translatedClass - self.filename = parsedClass.name.to_snake_case() + '.cc' - self.internalIncludes = [] - self.internalIncludes.append({'name': parsedClass.name.to_snake_case() + '.hh'}) - self.internalIncludes.append({'name': 'coreapi/linphonecore.h'}) - - namespace = parsedClass.find_first_ancestor_by_type(AbsApi.Namespace) - self.namespace = namespace.name.concatenate(fullName=True) if namespace is not None else None - -class CMakeLists(object): def __init__(self): self.classes = [] - self.interfaces = [] - + self.namespace = 'linphone' def render(renderer, item, path): tmppath = path + '.tmp' @@ -658,11 +647,22 @@ def main(): argparser.add_argument('-o --output', type=str, help='the directory where to generate the source files', dest='outputdir', default='.') args = argparser.parse_args() - entries = os.listdir(args.outputdir) - if 'include' not in entries: - os.mkdir(args.outputdir + '/include') - if 'src' not in entries: - os.mkdir(args.outputdir + '/src') + includedir = args.outputdir + '/include/linphone++' + srcdir = args.outputdir + '/src' + + try: + os.mkdir(includedir) + except OSError as e: + if e.errno != errno.EEXIST: + print("Cannot create '{0}' dircetory: {1}".format(includedir, e.strerror)) + sys.exit(1) + + try: + os.mkdir(srcdir) + except OSError as e: + if e.errno != errno.EEXIST: + print("Cannot create '{0}' dircetory: {1}".format(srcdir, e.strerror)) + sys.exit(1) project = CApi.Project() project.initFromDir(args.xmldir) @@ -680,37 +680,27 @@ def main(): else: print('warning: {0} enum won\'t be translated because of parsing errors'.format(item[0])) - render(renderer, header, args.outputdir + '/include/enums.hh') + render(renderer, header, includedir + '/enums.hh') mainHeader = MainHeader() - cmakelists = CMakeLists() + impl = ClassImpl() for _class in parser.classesIndex.values() + parser.interfacesIndex.values(): if _class is not None: try: header = ClassHeader(_class, translator) - impl = ClassImpl(_class, header._class) - headerName = _class.name.to_snake_case() + '.hh' - sourceName = _class.name.to_snake_case() + '.cc' mainHeader.add_include(headerName) + render(renderer, header, includedir + '/' + header.filename) - if type(_class) is AbsApi.Class: - cmakelists.classes.append({'header': headerName, 'source': sourceName}) - else: - cmakelists.interfaces.append({'header': headerName}) - - render(renderer, header, args.outputdir + '/include/' + header.filename) - - if type(_class) is AbsApi.Class: - render(renderer, impl, args.outputdir + '/src/' + impl.filename) + if type(_class) is not AbsApi.Interface: + impl.classes.append(header._class) except AbsApi.Error as e: print('Could not translate {0}: {1}'.format(_class.name.to_camel_case(fullName=True), e.args[0])) - render(renderer, mainHeader, args.outputdir + '/include/linphone.hh') - - render(renderer, cmakelists, args.outputdir + '/CMakeLists.txt') + render(renderer, mainHeader, includedir + '/linphone.hh') + render(renderer, impl, srcdir + '/linphone++.cc') if __name__ == '__main__':