makefile error: No rule to make target How to fix? - makefile

The error:
make: *** No rule to make target 'build-x86_64'. Stop.
My makefile:
x86_64_asm_source_files := $(shell find src/impl/x86_64 -name *.asm)
x86_64_asm_object_files := $(patsubst src/impl/x86_64/%.asm, build/x86_64/%.o, $(x86_64_asm_source_files))
$(x86_64_asm_object_files): build/x86_64/%.o : src/impl/x86_64/%.asm
mkdir -p $(dir $#) && \
nasm -f elf64 $(patsubst build/x86_64/%.o, src/impl/x86_64/%.asm, $#) -o $#
.PHONY: build-x86_64
build-x86_64: $(x86_64_asm_object_files)
mkdir -p dist/x86_64 && .
x86_64-elf-ld -n -o dist/x86_64/kernel.bin -T targets/x86_64/linker.ld $(x86_64_asm_object_files) && \
cp dist/x86_64/kernel.bin targets/x86_64/iso/boot/kernel.bin && \
grub-mkrescue /usr/lib/grub/i386-pc -o dist/x86_64/target.iso targets/x86_64/iso

Related

make: *** No rule to make target 'build-x86_64'. Stop. error in my OS when i run make build-x86_64

x86_64_asm_source_files := $(shell find src/impl/x86_64 -name *.asm)
x86_64_asm_object_files := $(patsubst src/impl/x86_64/%.asm, build/x86_64/%.o, $(x86_64_asm_source_files))
$(x86_64_asm_object_files): build/x86_64/%.o : src/impl/x86_64/%.asm
mkdir -p $(dir $#) && \
nasm -f elf64 $(patsubst build/x86_64/%.o, src/impl/x86_64/%.asm, $#) -o $#
.PHONY: build-x86_64
build-x86_64: $(x86_64_asm_object_files)
mkdir -p dist/x86_64 && \
x86_64-elf-ld -n -o dist/x86_64/kernel.bin -T targets/x86_64/linker.ld $(x86_64_asm_object_files) && \
cp dist/x86_64/kernel.bin targets/x86_64/iso/boot/kernel.bin && \
grub-mkrescue /usr/lib/grub/i386-pc -o dist/x86_64/kernel.iso targets/x86_64/iso

Function `wildcard` doesn't see $#

I have the following Makefile:
.PHONY: all clean run
INC_DIR = include
SRC_DIR = src
KERNEL_NAME = mykernel
AS = as
ASPARAMS = --32
CXX = g++
CXXPARAMS = -m32 -ffreestanding -fno-exceptions -fno-rtti -I$(INC_DIR)
#CXXPARAMS = -m32 -fno-use-cxa-atexit -nostdlib -fno-builtin -fno-rtti -fno-exceptions -fno-leading-underscore -I$(INC_DIR)
LDPARAMS = -melf_i386
BUILD_DIR = build
ISO_DIR = $(BUILD_DIR)/iso
ISO_BOOT = $(ISO_DIR)/boot
GRUB_CONFIG = $(ISO_BOOT)/grub/grub.cfg
SRC = $(wildcard $(SRC_DIR)/*.cpp)
SRC += $(wildcard $(SRC_DIR)/**/*.cpp)
SRC += $(wildcard $(SRC_DIR)/*.s)
OBJS = $(SRC:=.o)
OBJS := $(addprefix $(BUILD_DIR)/, $(OBJS))
.SECONDARY: $(OBJS)
all: $(KERNEL_NAME).iso
run: $(KERNEL_NAME).iso
qemu-system-i386 -cdrom $<
$(KERNEL_NAME).iso: $(GRUB_CONFIG) $(ISO_BOOT)/$(KERNEL_NAME).bin
grub-mkrescue -o $# $(ISO_DIR)
$(ISO_BOOT)/$(KERNEL_NAME).bin: $(SRC_DIR)/linker.ld $(OBJS)
ld $(LDPARAMS) -T $^ -o $# -nostdlib
$(GRUB_CONFIG):
mkdir -p $(dir $#)
echo 'set timeout=0' > $(GRUB_CONFIG)
echo 'set default=0' >> $(GRUB_CONFIG)
echo '' >> $(GRUB_CONFIG)
echo 'menuentry "$(KERNEL_NAME) OS" {' >> $(GRUB_CONFIG)
echo ' multiboot2 /boot/$(KERNEL_NAME).bin' >> $(GRUB_CONFIG)
echo ' boot' >> $(GRUB_CONFIG)
echo '}' >> $(GRUB_CONFIG)
$(BUILD_DIR)/%.cpp.o: %.cpp
echo $(dir $#)
echo $(wildcard (dir $#))
#ifeq ($(wildcard (dir $#)),)
# echo "mkdir -p $(dir $#)" ;
# $(CXX) $(CXXPARAMS) $< -c -o $#
#endif
$(BUILD_DIR)/%.s.o: %.s
#if [ ! -d $(dir $#) ]; then \
echo "mkdir -p $(dir $#)" ; \
mkdir -p $(dir $#) ; \
fi
$(AS) $(ASPARAMS) $< -o $#
clean:
rm -rf $(KERNEL_NAME).iso $(BUILD_DIR)
Why do I get the output with empty echo by running make? The directory build/src exists.
echo build/src/
build/src/
echo
echo build/src/
build/src/
echo
echo build/src/
build/src/
echo
echo build/src/
build/src/
echo
echo build/src/
build/src/
echo
echo build/src/
build/src/
echo
echo build/src/gui/
build/src/gui/
echo
echo build/src/gui/
build/src/gui/
echo
ld -melf_i386 -T src/linker.ld build/src/Keyboard.cpp.o build/src/VGArray.cpp.o build/src/mykernel.cpp.o build/src/TextCursor.cpp.o build/src/VideoContext.cpp.o build/src/GDTable.cpp.o build/src/gui/DrawContext.cpp.o build/src/gui/Window.cpp.o build/src/loader.s.o -o build/iso/boot/mykernel.bin -nostdlib
ld: cannot find build/src/Keyboard.cpp.o: No such file or directory
ld: cannot find build/src/VGArray.cpp.o: No such file or directory
ld: cannot find build/src/mykernel.cpp.o: No such file or directory
ld: cannot find build/src/TextCursor.cpp.o: No such file or directory
ld: cannot find build/src/VideoContext.cpp.o: No such file or directory
ld: cannot find build/src/GDTable.cpp.o: No such file or directory
ld: cannot find build/src/gui/DrawContext.cpp.o: No such file or directory
ld: cannot find build/src/gui/Window.cpp.o: No such file or directory
Makefile:33: recipe for target 'build/iso/boot/mykernel.bin' failed
make: *** [build/iso/boot/mykernel.bin] Error 1
I tried to make a minimal example, but it works right when build directory exists.
.PHONY: all clean
CXX = g++
OPTS = -Wall -Wextra
BUILD_DIR = build
APP = $(BUILD_DIR)/main
SRC_DIR = src
SRC = $(wildcard $(SRC_DIR)/*.cpp)
all: $(APP)
$(APP): $(APP).o
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.cpp
echo $(dir $#)
echo $(wildcard $(dir $#))
clean:
rm -rf $(BUILD_DIR) main *.o
Replace echo $(wildcard (dir $#)) by echo $(wildcard $(dir $#)) and things should work as you expect.
Note: SRC += $(wildcard $(SRC_DIR)/**/*.cpp) will not recurse in subdirectories. If you believed it would, try:
SRC = $(shell find $(SRC_DIR) -type f -name '*.cpp')
SRC += $(wildcard $(SRC_DIR)/*.s)

GNU-make: remove first directories

I'd like to simplify the following GNU make rules:
lib/dir1/org/eclipse/jetty/jetty-http/9.3.0.M2/jetty-http-9.3.0.M2.jar:
mkdir -p $(dir $#) && curl -o $# "http://central.maven.org/maven2/org/eclipse/jetty/jetty-http/9.3.0.M2/jetty-http-9.3.0.M2.jar"
lib/dir1/org/eclipse/jetty/jetty-util/9.3.0.M2/jetty-util-9.3.0.M2.jar:
mkdir -p $(dir $#) && curl -o $# "http://central.maven.org/maven2/org/eclipse/jetty/jetty-util/9.3.0.M2/jetty-util-9.3.0.M2.jar"
lib/dir1/javax/servlet/javax.servlet-api/3.1.0/javax.servlet-api-3.1.0.jar:
mkdir -p $(dir $#) && curl -o $# "http://central.maven.org/maven2/javax/servlet/javax.servlet-api/3.1.0/javax.servlet-api-3.1.0.jar"
lib/dir1/org/slf4j/slf4j-api/1.7.10/slf4j-api-1.7.10.jar:
mkdir -p $(dir $#) && curl -o $# "http://central.maven.org/maven2/org/slf4j/slf4j-api/1.7.10/slf4j-api-1.7.10.jar"
how can I remove the prefix 'lib/dir1' in the curl URL to get a simple rule like:
$(addsuffix lib/dir1/,org/eclipse/jetty/jetty-http/9.3.0.M2/jetty-http-9.3.0.M2.jar org/eclipse/jetty/jetty-util/9.3.0.M2/jetty-util-9.3.0.M2.jar javax/servlet/javax.servlet-api/3.1.0/javax.servlet-api-3.1.0.jar org/slf4j/slf4j-api/1.7.10/slf4j-api-1.7.10.jar):
mkdir -p $(dir $#) && curl -o $# \
"http://central.maven.org/maven2/$(something $#)"
something like 'substring-after'...
Doesn't $(patsubst lib/dir1/%,%,$#) work?

Makefile to compile lists of source files

I have lists of files that I want my Makefile to compile, one list for each source language:
CFILES= Src/Application/main.c Src/Core/data.c Lib/routines.c
ASFILES= Src/Application/startup.s Lib/sqrt.s
I want all the output in one directory:
OBJDIR= output
How do I do the equivalent of:
output/main.o : Src/Application/main.c
cc -c -o output/main.o Src/Application/main.c
output/data.o : Src/Core/data.c
cc -c -o output/data.o Src/Core/data.c
output/routines.o : Lib/routines.c
cc -c -o output/routines.o Lib/routines.c
output/startup.o : Src/Application/startup.s
as -o output/startup.o Src/Application/startup.s
output/sqrt.o : Lib/sqrt.s
as -o output/sqrt.o Lib/sqrt.s
The recipes are the same for every file in its list.
The input files are in all sorts of different directories and it is not acceptable to just list their filenames and use a search path to find them, their explicit paths must be used.
The output filename is the basename of the source file name with the extension changed to o. There are no duplicated basenames between the lists for the different source languages.
I do not want to have to list the object files, this should be derived from the source lists.
I am using gnu make, but bonus points for a portable solution.
Something like the following could do:
all :
OBJDIR := output
CFILES := Src/Application/main.c Src/Core/data.c Lib/routines.c
ASFILES := Src/Application/startup.s Lib/sqrt.s
target = ${OBJDIR}/$(patsubst %.s,%.o,$(notdir ${1}))
obj.c :=
obj.s :=
define obj
$(call target,${1}) : ${1} | ${OBJDIR}
obj$(suffix ${1}) += $(call target,${1})
${1} : ; mkdir -p `dirname $$#` && touch $$# # Create the source for testing. Remove this.
endef
define SOURCES
$(foreach src,${1},$(eval $(call obj,${src})))
endef
$(eval $(call SOURCES,${CFILES}))
$(eval $(call SOURCES,${ASFILES}))
all : ${obj.c} ${obj.s}
${obj.c} : % :
#echo cc -c -o $# $^; touch $# # echo and touch are for testing. Remove these.
${obj.s} : % :
#echo as -o $# $^; touch $# # echo and touch are for testing. Remove these.
${OBJDIR} :
mkdir $#
.PHONY: all
Output:
$ make
make: Entering directory '/home/max/tmp'
mkdir -p `dirname Src/Application/main.c` && touch Src/Application/main.c # Create the source for testing. Remove this.
mkdir output
cc -c -o output/main.c Src/Application/main.c
mkdir -p `dirname Src/Core/data.c` && touch Src/Core/data.c # Create the source for testing. Remove this.
cc -c -o output/data.c Src/Core/data.c
mkdir -p `dirname Lib/routines.c` && touch Lib/routines.c # Create the source for testing. Remove this.
cc -c -o output/routines.c Lib/routines.c
mkdir -p `dirname Src/Application/startup.s` && touch Src/Application/startup.s # Create the source for testing. Remove this.
as -o output/startup.o Src/Application/startup.s
mkdir -p `dirname Lib/sqrt.s` && touch Lib/sqrt.s # Create the source for testing. Remove this.
as -o output/sqrt.o Lib/sqrt.s
make: Leaving directory '/home/max/tmp'
I have little experience in writing makefiles, so this is just an attempt. In my example I have C and C++ files in a few directories and build a program made of these files.
$ cat Makefile
.PHONY : clean all
CC=gcc
CXX=g++
CFILES = c/f.c c/g.c
CPPFILES = cpp/main.cpp
OUTPUT = ./output
SOURCE_DIRS := $(dir $(CFILES))
SOURCE_DIRS += $(dir $(CPPFILES))
VPATH = $(sort $(SOURCE_DIRS))
C_FILENAMES := $(notdir $(CFILES))
CPP_FILENAMES += $(notdir $(CPPFILES))
OBJ_FILES := $(patsubst %.c, $(OUTPUT)/%.o, $(C_FILENAMES) )
OBJ_FILES += $(patsubst %.cpp, $(OUTPUT)/%.o, $(CPP_FILENAMES) )
all : $(OUTPUT)/program
$(OUTPUT)/program : $(OBJ_FILES)
g++ -o $# $^
$(OUTPUT)/%.o : %.cpp
$(shell mkdir -p $(OUTPUT) )
$(CXX) $(CXXFLAGS) -c $< -o $#
$(OUTPUT)/%.o : %.c
$(shell mkdir -p $(OUTPUT) )
$(CC) $(CFLAGS) -c $< -o $#
clean:
rm -fr $(OUTPUT)
And this is an example of using my makefile:
$ make
gcc -c c/f.c -o output/f.o
gcc -c c/g.c -o output/g.o
g++ -c cpp/main.cpp -o output/main.o
g++ -o output/program output/f.o output/g.o output/main.o
The following method should do what you want: compile all of your specified source files and put the object files in the directory ./output automatically. Of course, you need to provide compiler options, proper libraries necessary for linking, and so on.
OBJDIR =./output
SRCDIR1 =./Src/Application
SRCDIR2 =./Src/Core
SRCDIR3 =./Lib
SRC1 =$(SRCDIR1)/main.c
SRC2 =$(SRCDIR2)/data.c
SRC3 =$(SRCDIR3)/routines.c
SRC4 =$(SRCDIR1)/startup.s
SRC5 =$(SRCDIR3)/sqrt.s
OBJ1 =$(patsubst $(SRCDIR1)/%.c,$(OBJDIR)/%.o,$(SRC1))
OBJ2 =$(patsubst $(SRCDIR2)/%.c,$(OBJDIR)/%.o,$(SRC2))
OBJ3 =$(patsubst $(SRCDIR3)/%.c,$(OBJDIR)/%.o,$(SRC3))
OBJ4 =$(patsubst $(SRCDIR1)/%.s,$(OBJDIR)/%.o,$(SRC4))
OBJ5 =$(patsubst $(SRCDIR3)/%.s,$(OBJDIR)/%.o,$(SRC5))
vpath %.c $(SRCDIR1): $(SRCDIR2): $(SRCDIR3)
vpath %.s $(SRCDIR1): $(SRCDIR3)
all: $(OBJ1) $(OBJ2) $(OBJ3) $(OBJ4) $(OBJ5)
cc $^ -o executable
$(OBJDIR)/%.o: %.c | $(OBJDIR)
cc -c $< -o $#
$(OBJDIR)/%.o: %.s | $(OBJDIR)
cc -c $< -o $#
$(OBJDIR):
mkdir -p $(OBJDIR)

build error when compile openwrt package

I want to build package for openwrt
I use this openwrt Makefile :
include $(TOPDIR)/rules.mk
PKG_NAME:=libxmpp
PKG_VERSION:=2012-06-11
PKG_RELEASE=1
PKG_FIXUP:=autoreconf
include $(INCLUDE_DIR)/package.mk
define Package/libxmpp
SECTION:=libs
CATEGORY:=Libraries
TITLE:=xmpp library
DEPENDS:=+libstdcpp
endef
define Package/libxmpp/description
A xmpp client
endef
CONFIGURE_ARGS += \
--disable-threads \
--enable-static \
--enable-shared
USE_LOCAL=$(shell ls ./src/ 2>/dev/null >/dev/null && echo 1)
ifneq ($(USE_LOCAL),)
define Build/Prepare
$(CP) ./src/* $(PKG_BUILD_DIR)
endef
endif
define Package/libxmpp/install
$(INSTALL_DIR) $(1)/usr/lib
$(CP) $(PKG_BUILD_DIR)/libxmpp.so* $(1)/usr/lib
endef
define Build/InstallDev
$(INSTALL_DIR) $(1)/usr/include
$(CP) $(PKG_BUILD_DIR)/xmpp.h $(1)/usr/include
$(INSTALL_DIR) $(1)/lib
$(CP) $(PKG_BUILD_DIR)/libxmpp.so* $(1)/usr/lib
endef
$(eval $(call BuildPackage,libxmpp))
the Makefile of xmmp is as follow :
CFLAGS := -fPIC -O3 -g -Wall -Werror
MAJOR := 0
MINOR := 1
NAME := xmpp
VERSION := $(MAJOR).$(MINOR)
lib: lib$(NAME).so.$(VERSION)
lib$(NAME).so.$(VERSION): $(NAME).o
$(CXX) -shared -Wl,-soname,lib$(NAME).so.$(MAJOR) $^ -o $#
clean:
$(RM) *.o *.so*
but when compile the package I got this error :
make[3]: Entering directory `/home/anis/cwmp/AA3/package/libxmpp'
rm -f /home/anis/cwmp/AA3/staging_dir/target-i386_uClibc-0.9.33.2/stamp/.libxmpp_installed
make[3]: [clean-staging] Error 123 (ignored)
make[3]: Leaving directory `/home/anis/cwmp/AA3/package/libxmpp'
rm -rf /home/anis/cwmp/AA3/tmp/stage-libxmpp
mkdir -p /home/anis/cwmp/AA3/tmp/stage-libxmpp/host /home/anis/cwmp/AA3/staging_dir/target-i386_uClibc-0.9.33.2/packages /home/anis/cwmp/AA3/staging_dir/host/packages
install -d -m0755 /home/anis/cwmp/AA3/tmp/stage-libxmpp/usr/include
cp -fpR /home/anis/cwmp/AA3/build_dir/target-i386_uClibc-0.9.33.2/libxmpp-2012-06-11/xmpp.h /home/anis/cwmp/AA3/tmp/stage-libxmpp/usr/include
install -d -m0755 /home/anis/cwmp/AA3/tmp/stage-libxmpp/lib
cp -fpR /home/anis/cwmp/AA3/build_dir/target-i386_uClibc-0.9.33.2/libxmpp-2012-06-11/libxmpp.so* /home/anis/cwmp/AA3/tmp/stage-libxmpp/usr/lib
find /home/anis/cwmp/AA3/tmp/stage-libxmpp -name '*.la' | xargs -r rm -f;
if [ -f /home/anis/cwmp/AA3/staging_dir/target-i386_uClibc-0.9.33.2/packages/libxmpp.list ]; then /home/anis/cwmp/AA3/scripts/clean-package.sh "/home/anis/cwmp/AA3/staging_dir/target-i386_uClibc-0.9.33.2/packages/libxmpp.list" "/home/anis/cwmp/AA3/staging_dir/target-i386_uClibc-0.9.33.2"; fi
if [ -d /home/anis/cwmp/AA3/tmp/stage-libxmpp ]; then (cd /home/anis/cwmp/AA3/tmp/stage-libxmpp; find ./ > /home/anis/cwmp/AA3/tmp/stage-libxmpp.files); SHELL= /home/anis/cwmp/AA3/staging_dir/host/bin/flock /home/anis/cwmp/AA3/tmp/.staging-dir.flock -c ' mv /home/anis/cwmp/AA3/tmp/stage-libxmpp.files /home/anis/cwmp/AA3/staging_dir/target-i386_uClibc-0.9.33.2/packages/libxmpp.list && cp -fpR /home/anis/cwmp/AA3/tmp/stage-libxmpp/* /home/anis/cwmp/AA3/staging_dir/target-i386_uClibc-0.9.33.2/; '; fi
cp: cannot overwrite directory `/home/anis/cwmp/AA3/staging_dir/target-i386_uClibc-0.9.33.2/usr/lib' with non-directory
make[2]: *** [/home/anis/cwmp/AA3/staging_dir/target-i386_uClibc-0.9.33.2/stamp/.libxmpp_installed] Error 1
make[2]: Leaving directory `/home/anis/cwmp/AA3/package/libxmpp'
make[1]: *** [package/libxmpp/compile] Error 2
make[1]: Leaving directory `/home/anis/cwmp/AA3'
make: *** [package/libxmpp/compile] Error 2
My hunch is that it's this line:
$(CP) $(PKG_BUILD_DIR)/libxmpp.so* $(1)/usr/lib
Does resolving it to
$(CP) $(PKG_BUILD_DIR)/libxmpp.so* $(1)/usr/lib/
fix the issue?

Resources