Add bindings_perl and examples/perl_api_example
This commit is contained in:
@@ -2,6 +2,7 @@ cmake_minimum_required (VERSION 2.6)
|
||||
|
||||
# --- 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_JAVA OFF CACHE BOOL "Build the SourcetrailDB Java bindings.")
|
||||
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})
|
||||
|
||||
|
||||
# --- 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 ---
|
||||
|
||||
if (BUILD_BINDINGS_PYTHON)
|
||||
|
||||
@@ -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:
|
||||
|
||||
* Perl (via [SWIG](http://www.swig.org/))
|
||||
* Python (via [SWIG](http://www.swig.org/))
|
||||
* Java (via [SWIG](http://www.swig.org/))
|
||||
|
||||
@@ -94,6 +95,24 @@ $ make 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
|
||||
|
||||
Requirements:
|
||||
|
||||
@@ -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})
|
||||
@@ -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"
|
||||
)
|
||||
@@ -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.
|
||||
Executable
+7
@@ -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>
|
||||
Executable
+75
@@ -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";
|
||||
Reference in New Issue
Block a user