OpenWrt Forum Archive

Topic: How to add custom package from source?

The content of this topic has been archived on 17 Apr 2018. There are no obvious gaps in this topic, but there may still be some posts missing at the end.

Hi all, i'm trying to add some custom packages. For custom package i mean that i have a tarball with source files and i want to compile it and then get an ipkg to install in my openwrt kamikaze, that i have installed on a MT RouterBoard.

Which is the best way to get there? I knew that i must use SDK. The manual (wiki) is really confused, and i am too. I've tried to compile it too, inserting it in the trunk structure, inserting a Makefile in the package directory. Nothing! i get compiling errors, because it try to locate a lnx dir under my sources.

Waiting a response.... thanks
Bye

You don't need to start with the SDK, you can also start with the OpenWrt sources; the difference is mostly that the sources will build the compiler while the SDK already comes with the compiler. It's actually easier to use the sources, it just takes a little longer.

As for the package makefile, the real trick is understanding just how much OpenWrt's buildroot system does for you. This is not your traditional makefile, the goal is not to describe how each piece of the source is run through the compiler, and what optimization flags are used; there's already a makefile included with the source that does all that. All that you need to do is tell OpenWrt where to download the sources and a brief description of what they are for the ipkg entry. The actual compile is done by passing control over to whatever structure already exists within the source.

Compiling a typical linux application from source generally looks like this:

1. Extract the sources into a temporary directory.
    - is the source a tar.bz2? tar jxvf source.tar.bz2
    - is the source a tar.gz? tar zxvf source.tar.gz

2. Configure the source
    - if the source has a "configure" script, run it: ./configure

3. Compile the source
    - make

OpenWrt knows this pattern, you don't need to specify it. Hence the package Makefile can be simplified down to the following:

include $(TOPDIR)/rules.mk

# name of package
# version number of the sources you're using
# how many times you've released a package based on the above version number
PKG_NAME:=mypackage
PKG_VERSION:=1.0
PKG_RELEASE:=1

# name of the sources; using variables from above for the version
# server directory containing the above source file (assuming it's not already found in the local dl directory)
# md5sum to avoid corrupted downloads
PKG_SOURCE:=mypackage-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=http://example.com/download/sources
PKG_MD5SUM:=12345678901234567890

# sources will be unpacked into this directory (you shouldn't need to change this)
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)

include $(INCLUDE_DIR)/package.mk

# Metadata; information about what the package is for the ipkg listings
# to keep things simple, a number of fields have been left at their defaults
# and are not shown here.
define Package/mypackage
  TITLE:=one line description of mypackage
  MAINTAINER:=Your email address <user@example.com>
endef

define Package/mypackage/description
  A very long description of what mypackage is and why anyone would ever want to install it.

  Features:
  -  the ability to illustrate an openwrt package makefile
  - more features
endef

# We'll use the OpenWrt defaults to configure and compile the package. Otherwise we'd need to define
# Build/Configure - commands to invoke a configure (or similar) script
# Build/Compile - commands used to run make or otherwise build the source

