Skip to content

Commit

Permalink
initial commmit with working shared lib build for Node with N API
Browse files Browse the repository at this point in the history
  • Loading branch information
Jens committed Apr 22, 2019
0 parents commit 70b3663
Show file tree
Hide file tree
Showing 17 changed files with 931 additions and 0 deletions.
9 changes: 9 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
root = true

[*.cr]
charset = utf-8
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 2
trim_trailing_whitespace = true
10 changes: 10 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/docs/
/lib/
/bin/
/build
/.shards/
*.dwarf

# Libraries don't need dependency lock
# Dependencies will be locked in applications that use them
/shard.lock
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
language: crystal
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
The MIT License (MIT)

Copyright (c) 2019 Jens Berlips

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
65 changes: 65 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
.POSIX:

CRYSTAL = /usr/local/bin/crystal
CRYSTAL_SRC = /usr/local/Cellar/crystal/0.27.2/src/
CRYSTAL_LIB = /opt/brew/lib
CRFLAGS = --release

CFLAGS := \
'-DNODE_GYP_MODULE_NAME=binding' \
'-DUSING_UV_SHARED=1' \
'-DUSING_V8_SHARED=1' \
'-DV8_DEPRECATION_WARNINGS=1' \
'-D_DARWIN_USE_64_BIT_INODE=1' \
'-D_LARGEFILE_SOURCE' \
'-D_FILE_OFFSET_BITS=64' \
'-DBUILDING_NODE_EXTENSION' \
-Os \
-gdwarf-2 \
-mmacosx-version-min=10.7 \
-arch x86_64 \
-Wall \
-Wendif-labels \
-W \
-Wno-unused-parameter \
-fno-strict-aliasing \
-MMD

CCFLAGS := \
-shared \
-undefined \
dynamic_lookup \
-Wl,-no_pie \
-Wl,-search_paths_first \
-mmacosx-version-min=10.7 \
-arch x86_64 \
-stdlib=libc++ \
-init _crystal_library_init



INCS := \
-I$(HOME)/.node-gyp/11.14.0/include/node \
-I$(HOME)/.node-gyp/11.14.0/src \
-I$(HOME)/.node-gyp/11.14.0/deps/openssl/config \
-I$(HOME)/.node-gyp/11.14.0/deps/openssl/openssl/include \
-I$(HOME)/.node-gyp/11.14.0/deps/uv/include \
-I$(HOME)/.node-gyp/11.14.0/deps/zlib \
-I$(HOME)/.node-gyp/11.14.0/deps/v8/include

PRELUDE=./crystal/prelude.cr
CRYSTAL_PATH = src:$(CRYSTAL_SRC)
LIBS = $(CRYSTAL_SRC)/ext/libcrystal.a -lgc -ldl -levent -lpcre -lpthread -liconv -ljack
LDFLAGS = $(LIBS)

run: clean libjack2.o
c++ $(CCFLAGS) -o build/libjack2.node build/libjack2.o $(LDFLAGS)
node js/index.js

libjack2.o:
$(CRYSTAL) build $(CRFLAGS) --cross-compile --prelude $(PRELUDE) -o build/libjack2 src/libjack2.cr

clean: phony
rm -f libjack2.o *_test bc_flags

phony:
41 changes: 41 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# jack2cr

TODO: Write a description here

## Installation

1. Add the dependency to your `shard.yml`:

```yaml
dependencies:
jack2cr:
github: your-github-user/jack2cr
```
2. Run `shards install`

## Usage

```crystal
require "jack2cr"
```

TODO: Write usage instructions here

## Development

```bin/c2cr -I/usr/local/include/jack jack.h```

TODO: Write development instructions here

## Contributing

1. Fork it (<https://github.com/your-github-user/jack2cr/fork>)
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Add some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create a new Pull Request

## Contributors

- [Jens](https://github.com/your-github-user) - creator and maintainer
4 changes: 4 additions & 0 deletions js/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
//const addon = require('./test.node');
const addon = require('../build/libjack2.node');

addon.hello();
9 changes: 9 additions & 0 deletions shard.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
name: jack2js
version: 0.1.0

authors:
- Jens Berlips <[email protected]>

crystal: 0.27.2

license: MIT
11 changes: 11 additions & 0 deletions spec/jack2cr_spec.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
require "./spec_helper"

describe Jack2 do
# TODO: Write tests

it "works" do
client = Jack2::Client.new
client.register_port("out", Jack2::Client::PORT_OUTPUT)
puts client.ports
end
end
2 changes: 2 additions & 0 deletions spec/spec_helper.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
require "spec"
require "../src/jack2"
71 changes: 71 additions & 0 deletions src/crystal/main.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# @[Link(ldflags: "-")]
require "../libnode"

lib LibCrystalMain
@[Raises]
fun __crystal_main(argc : Int32, argv : UInt8**)
end

module Crystal
@@stdin_is_blocking = false
@@stdout_is_blocking = false
@@stderr_is_blocking = false

def self.main(&block)
puts "GC init"
GC.init

remember_blocking_state

status =
begin
yield
0
rescue ex
1
end

AtExitHandlers.run status
ex.inspect_with_backtrace STDERR if ex
STDOUT.flush
STDERR.flush

restore_blocking_state

status
end

def self.main(argc : Int32, argv : UInt8**)
main do
main_user_code(argc, argv)
end
end

def self.main_user_code(argc : Int32, argv : UInt8**)
LibCrystalMain.__crystal_main(argc, argv)
end

def self.remember_blocking_state
@@stdin_is_blocking = IO::FileDescriptor.fcntl(0, LibC::F_GETFL) & LibC::O_NONBLOCK == 0
@@stdout_is_blocking = IO::FileDescriptor.fcntl(1, LibC::F_GETFL) & LibC::O_NONBLOCK == 0
@@stderr_is_blocking = IO::FileDescriptor.fcntl(2, LibC::F_GETFL) & LibC::O_NONBLOCK == 0
end

def self.restore_blocking_state
STDIN.blocking = @@stdin_is_blocking
STDOUT.blocking = @@stdout_is_blocking
STDERR.blocking = @@stderr_is_blocking
end
end

# Dynamic lib on load function here
# specified in Makefile under
fun crystal_library_init(argc : Int32, argv : UInt8**) : Int32
Crystal.main(argc, argv)
Node::Jack2.setup
0
end
# fun main = crystal_library_init(argc : Int32, argv : UInt8**) : Int32
# puts "INIT2 "
# Crystal.main(argc, argv)
# end
89 changes: 89 additions & 0 deletions src/crystal/prelude.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# Entries to this file should only be ordered if macros are involved -
# macros need to be defined before they are used.
# A first compiler pass gathers all classes and methods, removing the
# requirement to place these in load order.
#
# When adding new files, use alpha-sort when possible. Make sure
# to also add them to `docs_main.cr` if their content need to
# appear in the API docs.

private macro no_win(stmt)
{% unless flag?(:win32) %}
{{stmt}}
{% end %}
end

# This list requires ordered statements
require "lib_c"

require "macros"
require "object"
require "comparable"
{% if flag?(:win32) %}
require "windows_stubs"
{% end %}
require "exception"
require "iterable"
require "iterator"
require "indexable"
require "string"

# Alpha-sorted list
# require "annotations"
require "array"
require "atomic"
require "bool"
require "box"
require "char"
require "char/reader"
require "class"
no_win require "concurrent"
require "./main"
require "deque"
require "dir"
require "enum"
require "enumerable"
require "env"
require "errno"
require "ext"
require "file"
require "float"
require "gc"
require "hash"
no_win require "iconv"
require "int"
require "intrinsics"
require "io"
require "kernel"
require "math/math"
no_win require "mutex"
require "named_tuple"
require "nil"
require "number"
# require "humanize"
# require "path"
require "pointer"
require "pretty_print"
require "primitives"
require "proc"
no_win require "process"
require "raise"
require "random"
require "range"
require "reference"
require "reflect"
require "regex"
require "set"
no_win require "signal"
require "slice"
require "static_array"
require "struct"
require "symbol"
no_win require "system"
no_win require "thread"
require "time"
require "tuple"
require "unicode"
require "union"
require "va_list"
require "value"
40 changes: 40 additions & 0 deletions src/libjack2.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
require "./tools"
require "./libjack2_c"

module Jack2
VERSION = "0.1.0"

class Client
PORT_OUTPUT = Jack2_c::JackPortFlags::JackPortIsOutput

def initialize
status = Jack2_c::JackStatus::JackFailure
@client = Jack2_c.jack_client_open("testclient", Jack2_c::JackOptions::JackNullOption, pointerof(status)) ||
raise "could not create client"
r = Jack2_c.jack_activate(@client)
raise "could not activate: #{r}" if r != 0
end

def finalize
Jack2_c.jack_client_close(@client) if @client
end

def register_port(name, port_type = PORT_OUTPUT)
Jack2_c.jack_port_register(@client, name,
Jack2_c::JACK_DEFAULT_AUDIO_TYPE,
port_type,
0) || raise "could not register port"
end

def client_name
String.new(Jack2_c.jack_get_client_name(@client))
end

def ports
ports_c = Jack2_c.jack_get_ports(@client, "", "", 0)
ports = ports_c.map_ptr_not_null { |a| String.new(a) }
Jack2_c.jack_free(ports_c)
ports
end
end
end
Loading

0 comments on commit 70b3663

Please sign in to comment.