OpenWRT. Makefile target pattern contains no '%' - makefile

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)),))

Related

Why is Makefile not including the header?

I'm trying to make a library for my project but I am very very new to Makefiles. I tried several configurations and adding -I but none worked.
I have the following three:
libft/
../includes/
....libft.h
../lst
....ft_lstnew.c
....ft_lstadd_front.c
....ft_lstadd_back.c
.... [...]
../src
....ft_isalpha.c
....ft_isalnum.c
.... [...]
And the following makefile:
NAME=libft.a
LIBSO=libft.so
CC=gcc
CFLAGS=-Wall -Wextra -Werror
SRC_DIR=src/
BONUS_DIR=lst/
OBJ_DIR=obj/
SRC_FILES= ft_bzero.c \
ft_isalmun.c \
ft_isalpha.c \
ft_isascii.c \
ft_isdigit.c \
ft_isprint.c \
ft_memchr.c \
ft_memcpy.c \
ft_memmove.c \
ft_memset.c \
ft_strchr.c \
ft_strlcat.c \
ft_strlcpy.c \
ft_strlen.c \
ft_strncmp.c \
ft_strrchr.c \
ft_tolower.c \
ft_toupper.c
BONUS_FILES=ft_lstadd_back.c \
ft_lstadd_front.c \
ft_lstdelone.c \
ft_lstclear.c \
ft_lstiter.c \
ft_lstlast.c \
ft_lstmap.c \
ft_lstnew.c \
ft_lstsize.c
SRC_PATH=$(addprefix $(SRC_DIR), $(SRC_FILES))
BONUS_PATH=$(addprefix $(BONUS_DIR), $(BONUS_FILES))
SRC_NAMES=$(SRC_FILES:.c=.o)
BONUS_NAMES=$(BONUS_FILES:.c=.o)
SRC_PATH_O=$(addprefix $(SRC_DIR), $(SRC_NAMES))
BONUS_PATH_O=$(addprefix $(BONUS_DIR), $(BONUS_NAMES))
HDR_NAME=libft.h
HDR_DIR=includes/
HDR= $(addprefix $(HDR_DIR),$(HDR_NAME))
all: $(NAME)
$(NAME): $(SRC_PATH_O)
ar rc $# $<
ranlib $#
$(OBJ_DIR):
mkdir $#
$(OBJ_DIR)%.o: $(SRC_DIR)%.c $(HDR_NAME)
$(CC) $(CFLAGS) -c $< -o $# -I $(HDR)
clean:
rm -rf $(OBJ_DIR)
fclean: clean
rm -f $(NAME)
re: fclean all
.PHONY: all clean fclean re
And I keep getting this each time I type make on the terminal:
gcc -Wall -Wextra -Werror -c -o src/ft_bzero.o src/ft_bzero.c
src/ft_bzero.c:1:10: fatal error: libft.h: No such file or directory
1 | #include "libft.h"
| ^~~~~~~~~
compilation terminated.
make: *** [<builtin>: src/ft_bzero.o] Error 1
Am I missing something? It's literally my first time.
Yes, you're missing some things.
First, look at the command line make shows:
gcc -Wall -Wextra -Werror -c -o src/ft_bzero.o src/ft_bzero.c
Note that the output here is not right for the recipe of the pattern rule you created: there's no -I option, and the object file is being written to src/ not obj/.
From this you should realize that your pattern rule is not being used at all, and instead make is using its built-in rule for building object files.
Why isn't your pattern rule being used? Let's look at it:
$(OBJ_DIR)%.o: $(SRC_DIR)%.c $(HDR_NAME)
what is this after variable expansion?
obj/%.o: src/%.c libft.h
This pattern (like all patterns) can only match if ALL the prerequisites either already exist or can be built. The src/%.c exists, after the pattern substitution. What about libft.h? No, that doesn't exist. What does exist is includes/libft.h but that's not the same thing.
So, this rule fails to match and make goes back to using its default rules.
If you want to say that every object file depends on that header, you have to use the correct path to the header file when you write the pattern.
Next, this is wrong:
$(CC) $(CFLAGS) -c $< -o $# -I $(HDR)
What is $(HDR)? It's the name of the file: include/libft.h. You don't include header file names with -I; you include directories that headers are looked for in. So you need $(HDR_DIR) here instead.

