Compiling C based library in C++ gives symbol lookup error in node addon api

Viewed 36

The following addon based on C library libpci-dev and C++ compiles successfully but gives lookup error when i try to call the addon from javascript.

I have following files

binding.gyp

{
  "targets": [
    {
      "target_name": "getSetPci",
      "cflags!": [ "-fno-exceptions" ],
      "cflags_cc!": [ "-fno-exceptions" ],
      "cflags_cc": ["-std=c++23", "-lpci"],
      "sources": [ 
        "index.cpp",
        "devbind.cpp",
        ],
      "include_dirs": [
        "<!@(node -p \"require('node-addon-api').include_dir\")",
        "/usr/include/x86_64-linux-gnu/pci/",
      ],
      'defines': [ 'NAPI_CPP_EXCEPTIONS' ],
      "libraries": [
        "-L/usr/lib/x86_64-linux-gnu/",
        "-Wl,-rpath,/usr/lib/x86_64-linux-gnu/libpci.so.3.8.0"
      ],
    }
  ]
}

devbind.cpp

#include "devbind.h"

void get_pci_device_details(std::string slot)
{
    struct pci_access *pacc;
    struct pci_dev *dev;
    std::string interface;

    pacc = pci_alloc();
    pci_init(pacc);     //Initialize the PCI library
    pci_scan_bus(pacc);     //We want to get the list of devices


    if (slot == "")
    {   
        for (dev=pacc->devices; dev; dev=dev->next) //Iterate over all devices
        {
            char namebuf[1024], *name, tmp_str[20], *driver, *iommu_group;
            std::string interfaces = "";

            pci_fill_info(dev, PCI_FILL_IDENT | PCI_FILL_BASES | PCI_FILL_CLASS | PCI_FILL_DRIVER | 
                    PCI_FILL_IOMMU_GROUP | PCI_FILL_IO_FLAGS | PCI_FILL_CLASS_EXT | PCI_FILL_SUBSYS );  //Fill in header info we need
            unsigned char c = pci_read_byte(dev, PCI_INTERRUPT_PIN); //Read config register directly

            sprintf(tmp_str, "%04x:%02x:%02x.%d", dev->domain, dev->bus, dev->dev, dev->func);
            std::cout << tmp_str << "\n";

            name = pci_lookup_name(pacc, namebuf, sizeof(namebuf), PCI_LOOKUP_CLASS,  dev->device_class);
            sprintf(tmp_str, "%s", name);
            std::cout << tmp_str << "\n";
            sprintf(tmp_str, "%04x", dev->device_class);
            std::cout << tmp_str << "\n";
        }
    }

    pci_cleanup(pacc);
}

devbind.h

#ifndef DEVBIND_H
#define DEVBIND_H

extern "C" {
    #include <pci/pci.h>
}
#include <string>
#include <iostream>

void get_pci_device_details(std::string slot = "");

#endif

index.cpp

#include <napi.h>
#include "devbind.h"

Napi::Value getPci(const Napi::CallbackInfo& info)
{   
    std::string dev;
    Napi::Env env = info.Env();
    

    if (info.Length() == 1)
    {
        if (!info[0].IsString())
        {
            Napi::TypeError::New(env, "Device slot should be in string.").ThrowAsJavaScriptException();
            return env.Null();
        }
        dev = (std::string)info[0].ToString();
        get_pci_device_details(dev);
    }
    else
        get_pci_device_details();
}

Napi::Object Init(Napi::Env env, Napi::Object exports) 
{
    exports.Set(Napi::String::New(env, "getPci"), Napi::Function::New(env, getPci));
    return exports;
}

NODE_API_MODULE(get_set_pci, Init)

index.js

const addon = require('bindings')('getSetPci')
var tmp = addon.getPci();
console.log(tmp);

The module builds successfully with

node-gyp build

But when i try to call the module from index.js, it gives the following error

node: symbol lookup error: /path/to/project/build/Release/getSetPci.node: undefined symbol: pci_alloc
0 Answers
Related