Makefile Troubles...

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Makefile Troubles...

Post by pcmattman »

I'm trying to clean up the source tree of my OS, and in the process am trying to make a "root" makefile that means that you can do everything from within one folder.

Currently I have this:

Code: Select all

# makes everything
all:
	$(MAKE) -f kernel.mk all
	$(MAKE) -f Userland/mattise_lib/Makefile all
	$(MAKE) -f Userland/Makefile all

# cleans everything
clean:
	@$(MAKE) -f kernel.mk clean
	@cd Userland/mattise_lib
	@$(MAKE) clean
	@cd ../../
	@$(MAKE) -f Userland/Makefile clean

#installs everything
install:
	@$(MAKE) -f kernel.mk install
	@cd Userland/mattise_lib
	@$(MAKE) install
	@$(MAKE) -f Userland/Makefile install

# builds the kernel
kernel_all:
	@$(MAKE) -f kernel.mk all

# cleans the kernel
kernel_clean:
	@$(MAKE) -f kernel.mk clean

# installs the kernel
kernel_install:
	@$(MAKE) -f kernel.mk install

# builds all the userland software
userland_all:
	@$(MAKE) -f Userland/Makefile all
	
# cleans all the userland software
userland_clean:
	@$(MAKE) -f Userland/Makefile clean

# installs all the userland software
userland_install:
	@$(MAKE) -f Userland/Makefile install

# builds the mattise library
mattiselib_all:
	@cd Userland/mattise_lib
	@$(MAKE) all

# cleans the mattise library
mattiselib_clean:
	@cd Userland/mattise_lib
	@$(MAKE) clean

# installs the mattise library
mattiselib_install:
	@cd Userland/mattise_lib
	@$(MAKE) install
It prints out:

Code: Select all