makefile C code compile and link in one step but want two separate steps

My currently working makefile uses gcc to compile and link in one step. It is 600 lines long so I have cut it down to just show you the 'compile and link' and hex stages (very cut down code here!)
$(PROGRAM_ELF): \
$(BSP_DIR)/install/lib/$(CONFIGURATION)/libmetal.a \
$(BSP_DIR)/install/lib/$(CONFIGURATION)/libmetal-gloss.a \
$(BSP_DIR)/metal.$(LINK_TARGET).lds
mkdir -p $(dir $#)
$(MAKE) -C $(SRC_DIR) $(basename $(notdir $#)) \
PORT_DIR=$(PORT_DIR) \
AR=$(RISCV_AR) \
CC=$(RISCV_GCC) \
CXX=$(RISCV_GXX) \
ASFLAGS="$(RISCV_ASFLAGS)" \
CCASFLAGS="$(RISCV_CCASFLAGS)" \
CFLAGS="$(RISCV_CFLAGS)" \
CXXFLAGS="$(RISCV_CXXFLAGS)" \
XCFLAGS="$(RISCV_XCFLAGS)" \
LDFLAGS="$(RISCV_LDFLAGS)" \
LDLIBS="$(RISCV_LDLIBS)" \
PROJ_SRC="$(PROJ_SRC)"
$(PROGRAM_HEX): \
$(PROGRAM_ELF)
$(RISCV_OBJCOPY) -O ihex $(PROGRAM_ELF) $#
mv $(PROGRAM_HEX) $(PROGRAM_TMP)
$(RISCV_OBJCOPY) -O verilog $(PROGRAM_ELF) $#
cp $(PROGRAM_HEX) $(PROGRAM_MEM)
mv $(PROGRAM_TMP) $(PROGRAM_HEX)
However, I need the 'compile and link stage' to be in 2 steps now as I'll be using a different compiler which has separate compile and link exes. How would I do this ? So the above would need to be split into 2. Examples online are a bit vague.
at its simplest, you use the gcc (or g++) -c option to compile the source without linking. This will generate an object file - which you can use in the linker state. Here is a simple example:
SOURCE = test.cpp
OBJECT = test.o
OUTPUT = run
all:
#g++ $(SOURCE) -c -o $(OBJECT) <------ Compile test.cpp, produces test.o
#g++ $(OBJECT) -o $(OUTPUT) <------ Links test.o into executable `run`
clean:
#$(RM) -rf $(OBJECT) $(OUTPUT)
That's it...
I did this which seemed to work:
#list of all files
PROJ_SRC = $(SRC_DIR)/plsi2c_riscv.c \
$(SRC_DIR)/SimSpi.c \
etc
#assume BUILD_FOLDER defined already
OBJ_FILES = $(addprefix $(BUILD_FOLDER)/,$(PROJ_SRC:.c=.o))
$(BUILD_FOLDER)/%.o: %.c
#Create the folder structure for the output file
#mkdir -p $(dir $#)
$(MY_CC) $(CCFLAGS) $< -o $#
$(BUILD_FOLDER)/example: $(OBJ_FILES)
mkdir -p $(dir $#)
#echo Linking $(notdir $#)
$(MY_LINK) $(LFLAGS) $^ $(LDLIBS) -o $#

Openwrt Makefile with custom compile definition does not get executed

I'm trying to get a custom compile definition to work to seperete "make compile" from "make install" but the custom definition Build/compile never gets executed.
define Build/compile
echo -e "\e[1;34m \nBuild/compile $(PKG_NAME)\n $<\e[0m" \
$(MAKE) $(MAKE_FLAGS) -C $(PKG_BUILD_DIR) \
DESTDIR="$(PKG_INSTALL_DIR)"
endef
this does not work when executed like: make -j1 V=s package/network/nodejs/node/compile
but the prepare step works:
define Build/Prepare
echo -e "\e[1;34m \nBuild/Prepare $(PKG_NAME)\n $<\e[0m"
endef
when executed with: make -j1 V=s package/network/nodejs/node/prepare
So please could you help to find out what goes wrong with the following script:
#
# Copyright (C) 2007-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:=nodejs
PKG_VERSION:=0.12.7
PKG_RELEASE:=0
PKG_SOURCE:=node-v$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://nodejs.org/dist/v$(PKG_VERSION)/
PKG_MD5SUM:=5523ec4347d7fe6b0f6dda1d1c7799d5
PKG_BUILD_DEPENDS:=nodejs/host
HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/node-v$(PKG_VERSION)
PKG_BUILD_DIR:=$(BUILD_DIR)/node-v$(PKG_VERSION)
#PKG_INSTALL:=1
PKG_BUILD_PARALLEL:=1
include $(INCLUDE_DIR)/host-build.mk
include $(INCLUDE_DIR)/package.mk
define Package/nodejs
SUBMENU:=Node.js
SECTION:=net
CATEGORY:=Network
TITLE:=Node.js Evented I/O for V8 JavaScript
URL:=http://nodejs.org
MAINTAINER:=Xin Ouyang <xinpascal#gmail.com>
DEPENDS:=#armeb||#arm||#i386 +libstdcpp +libpthread +librt +libopenssl +uclibcxx
endef
define Package/nodejs/description
Node.js is a platform built on Chrome's JavaScript runtime for easily
building fast, scalable network applications. Node.js uses an event-driven,
non-blocking I/O model that makes it lightweight and efficient, perfect
for data-intensive real-time applications that run across distributed
devices.
endef
define Package/nodejs-npm
SUBMENU:=Node.js
SECTION:=net
CATEGORY:=Network
TITLE:=Node Package Manager
URL:=https://npmjs.org
MAINTAINER:=Xin Ouyang <xinpascal#gmail.com>
DEPENDS:=#armeb||#arm||#i386 +libstdcpp +libpthread +librt +libopenssl +uclibcxx
endef
define Package/nodejs-npm/description
npm is the package manager for the Node JavaScript platform. It puts
modules in place so that node can find them, and manages dependency
conflicts intelligently.
endef
#We need to override all args becouse they are not compatible with the build script
CONFIGURE_ARGS:=
HOST_CONFIGURE_ARGS:=
HOST_CONFIGURE_CMD:=$(HOST_CONFIGURE_VARS) ./configure --without-snapshot ;
CONFIGURE_ARGS:= --without-snapshot
#HOST_CONFIGURE_ARGS:=
HOST_MAKE_FLAGS +=
BUILDTYPE=Release i18nsupport=off
define Build/Prepare
echo -e "\e[1;34m \nBuild/Prepare $(PKG_NAME)\n $<\e[0m"
endef
define Build/nodejs/Compile
echo -e "\e[1;34m \n Build/Compile $(PKG_NAME) \n $<\e[0m"
endef
define Build/compile
echo -e "\e[1;34m \nBuild/compile $(PKG_NAME)\n $<\e[0m" \
$(MAKE) $(MAKE_FLAGS) -C $(PKG_BUILD_DIR) \
DESTDIR="$(PKG_INSTALL_DIR)"
endef
define Package/nodejs/install
echo -e "\e[1;34m \nBuild/install $(PKG_NAME)\n $<\e[0m" \
$(MAKE) $(MAKE_FLAGS) -C $(PKG_BUILD_DIR) install DESTDIR=$(PKG_INSTALL_DIR)
$(INSTALL_DIR) $(1)/usr/bin
$(CP) $(PKG_INSTALL_DIR)/usr/bin/node $(1)/usr/bin/node
endef
define Package/nodejs-npm/install
$(INSTALL_DIR) $(1)/usr/bin
$(CP) $(PKG_INSTALL_DIR)/usr/bin/npm $(1)/usr/bin/npm
$(INSTALL_DIR) $(1)/usr/lib/node_modules
$(CP) -r $(PKG_INSTALL_DIR)/usr/lib/node_modules/npm/ \
$(1)/usr/lib/node_modules
endef
#define Build/InstallDev
# $(INSTALL_DIR) $(1)/usr/share/nodejs-src
# $(CP) $(PKG_BUILD_DIR)/* $(1)/usr/share/nodejs-src
#endef
$(eval $(call HostBuild))
$(eval $(call BuildPackage,nodejs))
$(eval $(call BuildPackage,nodejs-npm))
It should be Build/Compile, not compile (capital C).

Using Qmake in Makefile?

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?

Makefile question in OpenWRT build system

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

Resources