Add bindings_perl and examples/perl_api_example

This commit is contained in:
Andrew Pam
2020-10-05 16:22:55 +02:00
committed by mlangkabel
parent d352c8bf39
commit 20e3912a5f
8 changed files with 256 additions and 0 deletions
+14
View File
@@ -2,6 +2,7 @@ cmake_minimum_required (VERSION 2.6)
# --- Options --- # --- Options ---
set(BUILD_BINDINGS_PERL OFF CACHE BOOL "Build the SourcetrailDB Perl bindings.")
set(BUILD_BINDINGS_PYTHON OFF CACHE BOOL "Build the SourcetrailDB Python bindings.") set(BUILD_BINDINGS_PYTHON OFF CACHE BOOL "Build the SourcetrailDB Python bindings.")
set(BUILD_BINDINGS_JAVA OFF CACHE BOOL "Build the SourcetrailDB Java bindings.") set(BUILD_BINDINGS_JAVA OFF CACHE BOOL "Build the SourcetrailDB Java bindings.")
set(BUILD_EXAMPLES ON CACHE BOOL "Build the examples.") set(BUILD_EXAMPLES ON CACHE BOOL "Build the examples.")
@@ -45,6 +46,19 @@ set(CORE_BINARY_DIR "${CMAKE_BINARY_DIR}/core") # can be accessed in subdirector
add_subdirectory(${CORE_SOURCE_DIR} ${CORE_BINARY_DIR}) add_subdirectory(${CORE_SOURCE_DIR} ${CORE_BINARY_DIR})
# --- Perl Binding ---
if (BUILD_BINDINGS_PERL)
message(STATUS "The SourcetrailDB Perl bindings will be built.")
set(PERL_BINDING_TARGET_NAME "bindings_perl")
set(PERL_BINDING_OUTPUT_DIR "")
add_subdirectory("${CMAKE_SOURCE_DIR}/bindings_perl" "${CMAKE_BINARY_DIR}/bindings_perl")
else()
message(STATUS "Building the SourcetrailDB Perl bindings will be skipped. You can enable building this target by setting 'BUILD_BINDINGS_PERL' to 'ON'.")
endif()
# --- Python Binding --- # --- Python Binding ---
if (BUILD_BINDINGS_PYTHON) if (BUILD_BINDINGS_PYTHON)
+19
View File
@@ -35,6 +35,7 @@ __To get an overview on everything involved, please take a look at our [Language
Even though the core implementation is written in C++, this does not require you to write your indexer in C++ as well. Instead you can use a language binding (e.g. see [SWIG](http://www.swig.org/)). These language bindings are already available: Even though the core implementation is written in C++, this does not require you to write your indexer in C++ as well. Instead you can use a language binding (e.g. see [SWIG](http://www.swig.org/)). These language bindings are already available:
* Perl (via [SWIG](http://www.swig.org/))
* Python (via [SWIG](http://www.swig.org/)) * Python (via [SWIG](http://www.swig.org/))
* Java (via [SWIG](http://www.swig.org/)) * Java (via [SWIG](http://www.swig.org/))
@@ -94,6 +95,24 @@ $ make test_core
$ ./core/test_core $ ./core/test_core
``` ```
### Perl Bindings
Requirements:
* [Perl](https://www.perl.org/) needs to be included and linked against when building the Perl bindings. CMake will auto-detect your Perl installation. If you want to build against a specific version of Perl, please define the `PERL_LIBRARY` variable accordingly when running CMake. Make sure to link to the correct Perl version when building for different architectures (32bit/64bit).
* [SWIG 3.0.12](http://www.swig.org/) is used to automatically generate Perl binding code. Make sure that SWIG is added to your path environment variable.
If you want to build the Perl bindings run:
```
$ cd path/to/SourcetrailDB
$ mkdir build
$ cd build
$ cmake -DBUILD_BINDINGS_PERL=ON ..
$ make sourcetraildb
```
Swig is configured to generate the Perl binding code as a pre-build event, so you don't need to bother with updating manually.
### Python Bindings ### Python Bindings
Requirements: Requirements:
+45
View File
@@ -0,0 +1,45 @@
cmake_minimum_required (VERSION 2.6)
# --- Setup Paths ---
set(RESOURCES_SWIG_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../resources_swig")
set(GENERATED_SRC_DIR "${CMAKE_CURRENT_BINARY_DIR}/src")
set(PERL_BINDING_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR} PARENT_SCOPE)
set(SWIG_INTERFACE_FILE "${RESOURCES_SWIG_DIR}/interface/sourcetraildb.i")
# --- Find Perl ---
find_package(PerlLibs ${PERL_VERSION} REQUIRED)
# --- Find Swig ---
find_package(SWIG REQUIRED)
include(${SWIG_USE_FILE})
# --- Configure Target ---
set_source_files_properties(${SWIG_INTERFACE_FILE} PROPERTIES CPLUSPLUS ON)
include_directories(
"${RESOURCES_SWIG_DIR}/include"
"${CORE_SOURCE_DIR}/include"
${PERL_INCLUDE_DIRS}
)
swig_add_library(
${PERL_BINDING_TARGET_NAME}
TYPE SHARED
LANGUAGE perl
OUTPUT_DIR ${PERL_BINDING_OUTPUT_DIR}
OUTFILE_DIR ${GENERATED_SRC_DIR}
SOURCES ${SWIG_INTERFACE_FILE} ${RESOURCES_SWIG_DIR}/src/sourcetraildb.cpp
)
set_target_properties(${PERL_BINDING_TARGET_NAME}
PROPERTIES OUTPUT_NAME sourcetraildb)
swig_link_libraries(${PERL_BINDING_TARGET_NAME} ${PERL_LIBRARIES} ${LIB_CORE_TARGET_NAME})
+46
View File
@@ -0,0 +1,46 @@
cmake_minimum_required (VERSION 2.6)
set(EXAMPLE_NAME "perl_api_example")
# --- Configure Sourcetrail Project File ---
add_custom_target(
${EXAMPLE_NAME} ALL
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/src/example.pl ${CMAKE_CURRENT_BINARY_DIR}/example.pl
)
add_dependencies(${EXAMPLE_NAME} _${PERL_BINDING_TARGET_NAME})
if (MSVC)
STRING(REGEX REPLACE "/" "\\\\" BACKSLASHED_PERL_BINDING_OUTPUT_DIR ${PERL_BINDING_OUTPUT_DIR})
STRING(REGEX REPLACE "/" "\\\\" BACKSLASHED_CMAKE_CURRENT_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
add_custom_command(
TARGET ${EXAMPLE_NAME} POST_BUILD
COMMAND xcopy \"${BACKSLASHED_PERL_BINDING_OUTPUT_DIR}\\$(Configuration)\\sourcetraildb*\" \"${BACKSLASHED_CMAKE_CURRENT_BINARY_DIR}\" /Y
)
add_custom_command(
TARGET ${EXAMPLE_NAME} POST_BUILD
COMMAND xcopy \"${BACKSLASHED_PERL_BINDING_OUTPUT_DIR}\\sourcetraildb.pm\" \"${BACKSLASHED_CMAKE_CURRENT_BINARY_DIR}\" /Y
)
else()
add_custom_command(
TARGET ${EXAMPLE_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy ${PERL_BINDING_OUTPUT_DIR}/sourcetraildb* ${CMAKE_CURRENT_BINARY_DIR}
)
if (APPLE)
add_custom_command(
TARGET ${EXAMPLE_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E rename ${CMAKE_CURRENT_BINARY_DIR}/sourcetraildb.dylib ${CMAKE_CURRENT_BINARY_DIR}/sourcetraildb.so
)
endif()
endif()
set(PERL_API_EXAMPLE_DATA_PATH "${CMAKE_CURRENT_SOURCE_DIR}/data")
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/${EXAMPLE_NAME}.srctrlprj.in"
"${CMAKE_CURRENT_BINARY_DIR}/${EXAMPLE_NAME}.srctrlprj"
)
+30
View File
@@ -0,0 +1,30 @@
## Python API Example
### Requirements
* CMake
* C++ Compiler
* Perl
* SWIG
### Running from Command Line
* Run cmake with `BUILD_BINDINGS_PERL=ON`
* Build target `sourcetraildb`
* Copy two files from the `bindings_perl` build directory into `SourcetrailDB/examples/perl_api_example/src`:
- `sourcetraildb.pm`
- Windows: `sourcetraildb.dll`
- Linux: `sourcetraildb.so`
- macOS: `sourcetraildb.dylib` and rename to `sourcetraildb.so`
* Run example from the directory `SourcetrailDB/examples/perl_api_example/src` with:
```
$ perl example.pl --database-file-path=absolute/path/to/SourcetrailDB/examples/perl_api_example/src/example.srctrldb --source-file-path=absolute/path/to/SourcetrailDB/examples/perl_api_example/data/file.pl
```
### Running with Sourcetrail
* Run cmake with `BUILD_EXAMPLES=ON` and `BUILD_BINDINGS_PERL=ON`
* Build target `sourcetraildb` and `perl_api_example`.
* Open `perl_api_exampl.srctrlprj` located in the build directory of `perl_api_example` with Sourcetrail and index the project.
+7
View File
@@ -0,0 +1,7 @@
package MyClass;
my $my_member = 1;
sub my_method {
return $my_member;
}
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8" ?>
<config>
<source_groups>
<source_group_2e83e5fa-b0f8-453b-a1fc-2abdb66bd967>
<custom_command>perl example.pl --database-file-path=%{DATABASE_FILE_PATH} --source-file-path=%{SOURCE_FILE_PATH} --database-version=%{DATABASE_VERSION}</custom_command>
<name>Custom Command Source Group</name>
<run_in_parallel>0</run_in_parallel>
<source_extensions>
<source_extension>.pl</source_extension>
<source_extension>.pm</source_extension>
</source_extensions>
<source_paths>
<source_path>@PERL_API_EXAMPLE_DATA_PATH@/file.pl</source_path>
</source_paths>
<status>enabled</status>
<type>Custom Command Source Group</type>
</source_group_2e83e5fa-b0f8-453b-a1fc-2abdb66bd967>
</source_groups>
<version>7</version>
</config>
+75
View File
@@ -0,0 +1,75 @@
#!/usr/bin/perl
use v5.10;
use strict;
use warnings;
use Getopt::Long;
use FindBin;
use lib $FindBin::Bin;
use sourcetraildb;
my ( $database_file_path, $source_file_path );
my $db_version = 0;
GetOptions(
'database-file-path=s' => \$database_file_path,
'source-file-path=s' => \$source_file_path,
'database-version=i' => \$db_version,
);
say "SourcetrailDB Perl API Example";
my $supported_db_version = sourcetraildb::getSupportedDatabaseVersion;
say "Supported database version: $supported_db_version";
die "ERROR: Only supports database version: $supported_db_version. Requested version: $db_version\n"
if $db_version > 0 and $db_version != $supported_db_version;
die "ERROR: " . sourcetraildb::getLastError unless sourcetraildb::open($database_file_path);
say "Clearing loaded database now...";
sourcetraildb::clear;
say "start indexing";
sourcetraildb::beginTransaction;
my $file_id = sourcetraildb::recordFile($source_file_path);
sourcetraildb::recordFileLanguage( $file_id, 'perl' );
die "ERROR: " . sourcetraildb::getLastError if sourcetraildb::getLastError;
my $symbol_id = sourcetraildb::recordSymbol(
'{ "name_delimiter": "::", "name_elements": [ { "prefix": "", "name": "MyClass", "postfix": "" } ] }');
sourcetraildb::recordSymbolDefinitionKind( $symbol_id, $sourcetraildb::DEFINITION_EXPLICIT );
sourcetraildb::recordSymbolKind( $symbol_id, $sourcetraildb::SYMBOL_PACKAGE );
sourcetraildb::recordSymbolLocation( $symbol_id, $file_id, 1, 9, 1, 15 );
sourcetraildb::recordSymbolScopeLocation( $symbol_id, $file_id, 1, 1, 7, 2 );
my $member_id
= sourcetraildb::recordSymbol( '{ "name_delimiter": "::", "name_elements": [ '
. '{ "prefix": "", "name": "MyClass", "postfix": "" }, '
. '{ "prefix": "$", "name": "my_member", "postfix": "" } '
. '] }' );
sourcetraildb::recordSymbolDefinitionKind( $member_id, $sourcetraildb::DEFINITION_EXPLICIT );
sourcetraildb::recordSymbolKind( $member_id, $sourcetraildb::SYMBOL_FIELD );
sourcetraildb::recordSymbolLocation( $member_id, $file_id, 3, 4, 3, 13 );
my $method_id
= sourcetraildb::recordSymbol( '{ "name_delimiter": "::", "name_elements": [ '
. '{ "prefix": "", "name": "MyClass", "postfix": "" }, '
. '{ "prefix": "&", "name": "my_method", "postfix": "" } '
. '] }' );
sourcetraildb::recordSymbolDefinitionKind( $method_id, $sourcetraildb::DEFINITION_EXPLICIT );
sourcetraildb::recordSymbolKind( $method_id, $sourcetraildb::SYMBOL_METHOD );
sourcetraildb::recordSymbolLocation( $method_id, $file_id, 5, 5, 5, 13 );
sourcetraildb::recordSymbolScopeLocation( $method_id, $file_id, 6, 1, 7, 1 );
my $usage_id = sourcetraildb::recordReference( $method_id, $member_id, $sourcetraildb::REFERENCE_USAGE );
sourcetraildb::recordReferenceLocation( $usage_id, $file_id, 6, 9, 6, 18 );
sourcetraildb::commitTransaction;
die "ERROR: " . sourcetraildb::getLastError if sourcetraildb::getLastError;
die "ERROR: " . sourcetraildb::getLastError unless sourcetraildb::close;
say "done";