Cmake custom package install rule

I recently added custom packages to my openwrt environment.
I noticed something i find strange.
My package compiles successfully and the install rule defined inside the cmake file seems to be use only to create the opkg package. In fact this created package works perfectly if a copy it on the target and install it.
In another side, when i build firmware image, my binary is not installed in the rootfs and to get it works, i had to define a second install rule within package makefile:

efine Package/xxxxxx/install
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/xxxx $(1)/usr/bin/

it works like a charm but i'm wondering why i had to define a second install rule to do exactlty the same thing that i defined within my cmake ...
Is it normal ? did i do something wrong ?

This is a source of error because if i want to my package works when i generate and flash the image on target and i also want to get the opkg package to upgrade for example a target without reflashing, i have to ensure both install rules are correctly defined !

Thank's for help

Just to add something to my previous post. My conclusion is the opkg package is not used by the openwrt build system to install on "local rootfs" before creating global firmware image. Thus, if i want to be sure my package works correctly, i have to test it on a target.
The local rootfs generation and the package generation seems to be completely independant operations in openwrt.

Is my understanding correct ?

I ask those question because i also used buildroot and yocto. Buildroot does not (as far as i kwnow) contain package manager (unlike yocto).
Yocto use the created package, install it on "local tootfs" and generates image.
The install rule is defined once (in my case in cmakefile)

Thank's for help


Without actually seeing your makefile, we can only guess.

Here is what happens via make:

  1. default make build/install into ../build_dir/target-(arch)/(packagename)/ipkg-install
  2. gather opkg install files + strip into ../build_dir/target-(arch)/(packagename)/ipkg-(target name)
  3. install in target-root: ../staging_dir/target/root-(target)
  4. install dev/host/build only stuff into ../staging_dir/target/...

So the root-(target) dir under staging mirrors what you will have on your device.

As example i do a quick test of my build bins via qemu-userspace this way:

  • install my feed to get qemu-userspace
    now add/build qemu-userspace bins for host via:
./scripts/feeds install -p extra qemu-userspace
make package/qemu-userspace/host/compile -j8

Test build samba binary for default target:
./staging_dir/hostpkg/bin/qemu-mips -L staging_dir/target-mips_24kc_musl/root-ath79/ staging_dir/target-mips_24kc_musl/root-ath79/usr/sbin/smbd -V

As you can see i hand the staging root as our qemu base root-fs path.

This way i can do a basic check if the build binary can find/use all its shared libs and if i build the correct version or check other simple command-line parameters. I use this so i don't have to verify/test always via my live devices on rather trivial changes/updates.
This is also faster/simpler than setting up a full qemu system for openWrt.

Thanks for your quick response.

My makefile:

include $(TOPDIR)/


include $(INCLUDE_DIR)/
include $(INCLUDE_DIR)/

define Package/custom_websocket_server
	TITLE:=loopback websocket server for test purpose
	DEPENDS:=+libstdcpp +ixwebsocket +libatomic

define Package/custom_websocket_server/description
	loopback websocket server for test purpose

define Build/Prepare
	cp -rL $(PKG_BUILD_DIR)/../../../package/polestar/ws-server/src/* $(PKG_BUILD_DIR)/.

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

$(eval $(call BuildPackage,custom_websocket_server))

My CMake install rule

        RUNTIME DESTINATION /usr/bin/)

I want to have only one install rule (cmake)
If a remove the makefile install rule, my binary is not installed within "4. install in target-root: `../staging_dir/target/root-(target)"

is it normal ?

Thank's for help


Regarding the qemu, i never used it but it is a very good idea, i will try.

You miss the PKG_INSTALL:=1 line if you want your package default installed.
The basic rule is to use this macro to trigger the default install routine, but into the ipk_install target dir, from there you can pick what you actually want to install for openwrt via the define /install section.
The reason is many default install routines add manuals and dev headers/files, but we want just whats needed on the target device aka the bins/libs and init stuff.

1 Like