Reputation: 492
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
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
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