define Package/mypackage/install
        # Now that we have the source compiled (magic huh?) we need to copy files out of the source
        # directory and into our ipkg file. These are shell commands, so make sure you start the lines
        # with a TAB. $(1) here represents the root filesystem on the router.

        # make a directory for the config
        $(INSTALL_DIR) $(1)/etc/mypackage/

        # copy the config
        $(INSTALL_CONF) $(PKG_BUILD_DIR)/mypackage.conf $(1)/etc/mypackage

        # make a directory for some random data files required by mypackage
        $(INSTALL_DIR) $(1)/usr/share/mypackage

        # copy the data files
        $(INSTALL_DATA) $(PKG_BUILD_DIR)/data/* $(1)/usr/share/mypackage

        # copy the binary
        $(INSTALL_BIN) $(PKG_BUILD_DIR)/mypackage $(1)/usr/bin
endef

This makefile would then be saved as "package/mypackage/Makefile".

Thanks for this useful example Makefile! For my project i need to install a cross layer interface (xian). I've tried to modify your example to insert it, also if it was different because it was not a "normal" package, instead it does not have a bin ad some data, it has some libs and 2 kernel module.
So i only added shell code to install right files in the right places. The problem is that my package does not appear in the menuconfig! now i'm trying adding a line in the .config... i will see...
if i have some kernel modules i have to write down in the Makefile the lines like $(call Autoload.... etc?   because i found them in another Makefile...

Oops, I somehow lost the line from the example

$(eval $(call BuildPackage,mypackage))

That's the magic line that transforms the template into a valid makefile.

Check out the existing packages for examples; i'm travelling so I can't do any indepth answers from a pda.

It doesn't compile! i can't find in the menuconfig the line of my package to select, in fact i can't find any compiled result trying to search with command find....

post your makefile and where you're saving it to (if to packages and not trunk/packages check if it is soft-linked)

This is my copy of previous posted Makefile, i've changed it according to my package... it has default compile so i wrote down only the install directive. I'd expect to view it in the menuconfig, to choose the <M> option, so it would compile but not install! (so in reality the install directive are superfluous)

 
include $(TOPDIR)/rules.mk

# name of package
# version number of the sources you're using
# how many times you've released a package based on the above version number
PKG_NAME:=xian
PKG_VERSION:=1.1
PKG_RELEASE:=1

# name of the sources; using variables from above for the version
# server directory containing the above source file (assuming it's not already found in the local dl directory)
# md5sum to avoid corrupted downloads
#pkgsource is wrong but i put my tar-gz in dl directory
PKG_SOURCE:=xian-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=http://example.com/download/sources
PKG_MD5SUM:=de2d6249665fcb627ecab4e82916096e

# sources will be unpacked into this directory (you shouldn't need to change this)
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)

include $(INCLUDE_DIR)/package.mk

# Metadata; information about what the package is for the ipkg listings
# to keep things simple, a number of fields have been left at their defaults
# and are not shown here.
define Package/xian
  TITLE:=Xian: a cross layer interface for wireless
  MAINTAINER:=paolo.via@halservice.it
endef

define Package/xian/description
  Xian a very long description

  Features:
  -  the ability to illustrate an openwrt package makefile
  - more features
endef

# We'll use the OpenWrt defaults to configure and compile the package. Otherwise we'd need to define
# Build/Configure - commands to invoke a configure (or similar) script
# Build/Compile - commands used to run make or otherwise build the source

define Package/xian/install
    # Now that we have the source compiled (magic huh?) we need to copy files out of the source
    # directory and into our ipkg file. These are shell commands, so make sure you start the lines
    # with a TAB. $(1) here represents the root filesystem on the router.

    #copy the modules and insert it in the kernel
    $(INSTALL_DATA) $(PKG_BUILD_DIR)/obj/ksi.ko $(1)/lib/modules/2.6.19.1/
    $(INSTALL_DATA) $(PKG_BUILD_DIR)/obj/itm.ko $(1)/lib/modules/2.6.19.1/
    insmod ksi.ko
    insmod itm.ko

    # copy the data files
    $(INSTALL_DATA) $(PKG_BUILD_DIR)/obj/libusi.a $(1)/lib/
    $(INSTALL_DATA) $(PKG_BUILD_DIR)/obj/libusi.so $(1)/lib/
    $(INSTALL_DATA) $(PKG_BUILD_DIR)/obj/libusei.a $(1)/lib/
    $(INSTALL_DATA) $(PKG_BUILD_DIR)/obj/libusei-functions.so $(1)/lib/

    #create device
    mknod /dev/xian_itm c 24 0
    chmod a+rwx /dev/xian_itm

endef

$(eval $(call BuildPackage,xian))

Following some Makefile example (from original OpenWRT olsr) to try to compile my modified olsr. In that case it appears in the menuconfig!! but i doesn't compile....

 

include $(TOPDIR)/rules.mk

# name of package
# version number of the sources you're using
# how many times you've released a package based on the above version number
PKG_NAME:=olsr_emisfera
PKG_VERSION:=0.1
PKG_RELEASE:=1

# name of the sources; using variables from above for the version
# server directory containing the above source file (assuming it's not already found in the local dl directory)
# md5sum to avoid corrupted downloads
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=http://example.com/download/sources
#PKG_MD5SUM:=de2d6249665fcb627ecab4e82916096e

# sources will be unpacked into this directory (you shouldn't need to change this)
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)

include $(INCLUDE_DIR)/package.mk

# Metadata; information about what the package is for the ipkg listings
# to keep things simple, a number of fields have been left at their defaults
# and are not shown here.

define Package/olsr_emisfera/Default
 TITLE:=olsr emisfera
 DESCRIPTION:=do the right thing
endef

define Package/olsr_emisfera
  $(call Package/olsr_emisfera/Default)
  #MAINTAINER:=paolo.via@halservice.it
  SECTION:=net
  CATEGORY:=Network
  TITLE+= (daemon)
endef

define Package/olsr_emisfera/description
  Xian is a cross-layer interface that gives useful functions to provide useful information from PHY and MAC layer of 802.11 protocol.

endef

#define KernelPackage/o
#  $(call Package/xian/Default)
#  TITLE+= (kernel module)
#  DESCRIPTION+= che palle
#  FILES:=$(PKG_BUILD_DIR)/obj/ksi.$(LINUX_KMOD_SUFFIX)
#  FILES+=$(PKG_BUILD_DIR)/obj/itm.$(LINUX_KMOD_SUFFIX)
#  SUBMENU:=Network Support
#endef

# We'll use the OpenWrt defaults to configure and compile the package. Otherwise we'd need to define
# Build/Configure - commands to invoke a configure (or similar) script
# Build/Compile - commands used to run make or otherwise build the source

#define Package/xian/install
        # Now that we have the source compiled (magic huh?) we need to copy files out of the source
        # directory and into our ipkg file. These are shell commands, so make sure you start the lines
        # with a TAB. $(1) here represents the root filesystem on the router.

        # make a directory for the config
        #$(INSTALL_DIR) $(1)/etc/xian/

        # copy the config
        #$(INSTALL_CONF) $(PKG_BUILD_DIR)/.conf $(1)/etc/

        # make a directory for some random data files required by mypackage
        #$(INSTALL_DIR) $(1)/usr/share/xian

    #copy the modules and insert it in the kernel
#    $(INSTALL_DATA) $(PKG_BUILD_DIR)/obj/ksi.ko $(1)/lib/modules/2.6.19.1/
#    $(INSTALL_DATA) $(PKG_BUILD_DIR)/obj/itm.ko $(1)/lib/modules/2.6.19.1/

#    insmod ksi.ko
#    insmod itm.ko

        # copy the data files
 #       $(INSTALL_DATA) $(PKG_BUILD_DIR)/obj/libusi.a $(1)/lib/
#    $(INSTALL_DATA) $(PKG_BUILD_DIR)/obj/libusi.so $(1)/lib/
 #       $(INSTALL_DATA) $(PKG_BUILD_DIR)/obj/libusei.a $(1)/lib/
#    $(INSTALL_DATA) $(PKG_BUILD_DIR)/obj/libusei-functions.so $(1)/lib/

        # copy the binary
        #$(INSTALL_BIN) $(PKG_BUILD_DIR)/xian $(1)/usr/bin

    #create device
    
#    mknod /dev/xian_itm c 24 0
#    chmod a+rwx /dev/xian_itm
    
#endef

$(eval $(call BuildPackage,olsr_emisfera))
#$(eval $(call BuildKernelPackage,xian))

can you explain me?
thanks

Please put these tings on the wiki since it's more convenient than the forum.

Thanks for your explaining

that is a good help though

The discussion might have continued from here.