sgccarey
sgccarey

Reputation: 492

Linking pcap library in OpenWrt Makefile

My simple pcap test app compiles and runs fine using: gcc main.c -o test -lpcap

but when using the OpenWrt SDK: make package/myapp/compile V=s

I get the error message:

main.c:(.text.startup+0x24): undefined reference to `pcap_lookupdev'
collect2: error: ld returned 1 exit status

From what I've read, I need to add the line:

LDFLAGS = -lpcap

to one of the Makefiles, but I'm not sure where it should go. What confuses me is that I can use the pcap constant PCAP_ERRBUF_SIZE, can anyone tell me why I can access this, but not pcap functions?

main.c

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <pcap.h>

int main(int argc, char **argv)
{
    printf("Hello PCAP!\n");
    char *dev, errbuf[PCAP_ERRBUF_SIZE];
    printf("%d\n\n", PCAP_ERRBUF_SIZE);

    // Make works without this part
    dev = pcap_lookupdev(errbuf);
    printf("Device: %s\n", dev);
    return 0;
}

Makefile

include $(TOPDIR)/rules.mk

PKG_NAME:=myapp
PKG_VERSION:=0.1
PKG_RELEASE:=1

include $(INCLUDE_DIR)/package.mk
include $(INCLUDE_DIR)/cmake.mk


define Package/myapp
    SECTION:=utils
    CATEGORY:=Utilities
    DEPENDS:=+libpcap
    TITLE:=Intro to PCAP for OpenWrt
endef

define Package/myapp/description
    Outputs device name
endef

define Build/Prepare
    mkdir -p $(PKG_BUILD_DIR)
    LDFLAGS=-lpcap
    $(CP) ./src/* $(PKG_BUILD_DIR)/
endef

define Package/myapp/install
    $(INSTALL_DIR) $(1)/usr/bin
    $(INSTALL_BIN) $(PKG_BUILD_DIR)/myapp $(1)/usr/bin/

    $(INSTALL_DIR) $(1)/etc/init.d/
    $(INSTALL_BIN) files/myapp.init $(1)/etc/init.d/myapp
    $(INSTALL_DIR) $(1)/etc/config
    $(INSTALL_CONF) files/myapp.config $(1)/etc/config/myapp
endef

$(eval $(call BuildPackage,myapp))

Upvotes: 2

Views: 2680

Answers (2)

lithiumhead
lithiumhead

Reputation: 871

I figured out how to compile native C code for OpenWrt (runnin on a mips processor inside of a TP-LINK router) that depends on other libs (also in C) and generate .ipk s for both (the library and the executable) via a single makecommand. The library itself needed to be fetched from

I documented the efforts on my blog here

Basically there are three Makefiles involved - one for the library which tells the build system where to get the tarball from. The other two would be for your native C code. Consider my case for example: I want compile my code (mfm383c) that makes uses of a library (libmodbus):

/package/libmodbus/Makefile - this specifies URL from where to get the tar ball of the sources and the system will fetch the sources and compile it for you. It also tells the system where to place the .so file when the .ipk is installed on the OpenWrt target

/package/mfm383c/src/Makefile - this Makefile take care of telling the build system how to compile the .c and .h and also passes the dependency flag to the linker (-lmodbus)

/package/mfm383c/Makefile - This Makefile is the most important of the three - it tells the build system to build the libmodbus library before building mfm383c to ensure that the dependencies are met. We also need to make sure that the modbus.h file included in mfm383c.c can be found in the right place. The most notable section of this file being the following line at the end:

$(eval $(call BuildPackage,mfm383c,+libmodbus))

and the part about the code being dependent on another package in the define section:

DEPENDS:=+libmodbus

All three makefile are posted on my blog - they were too big to post here

Upvotes: 1

Etan Reisner
Etan Reisner

Reputation: 80941

Constants and the like used in code are resolved during compilation and come from header files. So the pcap.h header file is found (apparently by default).

I would have expected DEPENDS:=+libpcap to handle the linking for you (I'm not sure why else it would be necessary, but ). (Is that the correct format for that line?)

You actually want LDLIBS not LDFLAGS for this (assuming you are using the built-in rules and variables). See 10.3 Implicit Variables for what they each mean.

Without knowing what the rest of that make framework is doing though I can't say whether either LDLIBS or LDFLAGS will actually work though. That framework might have its own variable for this.

Upvotes: 1

Related Questions