$ make all
make -f kernel.mk all
make[1]: Entering directory `/cygdrive/c/osdev/mattiseos/cpp_kernel'
make[1]: Nothing to be done for `all'.
make[1]: Leaving directory `/cygdrive/c/osdev/mattiseos/cpp_kernel'
make -f Userland/mattise_lib/Makefile all
make[1]: Entering directory `/cygdrive/c/osdev/mattiseos/cpp_kernel'
make[1]: *** No rule to make target `crt0.o', needed by `mattise.a'.  Stop.
make[1]: Leaving directory `/cygdrive/c/osdev/mattiseos/cpp_kernel'
make: *** [all] Error 2
If I change into the child directories (eg. cd "Userland/mattise_lib", pretty much what "clean" and "install" use except with "all"):

Code: Select all

$ make all
make -f kernel.mk all
make[1]: Entering directory `/cygdrive/c/osdev/mattiseos/cpp_kernel'
make[1]: Nothing to be done for `all'.
make[1]: Leaving directory `/cygdrive/c/osdev/mattiseos/cpp_kernel'
cd Userland/mattise_lib
make all
make[1]: Entering directory `/cygdrive/c/osdev/mattiseos/cpp_kernel'
make -f kernel.mk all
make[2]: Entering directory `/cygdrive/c/osdev/mattiseos/cpp_kernel'
make[2]: Nothing to be done for `all'.
make[2]: Leaving directory `/cygdrive/c/osdev/mattiseos/cpp_kernel'
cd Userland/mattise_lib
make all
make[2]: Entering directory `/cygdrive/c/osdev/mattiseos/cpp_kernel'
make -f kernel.mk all
make[2]: *** [all] Interrupt
make[1]: *** [all] Interrupt
make: *** [all] Interrupt
The command to produce the above is:

Code: Select all

	$(MAKE) -f kernel.mk all
	cd Userland/mattise_lib
	$(MAKE) all
	cd ../../
	$(MAKE) -f Userland/Makefile all
Any ideas?

Edit: One thing, this _does_ work:

Code: Select all

# builds the mattise library
mattiselib_all:
	cd Userland/mattise_lib
	$(MAKE) all
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

Sounds like the Makefile in Userland/mattise_lib is referencing "./crt.o", which will work when you've cd'd into that directory, but not when your working directory is elsewhere (at the root of your source tree, for example).

IRC there are some Make-defined variables like $(SRC_DIR) or something that give you an absolute path to the directory where make is being run from.

EDIT: I get around this problem by using autoconf/automake. They're dead useful!
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post by pcmattman »

JamesM wrote:EDIT: I get around this problem by using autoconf/automake. They're dead useful!
Could you point me to a tutorial? I take it that this means that you just "configure" and then "make" your OS?
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

http://www.galassi.org/mark//mydocs/aut ... l_toc.html

Thats the first one google picked up. I'll post my configure.in and Makefile.am files when I get home.

Essentially you make a 'configure.in' file which autoconf uses to generate a './configure' bash script. You can tell autoconf that, for example, you require both a working C and C++ compiler, you require the X11 libraries etc etc. Also you can pass parameters to ./configure, so e.g. I have the configure script automagically configure all my build directories for particular architectures (x86, x86_64 etc).

Then, automake uses Makefile.am files to produce Makefile.in files, which in turn are processed by the ./configure script into Makefiles. The advantage of this is that Makefile.am is very very high level.

For example, to produce a program called 'udev':

Code: Select all

bin_PROGRAMS = udev
udev_SOURCES = main.cc bleh.cc bleh2.cc

udev_LDADD = -lkernel
When generated with automake, you can just type:

Code: Select all

./configure
make
And you're done. The best thing is that it does multiple directories dead easily, which is a total pig (as you've found out) to do with Make natively.

JamesM
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

configure.in:

Code: Select all

AC_INIT(configure.in)

AM_CONFIG_HEADER(config.h)
AM_INIT_AUTOMAKE(jimix2, 0.1)

AC_ARG_ENABLE(serial-out, 
             [  --enable-serial-out     Redirects the standard kernel error to the serial 
port.],
             AC_DEFINE([SERIAL_OUT],[],[Serial out]))

case "$target_alias" in
  x86)
    AC_DEFINE([LANG_X86],[],[Compiling for the X86])
    ;;
  x86_64)
    AC_DEFINE([LANG_X86_64],[],[Compiling for the 64-bit X86])
    ;;
  x86_smp)
    AC_DEFINE([LANG_X86_SMP],[],[Compiling for the X86 with multiple 
processors])
    ;;
  x86_64_smp)
    AC_DEFINE([LANG_X86_64_SMP],[],[Compiling for the X86_64 with 
multiple processors])
    ;;
esac	

target_alias

CPPFLAGS=
CXXFLAGS=
AC_SUBST(CPPFLAGS)
AC_SUBST(CXXFLAGS)
CFLAGS=
CCAS=nasm
CCASFLAGS=
AC_SUBST(CCAS)
AC_SUBST(CCASFLAGS)

AC_LANG_CPLUSPLUS
AC_PROG_CXX
AC_PROG_CC
AC_PROG_RANLIB
AM_PROG_AS
AC_PROG_LIBTOOL

AC_OUTPUT(Makefile initrd/Makefile initrd/udev/Makefile src/Makefile \
	src/arch/Makefile src/arch/x86/Makefile src/arch/x86_64/Makefile src/common/Makefile \
	src/fs/Makefile src/lib/Makefile src/memory/Makefile src/process/Makefile \
	src/utilities/Makefile)
top-level Makefile.am:

Code: Select all

# not a GNU package. You can remove this line, if
# have all needed files, that a GNU package needs
AUTOMAKE_OPTIONS = foreign 1.4

SUBDIRS = src initrd

bochs: all
	cd ../../scripts && \
	./update_image.sh ../jimix2/trunk/src/kernel ../jimix2/trunk/initrd/initrd.img ../images/floppy.img && \
	./run_bochs.sh ../images/floppy.img

qemu: all
	cd ../../scripts && \
	./update_image.sh ../jimix2/trunk/src/kernel ../jimix2/trunk/initrd/initrd.img ../images/floppy.img && \
	./run_qemu.sh ../images/floppy.img

qemu-debug: all
	cd ../../scripts && \
	./update_image.sh ../jimix2/trunk/src/kernel ../jimix2/trunk/initrd/initrd.img ../images/floppy.img && \
	./run_qemu_debug.sh ../images/floppy.img

bochs-debug: all
	cd ../../scripts && \
	./update_image.sh ../jimix2/trunk/src/kernel ../jimix2/trunk/initrd/initrd.img ../images/floppy.img && \
	./run_bochs_debug.sh ../images/floppy.img

extraclean: clean
	-rm src/libjimix.a

clean-libc:
	cd newlib-1.15.0/newlib/ && make clean 
	-rm newlib-1.15.0/newlib/libc/sys/lib.a
	-rm newlib-1.15.0/newlib/libc/sys/crt0.o

libc:
	cd newlib-1.15.0/newlib/ && make
main src/Makefile.am:

Code: Select all

bin_PROGRAMS = kernel libkernel.so

# set the include path found by configure
INCLUDES = $(all_includes)

SUBDIRS = arch common fs lib memory process utilities
LDADD=libjimix.a
kernel_SOURCES = Boot.s ElfParser.cc Kernel.cc Kernel.h Multiboot.cc \
	Multiboot.h
kernel_DEPENDENCIES=libjimix.a

# the library search path. - Use the custom linker script Link.ld.
kernel_LDFLAGS = -all-static $(all_libraries) -T Link.ld
AM_CFLAGS = -fno-builtin -fno-exceptions -fno-rtti -fno-stack-protector -m32 \
	-nostdlib -I. -I./common/ -I./memory/
AM_CXXFLAGS = -I. -I./common/ -I./fs -I./memory/ -I./process -I./utilities/ \
	-fno-builtin -fno-exceptions -fno-rtti -fno-stack-protector -m32 -nostartfiles \
	-nostdlib -DKERNEL

libkernel_so_SOURCES= Boot.s ElfParser.cc Kernel.cc Kernel.h Multiboot.cc \
        Multiboot.h useSymbols.cc
libkernel_so_DEPENDENCIES=libjimix.a
libkernel_so_LDFLAGS=-TLink.ld -shared -O0 $(all_libraries)

.s.o:
	nasm -f elf $<

libjimix.a: 
	-rm -rf libjimix.a tmp
	mkdir tmp
	cd tmp; \
	ar x ../common/libjimix.a; \
	ar x ../memory/libjimix.a; \
	ar x ../utilities/libjimix.a; \
	ar x ../process/libjimix.a; \
	ar x ../arch/libjimix.a; \
	ar x ../fs/libjimix.a; \
	cp ../*.o ./ ;\
	ar cru ../libjimix.a *.o
	ranlib libjimix.a
	rm -rf tmp

extraclean: clean
	-rm libjimix.a
	-rm *.o

noinst_HEADERS = errno.h
Hope that should be pretty self-explanatory.
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post by pcmattman »

Makes sense. I'll have to try to implement that into my own kernel, if I can't figure out how to fix this problem :D
User avatar
Kevin McGuire
Member
Member
Posts: 843
Joined: Tue Nov 09, 2004 12:00 am
Location: United States
Contact:

Post by Kevin McGuire »

IRC there are some Make-defined variables like $(SRC_DIR) or something that give you an absolute path to the directory where make is being run from.
$(CURDIR)

About Auto Configure
I was looking at that the other day. It could be useful as long as it plays nice in Windows and Linux.
nick8325
Member
Member
Posts: 200
Joined: Wed Oct 18, 2006 5:49 am

Post by nick8325 »

I think you need to use, e.g., $(MAKE) -C Userland instead of $(MAKE) -f Userland/Makefile.
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post by pcmattman »

nick8325 wrote:I think you need to use, e.g., $(MAKE) -C Userland instead of $(MAKE) -f Userland/Makefile.
Works a charm. Thanks for the help.
Post Reply