Coder Social home page Coder Social logo

llnl / shroud Goto Github PK

View Code? Open in Web Editor NEW
91.0 6.0 7.0 25.86 MB

Shroud: generate Fortran and Python wrappers for C and C++ libraries

License: BSD 3-Clause "New" or "Revised" License

Makefile 2.06% Python 21.23% C 16.68% C++ 30.47% Fortran 29.31% Lua 0.10% SWIG 0.05% Shell 0.06% CMake 0.03% Cython 0.02%
fortran python language-bindings cpp c-plus-plus c build-tools radiuss

shroud's Introduction

Shroud: generate Fortran and Python wrappers for C and C++ libraries.

Shroud is a tool for creating a Fortran or Python interface to a C or C++ library. It can also create a C API for a C++ library.

The user creates a YAML file with the C/C++ declarations to be wrapped along with some annotations to provide semantic information and code generation options. Shroud produces a wrapper for the library. The generated code is highly-readable and intended to be similar to code that would be hand-written to create the bindings.

verb

  1. wrap or dress (a body) in a shroud for burial.
  2. cover or envelop so as to conceal from view.

Build Status Documentation Status

Goals

  • Simplify the creating of wrapper for a C++ library.
  • Preserves the object-oriented style of C++ classes.
  • Create an idiomatic wrapper API from the C++ API.
  • Generate code which is easy to understand.
  • No dependent runtime library.

Example

The user creates a YAML file which includes declarations from zoo.hpp.

library: zoo
cxx_header: zoo.hpp

declarations:
- decl: class Animal
  declarations:
  - decl: Animal()
  - decl: void speak(const std::string &word)

This creates a Fortran interface which can be used as:

use zoo_mod
type(Animal) dog
dog = Animal()
dog%speak("woof")

And from Python

import zoo
dog = zoo.Animal()
dog.speak("woof")

Documentation

To get started using Shroud, check out the full documentation:

http://shroud.readthedocs.io/en/develop

Presentation at FortranCon2020

https://www.youtube.com/watch?v=1mdI-M94vDc Slides

Mailing List

[email protected]

https://groups.io/g/shroud-users

Required Packages

C++ to C to Fortran

The generated Fortran requires a Fortran 2003 compiler.

C++ or C to Python

The generated Python requires Python 2.7 or 3.4+.

Python features:

  • Uses NumPy for arrays. Also able to use Python lists if NumPy is overkill.
  • Uses extension type for classes.
  • Creates readable source.

Getting started

Shroud can be installed using pip

pip install llnl-shroud

This can be done in a virtual environment as

cd my_project_folder
virtualenv my_project
source my_project/bin/activate
pip install llnl-shroud

This assumes the bash shell. Source activate.csh for csh.

In addition, a file created by shiv is available from the github release. Shroud and PyYAML are bundled into a single executable which uses the Python3 on your path. Shiv requires Python 3.6+.

wget https://github.com/LLNL/shroud/archive/shroud-0.13.0.pyz

License

Copyright (c) 2017-2024, Lawrence Livermore National Security, LLC. Produced at the Lawrence Livermore National Laboratory.

SPDX-License-Identifier: (BSD-3-Clause)

See LICENSE for details

Unlimited Open Source - BSD 3-clause Distribution LLNL-CODE-738041 OCEC-17-143

SPDX usage

Individual files contain SPDX tags instead of the full license text. This enables machine processing of license information based on the SPDX License Identifiers that are available here: https://spdx.org/licenses/

Files that are licensed as BSD 3-Clause contain the following text in the license header:

SPDX-License-Identifier: (BSD-3-Clause)

External Packages

Shroud bundles some of its external dependencies in its repository. These packages are covered by various permissive licenses. A summary listing follows. See the license included with each package for full details.

PackageName: fruit
PackageHomePage: https://sourceforge.net/projects/fortranxunit/
PackageLicenseDeclared: BSD-3-Clause

shroud's People

Contributors

aaroncblack avatar kennyweiss avatar ltaylor16 avatar rrsettgast avatar vsoch avatar white238 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

shroud's Issues

Add interface wrapper for functions with default arguments defined as class members

Hello!

I have noticed one thing while defining member functions of a class containing default arguments.

If the Shroud script is just for the function, e.g.:

library: Tutorial
format:
  F_filename_suffix: F90
cxx_header: tutorial.hpp

declarations:
- decl: int Method1(int arg1)
- decl: int Method2(int arg1, int arg2 = 1, double arg3 = 0.5)

The Fortran wraper will have an interface wraper defined as:

    interface method2
        module procedure method2_0
        module procedure method2_1
        module procedure method2_2
    end interface method2

Thus, one may use the function as, for example, value = method2(arg1,optional_args).

However, if the functions is defined as class member, e.g.:

library: Tutorial
format:
  F_filename_suffix: F90
cxx_header: tutorial.hpp

- decl: namespace tutorial
  declarations:
  - decl: class Class1
    declarations:
    - decl: Class1(int arg1, int arg2 = 1, double arg3 = 0.5) +name(new)
    - decl: ~Class1() +name(delete)
    - decl: int Method1(int arg1)
    - decl: int Method2(int arg1, int arg2 = 1, double arg3 = 0.5)

The Fortran wrapper contains only the interface for the constructor:

    interface class1
        module procedure class1_new_0
        module procedure class1_new_1
        module procedure class1_new_2
    end interface class1

And the functions are defined as procedures inside the defined type:

        procedure :: method1 => class1_method1
        procedure :: method2_0 => class1_method2_0
        procedure :: method2_1 => class1_method2_1
        procedure :: method2_2 => class1_method2_2
        [...]
        generic :: method1 => method1_0, method1_1, method1_2
        generic :: method2 => method2_0, method2_1, method2_2

Thus one may use the functions in the main Fortran program as type-bound functions:

cptr = Class1(1, 2, 0.1) 

value1 = cptr%method1(1)
value2 = cptr%method2(1, optional_args)

In this case, method1 can also be used as class1_method1(cptr, 1). However this is not possible for method2. I have managed to solve this by manually adding the interface for method2:

    interface class1_method2
        module procedure method2_0
        module procedure method2_1
        module procedure method2_2
    end interface class1_method2

However, if one needs to run shroud again it will be needed to keep inserting the interface into the fortran wrapper. It seems there is no splicer to keep this additions in the splicer.f file.

Is there some shroud input I am missing for this case?

Thank you very much!
Felipe Silva Carvalho

Feature request: pull full spec from header file

One of the problems we encountered with handwritten INTERFACE declarations is the divergence of the C declaration and the Fortran declaration which doesn't get caught by any tool. In that example Shroud helps already by generating the INTERFACE part (and needed wrappers, like the string), but one still has to maintain the declaration in 2 different files.

It would be awesome if Shroud could pull the full declaration automatically from a C header file and one would simply have to name the function/struct to import. It seems that pycparser would be suitable for supporting C.

cpp_if not taken in account for associated method

When trying to generate wrapper for the following C++ code, I end up with an error at link time when linking against the Fortran module.

C++ is like:

class Foo {
  public:
    void baz() {};
    void bar() {};
};

I do not want to expose the symbol bar if ENABLE_BAR is not defined. So the YAML is such as:

declarations:
  - decl: class Foo
    declarations:
      - decl: void baz()
      - decl: void bar()
        cpp_if: if defined(ENABLE_FOOBAR)

The result is such as:

    type foo
        type(SHROUD_foo_capsule) :: cxxmem
        ! splicer begin class.Foo.component_part
        ! splicer end class.Foo.component_part
    contains
        procedure :: baz => foo_baz
        procedure :: bar => foo_bar
        procedure :: get_instance => foo_get_instance
        procedure :: set_instance => foo_set_instance
        procedure :: associated => foo_associated
        ! splicer begin class.Foo.type_bound_procedure_part
        ! splicer end class.Foo.type_bound_procedure_part
    end type foo

    [... removing operators ...]

    interface

        subroutine c_foo_baz(self) &
                bind(C, name="TES_foo_baz")
            import :: SHROUD_foo_capsule
            implicit none
            type(SHROUD_foo_capsule), intent(IN) :: self
        end subroutine c_foo_baz

#ifdef ENABLE_BAR
        subroutine c_foo_bar(self) &
                bind(C, name="TES_foo_bar")
            import :: SHROUD_foo_capsule
            implicit none
            type(SHROUD_foo_capsule), intent(IN) :: self
        end subroutine c_foo_bar
#endif

        ! splicer begin class.Foo.additional_interfaces
        ! splicer end class.Foo.additional_interfaces
    end interface

contains

    subroutine foo_baz(obj)
        class(foo) :: obj
        ! splicer begin class.Foo.method.baz
        call c_foo_baz(obj%cxxmem)
        ! splicer end class.Foo.method.baz
    end subroutine foo_baz

#ifdef ENABLE_BAR
    subroutine foo_bar(obj)
        class(foo) :: obj
        ! splicer begin class.Foo.method.bar
        call c_foo_bar(obj%cxxmem)
        ! splicer end class.Foo.method.bar
    end subroutine foo_bar
#endif

    [... Removing useless function implementation ...]

end module foo_mod

In the case where ENABLE_BAR is not defined, the module will not be able to expose the foo%bar as foo_bar subroutine will not be defined, nor the c_foo_bar interface.

If I define the following FORTRAN program:

program fortran_test
    use foo_mod
    implicit none

    type(foo) :: f

    call f%baz
#ifdef ENABLE_BAR
    call f%bar
#endif
end program fortran_test

and try to link it to the module, I have the following error risen:

wrapfFoo.F:30:17:

         procedure :: bar => foo_bar
                 1
Error: 'foo_bar' must be a module procedure or an external procedure with an explicit interface at (1)

One solution would be to add a check to node.cpp_if when defining the procedure in the type definition in the wrapfFoo.f file generated, in order to add the preprocessor directives.

A<int> as a return value

I have a function that returns a templated class, such as A<int> func2().
Here is an example configuration:

library: abc
namespace: abc

declarations:

- decl: template<typename T> class A
  cxx_template:
    - instantiation: <int>
  declarations:
  - decl: A()
- decl: vector<int> func1()
- decl: A<int> func2()

In a few places in the generated code the type is ignored and instead of A<int> or A_int we get just A (it works correctly for vector<int>, though).
For example, in wrapabc.cpp I get destructors for both A<int> and A (the latter won't compile of course):

// Release library allocated memory.
void ABC_SHROUD_memory_destructor(ABC_SHROUD_capsule_data *cap)
{
    void *ptr = cap->addr;
    switch (cap->idtor) {
    case 0:   // --none--
    {
        // Nothing to delete
        break;
    }
    case 1:   // abc::A<int>
    {
        abc::A<int> *cxx_ptr = reinterpret_cast<abc::A<int> *>(ptr);
        delete cxx_ptr;
        break;
    }
    case 2:   // std_vector_int
    {
        std::vector<int> *cxx_ptr = reinterpret_cast<std::vector<int> *>(ptr);
        delete cxx_ptr;
        break;
    }
    case 3:   // abc::A
    {
        abc::A *cxx_ptr = reinterpret_cast<abc::A *>(ptr);
        delete cxx_ptr;
        break;
    }
    default:
    {
        // Unexpected case in destructor
        break;
    }
    }
    cap->addr = nullptr;
    cap->idtor = 0;  // avoid deleting again
}

Error generating python bindings for C++ bool variable

I am getting a Python NameError when trying to generate python bindings for a boolean variable in a C++ class. I have created a simple reproducer shown below:

example.hpp

#ifndef EXAMPLE_H
#define EXAMPLE_H

class Example{
    public:
        bool example_flag = true;
}

#endif

with the yaml file reproducer.yaml:

options:
  wrap_fortran: False
  wrap_c: False
  wrap_python: True

declarations:

- decl: class Example
  cxx_header: example.hpp
  declarations:
  - decl: Example(void);
  - decl: bool require_example_flag;

When I run shroud-0.13.0 reproducer.yaml I get the following error:

Wrote library_types.yaml
Traceback (most recent call last):
  File "/collab/usr/gapps/python/build/spack-toss4.2/var/spack/environments/python310/._view/i74j3perqsso644fvgbrjnzhyuvpn42l/lib/python3.10/runpy.py", line 196, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "/collab/usr/gapps/python/build/spack-toss4.2/var/spack/environments/python310/._view/i74j3perqsso644fvgbrjnzhyuvpn42l/lib/python3.10/runpy.py", line 86, in _run_code
    exec(code, run_globals)
  File "/usr/gapps/shroud/public/toss_4_x86_64_ib/bin/shroud-0.13.0/__main__.py", line 3, in <module>
  File "/usr/gapps/shroud/public/toss_4_x86_64_ib/bin/shroud-0.13.0/_bootstrap/__init__.py", line 253, in bootstrap
  File "/usr/gapps/shroud/public/toss_4_x86_64_ib/bin/shroud-0.13.0/_bootstrap/__init__.py", line 38, in run
  File "/g/g16/rhathaw/.shiv/shroud-0.13.0.pyz_acfbdc8350559952ecaebb807395b07c2a838cb4aad878fbbda80f02ad07859b/site-packages/shroud/main.py", line 311, in main
    main_with_args(args)
  File "/g/g16/rhathaw/.shiv/shroud-0.13.0.pyz_acfbdc8350559952ecaebb807395b07c2a838cb4aad878fbbda80f02ad07859b/site-packages/shroud/main.py", line 537, in main_with_args
    wrapp.Wrapp(newlibrary, config, splicers["py"]).wrap_library()
  File "/g/g16/rhathaw/.shiv/shroud-0.13.0.pyz_acfbdc8350559952ecaebb807395b07c2a838cb4aad878fbbda80f02ad07859b/site-packages/shroud/wrapp.py", line 191, in wrap_library
    self.wrap_namespace(newlibrary.wrap_namespace, top=True)
  File "/g/g16/rhathaw/.shiv/shroud-0.13.0.pyz_acfbdc8350559952ecaebb807395b07c2a838cb4aad878fbbda80f02ad07859b/site-packages/shroud/wrapp.py", line 261, in wrap_namespace
    self.wrap_class(cls, modinfo)
  File "/g/g16/rhathaw/.shiv/shroud-0.13.0.pyz_acfbdc8350559952ecaebb807395b07c2a838cb4aad878fbbda80f02ad07859b/site-packages/shroud/wrapp.py", line 453, in wrap_class
    self.wrap_class_variable(node, var, fileinfo)
  File "/g/g16/rhathaw/.shiv/shroud-0.13.0.pyz_acfbdc8350559952ecaebb807395b07c2a838cb4aad878fbbda80f02ad07859b/site-packages/shroud/wrapp.py", line 829, in wrap_class_variable
    .format(stmts0))
NameError: name 'stmts0' is not defined. Did you mean: 'stmts'?

Add examples shroud user projects?

It would be helpful to potential users if shroud had two simple standalone example projects (e.g. with only one or two functions):

  • A cmake (or blt) C++ project that generates Fortran and Python bindings
  • A make-based C++ project that generates Fortran and Python bindings

These could help users understand how to set up shroud within their project.

They could be placed in a new top-level directory, e.g. <shroud>/examples,
described in the user docs and CI tested (e.g. through travis).

string member variable: Error with template

If I try to declare member variable of type string:

library: abc
namespace: abc
cxx_header: abc.hpp

declarations:
- decl: class A
  declarations:
  - decl: string x;

I get:

Error with template: '{cxx_var}{cxx_member}c_str()'

options not read from config file

Hi shroud team!

I was using shroud just now, and expecting this config to generate Python output:

library: abispack
namespace: abispack
cxx_header: include/abispack.h

options:
  wrap_fortran: False
  wrap_c: False
  wrap_python: True
  debug: True

declarations:
- decl: class Libabigail
  declarations:
  - decl: Libabigail()
  - decl: void GetVersion()

The problem is that it didn't - it only made a .f (fortran I think?) file!

# cat abispack.log 
Close wraplibrary.cpp
Close typeslibrary.h
Close wrapflibrary.f

I inspected the client to see that I could add an --option and this seemed to work!

# shroud --option wrap_python=True --option wrap_fortran=False --option wrap_c=False --option debug=True abispack.yml 
Wrote pylibrarymodule.cpp
Wrote pylibrarymodule.hpp
Wrote setup.py

But I'd really like to be able to have these options in my yaml configuration file and just run shroud abigail.yml. Thanks for your help!

Wrapping a const function that returns a pointer

In the references example, there is the following case:

  - decl: double* getArray() +dimension(getSize())

I ran into a problem wrapping the function if it is const, e.g.

  - decl: double* getArray() const +dimension(getSize())

The errors were of the form:

<src>.cpp: error: a value of type "const ArrayWrapper *" cannot be used to initialize an entity of type "ArrayWrapper *"
      ArrayWrapper *obj = static_cast<const ArrayWrapper *>(self->addr);

Could you please add the const versions of these functions, with shroud wrappers?

adding header files to wrapNAME.cpp

With this config:

library: abc
namespace: abc
#cxx_header: a.hpp

declarations:

- decl: class A
  cxx_header: a.hpp
  declarations:
  - decl: A()

- decl: class B
  cxx_header: b.hpp
  declarations:
  - decl: B()

wrapA.cpp has #include "a.hpp" and wrapB.cpp has #include "b.hpp".
wrapabc.cpp which uses both abc::A and abc::B in ABC_SHROUD_memory_destructor doesn't have these includes. I could specify global cxx_header, but can I add more than one header there? Ideally, these headers would be included automatically.

template struct

I'm just starting using shroud. I tried to wrap a templated struct.

First, with class template it works as expected, for example

library: abc
declarations:
- decl: template<typename T> class Abc
  cxx_template:
    - instantiation: <float>

but if I try to use struct instead of class:

library: abc
options:
  wrap_struct_as: class
declarations:
- decl: template<typename T> struct Abc
  cxx_template:
    - instantiation: <float>

shroud gives error (regardless of what wrap_struct_as is set to):

RuntimeError: Parse Error
template<typename T> struct Abc
                     ^
Expected TYPE_SPECIFIER, found STRUCT 'struct'

Is there a workaround?

Thanks for this project, it will save me a lot of work.

Undefined symbol on Python import

Today is my first day using shroud - apologies if I'm hugely missing something!

I've created a yaml configuration file and I've gotten everything to work to run shroud, and install the Python library. But when I get to the moment of truth to import...

In [1]: import abispack
---------------------------------------------------------------------------
ImportError                               Traceback (most recent call last)
<ipython-input-1-3fb25805f954> in <module>
----> 1 import abispack

ImportError: /usr/local/lib/python3.8/dist-packages/abispack-0.0.0-py3.8-linux-x86_64.egg/abispack.cpython-38-x86_64-linux-gnu.so: undefined symbol: _ZN8abispack10Libabigail10GetVersionEv

oh no! Could you point me in the right direction for why the symbol is not defined? You can see all my code here

I noticed issue #39, and if I can figure this out for my own little Python project I could offer to help with a dummy example for here. I also saw that json isn't supported: https://github.com/LLNL/shroud/blob/develop/shroud/main.py#L439. Is this something that would be of interest? That would be fairly easy to add a function to load there.

splicer as YAML multiline text

A feature request.
Splicer code in a list works fine:

splicer_code:
  c:
    CXX_definitions:
      - '// aaa'
      - '// bbb'

It's not super important, but in some cases it'd be slightly more convenient to have it as multiline text.
If I try this:

splicer_code:
  c:
    CXX_definitions: |
      // aaa
      // bbb

I get one character per line

// splicer begin CXX_definitions
/
/
 
a
a
a
...

Function returning string* type

Hello!

First of all: thank you very much for developing shroud!

I am working in a code which needs to access a string pointer. I have managed it to work when the string pointer points to a single string. However, I would like to do it with a string pointer poiting to a array of strings.

Looking the scripts available here I have found one which seems to be what I need:

In strings.yaml : - decl: const std::string *get_str_ptr() +deref(pointer)

However, I am getting an error saying:

Wrote tutorial_types.yaml
Error with template: 'int {c_var_len}' 

and (I bilieve) it is due to +deref(pointer) option.

I will put the scripts to generate the necessary files and run my test example below:

tutorial.yaml

library: Tutorial
format:
  F_filename_suffix: F90
cxx_header: tutorial.hpp

declarations:
- decl: namespace tutorial
  declarations:
  - decl: class Class1  
    declarations:
    - decl: Class1() +name(new)
    - decl: void printvalues()
    - decl: int* get_int_ptr(int *len +intent(out)+hidden) +deref(pointer) +dimension(len)

    ####################### Modify here #######################
    # - decl: const std::string *get_str_ptr() +deref(pointer)
    ###########################################################
    
    - decl: ~Class1() +name(delete)

tutorial.hpp

#ifndef CLASS1_HPP
#define CLASS1_HPP
#include <iostream>
#include<string.h>
using namespace std;

namespace tutorial {

    struct str1{
        int *iptr;
        string *names;
        int str_size;
        int iptr_size;
    };
    typedef struct str1 str1;

    class Class1
    {
    public:
      Class1();

      void printvalues();

      int* get_int_ptr(int *len);

      //////////////// Modify here ////////////////
      const string* get_str_ptr();
      ////////////////////////////////////////////

      ~Class1();

    };

}

#endif // CLASS1_HPP

