crystal-lang / crystal_lib Goto Github PK
View Code? Open in Web Editor NEWAutomatic binding generator for native libraries in Crystal
Automatic binding generator for native libraries in Crystal
The LLVM example substitutes a command output inside @[Link(ldflags: …)]
, but not inside @[Include(flags: …)]
. Is there a way to do the latter? If not, it would be nice to have it.
Trying to compile it, but have errors:
✓ ~/dev/crystal_lib git:master ➜ make
crystal build src/crystal_lib.cr
Error in /Users/fazibear/dev/crystal_lib/src/crystal_lib.cr:55: instantiating 'Clang::Cursor#declaration?()'
puts "#{cursor.declaration?} #{cursor.spelling} #{cursor.kind} #{cursor.type.spelling}" #{cursor.type.canonical_type.spelling} #{cursor.type.kind} #{cursor.type.canonical_type.kind}"
^~~~~~~~~~~~
in /Users/fazibear/dev/crystal_lib/libs/clang/cursor.cr:45: argument #1 of 'LibClang#is_declaration' must be LibClang::CursorKind, not Int32
LibClang.is_declaration(kind) != 0
^~~~
make: *** [crystal_lib] Error 1
✓ ~/dev/crystal_lib git:master ➜ crystal --version
Crystal 0.5.3 [eac061b] (Thu Nov 6 21:50:52 UTC 2014)
crystal_lib segfaults on AArch64 hardware, because of an infinite loop on clang_visitChildren
with LLVM 3.9 and merely crashes with LLVM 3.8. I haven't investigated to understand why, yet.
I'm trying to generate wrapper for igraph. Here is one case that is missed: when function names are the same when turned into lowercase.
A function name ending with a lowercase D:
fun revolver_ml_d = igraph_revolver_ml_d(graph : T*, niter : IntegerT, kernel : VectorT*, cites : VectorT*, delta : RealT, filter : VectorT*, logprob : RealT*, logmax : RealT*) : LibC::Int
And the function name with a uppercase D:
fun revolver_ml_d = igraph_revolver_ml_D(graph : T*, res : VectorT*, fmin : RealT*, abstol : RealT, reltol : RealT, maxit : LibC::Int, a_fun : VectorT*, VectorT*, Void* -> RealT, d_a_fun : VectorT*, VectorT*, VectorT*, Void* -> Void, filter : VectorT*, fncount : IntegerT*, grcount : IntegerT*) : LibC::Int
Then it gives error when I try to use it, saying you redefined.
Looks like we have a problem:
$ crystal src/main.cr -- examples/lib_git2.cr
Showing last frame. Use --error-trace for full trace.
In src/crystal_lib/lib_body_transformer.cr:56:17
56 | rescue ex : Crystal::CodeError
^
Error: undefined constant Crystal::CodeError
######## This happens when trying to use make, as well:
$ make
crystal build src/main.cr
Showing last frame. Use --error-trace for full trace.
In src/crystal_lib/lib_body_transformer.cr:56:17
56 | rescue ex : Crystal::CodeError
######## This is the error trace:
$ crystal build src/main.cr --error-trace
In src/main.cr:5:20
5 | transformed = node.transform visitor
^--------
Error: instantiating 'Crystal::ASTNode+#transform(CrystalLib::LibTransformer)'
In /usr/share/crystal/src/compiler/crystal/syntax/transformer.cr:7:26
7 | node = transformer.transform self
^--------
Error: instantiating 'CrystalLib::LibTransformer#transform(Crystal::ASTNode+)'
In src/crystal_lib/lib_transformer.cr:21:29
21 | node.body = node.body.transform CrystalLib::LibBodyTransformer.new(nodes)
^--------
Error: instantiating 'Crystal::ASTNode+#transform(CrystalLib::LibBodyTransformer)'
In /usr/share/crystal/src/compiler/crystal/syntax/transformer.cr:7:26
7 | node = transformer.transform self
^--------
Error: instantiating 'CrystalLib::LibBodyTransformer#transform(Crystal::ASTNode+)'
In src/crystal_lib/lib_body_transformer.cr:56:17
56 | rescue ex : Crystal::CodeError
########## I'm using Linux Mint 20 Ulyana on a Intel i7 machine. Crystal is as follows:
$ crystal --version
Crystal 0.35.1 [5999ae29b] (2020-06-19)
LLVM: 8.0.0
Default target: x86_64-unknown-linux-gnu
I stumbled upon some enums in linux libc headers that look like this (I'm trying to automatize Crystal's LibC definitions):
enum {
IPPROTO_IP = 0,
#define IPPROTO_IP IPPROTO_IP
IPPROTO_TCP = 8,
#define IPPROTO_TCP IPPROTO_TCP
};
When trying to extract the constants, CrystalLib will output the following, when I would have expected the actual integers:
IPPROTO_IP = IPPROTO_IP
IPPROTO_TCP = IPPROTO_TCP
I tried to investigate if we could know that the macro definition was inside an enum but to no avail, the visit(cursor)
method first receives the macros then the enum declaration. I can't even export the enum and have constants use its values since the enum is unamed —and this is an internal implementation detail that wouldn't play well with other libc anyway.
(I had difficulty coming up with a good title for this.) Since #8 was fixed, the tool can now successfully parse and generate code for Eina.h which is excellent. The generated code even almost compiles without manual intervention 😀. However, there is one issue with the generated code: It defines the struct X___Data
twice, causing it to fail to compile. The two definitions start here and here respectively.
I have been trying to get the examples to work on mac because I really want to bind a few c libs that are not in crystal. I have been getting these errors. Is this a mac think or is this due to the experimental nature of this?
$ crystal src/main.cr -- examples/lib_curses.cr
Unhandled exception: can't find function refresh (Exception)
from src/crystal_lib/lib_body_transformer.cr:17:5 in 'transform'
from /Users/jack/.anyenv/envs/crenv/versions/0.26.0/src/compiler/crystal/syntax/transformer.cr:7:14 in 'transform'
from /Users/jack/.anyenv/envs/crenv/versions/0.26.0/src/compiler/crystal/syntax/transformer.cr:23:19 in 'transform'
from /Users/jack/.anyenv/envs/crenv/versions/0.26.0/src/compiler/crystal/syntax/transformer.cr:7:14 in 'transform'
from src/crystal_lib/lib_transformer.cr:21:7 in 'transform'
from /Users/jack/.anyenv/envs/crenv/versions/0.26.0/src/compiler/crystal/syntax/transformer.cr:7:14 in 'transform'
from /Users/jack/.anyenv/envs/crenv/versions/0.26.0/src/compiler/crystal/syntax/transformer.cr:23:19 in 'transform'
from /Users/jack/.anyenv/envs/crenv/versions/0.26.0/src/compiler/crystal/syntax/transformer.cr:7:14 in 'transform'
from src/main.cr:5:1 in '__crystal_main'
from /Users/jack/.anyenv/envs/crenv/versions/0.26.0/src/crystal/main.cr:104:5 in 'main_user_code'
from /Users/jack/.anyenv/envs/crenv/versions/0.26.0/src/crystal/main.cr:93:7 in 'main'
from /Users/jack/.anyenv/envs/crenv/versions/0.26.0/src/crystal/main.cr:133:3 in 'main'
When creating binding for igraph,
the crystal_lib generates "alias VaList = LibC::VaList" statement but it says "undefined constant LibC::VaList" when I include the generated content. I have to replace it with: alias VaList = UInt8[24] then it works.
https://github.com/igraph/igraph/search?p=3&q=va_list&utf8=%E2%9C%93
See the generated code: https://github.com/aladagemre/crystal-igraph/blob/0ce58a79bdeab565af3dca6e19bcfbf2285b9b9c/lib_igraph.cr
one comment: va_list is a variable list of arguments. translating it to LibC::VaList is incorrect.
CrystalLib fails to find a function that is hidden behind a macro. For example in FreeBSD the inet_pton
method is defined indirectly, and CrystalLib fails with unknown function "inet_pton"
since it references a Define, not a FunDef:
#define inet_pton __inet_pton
int __inet_pton(int, char*, void*);
Using this input:
@[Include("eina-1/Eina.h", flags: "-I/usr/include/efl-1 -I/usr/include/eina-1 -I/usr/include/eina-1/eina -I /usr/lib/clang/3.7.0/include", prefix: %w(eina_))]
@[Link("eina")]
lib LibEina
end
The following stacktrace is produced:
Unsupported primitive kind: Invalid (Exception)
[4889111] *CallStack::unwind:Array(Pointer(Void)) +87
[4889002] *CallStack#initialize<CallStack>:Array(Pointer(Void)) +10
[4888954] *CallStack::new:CallStack +42
[4895233] *Exception#initialize<Exception, String, Nil>:CallStack +33
[4895169] *Exception::new<String>:Exception +97
[4829670] *raise<String>:NoReturn +6
[5570102] *CrystalLib::TypeMapper#map_internal<CrystalLib::TypeMapper, CrystalLib::PrimitiveType>:Crystal::Path +966
[5568664] *CrystalLib::TypeMapper#map_non_recursive<CrystalLib::TypeMapper, CrystalLib::Type+>:Crystal::ASTNode+ +136
[5573923] *CrystalLib::TypeMapper#map_internal<CrystalLib::TypeMapper, CrystalLib::TypedefType>:Crystal::ASTNode+ +787
[5568837] *CrystalLib::TypeMapper#map_non_recursive<CrystalLib::TypeMapper, CrystalLib::Type+>:Crystal::ASTNode+ +309
[5573923] *CrystalLib::TypeMapper#map_internal<CrystalLib::TypeMapper, CrystalLib::TypedefType>:Crystal::ASTNode+ +787
[5568837] *CrystalLib::TypeMapper#map_non_recursive<CrystalLib::TypeMapper, CrystalLib::Type+>:Crystal::ASTNode+ +309
[5576764] *CrystalLib::TypeMapper#map_internal<CrystalLib::TypeMapper, CrystalLib::FunctionType>:Crystal::Fun +204
[5568888] *CrystalLib::TypeMapper#map_non_recursive<CrystalLib::TypeMapper, CrystalLib::Type+>:Crystal::ASTNode+ +360
[5568494] *CrystalLib::TypeMapper#map<CrystalLib::TypeMapper, CrystalLib::Type+>:Crystal::ASTNode+ +14
[5577836] *CrystalLib::TypeMapper#expand_pending_structs<CrystalLib::TypeMapper>:Nil +412
[5568509] *CrystalLib::TypeMapper#map<CrystalLib::TypeMapper, CrystalLib::Type+>:Crystal::ASTNode+ +29
[5577836] *CrystalLib::TypeMapper#expand_pending_structs<CrystalLib::TypeMapper>:Nil +412
[5568509] *CrystalLib::TypeMapper#map<CrystalLib::TypeMapper, CrystalLib::Type+>:Crystal::ASTNode+ +29
[5586682] *CrystalLib::PrefixImporter#map_type<CrystalLib::PrefixImporter, CrystalLib::Type+>:Crystal::ASTNode+ +10
[5586197] *CrystalLib::PrefixImporter#process<CrystalLib::PrefixImporter, CrystalLib::Function>:Array(Crystal::ASTNode+)? +469
[5584500] *CrystalLib::PrefixImporter::import<Array(CrystalLib::ASTNode+), Array(String)>:Crystal::ASTNode+ +292
[5480048] *CrystalLib::LibTransformer#transform<CrystalLib::LibTransformer, Crystal::LibDef>:Crystal::LibDef +208
[5308496] *Crystal::ASTNode+ +160
[5481660] *CrystalLib::LibTransformer +124
[5308544] *Crystal::ASTNode+ +208
[4829276] ???
[4843120] main +32
[140311053354512] __libc_start_main +240
[4801753] _start +41
[0] ???
I've most likely screwed up in the definition, but just making this issue in case I didn't.
Lib file:
@[Include(
"libssh/ssh2.h",
"libssh/server.h",
"libssh/libssh.h",
"libssh/sftp.h",
"libssh/callbacks.h",
"libssh2.h",
)]
@[Link("ssh2")]
lib LibSSH
end
Trying to generate the headers I get:
/usr/include/unistd.h:229:10: fatal error: 'stddef.h' file not found
@[Link("ssh2")]
lib LibSSH
end
Did I do something wrong ? did I miss something ?
Hello,
I'm trying to port a C/C++ lib that defines enums and types which names is written a CamelCased way (it does not really respects C naming convention).
My problem here: when crystal_lib generates my code, every CamelCased names are Capitalized.
Here is an example:
$ cat /tmp/test.h
typedef enum TSomeEnum
{
TSomeValue,
TSomeOtherValue,
} TSomeEnum;
enum TSomeEnum test();
$ cat test.cr
@[Include("/tmp/test.h", prefix: "test", remove_prefix: false)]
lib LibTest
end
$ crystal src/main.cr -- test.cr
lib LibTest
fun test : Tsomeenum
enum Tsomeenum
Tsomevalue = 0
Tsomeothervalue = 1
end
end
As you can see, the TSomeEnum
type is transformed to Tsomeenum
and TSomeValue
is transformed to Tsomevalue
.
This can be quite confusing when using the crystal lib that was generated this way since constants and types names does not match the C ones (and it's doc).
Is this a desired behavior ? If yes, is there any (easy) way I can make the names being generated in CamelCase ?
Hello,
I was just bitten by the fact that when translating structs, bitfields are not interpreted properly.
(I am using the libgen wrapper but I don't think it matters in this case).
For eg fuse_file_info
struct fuse_file_info {
int flags;
unsigned int writepage : 1;
unsigned int direct_io : 1;
...
}
is translated to
struct fuse_file_info {
flags : LibC::Int
writepage : LibC::UInt
direct_io : LibC::UInt
...
}
And as such, assignment like fi.writepage = 0
may have a lot of side effect, ranging from incorrect value to stack smashing, due to the misalignment of the resulting structure compared to original definition.
I saw that there was a closed discussion on the matter on crystal side #3898.
Currently I am not sure how to address that on my code.
I don't know if it is possible,
but it would be nice at least, if crystal_lib would be able to issue warning or error message when bitfields are encoutered, so that the discovery is not delayed too much...
Or ideally, even if there is no bitfield support in crystal, that a placeholder is put into the structure, so that resulting translation is compatible in term of memory layout.
Env: macOS 10.12.2, LLVM 3.9.1
This test is failing with LLVM 3.9:
crystal_lib/spec/parser_spec.cr
Line 237 in 029bd72
This is a reduced snippet to reproduce the issue:
require "../src/crystal_lib"
require "../src/clang"
include CrystalLib
nodes = Parser.parse("int some_var[];")
var = nodes.last.as(Var)
pp var
When linking against LLVM 3.7, the code above yields:
var # => #<CrystalLib::Var:0x10feca4e0
@name="some_var",
@type=
#<CrystalLib::IncompleteArrayType:0x10feca500
@type=#<CrystalLib::PrimitiveType:0x10ee4dfc0 @kind=Int>>>
Whereas linking against LLVM 3.9, it yields:
var # => #<CrystalLib::Var:0x10327a4a0
@name="some_var",
@type=
#<CrystalLib::ConstantArrayType:0x10327a4c0
@size=1,
@type=#<CrystalLib::PrimitiveType:0x1029bbfc0 @kind=Int>>>
I'll be happy to send in a PR to fix the test, but I'm not sure what's the right way to go. If I fix it for 3.9, it'll fail on 3.7.
I could put the test behind an {% if %}
that checks for the current LLVM version and tests conditionally, but would that make sense? Instead of doing that, I guess it'd make more sense simply to remove the test and trust whatever type the underlying clang version tells us to assign to that expression.
Hello. Thanks for the great tool.
However, the tool seems to fail to parse structs with bit fields.
Please provide support for bit fields.
First I got:
undefined constant Crystal::StructOrUnionDef (did you mean 'Crystal::CStructOrUnionDef')
and once I fixed that, I got:
in ./src/crystal_lib/type_mapper.cr:147: undefined constant Crystal::StructDef
klass = type.kind == :struct ? Crystal::StructDef : Crystal::UnionDef
Running with:
@[Include(
"cassandra.h"
prefix: %w(CASS_ cass_))]
@[Link("cassandra")]
lib LibCassandra
end
Here's the header file for reference: cassandra.h
I just got: "can't parse value of constant O_RDONLY: 00"
I suppose we should transform the value to 0o0
when value starts with a 0
.
typedef struct my_opaque_t my_opaque_t;
void my_func(my_opaque_t *obj);
Generates:
alias MyOpaqueT = Void # first definition of `MyOpaqueT`
fun my_func(obj : MyOpaqueT)
type MyOpaqueT = Pointer(Void) # second definition of `MyOpaqueT`
I've made a little program to test this (bew/crystal_lib - test.cr):
Outputs:
# // typedef different names
# typedef struct my_opaque_struct my_opaque_t;
alias MyOpaqueStruct = Void # note: it should be `MyOpaqueT` ?
# // typedef different name, + func
# typedef struct my_opaque_struct my_opaque_t;
# void my_func(my_opaque_t *obj);
alias MyOpaqueStruct = Void
fun my_func(obj : MyOpaqueT)
type MyOpaqueT = Pointer(Void)
# // typedef same name
# typedef struct my_opaque_t my_opaque_t;
alias MyOpaqueT = Void
# // typedef same name, + func
# typedef struct my_opaque_t my_opaque_t;
# void my_func(my_opaque_t *obj);
alias MyOpaqueT = Void
fun my_func(obj : MyOpaqueT)
type MyOpaqueT = Pointer(Void)
We can see that the typedef
generates the alias
, and the function declaration generates the fun
and the type
.
Looking at the code, I've found that the type
is generated when mapping the function argument: the argument type is parsed as a PointerType to a StructOrUnion
. In the mapping of the pointer, a check is made for an opaque type, succeeds, then creates a new typedef with the same name as the alias
.
I'm not sure how we could properly fix this, as I like the way it auto creates a type
of Pointer(Void)
for opaque types. Maybe we should rename the generated type
and add Ptr
(or _
) at the end, to ensure there's no conflict.
The example would be:
# // typedef same name, + func
# typedef struct my_opaque_t my_opaque_t;
# void my_func(my_opaque_t *obj);
alias MyOpaqueT = Void
fun my_func(obj : MyOpaqueTPtr)
type MyOpaqueTPtr = Pointer(Void)
If so, this should probably be specified... I've spent quite some time trying to get this to work.
make
crystal build src/main.cr
/usr/bin/ld: cannot find -lclang
collect2: error: ld returned 1 exit status
Error: execution of command failed with code: 1: cc -o "/home/tim/source/crystal_lib/main" "${@}" -rdynamic
llvm-config-3.6 --ldflags 2>/dev/null || llvm-config-3.5 --ldflags 2>/dev/null || llvm-config --ldflags 2>/dev/null-lclang -lpcre -lgc -lpthread /opt/crystal/src/ext/libcrystal.a -levent -lrt -ldl -L/usr/lib -L/usr/local/lib
Makefile:2: recipe for target 'crystal_lib' failed
make: *** [crystal_lib] Error 1
First off, this may be a problem with the compiler itself, but other libs work under the same circumstances
Steps to reproduce:
Run Ubuntu 14.04, for example:
vagrant init ubuntu/trusty64
vagrant up
vagrant ssh
curl http://dist.crystal-lang.org/apt/setup.sh | sudo bash
sudo apt-get install -qy build-essential llvm-3.6-dev crystal git
git clone https://github.com/crystal-lang/crystal_lib
cd crystal_lib/
crystal spec
Error:
Error in /opt/crystal/src/compiler/crystal/types.cr:2149: expanding macro
getter link_attributes : Array(LinkAttribute)?
^~~~~~
in macro 'getter' /opt/crystal/src/object.cr:221, line 3:
1.
2.
3. @link_attributes : Array(LinkAttribute) | ::Nil
4.
5.
6.
7. def link_attributes
8. @link_attributes
9. end
10.
11.
@link_attributes : Array(LinkAttribute) | ::Nil
^~~~~~~~~~~~~
undefined constant LinkAttribute
Some other things I tried: https://travis-ci.org/BlaXpirit/crystal-lib/builds
The current implementation does not seems to support enumerated types, is that desired ?
Example:
$ cat <<'EOF' > mylib.h
enum MyEnumeratedType {
MY_FIRST,
MY_SECOND,
MY_THIRD,
};
EOF
$ cat <<'EOF' > mylib.cr
@[Include("./mylib.h", prefix: %w(My MY_))]
lib MyLib
end
EOF
$ crystal src/main.cr -- mylib.cr
input.c:1:10: error: './mylib.h' file not found with <angled> include; use "quotes" instead
lib MyLib
end
Tests has been made with 029bd72 and Crystal 0.20.5 .
The type is generated here:
This occurs on Debian Linux, not sure if LibC::Bool
is missing for that platform in crystal or it's not something defined for any platform
root@86ddba087d31:~/crystal_lib# make crystal_lib
crystal build src/crystal_lib.cr
Error in ./src/crystal_lib/parser.cr:12: undefined constant Clang::TranslationUnit
@tu : Clang::TranslationUnit
^~~~~~~~~~~~~~~~~~~~~~
make: *** [crystal_lib] Error 1
Unexposed enums in struct fields lead to generation of bindings with Void as field's type.
As struct's fields cannot have the Void type, the generated binding is broken.
To reproduce:
$ cat <<'EOF' > /tmp/bug.h
struct st {
int a;
enum { x, y } b;
};
struct st *test();
EOF
$ crystal src/main.cr <<'EOF'
@[Include("/tmp/bug.h", prefix: %w(test))]
lib LibTest
end
EOF
lib LibTest
fun = test : St*
struct St
a : LibC::Int
b : Void
end
end
When trying to use the binding, the following error is thrown at compile time: can't use Void as a struct field type
.
Instead of generating struct stat
, can the bindings use LibC::Stat
?
I tried opening the issue with libgen
. The author suggested I ask here.
typedef struct LCUI_BackgroundPosition {
int using_value;
union {
struct {
char x, y;
};
int value;
};
} LCUI_BackgroundPosition;
Would not compile correctly.
With Crystal 0.20.1 (2016-12-06)
I get
..........EE..E.EEE..E....F.EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
Finished in 543.53 milliseconds
74 examples, 1 failures, 53 errors, 0 pending
I didn't tried with older crystal version, I just discovered this tool and tried to use it !
I also get a lot of /usr/include/stdlib.h:32:10: fatal error: 'stddef.h' file not found
, I'm on :
Linux BB-8 4.8.12-3-ARCH
Thanks
I cannot parse long long (Vector)
with this lib. I think this might be a problem with the Crystal compiler but I dont know
@[Include(
"immintrin.h",
)]
lib Immintrin
end
crystal build src/main.cr --mattr avx
./main examples/lib_simd.cr
Unhandled exception: Don't know how to convert __attribute__((__vector_size__(1 * sizeof(long long)))) long long (Vector) (Exception)
from src/crystal_lib/parser.cr:298:7 in 'type'
from src/crystal_lib/parser.cr:145:5 in 'visit_typedef_declaration'
from src/crystal_lib/parser.cr:80:7 in 'visit'
from src/crystal_lib/parser.cr:39:7 in '->'
from /usr/local/Cellar/crystal/1.2.1/src/primitives.cr:266:3 in '->'
from _ZN5clang8cxcursor13CursorVisitor5VisitE8CXCursorb
from _ZN5clang8cxcursor13CursorVisitor23handleDeclForVisitationEPKNS_4DeclE
from _ZN5clang8cxcursor13CursorVisitor16VisitDeclContextEPNS_11DeclContextE
from _ZN5clang8cxcursor13CursorVisitor13VisitChildrenE8CXCursor
from clang_visitChildren
from lib/clang/src/cursor.cr:36:7 in 'visit_children'
from src/crystal_lib/parser.cr:38:5 in 'parse'
from src/crystal_lib/parser.cr:15:5 in 'parse'
from src/crystal_lib/lib_transformer.cr:18:5 in 'transform'
from /usr/local/Cellar/crystal/1.2.1/src/compiler/crystal/syntax/transformer.cr:7:14 in 'transform'
from /usr/local/Cellar/crystal/1.2.1/src/compiler/crystal/syntax/transformer.cr:23:9 in 'transform'
from /usr/local/Cellar/crystal/1.2.1/src/compiler/crystal/syntax/transformer.cr:7:14 in 'transform'
from src/main.cr:5:1 in '__crystal_main'
from /usr/local/Cellar/crystal/1.2.1/src/crystal/main.cr:110:5 in 'main_user_code'
from /usr/local/Cellar/crystal/1.2.1/src/crystal/main.cr:96:7 in 'main'
from /usr/local/Cellar/crystal/1.2.1/src/crystal/main.cr:119:3 in 'main'
Since clang 3.9 introduced new Elaborated type, leading sturct typedef unbindable.
crystal src/main.cr -- examples/libc.cr
Don't know how to convert struct div_t (119) (Exception) 0x496e37: *CallStack::unwind:Array(Pointer(Void)) at ?? 0x496dca: *CallStack#initialize:Array(Pointer(Void)) at ?? 0x496d9a: *CallStack::new:CallStack at ?? 0x485f0e: *raise:NoReturn at ?? 0x485efe: ??? at ?? 0x59458d: *CrystalLib::Parser#type:CrystalLib::Type+ at ?? 0x5957ce: *CrystalLib::Parser#visit_typedef_declaration:CrystalLib::Typedef at ?? 0x592cc0: *CrystalLib::Parser#visit:(CrystalLib::ASTNode+ | Nil) at ?? 0x49454d: ~procProc(Clang::Cursor, Clang::VisitResult) at ?? 0x4944b0: ~procProc(LibClang::Cursor, LibClang::Cursor, Pointer(Void), Clang::VisitResult) at ?? 0x7f7859fa7f15: ??? at ?? 0x7f7859fa745d: ??? at ?? 0x7f7859fa7582: ??? at ?? 0x7f7859fa7bac: ??? at ?? 0x7f7859fb0704: clang_visitChildren at ?? 0x5975c8: *Clang::Cursor#visit_children<&Proc(Clang::Cursor, Clang::VisitResult)>:UInt32 at ?? 0x592a7e: *CrystalLib::Parser#parse:UInt32 at ?? 0x5927bc: *CrystalLib::Parser::parse:Array(CrystalLib::ASTNode+) at ?? 0x58f6bb: *CrystalLib::LibTransformer#transform:Crystal::LibDef at ?? 0x544715: *Crystal::ASTNode+ at ?? 0x58febb: *CrystalLib::LibTransformer at ?? 0x544745: *Crystal::ASTNode+ at ?? 0x48596d: ??? at ?? 0x492ab9: main at ?? 0x7f7858a75291: __libc_start_main at ?? 0x48513a: _start at ?? 0x0: ??? at ??
For most of examples I get this exception:
Don't know how to convert union __mbstate_t (119) (Exception)
0x106cd57d2: *CallStack::unwind:Array(Pointer(Void)) at ??
0x106cd5771: *CallStack#initialize:Array(Pointer(Void)) at ??
0x106cd5748: *CallStack::new:CallStack at ??
0x106cc3d31: *raise<Exception>:NoReturn at ??
0x106cc3d11: *raise<String>:NoReturn at ??
0x106dce8eb: *CrystalLib::Parser#type<Clang::Type>:CrystalLib::Type+ at ??
0x106dcf951: *CrystalLib::Parser#visit_typedef_declaration<Clang::Cursor>:CrystalLib::Typedef at ??
0x106dcd2ec: *CrystalLib::Parser#visit<Clang::Cursor>:(CrystalLib::ASTNode+ | Nil) at ??
0x106cd3d6a: ~procProc(Clang::Cursor, Clang::VisitResult)@src/crystal_lib/parser.cr:22 at ??
0x106cd3ce7: ~procProc(LibClang::Cursor, LibClang::Cursor, Pointer(Void), Clang::VisitResult)@src/clang/cursor.cr:52 at ??
0x106f7bf0e: _ZN5clang8cxcursor13CursorVisitor5VisitE8CXCursorb at ??
0x106f7d99a: _ZN5clang8cxcursor13CursorVisitor23handleDeclForVisitationEPKNS_4DeclE at ??
0x106f7da43: _ZN5clang8cxcursor13CursorVisitor16VisitDeclContextEPNS_11DeclContextE at ??
0x106f7c8a3: _ZN5clang8cxc0x106f7c8a3: _ZN5clang8cxcursor13CursorVisitor13VisitChildrenE8CXCursor at ??
Unhandled exception in spawn:
end of file reached (IO::EOFError)
0x106cd57d2: *CallStack::unwind:Array(Pointer(Void)) at ??
0x106cd5771: *CallStack#initialize:Array(Pointer(Void)) at ??
0x106cd5748: *CallStack::new:CallStack at ??
0x106cd1cc1: *raise<IO::EOFError>:NoReturn at ??
0x106cfa1d3: *IO::FileDescriptor+@IO#read_fully<Slice(UInt8)>:Int32 at ??
0x106d034cf: *IO::ByteFormat::LittleEndian::decode<Int32:Class, IO::FileDescriptor+>:Int32 at ??
0x106ceef72: *Int32@Int::from_io<IO::FileDescriptor+, IO::ByteFormat::LittleEndian:Module>:Int32 at ??
0x106cfc572: *IO::FileDescriptor+@IO#read_bytes<Int32:Class>:Int32 at ??
0x106d118c5: *Event::SignalHandler#run:NoReturn at ??
0x106cd209c: ~procProc(Nil)@/usr/local/Cellar/crystal-lang/0.20.5_2/src/event/signal_handler.cr:93 at ??
0x106cdf794: *Fiber#run:(IO::FileDescriptor | Nil) at ??
0x106cd2089: ~proc2Proc(Fiber, (IO::FileDescriptor | Nil))@/usr/local/Cellar/crystal-lang/0.20.5_2/src/fiber.cr:29 at ??
ber, (IO::FileDescriptor | Nil))@/usr/local/Cellar/c0x106f86ad6: clang_visitChildren at ??
0x106dd157f: *Clang::Cursor#visit_children<&Proc(Clang::Cursor, Clang::VisitResult)>:UInt32 at ??
0x106dcd12f: *CrystalLib::Parser#parse:UInt32 at ??
0x106dcce9a: *CrystalLib::Parser::parse<String, Array(String)>:Array(CrystalLib::ASTNode+) at ??
0x106dc9f4c: *CrystalLib::LibTransformer#transform<Crystal::LibDef>:Crystal::LibDef at ??
0x106d7b33f: *Crystal::ASTNode+@Crystal::ASTNode#transform<CrystalLib::LibTransformer>:Crystal::ASTNode+ at ??
0x106dca810: *CrystalLib::LibTransformer@Crystal::Transformer#transform<Crystal::Expressions>:Crystal::ASTNode+ at ??
0x106d7b36c: *Crystal::ASTNode+@Crystal::ASTNode#transform<CrystalLib::LibTransformer>:Crystal::ASTNode+ at ??
0x106cc38c4: __crystal_main at ??
0x106cd22c8: main at ??
I'm getting this error trying to generate the examples.
I have libllvm3.6v5 and libllvm3.6-dbg packages installed.
I also have llvm 3.8 installed.
I'm not sure how this linking works.
> crystal src/main.cr -- examples/lib_git2.cr
/usr/bin/ld: /opt/crystal/embedded/lib/../lib/libgc.a(os_dep.o): undefined reference to symbol '_end'
//usr/lib/x86_64-linux-gnu/libLLVM-3.6.so.1: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
Error: execution of command failed with code: 1: `cc -o "/home/zac/.cache/crystal/crystal-run-main.tmp" "${@}" -rdynamic -L/usr/lib -L/usr/local/lib `llvm-config-3.6 --ldflags 2>/dev/null || llvm-config-3.5 --ldflags 2>/dev/null || llvm-config --ldflags 2>/dev/null` -lclang -lpcre -lgc -lpthread /opt/crystal/src/ext/libcrystal.a -levent -lrt -ldl`
Some version info:
> llvm-config-3.6 --version
3.6.2
> llvm-config --version
3.8.0
> crystal -v
Crystal 0.18.0 [25b7925] (2016-06-14)
> cat /proc/version
Linux version 4.4.0-24-generic (buildd@lgw01-12) (gcc version 5.3.1 20160413 (Ubuntu 5.3.1-14ubuntu2.1) ) #43-Ubuntu SMP Wed Jun 8 19:27:37 UTC 2016
> cat /etc/issue
Ubuntu 16.04 LTS \n \l
Crystal 0.21.0 [c2c2276ec] (2017-02-23)
crystal src/main.cr :(
Invalid memory access (signal 11) at address 0x0
[94640267773469] __crystal_sigfault_handler +61
[140254629044352] ???
[140254606926918] strlen +38
[94640283501998] ???
[94640283521243] ???
[94640283835563] ???
[94640283898265] ???
[94640283669712] ???
[94640283890829] ???
[94640283669712] ???
[94640283809539] ???
[94640283835540] ???
[94640283898265] ???
[94640283669712] ???
[94640283849580] ???
[94640283672155] ???
[94640283670648] ???
[94640283809539] ???
[94640283835540] ???
[94640283898265] ???
[94640283669712] ???
[94640283849580] ???
[94640283672155] ???
[94640283670648] ???
[94640283809539] ???
[94640283835540] ???
[94640283898265] ???
[94640283669712] ???
[94640283697939] ???
[94640283670648] ???
[94640283809539] ???
[94640283835540] ???
[94640283898265] ???
[94640283669712] ???
[94640283849580] ???
[94640283672155] ???
[94640283670648] ???
[94640283809539] ???
[94640283686823] ???
[94640283892600] ???
[94640283669712] ???
[94640283809539] ???
[94640283835540] ???
[94640283898265] ???
[94640283669712] ???
[94640283670648] ???
[94640283809539] ???
[94640283835540] ???
[94640283898265] ???
[94640283669712] ???
[94640283849580] ???
[94640283672155] ???
[94640283670648] ???
[94640283809539] ???
[94640283835540] ???
[94640283898265] ???
[94640283887507] ???
[94640283669712] ???
[94640283849580] ???
[94640283672155] ???
[94640283670648] ???
[94640283809539] ???
[94640283835540] ???
[94640283898265] ???
[94640283669712] ???
[94640283849580] ???
[94640283672155] ???
[94640283670648] ???
[94640283243661] ???
[94640292248181] ???
[94640292924265] ???
[94640268009197] ???
[94640267771725] main +18877
[140254606533265] __libc_start_main +241
[94640267608026] _start +42
[0] ???
When generating binding for igraph see
typedef struct igraph_s {
igraph_integer_t n;
igraph_bool_t directed;
igraph_vector_t from;
igraph_vector_t to;
igraph_vector_t oi;
igraph_vector_t ii;
igraph_vector_t os;
igraph_vector_t is;
void *attr;
} igraph_t;
This code is translated into
struct S
n : IntegerT
directed : BoolT
from : VectorT
to : VectorT
oi : VectorT
ii : VectorT
os : VectorT
is : VectorT
attr : Void*
end
type T = S
And then uses T* whenever functions indeed expect S_. When we replace all T_ with S*, the code works.
@watzon just found a bug while trying to compile a binding for OpenSSL's PKCS7
library (see olbat/libgen#48).
The bug can be reproduced using the following code (assuming that OpenSSL's
headers are available):
$ crystal src/main.cr <<'EOF'
@[Include("openssl/pkcs7.h", prefix: %w(PKCS7_))]
lib LibPKCS7
end
EOF
Unhandled exception: Couldn't import type: PKCS7_SIGNED (Exception)
from src/crystal_lib/type_mapper.cr:190:5 in 'map_internal'
from src/crystal_lib/type_mapper.cr:0:36 in 'map_non_recursive'
from src/crystal_lib/type_mapper.cr:72:18 in 'map_internal'
from src/crystal_lib/type_mapper.cr:34:36 in 'map_non_recursive'
from src/crystal_lib/type_mapper.cr:30:5 in 'map'
from src/crystal_lib/type_mapper.cr:250:77 in 'expand_pending_structs'
from src/crystal_lib/type_mapper.cr:30:35 in 'map'
from src/crystal_lib/type_mapper.cr:250:77 in 'expand_pending_structs'
from src/crystal_lib/type_mapper.cr:30:35 in 'map'
from src/crystal_lib/prefix_importer.cr:102:5 in 'map_type'
from src/crystal_lib/prefix_importer.cr:46:101 in 'process'
from src/crystal_lib/prefix_importer.cr:5:7 in 'import'
from src/crystal_lib/lib_transformer.cr:24:19 in 'transform'
from /usr/lib/crystal/compiler/crystal/syntax/transformer.cr:7:14 in 'transform'
from /usr/lib/crystal/compiler/crystal/syntax/transformer.cr:23:9 in 'transform'
from /usr/lib/crystal/compiler/crystal/syntax/transformer.cr:7:14 in 'transform'
from src/main.cr:5:1 in '__crystal_main'
from /usr/lib/crystal/crystal/main.cr:97:5 in 'main_user_code'
from /usr/lib/crystal/crystal/main.cr:86:7 in 'main'
from /usr/lib/crystal/crystal/main.cr:106:3 in 'main'
from __libc_start_main
from _start
from ???
After a bit of testing, I came up with a simple example to reproduce the bug:
$ cat <<'EOF' > /tmp/bug.h
typedef struct first_st {
struct second_st *second;
} FIRST_ST;
struct second_st {
FIRST_ST *first;
};
struct second_st * test_function();
EOF
$ crystal src/main.cr <<'EOF'
@[Include("/tmp/bug.h", prefix: %w(test_))]
lib LibTest
end
EOF
Unhandled exception: Couldn't import type: FIRST_ST (Exception)
from src/crystal_lib/type_mapper.cr:190:5 in 'map_internal'
from src/crystal_lib/type_mapper.cr:0:36 in 'map_non_recursive'
from src/crystal_lib/type_mapper.cr:72:18 in 'map_internal'
from src/crystal_lib/type_mapper.cr:34:36 in 'map_non_recursive'
from src/crystal_lib/type_mapper.cr:30:5 in 'map'
from src/crystal_lib/type_mapper.cr:250:77 in 'expand_pending_structs'
from src/crystal_lib/type_mapper.cr:30:35 in 'map'
from src/crystal_lib/prefix_importer.cr:102:5 in 'map_type'
from src/crystal_lib/prefix_importer.cr:48:5 in 'process'
from src/crystal_lib/prefix_importer.cr:5:7 in 'import'
from src/crystal_lib/lib_transformer.cr:24:19 in 'transform'
from /usr/lib/crystal/compiler/crystal/syntax/transformer.cr:7:14 in 'transform'
from /usr/lib/crystal/compiler/crystal/syntax/transformer.cr:23:9 in 'transform'
from /usr/lib/crystal/compiler/crystal/syntax/transformer.cr:7:14 in 'transform'
from src/main.cr:5:1 in '__crystal_main'
from /usr/lib/crystal/crystal/main.cr:97:5 in 'main_user_code'
from /usr/lib/crystal/crystal/main.cr:86:7 in 'main'
from /usr/lib/crystal/crystal/main.cr:106:3 in 'main'
from __libc_start_main
from _start
from ???
Problem seems to occur with circular struct dependencies that also uses type definitions (without the typedef everything is working fine).
My guess is that second_st is expanded too early (I didn't look at the code yet).
The lib does not compile anymore with Crystal 0.28 (more details, see olbat/libgen#33):
...
in lib/crystal_lib/src/clang.cr:1: while requiring "./clang/*"
require "./clang/*"
^
in lib/crystal_lib/src/clang/index.cr:2: while requiring "compiler/crystal/config"
require "compiler/crystal/config"
^
in /usr/lib/crystal/compiler/crystal/config.cr:37: undefined constant Crystal::Codegen::Target
@@default_target : Crystal::Codegen::Target?
The issue seems to be present with every LLVM versions and platforms I've tested (see
https://travis-ci.org/olbat/libgen/builds/523117414) [the macOS builds did not fail because they were still using Crystal 0.27].
I suspect crystal-lang/crystal#7282 to be related to this issue, I'm still trying to find out how.
There is need to import bitwise flag definitions: https://github.com/bitcoin-core/secp256k1/blob/01b819a8c7d485fdd3f024d77273f5769d75b2d3/include/secp256k1.h#L191-L214
Currently, any expressions are ignored:
Given examples/libuv.cr
:
@[Include("uv.h", prefix: %w(uv_))]
@[Link("uv")]
lib LibUV
end
$ crystal src/main.cr -- examples/lib
Unhandled exception: Couldn't import type: uv__io_t (Exception)
from src/crystal_lib/type_mapper.cr:190:5 in 'map_internal'
from src/crystal_lib/type_mapper.cr:34:36 in 'map_non_recursive'
from src/crystal_lib/type_mapper.cr:72:5 in 'map_internal'
from src/crystal_lib/type_mapper.cr:34:36 in 'map_non_recursive'
from src/crystal_lib/type_mapper.cr:72:5 in 'map_internal'
from src/crystal_lib/type_mapper.cr:34:36 in 'map_non_recursive'
from src/crystal_lib/type_mapper.cr:30:35 in 'map'
from src/crystal_lib/type_mapper.cr:250:15 in 'expand_pending_structs'
from src/crystal_lib/type_mapper.cr:30:35 in 'map'
from src/crystal_lib/type_mapper.cr:250:15 in 'expand_pending_structs'
from src/crystal_lib/type_mapper.cr:30:35 in 'map'
from src/crystal_lib/prefix_importer.cr:75:5 in 'process'
from src/crystal_lib/prefix_importer.cr:5:7 in 'import'
from src/crystal_lib/lib_transformer.cr:24:7 in 'transform'
from /usr/share/crystal/src/compiler/crystal/syntax/transformer.cr:7:14 in 'transform'
from /usr/share/crystal/src/compiler/crystal/syntax/transformer.cr:23:19 in 'transform'
from /usr/share/crystal/src/compiler/crystal/syntax/transformer.cr:7:14 in 'transform'
from src/main.cr:5:1 in '__crystal_main'
from /usr/share/crystal/src/crystal/main.cr:97:5 in 'main_user_code'
from /usr/share/crystal/src/crystal/main.cr:86:7 in 'main'
from /usr/share/crystal/src/crystal/main.cr:106:3 in 'main'
from __libc_start_main
from _start
from ???
I failed to convert a C header with a reference to limits.h
, because it eventually #include_next
the compiler's own limits.h
which can't be found.
I think crystal_lib
should add this folder automatically to it's search path. The default place, as per the clang tooling documentation, is $(dirname $(which clang-3.5))/../lib/clang/3.5/include
but different Linux distributions are putting them in different locations. See https://github.com/Rip-Rip/clang_complete/blob/master/plugin/libclang.py#L28 for example.
I'm on macOS High Sierra and tried both
make
and
LLVM_CONFIG=/usr/local/Cellar/llvm/6.0.1/bin/llvm-config make
(and also tried llvm 5), but I get
type_mapper.cr:128: no overload matches 'Crystal::Alias.new' with types String, Crystal::Path
I'll see if I can fix, but I may not have cycles until later.
This example gives no output during conversion:
typedef enum MyEnum {
MyA = 0, MyB = 1, MyC = 2
} MyEnum;
Error:
ubuntu@ubuntu-xenial:/d/github/crystal_lib$ crystal run src/main.cr -- examples/lib_git2.cr
/usr/bin/ld: /opt/crystal/embedded/lib/../lib/libgc.a(os_dep.o): undefined reference to symbol '_end'
//usr/lib/x86_64-linux-gnu/libLLVM-3.5.so.1: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
Error: execution of command failed with code: 1: `cc -o "/home/ubuntu/.cache/crystal/crystal-run-main.tmp" "${@}" -rdyn
amic `llvm-config-3.6 --ldflags 2>/dev/null || llvm-config-3.5 --ldflags 2>/dev/null || llvm-config --ldflags 2>/dev/nu
ll` -lclang -lpcre -lgc -lpthread /opt/crystal/src/ext/libcrystal.a -levent -lrt -ldl -L/usr/lib -L/usr/local/lib`
I installed the required libaries that I found in the travis file and I have the latest crystal version that is released for ubuntu.
Any ideas i have LLVM 3.6 and Clang installed
root@86ddba087d31:/crystal_lib# make/crystal_lib# dpkg -l | grep llvm
crystal build src/main.cr
/opt/crystal/src/llvm/ext/llvm_ext.o: In function LLVMNewDIBuilder': llvm_ext.cc:(.text.LLVMNewDIBuilder+0x25): undefined reference to
llvm::DIBuilder::DIBuilder(llvm::Module&)'
/opt/crystal/src/llvm/ext/llvm_ext.o: In function LLVMDIBuilderCreateLexicalBlock': llvm_ext.cc:(.text.LLVMDIBuilderCreateLexicalBlock+0x8): undefined reference to
llvm::DIBuilder::createLexicalBlock(llvm::DIDescriptor, llvm::DIFile, unsigned int, unsigned int, unsigned int)'
/opt/crystal/src/llvm/ext/llvm_ext.o: In function LLVMDIBuilderGetOrCreateTypeArray': llvm_ext.cc:(.text.LLVMDIBuilderGetOrCreateTypeArray+0x5): undefined reference to
llvm::DIBuilder::getOrCreateArray(llvm::ArrayRefllvm::Value*)'
/opt/crystal/src/llvm/ext/llvm_ext.o: In function LLVMDIBuilderGetOrCreateArray': llvm_ext.cc:(.text.LLVMDIBuilderGetOrCreateArray+0x5): undefined reference to
llvm::DIBuilder::getOrCreateArray(llvm::ArrayRefllvm::Value*)'
/opt/crystal/src/llvm/ext/llvm_ext.o: In function LLVMDIBuilderCreateSubroutineType': llvm_ext.cc:(.text.LLVMDIBuilderCreateSubroutineType+0x7): undefined reference to
llvm::DIBuilder::createSubroutineType(llvm::DIFile, llvm::DIArray, unsigned int)'
/opt/crystal/src/llvm/ext/llvm_ext.o: In function LLVMDIBuilderCreateLocalVariable': llvm_ext.cc:(.text.LLVMDIBuilderCreateLocalVariable+0x59): undefined reference to
llvm::DIRefllvm::DIType::DIRef(llvm::Value const_)'
/opt/crystal/src/llvm/ext/llvm_ext.o: In function LLVMDIBuilderInsertDeclareAtEnd': llvm_ext.cc:(.text.LLVMDIBuilderInsertDeclareAtEnd+0x8): undefined reference to
llvm::DIBuilder::insertDeclare(llvm::Value_, llvm::DIVariable, llvm::BasicBlock_)'
/opt/crystal/src/llvm/ext/llvm_ext.o: In function LLVMDIBuilderCreateEnumerationType': llvm_ext.cc:(.text.LLVMDIBuilderCreateEnumerationType+0x8f): undefined reference to
llvm::DIBuilder::createEnumerationType(llvm::DIDescriptor, llvm::StringRef, llvm::DIFile, unsigned int, unsigned long, unsigned long, llvm::DIArray, llvm::DIType, llvm::StringRef)'
/opt/crystal/src/llvm/ext/llvm_ext.o: In function LLVMDIBuilderCreateStructType': llvm_ext.cc:(.text.LLVMDIBuilderCreateStructType+0xab): undefined reference to
llvm::DIBuilder::createStructType(llvm::DIDescriptor, llvm::StringRef, llvm::DIFile, unsigned int, unsigned long, unsigned long, unsigned int, llvm::DIType, llvm::DIArray, unsigned int, llvm::DIType, llvm::StringRef)'
/opt/crystal/src/llvm/ext/llvm_ext.o: In function LLVMTemporaryMDNode': llvm_ext.cc:(.text.LLVMTemporaryMDNode+0x7): undefined reference to
llvm::MDNode::getTemporary(llvm::LLVMContext&, llvm::ArrayRefllvm::Value_)'
collect2: error: ld returned 1 exit status
Error: execution of command failed with code: 1: cc -o "/root/crystal_lib/main" "${@}" -rdynamic -lz -lssl -lcrypto /opt/crystal/src/llvm/ext/llvm_ext.o
(llvm-config-3.6 --libs --system-libs --ldflags 2> /dev/null) || (llvm-config-3.5 --libs --system-libs --ldflags 2> /dev/null) || (llvm-config --libs --system-libs --ldflags 2>/dev/null)-lstdc++
llvm-config-3.6 --ldflags 2>/dev/null || llvm-config-3.5 --ldflags 2>/dev/null || llvm-config --ldflags 2>/dev/null-lclang /opt/crystal/src/ext/libcrystal.a -levent -lrt -lpcre -lm -lgc -lpthread -ldl
make: *** [crystal_lib] Error 1
root@86ddba087d31:
ii libllvm3.6:amd64 1:3.6-2ubuntu1trusty1 amd64 Modular compiler and toolchain technologies, runtime librarytrusty1 amd64 Modular compiler and toolchain technologies
ii llvm-3.6 1:3.6-2ubuntu1
ii llvm-3.6-dev 1:3.6-2ubuntu1trusty1 amd64 Modular compiler and toolchain technologies, libraries and headerstrusty1 amd64 Modular compiler and toolchain technologies, IR interpreter
ii llvm-3.6-runtime 1:3.6-2ubuntu1
root@86ddba087d31:/crystal_lib# dpkg -l | grep clangtrusty1 amd64 clang library - Development package
ii libclang-3.6-dev 1:3.6-2ubuntu1
ii libclang-common-3.6-dev 1:3.6-2ubuntu1trusty1 amd64 clang library - Common development packagetrusty1 amd64 C interface to the clang library
ii libclang1-3.6:amd64 1:3.6-2ubuntu1
root@86ddba087d31:/crystal_lib# crystal --version/crystal_lib#
Crystal 0.15.0 [0f62400](Fri Apr 1 17:04:54 UTC 2016)
root@86ddba087d31:
/usr/include/time.h:37:11: fatal error: 'stddef.h' file not found
Don't know how to convert struct __fsid_t (119) (Exception)
Here is my quite working tool for generating C bindings in Crystal
Written in ruby, based on gen_ffi gem.
https://github.com/fazibear/crystal_lib_gen
Hope you like it :)
Hello,
I'm trying to port a library that uses a va_list
type (from stdargs.h) using crystal_lib.
The problem is that it generates an alias to LibC::VaList
that doesn't seems to exists in any of crystal's lib C bindings so I get an undefined constant LibC::VaList
at compile time.
Example:
$ cat /tmp/test.h
#include <stdarg.h>
void test(va_list vl);
$ cat test.cr
require "lib_c"
@[Include("/tmp/test.h", prefix: "test", remove_prefix: false)]
lib LibTest
end
$ crystal src/main.cr -- test.cr
require "lib_c"
lib LibTest
fun test(vl : VaList)
alias X__GnucVaList = LibC::VaList
alias VaList = X__GnucVaList
end
Am I doing something wrong ?
I've tried version 16, 17.4, 18.0 and get the same error.
I get this error with all the examples.
Running with this command:
crystal src/main.cr -- examples/lib_curses.cr
Gives these results:
Error in ./src/main.cr:6: instantiating 'Crystal::ASTNode+#transform(CrystalLib::LibTransformer)'
transformed = node.transform visitor
^~~~~~~~~
in /opt/crystal/src/compiler/crystal/syntax/transformer.cr:7: instantiating 'CrystalLib::LibTransformer#transform(Crystal::ASTNode+)'
node = transformer.transform self
^~~~~~~~~
in ./src/crystal_lib/lib_transformer.cr:17: instantiating 'process_includes()'
headers, flags, prefixes, remove_prefix = process_includes
^~~~~~~~~~~~~~~~
in ./src/crystal_lib/lib_transformer.cr:36: instantiating 'Array(Crystal::Attribute)#each()'
@includes.each do |attr|
^~~~
in /opt/crystal/src/array.cr:813: instantiating 'each_index()'
each_index do |i|
^~~~~~~~~~
in /opt/crystal/src/array.cr:813: instantiating 'each_index()'
each_index do |i|
^~~~~~~~~~
in ./src/crystal_lib/lib_transformer.cr:36: instantiating 'Array(Crystal::Attribute)#each()'
@includes.each do |attr|
^~~~
in ./src/crystal_lib/lib_transformer.cr:37: instantiating 'Array(Crystal::ASTNode+)#each()'
attr.args.each do |arg|
^~~~
in /opt/crystal/src/array.cr:813: instantiating 'each_index()'
each_index do |i|
^~~~~~~~~~
in /opt/crystal/src/array.cr:813: instantiating 'each_index()'
each_index do |i|
^~~~~~~~~~
in ./src/crystal_lib/lib_transformer.cr:37: instantiating 'Array(Crystal::ASTNode+)#each()'
attr.args.each do |arg|
^~~~
in ./src/crystal_lib/lib_transformer.cr:42: undefined method 'raise' for Crystal::Nop (compile-time type is Crystal::ASTNode+)
arg.raise "Include attribute value must be a string literal"
^~~~~
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.