Compile a kernel module (error stage 2, MODPOST 0) - linux

I'm trying to compile a sample kernel module (test.c) on my Arch linux just typing make in the directory with source and Makefile.
It creates empty folder .tmp_versions and empty files Module.symvers and modules.order, but no .ko
I also tried to compile it under virtual machine with Ubuntu, but I have absolutely the same output. Samples were from the Internet (2 ones).
What I should do else to compile it?
Makefile:
obj−m += test.o
default:
$(MAKE) -C /lib/modules/$(shell uname -r)/build SUBDIRS=$(PWD) modules
clean:
$(MAKE) -C $(KDIR) M=$(PWD) clean
But it shows me:
make -C /lib/modules/4.18.14-arch1-1-ARCH/build SUBDIRS=/home/hime/Documents/module modules
make[1]: Entering directory '/usr/lib/modules/4.18.14-arch1-1-ARCH/build'
Building modules, stage 2.
MODPOST 0 modules
make[1]: Leaving directory '/usr/lib/modules/4.18.14-arch1-1-ARCH/build'
or (verbose):
make -C "/lib/modules/4.18.14-arch1-1-ARCH/build" SUBDIRS="/home/hime/Documents/module" modules V=1
make[1]: Entering directory '/usr/lib/modules/4.18.14-arch1-1-ARCH/build'
test -e include/generated/autoconf.h -a -e include/config/auto.conf || ( \
echo >&2; \
echo >&2 " ERROR: Kernel configuration is invalid."; \
echo >&2 " include/generated/autoconf.h or include/config/auto.conf are missing.";\
echo >&2 " Run 'make oldconfig && make prepare' on kernel src to fix it."; \
echo >&2 ; \
/bin/false)
mkdir -p /home/hime/Documents/module/.tmp_versions ; rm -f /home/hime/Documents/module/.tmp_versions/*
make -f ./scripts/Makefile.build obj=/home/hime/Documents/module
(cat /dev/null; ) > /home/hime/Documents/module/modules.order
make -f ./scripts/Makefile.modpost
find /home/hime/Documents/module/.tmp_versions -name '*.mod' | xargs -r grep -h '\.ko$' | sort -u | sed 's/\.ko$/.o/' | scripts/mod/modpost -m -a -i ./Module.symvers -I /home/hime/Documents/module/Module.symvers -o /home/hime/Documents/module/Module.symvers -S -w -s -T -
make[1]: Leaving directory '/usr/lib/modules/4.18.14-arch1-1-ARCH/build'

Related

Makefile not recognizing already generated sources

I'm trying to generate an RPM with a makefile, the behavior I'm expecting from the makefile is the following:
If RPM doesn't exist and the sources are not yet prepared, go ahead and do both: generate sources and then the RPM
If RPM already exist but the sources changed, go ahead and prepare the sources and generate the RPM once again
If the sources haven't changed and the RPM already exist don't do anything
However, right now the behavior I'm getting from the makefile below is not quite the way I want it, as it recognizes whether the RPM exist but when it comes down to the sources it doesn't really recognize that they already exist.
Here's the makefile:
SHELL = /bin/bash
.SHELLFLAGS = -o pipefail -c
COLORIZE := 2>&1 | sed -re "s/^(Executing|Wrote)(.*: )/"$$'\E'"[32m\1\2"$$'\E'"[0m/g" \
-e "s/(error[s]?)/"$$'\E'"[31m\1"$$'\E'"[0m/ig" \
-e "s/(warn|warning)/"$$'\E'"[33m\1"$$'\E'"[0m/ig"
SPEC := $(shell find . -name \*spec -printf '%f' -quit)
ARCH := $(shell rpm -q --qf '%{arch}' --specfile $(SPEC))
DIST := .el
NAME := $(basename $(SPEC))
RELEASE := $(shell rpm -q --qf '%{release}' --specfile $(SPEC) | cut -d. -f1)
VERSION := $(shell rpm -q --qf '%{version}' --specfile $(SPEC))
BUILDDIR := ./rpm-build
RPM := $(BUILDDIR)/RPMS/$(ARCH)/$(NAME)-$(VERSION)-$(RELEASE)$(DIST).$(ARCH).rpm
RPMBUILD := rpmbuild --define "_topdir %(pwd)/$(BUILDDIR)" \
--define "_source_filedigest_algorithm md5" \
--define "_binary_filedigest_algorithm md5" \
--define "_source_payload w9.gzdio" \
--define "_binary_payload w9.gzdio" \
--define "_sourcedir %{_topdir}/SOURCES" \
--define "_target_os linux" \
--define "dist .el"
SOURCE0 := $(BUILDDIR)/SOURCES/$(NAME)-$(VERSION).jar
.PHONY: all clean
all: $(RPM)
$(BUILDDIR):
#mkdir -p $(BUILDDIR)/{BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS,TEMP}
$(SOURCE0): $(BUILDDIR) $(SPEC)
spectool -g -C $(BUILDDIR)/SOURCES $(SPEC)
$(RPM): $(SPEC) $(SOURCE0)
#echo -e "Building $(RPM)"
$(RPMBUILD) -bb $< $(COLORIZE)
clean:
#- $(RM) -rf ./$(BUILDDIR)
Is there anything I'm doing wrong for managing the sources, I just don't want them to be prepared everytime I run a make command ?
You should never have a target with a directory as a prerequisite, because directory timestamps are updated at unusual times. I shouldn't say "never"; it can be very useful but it means something quite different than what you think.
You can try using an order-only prerequisite for this:
$(BUILDDIR):
#mkdir -p $(BUILDDIR)/{BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS,TEMP}
$(SOURCE0): $(SPEC) | $(BUILDDIR)
spectool -g -C $(BUILDDIR)/SOURCES $(SPEC)
Or you can just put the mkdir inside the recipe:
$(SOURCE0): $(SPEC)
#mkdir -p $(BUILDDIR)/{BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS,TEMP}
spectool -g -C $(BUILDDIR)/SOURCES $(SPEC)
Note, you're using bash-specific issues here ({}). If you want to be portable you need to add:
SHELL := /bin/bash
to your makefile.

Counter to add up number of issues/failures for a summary at the end

I have a makefile like this:
default:
%:
#$(MAKE) -i -C subdir1 $*
#$(MAKE) -i -C subdir2 $*
#$(MAKE) -i -C subdir3 $*
#$(MAKE) -i -C subdir4 $*
#$(MAKE) -i -C subdir5 $*
The basic concept is that I have 5 (or more) sub projects which I will call make on sequentially. I use "-i" flag so that the make can continue to the end and the "-C dir" flag to call make in a sub-directory.
So, lets say that sub project 2 and 5 are failing, then at the end I want to be able to print something like:
3 projects built ok, 2 projects have errors.
So I think I want a counter of some sort, but I have no idea how I can set/increment it on an error. Any ideas?
As every call to $(MAKE) spawns its own subprocess, I can't think of a way to record these numbers easily with an ordinary make variable. You can, however, log the return value of each invocation to a (possibly hidden) file and then grep for your build stats like this:
errLog = .errLog
default:
%:
#$(MAKE) -i -C subdir1 $*; echo $$? > $(errLog)
#$(MAKE) -i -C subdir2 $*; echo $$? >> $(errLog)
#$(MAKE) -i -C subdir3 $*; echo $$? >> $(errLog)
#$(MAKE) -i -C subdir4 $*; echo $$? >> $(errLog)
#$(MAKE) -i -C subdir5 $*; echo $$? >> $(errLog)
#echo "`grep -c '^0' $(errLog)` built ok, `grep -c '^[^0]' $(errLog)` have errors."
Note that the first output redirection must be a single > to overwrite previous return codes in the file, while all others should be two > to not overwrite the file content.

Why does "make all" seem to skip "all:" rule?

I am trying to analyze the following makefile and reproduce its "behavior" step by step.
Although I type "make all" it seems this makefile skips the "all:" line and jumps straight to "build/*.o" (hence the echo's).
The file and its corresponding output:
TOOLCHAIN ?= arm-none-eabi-
SOURCES = Demo/main.c \
Demo/startup.c \
Demo/Drivers/rpi_gpio.c \
Demo/Drivers/rpi_irq.c \
Source/tasks.c \
Source/list.c \
Source/portable/GCC/RaspberryPi/port.c \
Source/portable/GCC/RaspberryPi/portisr.c \
Source/portable/MemMang/heap_4.c
OBJECTS = $(patsubst %.c,build/%.o,$(SOURCES))
INCDIRS = Source/include Source/portable/GCC/RaspberryPi \
Demo/Drivers Demo/
CFLAGS = -Wall $(addprefix -I ,$(INCDIRS))
CFLAGS += -D RPI2
CFLAGS += -march=armv7-a -mtune=cortex-a7 -mfloat-abi=hard -mfpu=neon-vfpv4
ASFLAGS += -march=armv7-a -mcpu=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard
LDFLAGS =
.PHONY: all clean
all: $(MOD_NAME)
echo "in all"
$(MOD_NAME): $(OBJECTS)
echo "in mod name"
ld -shared $(LDFLAGS) $< -o $#
build/%.o: %.c
echo -e "\nin build/*.o:*.c\n"
mkdir -p $(dir $#)
$(TOOLCHAIN)gcc -c $(CFLAGS) $< -o $#
build/%.o: %.s
echo -e "in build/*.o:*.s\n"
mkdir -p $(dir $#)
$(TOOLCHAIN)as $(ASFLAGS) $< -o $#
all: kernel7.list kernel7.img kernel7.syms kernel7.hex
echo -e"in kernel all\n"
$(TOOLCHAIN)size kernel7.elf
kernel7.img: kernel7.elf
$(TOOLCHAIN)objcopy kernel7.elf -O binary $#
echo -e "in kernel7.img\n"
kernel7.list: kernel7.elf
echo -e "kernel7.list\n"
$(TOOLCHAIN)objdump -D -S kernel7.elf > $#
kernel7.syms: kernel7.elf
echo -e "kernel7.syms\n"
$(TOOLCHAIN)objdump -t kernel7.elf > $#
kernel7.hex : kernel7.elf
echo -e "kernel7.hex\n"
$(TOOLCHAIN)objcopy kernel7.elf -O ihex $#
kernel7.elf: $(OBJECTS)
echo -e "kernel7.elf\n"
$(TOOLCHAIN)ld $^ -static -Map kernel7.map -o $# -T Demo/raspberrypi.ld
clean:
rm -f $(OBJECTS)
rm -f kernel7.list kernel7.img kernel7.syms
rm -f kernel7.elf kernel7.hex kernel7.map
rm -rf build
echo -e "cleaning \n"
I tried to replicate this behaviour myself with a tiny piece of code. But it doesn't seem to work:
SOURCES = Demo/Drivers/rpi_irq.c \
Demo/Drivers/rpi_gpio.c
OBJECTS = $(patsubst %.c,build/%.o,$(SOURCES))
.PHONY: all clean
all: $(MOD_NAME)
echo "making all"$(SOURCES)
$(MOD_NAME): $(OBJECTS)
echo "MOD_NAME"
build/%.o:%.c
mkdir -p $(dir $#)
arm-none-eabi-gcc -march=armv7-a -mcpu=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=har $< -o $#
As you can see thanks to the echo's my code just doesn't even build my source code. I'd expect it to go from all->MOD_NAME->build. (This is all the output I get)
So my questions are:
How does the makefile I am analyzing manage to go straight to build/*.o?
Why does my implementation, which I think should do the same doesn't even compile my source code?
The Makefile that you copied contains 2 rules for "all".
The first depends on $(MOD_NAME) which might be empty.
The second rule depends on multiple files "kernel7.*" which themselves depend on "kernel7.elf".
Finally "kernel7.elf" depends on $(OBJECTS).
This last rule is responsible that all your source files will be compiled.
The first rule with $(MOD_NAME) does not need to cause any compilation at all.
In your own Makefile you only have a rule for "all" depending on $(MOD_NAME).
If $(MOD_NAME) is empty in your Makefile as well, you do not have any dependency for "all" at all.
If "all" does not depend on anything, no source files will be compiled.
To solve your problem you need to provide some content for $(MOD_NAME).
all is trying to build $(MOD_NAME), which has dependencies of $(OBJECTS), which it is trying to build.
There are two all's here, which is a problem.

How to install cross compiled cups to target board?

I Cross compiled cups 1.7.0 for sitara arm linux 6
I followed
./configure --host=arm-linux-gnueabihf --disable-gssapi --prefix=/media/rootfs
make
make install
All cups related files are automatically saved in sd card ,
but it shows error on typing cupsd command and not starting cups server
cupsd: Child exited on signal 1.
On checking /etc/cups/cupsd.conf, several paths in the configuration files are
/media/rootfs/var/run/cups/cups.sock
instead of
/var/run/cups/cups.sock
1)how to install this compiled cups to target board without --prefix?
2)Is there any step missing for cross compilation?
Any help will be thankfull.
This is Makefile
#
# "$Id: Makefile 11107 2013-07-08 13:47:51Z msweet $"
#
# Top-level Makefile for CUPS.
#
# Copyright 2007-2013 by Apple Inc.
# Copyright 1997-2007 by Easy Software Products, all rights reserved.
#
# These coded instructions, statements, and computer programs are the
# property of Apple Inc. and are protected by Federal copyright
# law. Distribution and use rights are outlined in the file "LICENSE.txt"
# which should have been included with this file. If this file is
# file is missing or damaged, see the license at "http://www.cups.org/".
#
include Makedefs
#
# Directories to make...
#
DIRS = cups test $(BUILDDIRS)
#
# Make all targets...
#
all:
chmod +x cups-config
echo Using ARCHFLAGS="$(ARCHFLAGS)"
echo Using ALL_CFLAGS="$(ALL_CFLAGS)"
echo Using ALL_CXXFLAGS="$(ALL_CXXFLAGS)"
echo Using CC="$(CC)"
echo Using CXX="$(CC)"
echo Using DSOFLAGS="$(DSOFLAGS)"
echo Using LDFLAGS="$(LDFLAGS)"
echo Using LIBS="$(LIBS)"
for dir in $(DIRS); do\
echo Making all in $$dir... ;\
(cd $$dir ; $(MAKE) $(MFLAGS) all $(UNITTESTS)) || exit 1;\
done
#
# Make library targets...
#
libs:
echo Using ARCHFLAGS="$(ARCHFLAGS)"
echo Using ALL_CFLAGS="$(ALL_CFLAGS)"
echo Using ALL_CXXFLAGS="$(ALL_CXXFLAGS)"
echo Using CC="$(CC)"
echo Using CXX="$(CC)"
echo Using DSOFLAGS="$(DSOFLAGS)"
echo Using LDFLAGS="$(LDFLAGS)"
echo Using LIBS="$(LIBS)"
for dir in $(DIRS); do\
echo Making libraries in $$dir... ;\
(cd $$dir ; $(MAKE) $(MFLAGS) libs) || exit 1;\
done
#
# Make unit test targets...
#
unittests:
echo Using ARCHFLAGS="$(ARCHFLAGS)"
echo Using ALL_CFLAGS="$(ALL_CFLAGS)"
echo Using ALL_CXXFLAGS="$(ALL_CXXFLAGS)"
echo Using CC="$(CC)"
echo Using CXX="$(CC)"
echo Using DSOFLAGS="$(DSOFLAGS)"
echo Using LDFLAGS="$(LDFLAGS)"
echo Using LIBS="$(LIBS)"
for dir in $(DIRS); do\
echo Making all in $$dir... ;\
(cd $$dir ; $(MAKE) $(MFLAGS) unittests) || exit 1;\
done
#
# Remove object and target files...
#
clean:
for dir in $(DIRS); do\
echo Cleaning in $$dir... ;\
(cd $$dir; $(MAKE) $(MFLAGS) clean) || exit 1;\
done
#
# Remove all non-distribution files...
#
distclean: clean
$(RM) Makedefs config.h config.log config.status
$(RM) cups-config
$(RM) conf/cupsd.conf conf/mime.convs conf/pam.std conf/snmp.conf
$(RM) doc/help/ref-cupsd-conf.html doc/help/standard.html doc/index.html
$(RM) man/client.conf.man
$(RM) man/cups-deviced.man man/cups-driverd.man
$(RM) man/cups-lpd.man man/cupsaddsmb.man man/cupsd.man
$(RM) man/cupsd.conf.man man/drv.man man/lpoptions.man
$(RM) packaging/cups.list
$(RM) packaging/cups-desc.plist packaging/cups-info.plist
$(RM) templates/header.tmpl
$(RM) desktop/cups.desktop
$(RM) scheduler/cups.sh scheduler/cups-lpd.xinetd
$(RM) scheduler/org.cups.cups-lpd.plist scheduler/cups.xml
-$(RM) doc/*/index.html
-$(RM) templates/*/header.tmpl
-$(RM) -r autom4te*.cache clang cups/charmaps cups/locale driver/test
#
# Make dependencies
#
depend:
for dir in $(DIRS); do\
echo Making dependencies in $$dir... ;\
(cd $$dir; $(MAKE) $(MFLAGS) depend) || exit 1;\
done
#
# Run the clang.llvm.org static code analysis tool on the C sources.
# (at least checker-231 is required for scan-build to work this way)
#
.PHONY: clang clang-changes
clang:
$(RM) -r clang
scan-build -V -k -o `pwd`/clang $(MAKE) $(MFLAGS) clean all
clang-changes:
scan-build -V -k -o `pwd`/clang $(MAKE) $(MFLAGS) all
#
# Generate a ctags file...
#
ctags:
ctags -R .
#
# Install everything...
#
install: install-data install-headers install-libs install-exec
#
# Install data files...
#
install-data:
echo Making all in cups...
(cd cups; $(MAKE) $(MFLAGS) all)
for dir in $(DIRS); do\
echo Installing data files in $$dir... ;\
(cd $$dir; $(MAKE) $(MFLAGS) install-data) || exit 1;\
done
echo Installing cups-config script...
$(INSTALL_DIR) -m 755 $(BINDIR)
$(INSTALL_SCRIPT) cups-config $(BINDIR)/cups-config
#
# Install header files...
#
install-headers:
for dir in $(DIRS); do\
echo Installing header files in $$dir... ;\
(cd $$dir; $(MAKE) $(MFLAGS) install-headers) || exit 1;\
done
if test "x$(privateinclude)" != x; then \
echo Installing config.h into $(PRIVATEINCLUDE)...; \
$(INSTALL_DIR) -m 755 $(PRIVATEINCLUDE); \
$(INSTALL_DATA) config.h $(PRIVATEINCLUDE)/config.h; \
fi
#
# Install programs...
#
install-exec: all
for dir in $(DIRS); do\
echo Installing programs in $$dir... ;\
(cd $$dir; $(MAKE) $(MFLAGS) install-exec) || exit 1;\
done
#
# Install libraries...
#
install-libs: libs
for dir in $(DIRS); do\
echo Installing libraries in $$dir... ;\
(cd $$dir; $(MAKE) $(MFLAGS) install-libs) || exit 1;\
done
#
# Uninstall object and target files...
#
uninstall:
for dir in $(DIRS); do\
echo Uninstalling in $$dir... ;\
(cd $$dir; $(MAKE) $(MFLAGS) uninstall) || exit 1;\
done
echo Uninstalling cups-config script...
$(RM) $(BINDIR)/cups-config
-$(RMDIR) $(BINDIR)
#
# Run the test suite...
#
test: all unittests
echo Running CUPS test suite...
cd test; ./run-stp-tests.sh
check: all unittests
echo Running CUPS test suite with defaults...
cd test; ./run-stp-tests.sh 1 0 n n
debugcheck: all unittests
echo Running CUPS test suite with debug printfs...
cd test; ./run-stp-tests.sh 1 0 n y
#
# Create HTML documentation using Mini-XML's mxmldoc (http://www.msweet.org/)...
#
apihelp:
for dir in cgi-bin cups filter ppdc scheduler; do\
echo Generating API help in $$dir... ;\
(cd $$dir; $(MAKE) $(MFLAGS) apihelp) || exit 1;\
done
framedhelp:
for dir in cgi-bin cups filter ppdc scheduler; do\
echo Generating framed API help in $$dir... ;\
(cd $$dir; $(MAKE) $(MFLAGS) framedhelp) || exit 1;\
done
#
# Create an Xcode docset using Mini-XML's mxmldoc (http://www.msweet.org/)...
#
docset: apihelp
echo Generating docset directory tree...
$(RM) -r org.cups.docset
mkdir -p org.cups.docset/Contents/Resources/Documentation/help
mkdir -p org.cups.docset/Contents/Resources/Documentation/images
cd man; $(MAKE) $(MFLAGS) html
cd doc; $(MAKE) $(MFLAGS) docset
cd cgi-bin; $(MAKE) $(MFLAGS) makedocset
cgi-bin/makedocset org.cups.docset \
`svnversion . | sed -e '1,$$s/[a-zA-Z]//g'` \
doc/help/api-*.tokens
$(RM) doc/help/api-*.tokens
echo Indexing docset...
/Applications/Xcode.app/Contents/Developer/usr/bin/docsetutil index org.cups.docset
echo Generating docset archive and feed...
$(RM) org.cups.docset.atom
/Applications/Xcode.app/Contents/Developer/usr/bin/docsetutil package --output org.cups.docset.xar \
--atom org.cups.docset.atom \
--download-url http://www.cups.org/org.cups.docset.xar \
org.cups.docset
#
# Lines of code computation...
#
sloc:
for dir in cups scheduler; do \
(cd $$dir; $(MAKE) $(MFLAGS) sloc) || exit 1;\
done
#
# Make software distributions using EPM (http://www.msweet.org/)...
#
EPMFLAGS = -v --output-dir dist $(EPMARCH)
aix bsd deb depot inst pkg setld slackware swinstall tardist:
epm $(EPMFLAGS) -f $# cups packaging/cups.list
epm:
epm $(EPMFLAGS) -s packaging/installer.gif cups packaging/cups.list
rpm:
epm $(EPMFLAGS) -f rpm -s packaging/installer.gif cups packaging/cups.list
.PHONEY: dist
dist: all
$(RM) -r dist
$(MAKE) $(MFLAGS) epm
case `uname` in \
*BSD*) $(MAKE) $(MFLAGS) bsd;; \
Darwin*) $(MAKE) $(MFLAGS) osx;; \
Linux*) test ! -x /usr/bin/rpm || $(MAKE) $(MFLAGS) rpm;; \
SunOS*) $(MAKE) $(MFLAGS) pkg;; \
esac
#
# Don't run top-level build targets in parallel...
#
.NOTPARALLEL:
#
# End of "$Id: Makefile 11107 2013-07-08 13:47:51Z msweet $".
#
DSTROOT=/media/rootfs option in make install is the solution for cups.
./configure --host=arm-linux-gnueabihf --disable-gssapi --libdir=/usr/lib
make
sudo make install DSTROOT=/media/rootfs
Dont use --prefix.
cupsd: Child exited on signal 1.
This error is due to hardcoding of paths.You can avoid it by placing your installed executables in same directory by creating it in your rootfs.
There are two way to avoid above 1) while configuring the source-code give the prefixsome other folder like $HOME/cups so that this will be a standalone. create directory by the same name $HOME/cups same as you prefix in your rootfs copy this standalone executable as u mentioned in prefix.
e.g --prefix=/home/vinay/cups then make same directory path in your rootfs /home/vinay/cups and copy all your executables here.
For second way i am not sure it will work or not since for qt project i tried and its worked.By Use of sysroot
2)provide option --sysroot=/media/rootfs --prefix=/media/rootfs so that while executing ypur executables executable look correctly search the path with help of sysroot.

/bin/sh: Syntax Error: end of file unexpected

I am getting an error when running the following makefile with make -f makefile2 install (apart install the rest is working):
all:myapp
#which compiler
CC = gcc
#Where to install
INSTDIR = /usr/local/bin
#where are include files kept
INCLUDE = .
#Options for development
CFLAGS = -g -Wall -ansi
#Options for release
# CFLAGS = -O -Wall -ansi
myapp: main.o 2.o 3.o
$(CC) -o myapp main.o 2.o 3.o
main.o: main.c a.h
$(CC) -I$(INCLUDE) $(CFLAGS) -c main.c
2.o: 2.c a.h b.h
$(CC) -I$(INCLUDE) $(CFLAGS) -c 2.c
3.o: 3.c b.h c.h
$(CC) -I$(INCLUDE) $(CFLAGS) -c 3.c
clean:
-rm main.o 2.o 3.o
install: myapp
#if [ -d $(INSTDIR) ]; \
then \
cp myapp $(INSTDIR);\
chmod a+x $(INSTDIR)/myapp;\
chmod og-w $(INSTDIR)/myapp;\
echo "Installed in $(INSTDIR)";\
else
echo "Sorry, $(INSTDIR) does not exist";\
fi
I'm getting the following error:
error /bin/sh: 7: Syntax error: end of file unexpected
make: *** [install] Error 2
From what I understand it is a white space/tabulation/non unix character problem in the last lines of the makefile (after install:). But even trying to delete all spaces and replacing with tabulation I didn't manage to run the makefile properly. The code comes directly from a programming book I'm reading and is an example. Any help appreciated!
You're missing a trailing slash on your else under the install rule. It should be:
install: myapp
#if [ -d $(INSTDIR) ]; \
then \
cp myapp $(INSTDIR);\
chmod a+x $(INSTDIR)/myapp;\
chmod og-w $(INSTDIR)/myapp;\
echo "Installed in $(INSTDIR)";\
else\
echo "Sorry, $(INSTDIR) does not exist";\
fi

Resources