I'm trying to compile OpenWRT package. Already compile toolchain. From here I know it can be when use static pattern rules, but I don't. I checked the whole file for syntax errors - everything is fine (maybe I missed something).
OS: Ubuntu 20.04 Server
g++: 9.3.0
OpenWRT: 19.07.7
wiha#osboxes:~/source$ ./scripts/feeds update mypackage
Updating feed 'mypackage' from '\home\wiha\package_src\package' ...
Create index file './feeds/mypackage.index'
/home/wiha/source/feeds/mypackage.tmp/info/.files-packageinfo.mk:1: *** target pattern contains no '%'. Stop.
Makefile:
include $(TOPDIR)/rules.mk
PKG_NAME:=mypackage
PKG_VERSION:=0.1
PKG_RELEASE:=1
SOURCE_DIR:=../../..
include $(INCLUDE_DIR)/package.mk
define Package/mypackage
SECTION:=mypackage
CATEGORY:=Network
TITLE:=The router`s agent
DEPENDS:=+libopenssl +libjson-c +libcurl
URL:=https://www.example.com
endef
define Build/Prepare
mkdir -p $(PKG_BUILD_DIR)
# copy source files
$(CP) -r $(SOURCE_DIR)/src $(PKG_BUILD_DIR)/src
$(CP) $(SOURCE_DIR)/CMakeLists.txt $(PKG_BUILD_DIR)
rm -f $(PKG_BUILD_DIR)/CMakeCache.txt
rm -fR $(PKG_BUILD_DIR)/CMakeFiles
rm -f $(PKG_BUILD_DIR)/Makefile
rm -f $(PKG_BUILD_DIR)/cmake_install.cmake
rm -f $(PKG_BUILD_DIR)/progress.make
endef
define Build/Configure
IN_OPENWRT=1 \
AR="$(TOOLCHAIN_DIR)/bin/$(TARGET_CROSS)ar" \
AS="$(TOOLCHAIN_DIR)/bin/$(TARGET_CC) -c $(TARGET_CFLAGS)" \
LD="$(TOOLCHAIN_DIR)/bin/$(TARGET_CROSS)ld" \
NM="$(TOOLCHAIN_DIR)/bin/$(TARGET_CROSS)nm" \
CC="$(TOOLCHAIN_DIR)/bin/$(TARGET_CC)" \
GCC="$(TOOLCHAIN_DIR)/bin/$(TARGET_CC)" \
CXX="$(TOOLCHAIN_DIR)/bin/$(TARGET_CROSS)g++" \
RANLIB="$(TOOLCHAIN_DIR)/bin/$(TARGET_CROSS)ranlib" \
STRIP="$(TOOLCHAIN_DIR)/bin/$(TARGET_CROSS)strip" \
OBJCOPY="$(TOOLCHAIN_DIR)/bin/$(TARGET_CROSS)objcopy" \
OBJDUMP="$(TOOLCHAIN_DIR)/bin/$(TARGET_CROSS)objdump" \
TARGET_CPPFLAGS="$(TARGET_CPPFLAGS)" \
TARGET_CFLAGS="$(TARGET_CFLAGS)" \
TARGET_LDFLAGS="$(TARGET_LDFLAGS)" \
cmake $(PKG_BUILD_DIR)/CMakeLists.txt
endef
define Build/Compile
$(MAKE) -C $(PKG_BUILD_DIR)
$(STRIP) $(PKG_BUILD_DIR)/mypackage
endef
define Package/mypackage/install
$(CP) $(SOURCE_DIR)/files/* $(1)/
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/mypackage $(1)/usr/bin/
endef
$(eval $(call BuildPackage,mypackage))
.files-packageinfo.mk:
$(eval $(call PackageDir,Makefile:$(eval $(call BuildPackage,mypackage)),Makefile:$(eval $(call BuildPackage,mypackage)),))
Normally, what I would do is to create two makefiles; one manually and another automatically using qmake. Right now, I'd like to find a way to use qmake inside the makefile that I've created manually.
Here it is:
#
# Copyright (C) 2011 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=cloud
PKG_RELEASE:=1
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
include $(INCLUDE_DIR)/package.mk
define Package/cloud
SECTION:=Cloud
CATEGORY:=cloud
TITLE:=Package
endef
define Package/cloud/description
Cloud Package
endef
define Build/Prepare
mkdir -p $(PKG_BUILD_DIR)
$(CP) ./src/* $(PKG_BUILD_DIR)/
endef
define Build/Configure
endef
define Build/Compile
$(MAKE) -C $(PKG_BUILD_DIR) \
CC="$(TARGET_CC)" \
CFLAGS="$(TARGET_CFLAGS) -Wall" \
LDFLAGS="$(TARGET_LDFLAGS)"
endef
define Package/cloud/install
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/cloud$(1)/usr/sbin/
endef
$(eval $(call BuildPackage,cloud))
Is it possible?
Could OpenWrt run on barebox
Is there a portable application framework on top of uboot/barebox? So my source code is indepent from the low-level hardware.
Absolutely possible. I've been using barebox as a main bootloader for imx25 SoC. There is no barebox in a public packages though(I've never met it), but you can build your own "bootloader-barebox" package.
Just follow these links:
https://vivekian2.wordpress.com/2007/03/28/building-your-own-package-for-openwrt/
http://prplfoundation.org/wiki/Creating_an_OpenWrt_package_for_a_web_page
I'm not sure about framework, but you probably know that you can create an application. http://www.denx.de/wiki/view/DULG/UBootStandalone
Here is an example of Makefile for barebox:
#
# Copyright (C) 2013 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=barebox
PKG_VERSION:=0.1
PKG_RELEASE:=0
PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)
PKG_SOURCE:=$(PKG_NAME).tar.bz2
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=GIT-URL
PKG_SOURCE_VERSION:=93aeafd04365cdd5dcb958cc6982c672163154ee
PKG_SOURCE_SUBDIR:=$(PKG_NAME)
PKG_MD5SUM:=
PKG_TARGETS:=bin
include $(INCLUDE_DIR)/package.mk
define barebox/Default
TITLE:=
CONFIG:=
IMAGE:=
endef
define Package/barebox/template
define Package/barebox-$(1)
SECTION:=boot
CATEGORY:=Boot Loaders
TITLE:=$(2)
DEPENDS:=#TARGET_$(1)
URL:=http://localhost/
DEFAULT:=y if (TARGET_$(1)_Default)
VARIANT:=$(1)
endef
endef
define BuildBareboxPackage
$(eval $(barebox/Default))
$(eval $(barebox/$(1)))
$(call Package/barebox/template,$(1),$(TITLE))
endef
define barebox/imx
TITLE:=Barebox for the imx.
endef
BAREBOXS:=imx
ifdef BUILD_VARIANT
$(eval $(call barebox/$(BUILD_VARIANT)))
BAREBOX_CONFIG:=$(if $(CONFIG),$(CONFIG),$(BUILD_VARIANT))
BAREBOX_IMAGE:=$(if $(IMAGE),$(IMAGE),openwrt-$(BOARD)-$(BUILD_VARIANT)-barebox.bin)
endif
define Build/Prepare
$(call Build/Prepare/Default)
endef
define Build/Configure
$(CP) ./barebox-config $(PKG_BUILD_DIR)/.config
endef
define Build/Compile
$(MAKE) -C $(PKG_BUILD_DIR) \
CROSS_COMPILE=$(TARGET_CROSS) ARCH=arm
endef
define Package/barebox/install/template
define Package/barebox-$(1)/install
$(CP) $(PKG_BUILD_DIR)/barebox.bin $(BIN_DIR)/$(2)
endef
endef
$(foreach u,$(BAREBOXS), \
$(eval $(call Package/barebox/install/template,$(u),openwrt-$(BOARD)-$(u)-barebox.bin)) \
)
$(foreach u,$(BAREBOXS), \
$(eval $(call BuildBareboxPackage,$(u))) \
$(eval $(call BuildPackage,barebox-$(u))) \
)
I am following a tutorial for compiling my own package in openwrt.
In the /package/helloworld directory:
.../packege/helloworld$ ls
src Makefile
.../packege/helloworld$ ls src
hello.c main.c Makefile
.../packege/helloworld$vi Makefile
#helloworld makefile
include $(TOPDIR)/rules.mk
PKG_NAME:=helloworld
PKG_RELEASE:=1
PKG_VERSION:=0.1
PKG_BUILD_DEPENDS:=
include $(INCLUDE_DIR)/package.mk
define Package/helloworld
SECTION:=utils
CATEGORY:=Utilities
DEPENDS:=#TARGET_etrax
TITLE:=Yet Another Helloworld Application
endef
define Package/helloworld/description
This is helloworld :p
endef
define Build/Prepare
mkdir -p $(PKG_BUILD_DIR)
$(CP) ./src/* $(PKG_BUILD_DIR)/
endef
define Build/Compile
$(MAKE) -C $(PKG_BUILD_DIR) \
$(TARGET_CONFIGURE_OPTS) \
CFLAGS="$(TARGET_CFLAGS)"
endef
define Package/helloworld/install
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/helloworld $(1)/usr/bin/
endef
$(eval $(call BuildPackage,helloworld))
I have two questions about this Makefile:
I found there are commands, such as mkdir, $(CP),$(MAKE). I changed $(CP) to cp, and the compiling goes well. So I don't understand why these two kinds of formats exsits.
Where the parameters, such as $(PKG_BUILD_DIR), $(INSTALL_DIR), are defined in openwrt? I just found the place where $(TOPDIR) is defined but not the others.
Thanks
These are not different kinds of formats, cp is a Linux command, $(CP) is a makefile construction for "getting the value of make variable CP". Thus, under Linux it should expand to cp (i.e. should be initialized with this value somewhere), and , most probably, to copy under Windows (this is all particular setup-dependent since cp is not fully the same as copy). The same with $(MKDIR) and other system tools.
1.1. $(MAKE) is actually another thing - this is a special make variable which expands to make tool name with arguments/flags passed from command line. Read this.
These are all variables controlling where to build and where to install. See description here.
The following code is taken from OpenWRT project. Can someone give an abstract description? Thanks in advance!
#
# Copyright (C) 2007 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
SUBTARGETS:=clean download prepare compile install update refresh prereq dist distcheck
subtarget-default = $(filter-out ., \
$(if $($(1)/builddirs-$(2)),$($(1)/builddirs-$(2)), \
$(if $($(1)/builddirs-default),$($(1)/builddirs-default), \
$($(1)/builddirs))))
define subtarget
$(call warn_eval,$(1),t,T,$(1)/$(2): $($(1)/) $(foreach bd,$(call subtarget-default,$(1),$(2)),$(1)/$(bd)/$(2)))
endef
lastdir=$(word $(words $(subst /, ,$(1))),$(subst /, ,$(1)))
diralias=$(if $(findstring $(1),$(call lastdir,$(1))),,$(call lastdir,$(1)))
# Parameters: <subdir>
define subdir
$(call warn,$(1),d,D $(1))
$(foreach bd,$($(1)/builddirs),
$(call warn,$(1),d,BD $(1)/$(bd))
$(foreach target,$(SUBTARGETS),
$(foreach btype,$(buildtypes-$(bd)),
$(call warn_eval,$(1)/$(bd),t,T,$(1)/$(bd)/$(btype)/$(target): $(if $(QUILT),,$($(1)/$(bd)/$(btype)/$(target)) $(call $(1)//$(btype)/$(target),$(1)/$(bd)/$(btype))))
+$$(SUBMAKE) -C $(1)/$(bd) $(btype)-$(target) $(if $(findstring $(bd),$($(1)/builddirs-ignore-$(btype)-$(target))), || $(call MESSAGE, ERROR: $(1)/$(bd) [$(btype)] failed to build.))
$$(if $(call debug,$(1)/$(bd),v),,.SILENT: $(1)/$(bd)/$(btype)/$(target))
$(if $(call diralias,$(bd)),$(call warn_eval,$(1)/$(bd),l,T,$(1)/$(call diralias,$(bd))/$(btype)/$(target): $(1)/$(bd)/$(btype)/$(target)))
)
$(call warn_eval,$(1)/$(bd),t,T,$(1)/$(bd)/$(target): $(if $(QUILT),,$($(1)/$(bd)/$(target)) $(call $(1)//$(target),$(1)/$(bd))))
$(if $(BUILD_LOG),#mkdir -p $(BUILD_LOG_DIR)/$(1)/$(bd))
$(foreach variant,$(if $(BUILD_VARIANT),$(BUILD_VARIANT),$(if $($(1)/$(bd)/variants),$($(1)/$(bd)/variants),__default)),
+$(if $(BUILD_LOG),set -o pipefail;) $$(SUBMAKE) -C $(1)/$(bd) $(target) BUILD_VARIANT="$(filter-out __default,$(variant))" $(if $(BUILD_LOG),SILENT= 2>&1 | tee $(BUILD_LOG_DIR)/$(1)/$(bd)/$(target).txt) $(if $(findstring $(bd),$($(1)/builddirs-ignore-$(target))), || $(call MESSAGE, ERROR: $(1)/$(bd) failed to build$(if $(filter-out __default,$(variant)), (build variant: $(variant))).))
)
$$(if $(call debug,$(1)/$(bd),v),,.SILENT: $(1)/$(bd)/$(target))
# legacy targets
$(call warn_eval,$(1)/$(bd),l,T,$(1)/$(bd)-$(target): $(1)/$(bd)/$(target))
# aliases
$(if $(call diralias,$(bd)),$(call warn_eval,$(1)/$(bd),l,T,$(1)/$(call diralias,$(bd))/$(target): $(1)/$(bd)/$(target)))
)
)
$(foreach target,$(SUBTARGETS),$(call subtarget,$(1),$(target)))
endef
# Parameters: <subdir> <name> <target> <depends> <config options> <stampfile location>
define stampfile
$(1)/stamp-$(3):=$(if $(6),$(6),$(STAGING_DIR))/stamp/.$(2)_$(3)$(if $(5),_$(call confvar,$(5)))
$$($(1)/stamp-$(3)): $(TMP_DIR)/.build $(4)
#+$(SCRIPT_DIR)/timestamp.pl -n $$($(1)/stamp-$(3)) $(1) $(4) || \
$(MAKE) $$($(1)/flags-$(3)) $(1)/$(3)
#mkdir -p $$$$(dirname $$($(1)/stamp-$(3)))
#touch $$($(1)/stamp-$(3))
$$(if $(call debug,$(1),v),,.SILENT: $$($(1)/stamp-$(3)))
.PRECIOUS: $$($(1)/stamp-$(3)) # work around a make bug
$(1)//clean:=$(1)/stamp-$(3)/clean
$(1)/stamp-$(3)/clean: FORCE
#rm -f $$($(1)/stamp-$(3))
endef
The subdir template generates the standard make targets for a subdirectory.
It is called with the directory name as first argument, e.g. in package/Makefile it's 'package'
it then treats the variable package/builddirs as the list of subdirectories with valid build targets, which are contained in the SUBTARGETS variable.
For running the 'compile' target of a package 'foo', it allows you to run 'make package/foo/compile' which will recursively invoke make with the right environment variables in order to build the subdirectory.
This template also has support for some optional features that can be enabled through environment variables, e.g. for logging the output to a file, ignoring dependencies, etc.
It also supports selective debugging output.
The stampfile template is simply a small makefile target wrapper for speeding up builds by keeping a recursively timestamp-checked stampfile around it