I'm such a beginner on OpenWrt and Makefiles, trying to demonstrate "Helloworld" example of creating a package but at the package feed update step, from command ./scripts/feeds update mypackages I get this error
Updating feed 'mypackages' from '/home/onur/Desktop/OpenWRT/openwrt/mypackages' ...
Create index file './feeds/mypackages.index'
/home/onur/Desktop/OpenWRT/openwrt/feeds/mypackages.tmp/info/.files-packageinfo.mk:1: *** target pattern contains no '%'. Stop.
I have src-link mypackages /home/onur/Desktop/OpenWRT/openwrt/mypackages in my feeds.conf, "helloworld" C program compiled on /openwrt/helloworld directory and below is my Makefile:
include $(TOPDIR)/rules.mk
# Name, version and release number
# The name and version of your package are used to define the variable to point to the build directory of your package: $(PKG_BUILD_DIR)
PKG_NAME:=helloworld
PKG_VERSION:=1.0
PKG_RELEASE:=1
# Source settings (i.e. where to find the source codes)
# This is a custom variable, used below
SOURCE_DIR:=/home/onur/Desktop/OpenWRT/openwrt/helloworld
include $(INCLUDE_DIR)/package.mk
# Package definition; instructs on how and where our package will appear in the overall configuration menu ('make menuconfig')
define Package/helloworld
SECTION:=examples
CATEGORY:=Examples
TITLE:=Hello, World!
endef
# Package description; a more verbose description on what our package does
define Package/helloworld/description
A simple "Hello, world!" -application.
endef
# Package preparation instructions; create the build directory and copy the source code.
# The last command is necessary to ensure our preparation instructions remain compatible with the patching system.
define Build/Prepare
mkdir -p $(PKG_BUILD_DIR)
cp $(SOURCE_DIR)/* $(PKG_BUILD_DIR)
$(Build/Patch)
endef
# Package build instructions; invoke the target-specific compiler to first compile the source file, and then to link the file into the final executable
define Build/Compile
$(MAKE) -C $(PKG_BUILD_DIR) \
CXX="$(TARGET_CROSS)g++"
endef
# Package install instructions; create a directory inside the package to hold our executable, and then copy the executable we built previously into the folder
define Package/helloworld/install
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/helloworld $(1)/usr/bin
endef
# This command is always the last, it uses the definitions and variables we give above in order to get the job done
$(eval $(call BuildPackage,helloworld))
I know I may have mistake on cross-compile part but I don't think that's the issue that I'm having right now.
When I try to make this Makefile, I get that error.
Makefile:13: /package.mk: No such file or directory
make: *** No rule to make target '/package.mk'. Stop.
I can't find any problem like this anywhere. Why it can't even find "package.mk" file.
My directory structure is like, Top directory is Desktop/OpenWrt/openwrt and this Makefile is in Desktop/OpenWrt/openwrt/mypackage folder. I'm on Ubuntu 20.04
I found solution to my question on OpenWrt Forum. Here is the link of thread
I wrote my own openwrt package for my script and the compilation stage I put it in the package file as this path openwrt / feeds / package / is that the path is correct or not?
or if I have is for the compilation error:
make[1]: *** No rule to make target `package/test/compile'. Stop.
make: *** [package/test/compile] Error 2
THis my Makefile:
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=test
PKG_VERSION:=1.0
PKG_RELEASE:=1
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
DEPENDS:= +nmap +python
include $(INCLUDE_DIR)/package.mk
define Package/test
SECTION:=secure
CATEGORY:=Monitoring
TITLE:=test
define Package/test/description
test tis is my first package
endef
define Build/Prepare
mkdir -p $(PKG_BUILD_DIR)
$(CP) ./src/* $(PKG_BUILD_DIR)/
endef
define Package/test/install
$(INSTALL_DIR) $(1)/bin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/test $(1)/bin/
endef
$(eval $(call BuildPackage,test))
I need help please.
thanks.
You don't really have to put your source code anywhere in the /openwrt/ folder. It can be placed, let's say, in /Documents/[name] folder. However it is important that you put your OpenWRT-specific Makefile in the /openwrt/ tree. I am not sure if putting your Makefile in /openwrt/feeds/package is correct but I put my Makefiles in /openwrt/package/[name] folder which works fine. Your source code will be automatically copied by the toolchain to the same folder anyway.
Note: if you place your source code somewhere on your system (for example, in the Documents folder) you have to specify the path to it in your Makefile as follows: PKG_SOURCE_URL:=file://$(TOPDIR)/../Documents/[name]
Your make[1] errors are basically telling you that the toolchain could not find the Makefile. Try putting Makefile in /openwrt/package/[name].
I am having an issue with this makefile giving the fatal error: "Don't know how to make target calc.o". The naming is correct along with being in the working directory, and the other issue is that when I switch the order of the object files for default target file it will say it does not know how to make that target either, so the order does not seem to change anything or be one specific file. I am running the make command on a sun sparc unix server as well. The makefile is pasted below:
#The following rule tells make about possible suffixes
#(extensions) of file names.
.SUFFIXES: .c .o
#The following definition of CC ensures that
#gcc will be used to compile the C source files.
CC = gcc
#The following definition of CFLAGS ensures that
#the debugger can be used with the executable file (p1)
#created by running make.
CFLAGS = -g
#The following rule tells make how a ".o" file should
#be created from the corresponding ".c" file.
#Note that the "-c" option must be used here since we are
#compiling source files separately. (Note that the line
#following the ".c.o:" line begins with the "tab" character.)
.c.o:
$(CC) $(CFLAGS) -c $<
#Dependency rule for the default target and how the
#default target is to be created. (Note that the line
#following the dependency rule begins with the "tab"
#character.)
p2: main.o textToBin.o binToText.o calc.o
gcc main.o textToBin.o binToText.o calc.o -o p2
#Dependency rules for other targets. (We don't need to
#specify how these targets are created since we have already
#given a general rule for creating a ".o" file from the
#corresponding ".c" file.)
#NO HEADER FILES
#Target for removing unnecessary files.
clean:
rm -f *.o core
I have the following Makefile.am which is supposed to create foo.hdb and foo.cdb from foo.h (via the Python script):
TESTS = check_foo
check_PROGRAMS = check_foo
check_foo_SOURCES = check_foo.c $(top_builddir)/src/isti.h \
foo.cdb foo.h foo.hdb
check_foo_CFLAGS = #CHECK_CFLAGS# $(all_includes) -I../../clib/src/
check_foo_LDADD = $(top_builddir)/src/libcorm.la #CHECK_LIBS# -lsqlite3
%.hdb %.cdb: %.h
PYTHONPATH=$(top_builddir)/cgen/src python $(top_builddir)/cgen/src/isti/cgen/run.py $<
clean-local:
rm -f *.hdb *.cdb
However, although make foo.hdb and make foo.cdb work (call the Python code and generates the foo.hdb and foo.cdb files from foo.h), make clean check (or the two separately) does not (missing foo.hdb - no such file) - the pattern rule is not called to generate foo.hdb from foo.h.
In other words: the pattern rule is not being called for the files listed in check_foo_SOURCES.
How can I make this work? The rest of the autotools infrastructure is working fine. From looking at the Makefile I suspect the issue is with how autotools expands the check sources.
This is all on Linux with Gnu make. Here is the Makefile.
[Updated slightly to reflect the help from MadScientist].
Later update
The following Makefile (just make, not autotools) works fine, so the issue seems to be related to autotools and check support.
all: check_foo
CFLAGS=-I../../clib/src
LDFLAGS=-L../../clib/src/.libs
check_foo: check_foo.c foo.h corm_foo.h corm_foo.c
gcc $(CFLAGS) $(LDFLAGS) $^ -o $# -lcorm -lsqlite3
corm_%.h corm_%.c: %.h
PYTHONPATH=../../cgen/src python ../../cgen/src/isti/cgen/run.py $<
clean:
rm -f corm_*.h corm_*.c
rm -f *.o
(Note that I've switched from xxx.hdb to corm_xxx.h, etc, so that file extensions remain OK).
More Details
Since it seems to be related to the CHECK macros, this is configure.ac:
AC_INIT([corm], [0.1], [a.cooke#isti.com])
AC_CONFIG_MACRO_DIR([m4])
PKG_CHECK_MODULES([CHECK], [check >= 0.9.4])
AM_INIT_AUTOMAKE([-Wall foreign -Werror])
AC_PROG_CC_C99
AM_PROG_CC_C_O
LT_INIT
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_FILES([Makefile clib/Makefile clib/src/Makefile clib/tests/Makefile clib/docs/Makefile cgen/Makefile cgen/docs/Makefile example/Makefile example/src/Makefile])
AC_CHECK_PROGS([DOXYGEN], [doxygen], AC_MSG_WARN([Doxygen not found - continuing without Doxygen support]))
AM_CONDITIONAL([HAVE_DOXYGEN], [test -n "$DOXYGEN"])
AM_COND_IF([HAVE_DOXYGEN], [AC_CONFIG_FILES([clib/docs/Doxyfile cgen/docs/Doxyfile])])
SOLUTION
OK, so summarizing the various things below, there were two important issues (once I had fixed file extensions - see the "plain" makefile and fceller's answer), either one of which was sufficient to make things work:
(The handling of) Header files is complicated. Because of auto-dependencies, programatically generated header files break things. The solution is to use BUILT_SOURCES
But (the handling of) .c files is not complicated. So putting the corm_foo.c in front of check_foo.c would trigger the generation of that file. Since that also generates corm_foo.h, everything works (because check_foo.c now can include corm_foo.h).
Also, fceller has some good general points about tidy makefiles and explains why the "plain" makefile works.
The line
%.cdb: %.hdb
does not do anything. Check the GNU make manual and you'll see that a pattern rule without a command line is used to DELETE a previously defined rule with that same pattern. Since there's no previous rule, this is essentially a no-op.
If you have a command that creates TWO output files with ONE invocation of a rule, then you need to put both patterns in the same rule, like this:
%.cdb %.hdb: %.h
PYTHONPATH=$(top_builddir)/cgen/src python $(top_builddir)/cgen/src/isti/cgen/run.py $<
This will tell GNU make that both targets are generated from one invocation of the rule. BE AWARE! This syntax only has this behavior for pattern rules. Explicit rules with multiple targets do something entirely different (confusingly enough).
As for the make clean behavior, I'm not sure. The makefile generated by automake is too complex for me to just read it; it would require some debugging (run it and trace what happens). However, I suspect that the rules there are not designed properly to allow a clean target and a build target to both be run in the same invocation of make. Run the two commands separately and see if that works better:
make clean
make check
You need to tell automake that foo.hdb is a source file that is to be constructed. Add the following to Makefile.am:
BUILT_SOURCES = foo.hdb
First of all: you do not need to include the "*.h" in *_SOURCES. The automake will generated code to generate the dependencies. From the manual: Header files listed in a _SOURCES definition will be included in the distribution but otherwise ignored
The change you made in the plain Makefile ("Note that I've switched from xxx.hdb to corm_xxx.h, etc, so that file extensions remain OK") is essential. The automake FILTERS the *_SOURCES list using the filename extension in order to see what to call (CC, CXX, F77).
The following Makefile.am will work:
TEST = check_foo
check_PROGRAMS = check_foo
check_foo_SOURCES = check_foo.c foo.db.c
check_foo_CFLAGS =
check_foo_LDADD =
%.db.c %.db.h: %.h
echo "int i = 1;" > foo.db.c
echo "int j;" > foo.db.h
clean-local:
rm -f *.db.h *.db.c
Let me try to add an indirect answer/discussion to the existing direct ones.
I recently moved away from make for the same kind of reasons you experienced: it is extremely powerful but sometimes a bit difficult to debug when things do not go as expected.
I recently discovered pydoit which is very promising as a debuggable replacement build tool for make. Since the notion of "pattern rules" was not present in it, I proposed an independent package to do the job: fprules.
This is how you would perform the same task that you mention in your post, with doit and fprules:
from fprules import file_pattern
# all: check_foo
DOIT_CONFIG = {'default_tasks': ['check_foo']}
CFLAGS = '-I../../clib/src'
LDFLAGS = '-L../../clib/src/.libs'
# check_foo: check_foo.c foo.h corm_foo.h corm_foo.c
# gcc $(CFLAGS) $(LDFLAGS) $^ -o $# -lcorm -lsqlite3
def task_check_foo():
"""
Compiles the `check_foo` executable
"""
src_files = ('check_foo.c', 'foo.h', 'corm_foo.h', 'corm_foo.c')
dst_file = 'check_foo'
return {
'file_dep': src_files,
'actions': ["gcc %s %s %s -o %s -lcorm -lsqlite3" % (CFLAGS, LDFLAGS, ' '.join(src_files), dst_file)],
'verbosity': 2,
'targets': [dst_file],
'clean': True
}
# corm_%.h corm_%.c: %.h
# PYTHONPATH=../../cgen/src python ../../cgen/src/isti/cgen/run.py $<
def task_gen_corm():
"""
Generates files `corm_%.h` and `corm_%.c`
for each header file `%.h`.
"""
for data in file_pattern('./*.h', dict(h_file='./corm_%.h', c_file='./corm_%.c')):
yield {
'name': data.name,
'file_dep': [data.src_path],
'actions': ["PYTHONPATH=../../cgen/src python ../../cgen/src/isti/cgen/run.py %s" % data.src_path],
'verbosity': 2,
'targets': [data.h_file, data.c_file],
'clean': True
}
# clean:
# rm -f corm_*.h corm_*.c
# rm -f *.o
# No need to create tasks for this:
# with 'clean': True, `doit clean` will clean all target files
Then simply run doit in the folder.
Do not hesitate to provide feedback on the projects pages if needed: for example multiline commands are not supported, you can vote for them if you too feel that they are missing: https://github.com/pydoit/doit/issues/314
I'm trying to compile an open source project on windows under mingw/msys.
The makefile contains (among others) this line
#${MAKE} --no-print-directory -C . -f physfs.make
physfs.make contains (among others) these lines:
ifndef CC
CC = gcc
endif
when I ran make I get the following error:
Creating obj/Debug/physfs
physfs.c
make[1]: cc: Command not found
make[1]: *** [obj/Debug/physfs/physfs.o] Error 127
make: *** [physfs] Error 2
If I comment the ifndef / endif pair leaving CC = gcc intact, the build works. If instead of make I issue this command:
make -e CC=gcc
the build works as well. But when I run the following command in msys:
echo $CC
nothing is displayed.
I think there is something basic about how environment variables work in MSYS and make that I don't understand.
Could please some help me troubleshoot this issue, so I can understand why simple 'make' command complains and why the ifndef block doesn't function as I expect it to function.
CC is one of several implicit variables automatically defined in a make session, so the line ifndef CC should never evaluate to true.
This explains why you see nothing on the command line for echo $CC. The MSYS environment has no concept of CC.
If you want to see the value of variables from within a make session, you can always use the info function:
$(info $(CC))
This will echo the value of the CC variable to the console at the point when that line in the makefile is evaluated.