Commit acf0600e authored by François Grisez's avatar François Grisez

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
parent bbcabe0e
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)")
......@@ -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)
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
)
......@@ -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<belcard::BelCard> &Vcard::getVcard() {
}
{{/wrapperCbs}}
{{/_class}}
{{/classes}}
......@@ -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__':
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment