Skip to content

Instantly share code, notes, and snippets.

@niklasfi
Created March 22, 2011 22:07
Show Gist options
  • Save niklasfi/882188 to your computer and use it in GitHub Desktop.
Save niklasfi/882188 to your computer and use it in GitHub Desktop.
log
root@vs1145146:/var/www/node-gallery/exiv2node# node-waf configure build
Setting srcdir to : /var/www/node-gallery/exiv2node
Setting blddir to : /var/www/node-gallery/exiv2node/build
Checking for program g++ or c++ : /usr/bin/g++
Checking for program cpp : /usr/bin/cpp
Checking for program ar : /usr/bin/ar
Checking for program ranlib : /usr/bin/ranlib
Checking for g++ : ok
Checking for node path : not found
Checking for node prefix : ok /usr/local
Checking for exiv2 : yes
Checking for program pkg-config : /usr/bin/pkg-config
'configure' finished successfully (0.041s)
Waf: Entering directory `/var/www/node-gallery/exiv2node/build'
[1/2] cxx: exiv2node.cc -> build/default/exiv2node_1.o
../exiv2node.cc:1:16: error: v8.h: Datei oder Verzeichnis nicht gefunden
../exiv2node.cc:2:18: error: node.h: Datei oder Verzeichnis nicht gefunden
../exiv2node.cc:8: error: ‘node’ is not a namespace-name
../exiv2node.cc:8: error: expected namespace-name before ‘;’ token
../exiv2node.cc:9: error: ‘v8’ is not a namespace-name
../exiv2node.cc:9: error: expected namespace-name before ‘;’ token
../exiv2node.cc:14: error: expected class-name before ‘{’ token
../exiv2node.cc:17: error: ISO C++ forbids declaration of ‘Persistent’ with no type
../exiv2node.cc:17: error: expected ‘;’ before ‘<’ token
../exiv2node.cc:18: error: ‘Handle’ has not been declared
../exiv2node.cc:18: error: expected ‘,’ or ‘...’ before ‘<’ token
../exiv2node.cc:39: error: ISO C++ forbids declaration of ‘Handle’ with no type
../exiv2node.cc:39: error: expected ‘;’ before ‘<’ token
../exiv2node.cc:47: error: expected `;' before ‘struct’
../exiv2node.cc:50: error: ISO C++ forbids declaration of ‘Persistent’ with no type
../exiv2node.cc:50: error: expected ‘;’ before ‘<’ token
../exiv2node.cc:52: error: ISO C++ forbids declaration of ‘Persistent’ with no type
../exiv2node.cc:52: error: expected ‘;’ before ‘<’ token
../exiv2node.cc:56: error: ISO C++ forbids declaration of ‘Handle’ with no type
../exiv2node.cc:56: error: expected ‘;’ before ‘<’ token
../exiv2node.cc:82: error: expected `;' before ‘static’
../exiv2node.cc:82: error: ‘eio_req’ has not been declared
../exiv2node.cc:96: error: ‘eio_req’ has not been declared
../exiv2node.cc:139: error: ISO C++ forbids declaration of ‘Handle’ with no type
../exiv2node.cc:139: error: expected ‘;’ before ‘<’ token
../exiv2node.cc:167: error: expected `;' before ‘static’
../exiv2node.cc:167: error: ‘eio_req’ has not been declared
../exiv2node.cc:193: error: ‘eio_req’ has not been declared
../exiv2node.cc: In static member function ‘static void Exiv2Node::Init(int)’:
../exiv2node.cc:19: error: ‘HandleScope’ was not declared in this scope
../exiv2node.cc:19: error: expected `;' before ‘scope’
../exiv2node.cc:21: error: ‘Local’ was not declared in this scope
../exiv2node.cc:21: error: ‘FunctionTemplate’ was not declared in this scope
../exiv2node.cc:21: error: ‘t’ was not declared in this scope
../exiv2node.cc:21: error: ‘FunctionTemplate’ is not a class or namespace
../exiv2node.cc:21: error: ‘New’ was not declared in this scope
../exiv2node.cc:23: error: ‘s_ct’ was not declared in this scope
../exiv2node.cc:23: error: ‘Persistent’ was not declared in this scope
../exiv2node.cc:23: error: ‘::New’ has not been declared
../exiv2node.cc:25: error: ‘String’ has not been declared
../exiv2node.cc:27: error: ‘GetImageTags’ was not declared in this scope
../exiv2node.cc:27: error: ‘NODE_SET_PROTOTYPE_METHOD’ was not declared in this scope
../exiv2node.cc:28: error: ‘SetImageTags’ was not declared in this scope
../exiv2node.cc:30: error: ‘target’ was not declared in this scope
../exiv2node.cc:30: error: ‘String’ has not been declared
../exiv2node.cc: In static member function ‘static int Exiv2Node::GetImageTagsWorker(int*)’:
../exiv2node.cc:83: error: request for member ‘data’ in ‘* req’, which is of non-class type ‘int’
../exiv2node.cc: In static member function ‘static int Exiv2Node::AfterGetImageTags(int*)’:
../exiv2node.cc:97: error: ‘HandleScope’ was not declared in this scope
../exiv2node.cc:97: error: expected `;' before ‘scope’
../exiv2node.cc:98: error: request for member ‘data’ in ‘* req’, which is of non-class type ‘int’
../exiv2node.cc:99: error: ‘EV_DEFAULT_UC’ was not declared in this scope
../exiv2node.cc:99: error: ‘ev_unref’ was not declared in this scope
../exiv2node.cc:100: error: ‘class Exiv2Node’ has no member named ‘Unref’
../exiv2node.cc:102: error: ‘Local’ was not declared in this scope
../exiv2node.cc:102: error: ‘Value’ was not declared in this scope
../exiv2node.cc:102: error: ‘argv’ was not declared in this scope
../exiv2node.cc:104: error: ‘String’ was not declared in this scope
../exiv2node.cc:104: error: ‘::New’ has not been declared
../exiv2node.cc:104: error: ‘String’ is not a class or namespace
../exiv2node.cc:105: error: ‘::New’ has not been declared
../exiv2node.cc:105: error: ‘Null’ was not declared in this scope
../exiv2node.cc:107: error: ‘::New’ has not been declared
../exiv2node.cc:107: error: ‘Null’ was not declared in this scope
../exiv2node.cc:112: error: ‘Array’ was not declared in this scope
../exiv2node.cc:112: error: ‘tags’ was not declared in this scope
../exiv2node.cc:112: error: ‘Array’ is not a class or namespace
../exiv2node.cc:115: error: ‘String’ has not been declared
../exiv2node.cc:115: error: ‘String’ has not been declared
../exiv2node.cc:119: error: ‘::New’ has not been declared
../exiv2node.cc:124: error: ‘TryCatch’ was not declared in this scope
../exiv2node.cc:124: error: expected `;' before ‘try_catch’
../exiv2node.cc:125: error: ‘struct Exiv2Node::exiv2node_thread_data_t’ has no member named ‘cb’
../exiv2node.cc:125: error: ‘Context’ has not been declared
../exiv2node.cc:126: error: ‘try_catch’ was not declared in this scope
../exiv2node.cc:127: error: ‘FatalException’ was not declared in this scope
../exiv2node.cc:130: error: ‘struct Exiv2Node::exiv2node_thread_data_t’ has no member named ‘cb’
../exiv2node.cc: In static member function ‘static int Exiv2Node::SetImageTagsWorker(int*)’:
../exiv2node.cc:168: error: request for member ‘data’ in ‘* req’, which is of non-class type ‘int’
../exiv2node.cc:176: error: ‘Local’ was not declared in this scope
../exiv2node.cc:176: error: ‘Array’ was not declared in this scope
../exiv2node.cc:176: error: ‘keys’ was not declared in this scope
../exiv2node.cc:176: error: ‘struct Exiv2Node::exiv2node_thread_data_t’ has no member named ‘tags’
../exiv2node.cc:178: error: ‘Handle’ was not declared in this scope
../exiv2node.cc:178: error: ‘v8’ has not been declared
../exiv2node.cc:178: error: ‘key’ was not declared in this scope
../exiv2node.cc:179: error: ‘String’ has not been declared
../exiv2node.cc:180: error: ‘String’ has not been declared
../exiv2node.cc:180: error: ‘struct Exiv2Node::exiv2node_thread_data_t’ has no member named ‘tags’
../exiv2node.cc: In static member function ‘static int Exiv2Node::AfterSetImageTags(int*)’:
../exiv2node.cc:194: error: ‘HandleScope’ was not declared in this scope
../exiv2node.cc:194: error: expected `;' before ‘scope’
../exiv2node.cc:195: error: request for member ‘data’ in ‘* req’, which is of non-class type ‘int’
../exiv2node.cc:196: error: ‘EV_DEFAULT_UC’ was not declared in this scope
../exiv2node.cc:196: error: ‘ev_unref’ was not declared in this scope
../exiv2node.cc:197: error: ‘class Exiv2Node’ has no member named ‘Unref’
../exiv2node.cc:199: error: ‘Local’ was not declared in this scope
../exiv2node.cc:199: error: ‘Value’ was not declared in this scope
../exiv2node.cc:199: error: ‘argv’ was not declared in this scope
../exiv2node.cc:203: error: ‘::New’ has not been declared
../exiv2node.cc:203: error: ‘Null’ was not declared in this scope
../exiv2node.cc:205: error: ‘String’ was not declared in this scope
../exiv2node.cc:205: error: ‘::New’ has not been declared
../exiv2node.cc:205: error: ‘String’ is not a class or namespace
../exiv2node.cc:209: error: ‘TryCatch’ was not declared in this scope
../exiv2node.cc:209: error: expected `;' before ‘try_catch’
../exiv2node.cc:210: error: ‘struct Exiv2Node::exiv2node_thread_data_t’ has no member named ‘cb’
../exiv2node.cc:210: error: ‘Context’ has not been declared
../exiv2node.cc:211: error: ‘try_catch’ was not declared in this scope
../exiv2node.cc:212: error: ‘FatalException’ was not declared in this scope
../exiv2node.cc:215: error: ‘struct Exiv2Node::exiv2node_thread_data_t’ has no member named ‘cb’
../exiv2node.cc: At global scope:
../exiv2node.cc:224: error: expected constructor, destructor, or type conversion before ‘<’ token
../exiv2node.cc:227: error: variable or field ‘init’ declared void
../exiv2node.cc:227: error: ‘Handle’ was not declared in this scope
../exiv2node.cc:227: error: ‘Object’ was not declared in this scope
../exiv2node.cc:227: error: ‘target’ was not declared in this scope
../exiv2node.cc:230: error: expected constructor, destructor, or type conversion before ‘(’ token
Waf: Leaving directory `/var/www/node-gallery/exiv2node/build'
Build failed: -> task failed (err #1):
{task: cxx exiv2node.cc -> exiv2node_1.o}
#include <v8.h>
#include <node.h>
#include <unistd.h>
#include <string>
#include <exiv2/image.hpp>
#include <exiv2/exif.hpp>
using namespace node;
using namespace v8;
#define DEBUGMODE 1
#define debug_printf(...) do {if(DEBUGMODE)printf(__VA_ARGS__);} while (0)
class Exiv2Node: ObjectWrap {
public:
static Persistent<FunctionTemplate> s_ct;
static void Init(Handle<Object> target) {
HandleScope scope;
Local<FunctionTemplate> t = FunctionTemplate::New(New);
s_ct = Persistent<FunctionTemplate>::New(t);
s_ct->InstanceTemplate()->SetInternalFieldCount(1);
s_ct->SetClassName(String::NewSymbol("Exiv2Node"));
NODE_SET_PROTOTYPE_METHOD(s_ct, "getImageTags", GetImageTags);
NODE_SET_PROTOTYPE_METHOD(s_ct, "setImageTags", SetImageTags);
target->Set(String::NewSymbol("Exiv2Node"), s_ct->GetFunction());
}
Exiv2Node() {
}
~Exiv2Node() {
}
static Handle<Value> New(const Arguments& args) {
HandleScope scope;
Exiv2Node* exiv2node = new Exiv2Node();
exiv2node->Wrap(args.This());
return args.This();
}
/* structure for passing our various objects around libeio */
struct exiv2node_thread_data_t {
Exiv2Node *exiv2node;
Exiv2::Image::AutoPtr image;
Persistent<Function> cb;
std::string fileName;
Persistent<Object> tags;
std::string exifException;
};
static Handle<Value> GetImageTags(const Arguments& args) {
HandleScope scope;
/* Usage arguments */
if (args.Length() <= (1) || !args[1]->IsFunction())
return ThrowException(Exception::TypeError(String::New("Usage: <filename> <callback function>")));
Local<String> fileName = Local<String>::Cast(args[0]);
Local<Function> cb = Local<Function>::Cast(args[1]);
Exiv2Node* exiv2node = ObjectWrap::Unwrap<Exiv2Node>(args.This());
/* Set up our thread data struct, pass off to the libeio thread pool */
exiv2node_thread_data_t *thread_data = new exiv2node_thread_data_t();
thread_data->exiv2node = exiv2node;
thread_data->cb = Persistent<Function>::New(cb);
thread_data->fileName = std::string(*String::AsciiValue(fileName));
thread_data->exifException = std::string();
exiv2node->Ref();
eio_custom(GetImageTagsWorker, EIO_PRI_DEFAULT, AfterGetImageTags, thread_data);
ev_ref( EV_DEFAULT_UC);
return Undefined();
}
static int GetImageTagsWorker(eio_req *req) {
exiv2node_thread_data_t *thread_data = static_cast<exiv2node_thread_data_t *> (req->data);
/* Exiv2 processing of the file.. */
try {
thread_data->image = Exiv2::ImageFactory::open(thread_data->fileName);
thread_data->image->readMetadata();
} catch (Exiv2::AnyError& e) {
thread_data->exifException.append(e.what());
}
return 0;
}
/* Thread complete callback.. */
static int AfterGetImageTags(eio_req *req) {
HandleScope scope;
exiv2node_thread_data_t *thread_data = static_cast<exiv2node_thread_data_t *> (req->data);
ev_unref( EV_DEFAULT_UC);
thread_data->exiv2node->Unref();
Local<Value> argv[2];
if (!thread_data->exifException.empty()){
argv[0] = Local<String>::New(String::New(thread_data->exifException.c_str()));
argv[1] = Local<Value>::New(Null());
} else {
argv[0] = Local<Value>::New(Null());
/* Create a V8 array with all the image tags and their corresponding values */
Exiv2::ExifData &exifData = thread_data->image->exifData();
if (exifData.empty() == false) {
Local<Array> tags = Array::New();
Exiv2::ExifData::const_iterator end = exifData.end();
for (Exiv2::ExifData::const_iterator i = exifData.begin(); i != end; ++i) {
tags->Set(String::New(i->key().c_str()), String::New(i->value().toString().c_str()));
}
argv[1] = tags;
} else {
argv[1] = Local<Value>::New(Null());
}
}
/* Pass the argv array object to our callback function */
TryCatch try_catch;
thread_data->cb->Call(Context::GetCurrent()->Global(), 2, argv);
if (try_catch.HasCaught()) {
FatalException(try_catch);
}
thread_data->cb.Dispose();
// Assuming std::auto_ptr does its job here and Exiv2::Image::AutoPtr is destroyed when it goes out of scope here..
delete thread_data;
return 0;
}
/* Set Image Tag support.. */
static Handle<Value> SetImageTags(const Arguments& args) {
HandleScope scope;
/* Usage arguments */
if (args.Length() <= 2 || !args[2]->IsFunction())
return ThrowException(Exception::TypeError(String::New("Usage: <filename> <tags> <callback function>")));
Local<String> fileName = Local<String>::Cast(args[0]);
Local<Object> tags = Local<Object>::Cast(args[1]);
Local<Function> cb = Local<Function>::Cast(args[2]);
Exiv2Node* exiv2node = ObjectWrap::Unwrap<Exiv2Node>(args.This());
/* Set up our thread data struct, pass off to the libeio thread pool */
exiv2node_thread_data_t *thread_data = new exiv2node_thread_data_t();
thread_data->exiv2node = exiv2node;
thread_data->cb = Persistent<Function>::New(cb);
thread_data->fileName = std::string(*String::AsciiValue(fileName));
thread_data->tags = Persistent<Object>::New(tags);
thread_data->exifException = std::string();
exiv2node->Ref();
eio_custom(SetImageTagsWorker, EIO_PRI_DEFAULT, AfterSetImageTags, thread_data);
ev_ref( EV_DEFAULT_UC);
return Undefined();
}
static int SetImageTagsWorker(eio_req *req) {
exiv2node_thread_data_t *thread_data = static_cast<exiv2node_thread_data_t*> (req->data);
/* Read existing metadata.. TODO: also handle IPTC and XMP data here.. */
try {
thread_data->image = Exiv2::ImageFactory::open(thread_data->fileName);
thread_data->image->readMetadata();
Exiv2::ExifData &exifData = thread_data->image->exifData();
Local<Array> keys = thread_data->tags->GetPropertyNames();
for (unsigned i = 0; i < keys->Length(); i++) {
Handle<v8::Value> key = keys->Get(i);
Exiv2::Exifdatum& tag = exifData[*String::AsciiValue(key)];
tag.setValue(*String::AsciiValue(thread_data->tags->Get(key)));
}
/* Write the Exif data to the image file */
thread_data->image->setExifData(exifData);
thread_data->image->writeMetadata();
} catch (Exiv2::AnyError& e) {
thread_data->exifException.append(e.what());
}
return 0;
}
/* Thread complete callback.. */
static int AfterSetImageTags(eio_req *req) {
HandleScope scope;
exiv2node_thread_data_t *thread_data = static_cast<exiv2node_thread_data_t*> (req->data);
ev_unref( EV_DEFAULT_UC);
thread_data->exiv2node->Unref();
Local<Value> argv[1];
/* Create a V8 array with all the image tags and their corresponding values */
if (thread_data->exifException.empty()) {
argv[0] = Local<Value>::New(Null());
} else {
argv[0] = Local<String>::New(String::New(thread_data->exifException.c_str()));
}
/* Pass the argv array object to our callback function */
TryCatch try_catch;
thread_data->cb->Call(Context::GetCurrent()->Global(), 1, argv);
if (try_catch.HasCaught()) {
FatalException(try_catch);
}
thread_data->cb.Dispose();
// Assuming std::auto_ptr does its job here and Exiv2::Image::AutoPtr is destroyed when it goes out of scope here..
delete thread_data;
return 0;
}
};
Persistent<FunctionTemplate> Exiv2Node::s_ct;
extern "C" {
static void init(Handle<Object> target) {
Exiv2Node::Init(target);
}
NODE_MODULE(exiv2node, init)
;
}
import Options
from os import unlink, symlink, popen
from os.path import exists
def set_options(opt):
opt.tool_options("compiler_cxx")
def configure(conf):
conf.check_tool("compiler_cxx")
conf.check_tool("node_addon")
conf.check_cfg(package='exiv2')
pkgconfig = conf.find_program('pkg-config', var='PKGCONFIG', mandatory=True)
#exiv2_libdir = popen("%s --libdir exiv2" % pkgconfig).readline().strip()
conf.env.append_value("LIBPATH_EXIV2", "/usr/local/lib")
conf.env.append_value("LIB_EXIV2", "exiv2")
exiv2_incdir = popen("%s --cflags exiv2" % pkgconfig).readline().strip()
conf.env.append_value("CPPPATH_EXIV2", exiv2_incdir)
def build(bld):
obj = bld.new_task_gen("cxx", "shlib", "node_addon")
# obj.cxxflags = ["-g", "-D_FILE_OFFSET_BITS=64", "-D_LARGEFILE_SOURCE", "-Wall"]
obj.target = "exiv2node"
obj.source = "exiv2node.cc"
obj.uselib = "EXIV2"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment