use the WAF build system
authorRyan <ry@tinyclouds.org>
Sat, 4 Apr 2009 12:50:15 +0000 (14:50 +0200)
committerRyan <ry@tinyclouds.org>
Sat, 4 Apr 2009 12:50:15 +0000 (14:50 +0200)
14 files changed:
Makefile [deleted file]
deps/libeio/wscript [new file with mode: 0644]
deps/libev/wscript [new file with mode: 0644]
ragel.py [new file with mode: 0644]
src/node.cc [moved from node.cc with 99% similarity]
src/node.h [moved from node.h with 87% similarity]
src/node_http.cc [moved from node_http.cc with 98% similarity]
src/node_http.h [moved from node_http.h with 100% similarity]
src/node_tcp.cc [moved from node_tcp.cc with 96% similarity]
src/node_tcp.h [moved from node_tcp.h with 100% similarity]
src/node_timer.cc [moved from node_timer.cc with 100% similarity]
src/node_timer.h [moved from node_timer.h with 100% similarity]
waf [new file with mode: 0755]
wscript [new file with mode: 0644]

diff --git a/Makefile b/Makefile
deleted file mode 100644 (file)
index 0168a18..0000000
--- a/Makefile
+++ /dev/null
@@ -1,55 +0,0 @@
-EVDIR=$(HOME)/local/libev
-
-OIINC = $(HOME)/projects/oi/
-OILIB = $(HOME)/projects/oi/liboi.a
-
-V8INC = $(HOME)/src/v8/include
-#V8LIB = $(HOME)/src/v8/libv8_g.a
-V8LIB = $(HOME)/src/v8/libv8.a
-
-CFLAGS = -g -I$(V8INC) -I$(OIINC) -DHAVE_GNUTLS=0 -Ideps/ebb 
-LDFLAGS = -lev -pthread # -lefence
-
-ifdef EVDIR
-       CFLAGS += -I$(EVDIR)/include
-       LDFLAGS += -L$(EVDIR)/lib
-endif
-
-node: node.o node_tcp.o node_http.o node_timer.o ebb_request_parser.o
-       g++ -o node $^ $(LDFLAGS) $(V8LIB) $(OILIB)
-
-node.o: node.cc 
-       g++ $(CFLAGS) -c $<
-
-node_tcp.o: node_tcp.cc 
-       g++ $(CFLAGS) -c $<
-
-node_http.o: node_http.cc 
-       g++ $(CFLAGS) -c $<
-       
-node_timer.o: node_timer.cc 
-       g++ $(CFLAGS) -c $<
-       
-ebb_request_parser.o: ebb_request_parser.c deps/ebb/ebb_request_parser.h 
-       g++ $(CFLAGS) -c $<
-
-ebb_request_parser.c: deps/ebb/ebb_request_parser.rl
-       ragel -s -G2 $< -o $@
-
-PASS="\033[1;32mPASS\033[0m\n" 
-FAIL="\033[1;31mFAIL\033[0m\n" 
-
-test: node test/test_*
-       @for i in test/test_*; do \
-               if [ -x $$i ]; then \
-                       echo "\n\033[1m$$i\033[0m";     \
-                       ./$$i && echo $(PASS) || echo $(FAIL); \
-               fi \
-       done 
-
-clean:
-       rm -f ebb_request_parser.c
-       rm -f *.o 
-       rm -f node
-
-.PHONY: clean test
diff --git a/deps/libeio/wscript b/deps/libeio/wscript
new file mode 100644 (file)
index 0000000..0390d7c
--- /dev/null
@@ -0,0 +1,120 @@
+import Options
+
+def set_options(opt):
+  pass
+  #opt.tool_options('compiler_cc')
+
+def configure(conf):
+  print "--- libeio ---"
+  #conf.check_tool('compiler_cc')
+
+  conf.check_cc(lib="pthread", header_name="pthread.h", function_name="pthread_create", mandatory=True)
+
+  platform_string = "__" + Options.platform
+  if Options.platform == "linux2":
+    platform_string = "__linux"
+  conf.define(platform_string, 1)
+
+  conf.check_cc(msg="Checking for futimes(2)", define_name="HAVE_FUTIMES", fragment="""
+    #include <sys/types.h>
+    #include <sys/time.h>
+    #include <utime.h>
+    struct timeval tv[2];
+    int res;
+    int fd;
+    int main(void)
+    {
+       res = futimes (fd, tv);
+       return 0;
+    }
+  """)
+
+  conf.check_cc(msg="Checking for readahead(2)", define_name="HAVE_READAHEAD", fragment="""
+    #include <fcntl.h>
+    int main(void)
+    {
+       int fd = 0;
+       size_t count = 2;
+       ssize_t res;
+       res = readahead (fd, 0, count);
+       return 0;
+    }
+  """)
+
+  conf.check_cc(msg="Checking for fdatasync(2)", define_name="HAVE_FDATASYNC", fragment="""
+    #include <unistd.h>
+    int main(void)
+    {
+       int fd = 0;
+       fdatasync (fd);
+       return 0;
+    }
+  """)
+
+  conf.check_cc(msg="Checking for pread(2) and pwrite(2)", define_name="HAVE_PREADWRITE", fragment="""
+    #include <unistd.h>
+    int main(void)
+    {
+       int fd = 0;
+       size_t count = 1;
+       char buf;
+       off_t offset = 1;
+       ssize_t res;
+       res = pread (fd, &buf, count, offset);
+       res = pwrite (fd, &buf, count, offset);
+       return 0;
+    }
+  """)
+
+  conf.check_cc(msg="Checking for sendfile(2)" , defines=[platform_string + "=1"] , define_name="HAVE_SENDFILE" , fragment=""" 
+    # include <sys/types.h>
+    #if __linux
+    # include <sys/sendfile.h>
+    #elif __freebsd
+    # include <sys/socket.h>
+    # include <sys/uio.h>
+    #elif __hpux
+    # include <sys/socket.h>
+    #else
+    # error unsupported architecture
+    #endif
+    int main(void)
+    {
+       int fd = 0;
+       off_t offset = 1;
+       size_t count = 2;
+       ssize_t res;
+    #if __linux
+       res = sendfile (fd, fd, offset, count);
+    #elif __freebsd
+       res = sendfile (fd, fd, offset, count, 0, &offset, 0);
+    #elif __hpux
+       res = sendfile (fd, fd, offset, count, 0, 0);
+    #endif
+       return 0;
+    }
+  """)
+
+  conf.check_cc(msg="Checking for sync_file_range(2) ", fragment="""
+    #include <fcntl.h>
+    int main(void)
+    {
+       int fd = 0;
+       off64_t offset = 1;
+       off64_t nbytes = 1;
+       unsigned int flags = SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE|SYNC_FILE_RANGE_WAIT_AFTER;
+       ssize_t res;
+       res = sync_file_range (fd, offset, nbytes, flags);
+       return 0;
+    }
+  """, define_name="HAVE_SYNC_FILE_RANGE")
+
+  conf.write_config_header('config.h')
+
+def build(bld):
+  libeio = bld.new_task_gen("cc", "staticlib")
+  libeio.source = "eio.c"
+  libeio.target = 'eio'
+  libeio.name = 'eio'
+  libeio.includes = '. ../..'
+
diff --git a/deps/libev/wscript b/deps/libev/wscript
new file mode 100644 (file)
index 0000000..d484a7f
--- /dev/null
@@ -0,0 +1,55 @@
+import Options
+
+def set_options(opt):
+  pass
+  #opt.tool_options('compiler_cc')
+
+def configure(conf):
+  print "--- libev ---"
+  #conf.check_tool('compiler_cc')
+
+  platform_string = "__" + Options.platform
+  if Options.platform == "linux2":
+    platform_string = "__linux"
+  conf.define(platform_string, 1)
+
+  conf.check_cc(header_name="sys/inotify.h")
+  conf.check_cc(header_name="sys/epoll.h")
+  conf.check_cc(header_name="sys/event.h")
+  conf.check_cc(header_name="sys/queue.h")
+  conf.check_cc(header_name="port.h")
+  conf.check_cc(header_name="poll.h")
+  conf.check_cc(header_name="sys/select.h")
+  conf.check_cc(header_name="sys/eventfd.h")
+  conf.check_cc(header_name="sys/inotify.h", function_name="inotify_init")
+  conf.check_cc(header_name="sys/epoll.h", function_name="epoll_ctl")
+  conf.check_cc(header_name="sys/queue.h", function_name="kqueue")
+  conf.check_cc(header_name="port.h", function_name="port_create")
+  conf.check_cc(header_name="poll.h", function_name="poll")
+  conf.check_cc(header_name="sys/select.h", function_name="select")
+  conf.check_cc(header_name="sys/eventfd.h", function_name="eventfd")
+  code = """
+      #include <syscall.h>
+      #include <time.h>
+
+      int main() {
+          struct timespec ts; 
+          int status = syscall (SYS_clock_gettime, CLOCK_REALTIME, &ts);
+          return 0;
+      }
+  """
+  conf.check_cc(fragment=code, define_name="HAVE_CLOCK_SYSCALL")
+  conf.check_cc(lib="rt", header_name="time.h", function_name="clock_gettime")
+  conf.check_cc(lib="rt", header_name="time.h", function_name="nanosleep")
+  conf.check_cc(lib="m", header_name="math.h", function_name="ceil")
+
+  conf.define("HAVE_CONFIG_H", 1)
+  conf.write_config_header('config.h')
+
+def build(bld):
+  libev = bld.new_task_gen("cc", "staticlib")
+  libev.source = 'ev.c'
+  libev.target = 'ev'
+  libev.name = 'ev'
+  libev.includes = '. ../..'
+
diff --git a/ragel.py b/ragel.py
new file mode 100644 (file)
index 0000000..3bb96ac
--- /dev/null
+++ b/ragel.py
@@ -0,0 +1,35 @@
+#! /usr/bin/env python
+# encoding: utf-8
+
+"Ragel: '.rl' files are converted into .c files using 'ragel': {.rl -> .c -> .o}"
+
+import TaskGen, Task, Runner
+
+
+def rageltaskfun(task):
+       env = task.env
+       ragelbin = env.get_flat('RAGEL')
+       if ragelbin:
+               if task.inputs[0].srcpath(env) == '../src/config_parser.rl':
+                       cmd = '%s -o %s -C -T0 %s' % (ragelbin, task.outputs[0].bldpath(env), task.inputs[0].srcpath(env))
+               else:
+                       cmd = '%s -o %s -C -T1 %s' % (ragelbin, task.outputs[0].bldpath(env), task.inputs[0].srcpath(env))
+       else:
+               src = task.inputs[0].srcpath(env)
+               src = src[:src.rfind('.')] + '.c'
+               cmd = 'cp %s %s' % (src, task.outputs[0].bldpath(env))
+       return task.generator.bld.exec_command(cmd)
+
+rageltask = Task.task_type_from_func('ragel', rageltaskfun, vars = ['RAGEL'], color = 'BLUE', ext_in = '.rl', ext_out = '.c', before = 'c')
+
+@TaskGen.extension('.rl')
+@TaskGen.before('apply_core')
+def ragel(self, node):
+       out = node.change_ext('.c')
+       self.allnodes.append(out)
+       tsk = self.create_task('ragel')
+       tsk.set_inputs(node)
+       tsk.set_outputs(out)
+
+def detect(conf):
+       dang = conf.find_program('ragel', var='RAGEL')
similarity index 99%
rename from node.cc
rename to src/node.cc
index 45e0ed8..ad7b2f8 100644 (file)
--- a/node.cc
@@ -1,4 +1,6 @@
 #include "node.h"
+#define EV_STANDALONE 1
+#include <ev.c>
 
 #include "node_tcp.h"
 #include "node_http.h"
similarity index 87%
rename from node.h
rename to src/node.h
index 4bb9756..91ed676 100644 (file)
--- a/node.h
@@ -1,7 +1,9 @@
 #ifndef node_h
 #define node_h
 
+#define EV_STANDALONE 1
 #include <ev.h>
+
 #include <v8.h>
 
 void node_fatal_exception (v8::TryCatch &try_catch); 
similarity index 98%
rename from node_http.cc
rename to src/node_http.cc
index f00c311..92f66da 100644 (file)
@@ -7,6 +7,8 @@
 #include <string>
 #include <list>
 
+#include <assert.h>
+
 using namespace v8;
 using namespace std;
 
@@ -160,14 +162,11 @@ HttpRequest::Respond (Handle<Value> data)
     done = true;
   } else {
     Handle<String> s = data->ToString();
-    oi_buf *buf = oi_buf_new2(s->Length());
-
-    uint16_t expanded[s->Length()];
-    s->Write(expanded, 0, s->Length());
 
-    for(int i = 0; i < s->Length(); i++) {
-      buf->base[i] = expanded[i];
-    }
+    size_t l1 = s->Utf8Length(), l2;
+    oi_buf *buf = oi_buf_new2(l1);
+    l2 = s->WriteUtf8(buf->base, l1);
+    assert(l1 == l2);
 
     output.push_back(buf);
   }
similarity index 100%
rename from node_http.h
rename to src/node_http.h
similarity index 96%
rename from node_tcp.cc
rename to src/node_tcp.cc
index 2f9b061..febbe10 100644 (file)
@@ -139,7 +139,7 @@ client_destroy (Persistent<Value> _, void *data)
 
 TCPClient::TCPClient(Handle<Object> _js_client)
 {
-  oi_socket_init(&socket, 30.0); // TODO adjustable timeout
+  oi_socket_init(&socket, 300.0); // TODO adjustable timeout
   socket.on_connect = on_connect;
   socket.on_read    = on_read;
   socket.on_drain   = NULL;
@@ -205,8 +205,10 @@ void TCPClient::Write (Handle<Value> arg)
   } else {
     Local<String> s = arg->ToString();
 
-    oi_buf *buf = oi_buf_new2(s->Length());
-    s->WriteAscii(buf->base, 0, s->Length());
+    size_t l1 = s->Utf8Length(), l2;
+    oi_buf *buf = oi_buf_new2(l1);
+    l2 = s->WriteUtf8(buf->base, l1);
+    assert(l1 == l2);
 
     oi_socket_write(&socket, buf);
   }
@@ -280,6 +282,8 @@ TCPClient::OnClose()
 {
   HandleScope scope;
 
+  printf("onclose readyState %d\n", ReadyState());
+
   assert(READY_STATE_OPEN == ReadyState());
   js_client->Set(readyState_str, readyState_CLOSED);
 
similarity index 100%
rename from node_tcp.h
rename to src/node_tcp.h
similarity index 100%
rename from node_timer.cc
rename to src/node_timer.cc
similarity index 100%
rename from node_timer.h
rename to src/node_timer.h
diff --git a/waf b/waf
new file mode 100755 (executable)
index 0000000..383775c
Binary files /dev/null and b/waf differ
diff --git a/wscript b/wscript
new file mode 100644 (file)
index 0000000..ade7f3f
--- /dev/null
+++ b/wscript
@@ -0,0 +1,103 @@
+#! /usr/bin/env python
+import Options
+import os
+from os.path import join, dirname, abspath
+
+VERSION='0.0.1'
+APPNAME='node'
+
+srcdir = '.'
+blddir = 'build'
+
+def set_options(opt):
+  # the gcc module provides a --debug-level option
+  opt.tool_options('compiler_cxx')
+  opt.tool_options('compiler_cc')
+  opt.tool_options('ragel', tdir = '.')
+
+def configure(conf):
+  conf.check_tool('compiler_cxx')
+  conf.check_tool('compiler_cc')
+  conf.check_tool('ragel', tooldir = '.')
+
+  conf.sub_config('deps/libeio')
+  conf.sub_config('deps/libev')
+
+  # needs to match the symbols found in libeio and libev
+  # __solaris
+  # __linux
+  # __freebsd
+  # __hpux
+  # __solaris
+  platform_string = "__" + Options.platform
+  if Options.platform == "linux2":
+    platform_string = "__linux"
+  conf.define(platform_string, 1)
+
+  # liboi config
+  print "--- liboi ---"
+  if conf.check_cfg(package='gnutls', args='--cflags --libs', uselib_store="GNUTLS"):
+    conf.define("HAVE_GNUTLS", 1)
+
+  conf.define("HAVE_CONFIG_H", 1)
+  conf.write_config_header('config.h')
+
+
+def build(bld):
+
+  bld.add_subdirs('deps/libeio deps/libev')
+
+  ### v8
+  deps_src = join(bld.path.abspath(),"deps")
+  deps_tgt = join(bld.srcnode.abspath(bld.env),"deps")
+  v8dir_src = join(deps_src,"v8")
+  v8dir_tgt = join(deps_tgt, "v8")
+  v8lib = bld.env["staticlib_PATTERN"] % "v8"
+  v8 = bld.new_task_gen(
+    target=join("deps/v8",v8lib),
+    rule='cp -rf %s %s && cd %s && scons library=static' 
+      % ( v8dir_src
+        , deps_tgt
+        , v8dir_tgt
+        ),
+    before="cxx"
+  )
+  bld.env["CPPPATH_V8"] = "deps/v8/include"
+  bld.env["STATICLIB_V8"] = "v8"
+  bld.env["LIBPATH_V8"] = v8dir_tgt
+  bld.env["LINKFLAGS_V8"] = "-pthread"
+
+  ### oi
+  oi = bld.new_task_gen("cc", "staticlib")
+  oi.source = "deps/oi/oi_socket.c deps/oi/oi_buf.c"
+  oi.includes = "deps/oi/"
+  oi.name = "oi"
+  oi.target = "oi"
+  oi.uselib = "GNUTLS"
+
+  ### ebb
+  ebb = bld.new_task_gen("cc", "staticlib")
+  ebb.source = "deps/ebb/ebb_request_parser.rl"
+  ebb.includes = "deps/ebb/"
+  ebb.name = "ebb"
+  ebb.target = "ebb"
+
+  ### node
+  node = bld.new_task_gen("cxx", "program")
+  node.target = 'node'
+  node.source = """
+    src/node.cc
+    src/node_http.cc
+    src/node_tcp.cc
+    src/node_timer.cc
+  """
+  node.includes = """
+    src/ 
+    deps/v8/include
+    deps/libev
+    deps/libeio
+    deps/oi 
+    deps/ebb
+  """
+  node.uselib_local = "oi ev eio ebb"
+  node.uselib = "V8 PTHREAD"