tutorial.cpp

#include <iostream>
#include "tutorial.hpp"
#include <sstream>

namespace tutorial {
    static str1 s;

    Class1 :: Class1(){
        cout << "Object is being created!" << endl;   
        s.iptr_size = 4;
        s.str_size = 3;

        s.iptr = new int[s.iptr_size];
        s.names = new string[s.str_size];
        
        for(int i = 0; i < s.iptr_size; i++){
            s.iptr[i] = i+123;
        }

        s.names[0] = "test1";
        s.names[1] = "test2";
        s.names[2] = "test3";

    }

    void Class1 :: printvalues(){
        cout << "From printvalues:" << endl;
        for(int i = 0; i < s.iptr_size; i++){
            cout << "   iptr[" << i << "] = " << s.iptr[i] << endl;
        }

        for(int i = 0; i < s.str_size; i++){
            cout << "   names[" << i << "] = " << s.names[i] << endl;
        }
    }

    int* Class1 :: get_int_ptr(int *len){
        *len = s.iptr_size;
        return s.iptr;
    }

    //////////////// Modify here ////////////////
    const string* Class1 :: get_str_ptr(){
        return s.names;
    }
    ////////////////////////////////////////////

    Class1 :: ~Class1(){
        cout << "Object is being deleted!" << endl;
    }


}

test_shroud.F90

program test_shroud
    use iso_c_binding
    use tutorial_tutorial_mod
    type(class1) cptr
    integer, pointer :: iptr_f(:)
    !!!!! Create object
    cptr = Class1() 
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    call class1_printvalues(cptr)

    !!> Getting int* data from C++
    iptr_f => class1_get_int_ptr(cptr)
    !!> Print
    write(*,*) iptr_f

    !!> Want to print array os strings:
    ! write(*,*) class1_get_str_ptr(cptr)

    !!!!! Delete object
    call cptr%delete()
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
end program test_shroud

Makefile

# the compiler: gcc for C program, define as g++ for C++
CC = g++
GF90 = gfortran
LDLIBS  = -lgfortran -lstdc++ 

test_shroud: tutorial.o wraptutorial_Class1.o wrapfTutorial_tutorial.o test_shroud.F90
	$(GF90) tutorial.o wraptutorial_Class1.o wrapfTutorial_tutorial.o test_shroud.F90 -o main $(LDLIBS)

wrapfTutorial_tutorial.o: wraptutorial_Class1.o wrapfTutorial_tutorial.F90
	$(GF90) -c wrapfTutorial_tutorial.F90

wraptutorial_Class1.o: wraptutorial_Class1.cpp tutorial.o
	$(CC) -c wraptutorial_Class1.cpp

tutorial.o: tutorial.cpp
	$(CC) -c tutorial.cpp

I would like to get the pointer to strings as I have got the pointer to integers.

Thank you in advance!

Self-referential structure

Hello,

I am working with a self referential structure, so I have my .yalm file as

library: test
format:
  F_filename_suffix: F90
cxx_header: test.hpp

declarations:
- decl: |
    struct timer_cpp{
      int sublevels;
      timer_cpp *parent;
      timer_cpp **child;
    };
  options:
    literalinclude: True
    F_struct_getter_setter: False

However, the generated wrapper .h file (in this case wraptest.h) contains:

// wraptest.h
// This file is generated by Shroud 0.12.2. Do not edit.
/**
 * \file wraptest.h
 * \brief Shroud generated wrapper for test library
 */
// For C users and C++ implementation

#ifndef WRAPTEST_H
#define WRAPTEST_H

#include "typestest.h"

// splicer begin CXX_declarations
// splicer end CXX_declarations

#ifdef __cplusplus
extern "C" {
#endif


struct s_TES_timer_cpp {
    int sublevels;
    TES_timer_cpp * parent;
    TES_timer_cpp * * child;
};
typedef struct s_TES_timer_cpp TES_timer_cpp;

// splicer begin C_declarations
// splicer end C_declarations

#ifdef __cplusplus
}
#endif

#endif  // WRAPTEST_H

It gives an error while compiling because inside the struct definition it should be s_TES_timer_cpp * parent instead of TES_timer_cpp * parent.

Is there a way of redefining the variable type inside the struct definition, so I can get the missing s_?

Thanks in advance! :)

Pure functions

Hello :)

I am trying to implement a class member function whith the +pure input on shroud, i.e.:

library: Tutorial
format:
  F_filename_suffix: F90
cxx_header: tutorial.hpp

declarations:
- decl: namespace tutorial
  declarations:
  - decl: class Class1
    declarations:
    - decl: Class1() +name(new)
    - decl: ~Class1() +name(delete)
    - decl: int get_intvalue() +pure

By doing this I have the Fortran wrapper containing the prefixe pure for the function in the C interface:

   interface

        [...other functions implemented...]

        pure function c_class1_get_intvalue(self) result(SHT_rv)  bind(C, name="TUT_tutorial_Class1_get_intvalue")
            use iso_c_binding, only : C_INT
            import :: SHROUD_class1_capsule
            implicit none
            type(SHROUD_class1_capsule), intent(IN) :: self
            integer(C_INT) :: SHT_rv
        end function c_class1_get_intvalue

    end interface

But not for the function in the contains block:

    function class1_get_intvalue(obj) &
            result(SHT_rv)
        use iso_c_binding, only : C_INT
        class(class1) :: obj
        integer(C_INT) :: SHT_rv
        ! splicer begin namespace.tutorial.class.Class1.method.get_intvalue
        SHT_rv = c_class1_get_intvalue(obj%cxxmem)
        ! splicer end namespace.tutorial.class.Class1.method.get_intvalue
    end function class1_get_intvalue

I could solve this by changing from this to:

    pure function class1_get_intvalue(obj) &
            result(SHT_rv)
        use iso_c_binding, only : C_INT
        class(class1), intent(in) :: obj
        integer(C_INT) :: SHT_rv
        ! splicer begin namespace.tutorial.class.Class1.method.get_intvalue
        SHT_rv = c_class1_get_intvalue(obj%cxxmem)
        ! splicer end namespace.tutorial.class.Class1.method.get_intvalue
    end function class1_get_intvalue

Is this not supported yet or am I missing something?

Thank you very much!
Felipe Silva Carvalho

new release?

Thanks for developing shroud.
Would you mind tagging a new release and uploading it to PyPI?
There are many improvements since v0.12.2 (and pip install llnl-shroud installs 0.12.1).

options still not being honored

I'm not sure what broke since early this morning, but I'm running the same command, and none of my options are honored - the files are generated in the root directory instead of the subfolder I specified, and all formats are produced (even though I just asked for Python). I just installed fresh from the develop branch. Here is my abispack.yaml file:

library: abispack

# This must be relative to python directory targeted by shroud
cxx_header: ../abispack.hpp

options:
  wrap_fortran: False
  wrap_c: False
  wrap_python: True
  debug: True

declarations:
- decl: namespace abispack
  declarations:
  - decl: class Libabigail
    declarations:
    - decl: int HelloWorld()
    - decl: int Load(std::string path)
    - decl: int GetVersion()
    - decl: int ReadElfCorpus(std::string in_file_path, 
            std::vector<char> prepared_di_root_paths, bool load_all_types = true, 
            bool linux_kernel_mode = false);

And when I run the Makefile command:

# make shroud
cp setup.py _setup.py
shroud abispack.yaml --outdir-python abispack
.yaml

Everything is dumped in the present working directory (for all files types) AND generated in the subfolder. So maybe my options are being honored, but it's generated the default "everything" in the root anyway?

Wrote abispack_types.yaml
Wrote wrapabispack_Libabigail.h
Wrote wrapabispack_Libabigail.cpp
Wrote wrapabispack.cpp
Wrote typesabispack.h
Wrote wrapfabispack_abispack.f
Wrote wrapfabispack.f
Wrote pyabispack_Libabigailtype.cpp
Wrote pyabispack_abispackmodule.cpp
Wrote pyabispackmodule.cpp
Wrote pyabispackutil.cpp
Wrote pyabispackmodule.hpp
Wrote setup.py
cp _setup.py setup.py

I'm guessing this was a bug introduced this morning? Sorry for the noise, this was working at around 5am and isn't anymore.

Support for variadic templates

It seems like variadic templates don't work, it would be good if the following could be used:

        - decl: |
            template <typename strategy, typename... Args>
            Allocator makeAllocator(const std::string& name, Args... args)
          cxx-template:
            - instantiation: <umpire::strategy::DynamicPool, int, int>

Obviously I would expect to have to list all the arguments, but it would be nice if it worked ๐Ÿ˜„

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.