3

I have a file named: Makefile and a main.c file i am doing the next code in the main.c file

int main(int argc, char *argv[])
{

    //if 0 then it is default scheduling which is Round Robin.
    //if 1 then the scheduling will be Round Robin.
    //if 2 then the scheduling will be Priority based.
    //if 3 then both scheduling are acceptable, and we decide to use Round Robin.
    int scheduling = 0; 
    #ifdef SCHED_RR
            printf("SCHED_RR is defined\n");
            #ifdef SCHED_PB
                    printf("and also SCHED_PB is defined\n");
                    scheduling = 3;
            #else
                    scheduling = 1;
            #endif
    #elseif SCHED_PB
            printf("SCHED_PB is defined\n")
            scheduling = 2;
    #endif

    printf("the number of the scheduling is %d\n",scheduling);
    printf("bye bye\n");

    return 0;

}//main

as you can see i am checking if a macro has been defined and which one. now i want to run the program with my Makefile doing the next command line

make some_var=SCHED_RR

this pseudo command (because i don't know how to really do it) is meant to predefine the macro SCHED_RR also i want to be able to write the command

make some_var=SCHED_PB

and

make some_var1=SCHED_RR some_var2=SCHED_PB

the last one is for the case that someone would want to predefine both scheduling

now my problem is: i don't know how and where to write it in my Makefile and also how to write it in the command line?

this is my Makefile which of course shows that my real program is bigger so where and what should i add to this make file

OBJS = \
    bio.o\
    console.o\
    exec.o\
    file.o\
    fs.o\
    ide.o\
    ioapic.o\
    kalloc.o\
    kbd.o\
    lapic.o\
    log.o\
    main.o\
    mp.o\
    picirq.o\
    pipe.o\
    proc.o\
    spinlock.o\
    string.o\
    swtch.o\
    syscall.o\
    sysfile.o\
    sysproc.o\
    timer.o\
    trapasm.o\
    trap.o\
    uart.o\
    vectors.o\
    vm.o\



# Cross-compiling (e.g., on Mac OS X)
#TOOLPREFIX = i386-jos-elf-

# Using native tools (e.g., on X86 Linux)
#TOOLPREFIX = 

# Try to infer the correct TOOLPREFIX if not set
ifndef TOOLPREFIX
TOOLPREFIX := $(shell if i386-jos-elf-objdump -i 2>&1 | grep '^elf32-i386$$' >/dev/null 2>&1; \
    then echo 'i386-jos-elf-'; \
    elif objdump -i 2>&1 | grep 'elf32-i386' >/dev/null 2>&1; \
    then echo ''; \
    else echo "***" 1>&2; \
    echo "*** Error: Couldn't find an i386-*-elf version of GCC/binutils." 1>&2; \
    echo "*** Is the directory with i386-jos-elf-gcc in your PATH?" 1>&2; \
    echo "*** If your i386-*-elf toolchain is installed with a command" 1>&2; \
    echo "*** prefix other than 'i386-jos-elf-', set your TOOLPREFIX" 1>&2; \
    echo "*** environment variable to that prefix and run 'make' again." 1>&2; \
    echo "*** To turn off this error, run 'gmake TOOLPREFIX= ...'." 1>&2; \
    echo "***" 1>&2; exit 1; fi)
endif

# If the makefile can't find QEMU, specify its path here
#QEMU = 

# Try to infer the correct QEMU
ifndef QEMU
QEMU = $(shell if which qemu > /dev/null; \
    then echo qemu; exit; \
    else \
    qemu=/Applications/Q.app/Contents/MacOS/i386-softmmu.app/Contents/MacOS/i386-softmmu; \
    if test -x $$qemu; then echo $$qemu; exit; fi; fi; \
    echo "***" 1>&2; \
    echo "*** Error: Couldn't find a working QEMU executable." 1>&2; \
    echo "*** Is the directory containing the qemu binary in your PATH" 1>&2; \
    echo "*** or have you tried setting the QEMU variable in Makefile?" 1>&2; \
    echo "***" 1>&2; exit 1)
endif


CC = $(TOOLPREFIX)gcc
AS = $(TOOLPREFIX)gas
LD = $(TOOLPREFIX)ld
OBJCOPY = $(TOOLPREFIX)objcopy
OBJDUMP = $(TOOLPREFIX)objdump
#CFLAGS = -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer
CFLAGS = -fno-pic -static -fno-builtin -fno-strict-aliasing -Wall -MD -ggdb -m32 -Werror -fno-omit-frame-pointer
CFLAGS += $(shell $(CC) -fno-stack-protector -E -x c /dev/null >/dev/null 2>&1 && echo -fno-stack-protector)
ASFLAGS = -m32 -gdwarf-2 -Wa,-divide
# FreeBSD ld wants ``elf_i386_fbsd''
LDFLAGS += -m $(shell $(LD) -V | grep elf_i386 2>/dev/null)

xv6.img: bootblock kernel fs.img
    dd if=/dev/zero of=xv6.img count=10000
    dd if=bootblock of=xv6.img conv=notrunc
    dd if=kernel of=xv6.img seek=1 conv=notrunc

xv6memfs.img: bootblock kernelmemfs
    dd if=/dev/zero of=xv6memfs.img count=10000
    dd if=bootblock of=xv6memfs.img conv=notrunc
    dd if=kernelmemfs of=xv6memfs.img seek=1 conv=notrunc

bootblock: bootasm.S bootmain.c
    $(CC) $(CFLAGS) -fno-pic -O -nostdinc -I. -c bootmain.c
    $(CC) $(CFLAGS) -fno-pic -nostdinc -I. -c bootasm.S
    $(LD) $(LDFLAGS) -N -e start -Ttext 0x7C00 -o bootblock.o bootasm.o bootmain.o
    $(OBJDUMP) -S bootblock.o > bootblock.asm
    $(OBJCOPY) -S -O binary -j .text bootblock.o bootblock
    ./sign.pl bootblock

entryother: entryother.S
    $(CC) $(CFLAGS) -fno-pic -nostdinc -I. -c entryother.S
    $(LD) $(LDFLAGS) -N -e start -Ttext 0x7000 -o bootblockother.o entryother.o
    $(OBJCOPY) -S -O binary -j .text bootblockother.o entryother
    $(OBJDUMP) -S bootblockother.o > entryother.asm

initcode: initcode.S
    $(CC) $(CFLAGS) -nostdinc -I. -c initcode.S
    $(LD) $(LDFLAGS) -N -e start -Ttext 0 -o initcode.out initcode.o
    $(OBJCOPY) -S -O binary initcode.out initcode
    $(OBJDUMP) -S initcode.o > initcode.asm

kernel: $(OBJS) entry.o entryother initcode kernel.ld
    $(LD) $(LDFLAGS) -T kernel.ld -o kernel entry.o $(OBJS) -b binary initcode entryother
    $(OBJDUMP) -S kernel > kernel.asm
    $(OBJDUMP) -t kernel | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > kernel.sym

# kernelmemfs is a copy of kernel that maintains the
# disk image in memory instead of writing to a disk.
# This is not so useful for testing persistent storage or
# exploring disk buffering implementations, but it is
# great for testing the kernel on real hardware without
# needing a scratch disk.
MEMFSOBJS = $(filter-out ide.o,$(OBJS)) memide.o
kernelmemfs: $(MEMFSOBJS) entry.o entryother initcode fs.img
    $(LD) $(LDFLAGS) -Ttext 0x100000 -e main -o kernelmemfs entry.o  $(MEMFSOBJS) -b binary initcode entryother fs.img
    $(OBJDUMP) -S kernelmemfs > kernelmemfs.asm
    $(OBJDUMP) -t kernelmemfs | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > kernelmemfs.sym

tags: $(OBJS) entryother.S _init
    etags *.S *.c

vectors.S: vectors.pl
    perl vectors.pl > vectors.S

ULIB = ulib.o usys.o printf.o umalloc.o uthread.o

_%: %.o $(ULIB)
    $(LD) $(LDFLAGS) -N -e main -Ttext 0 -o $@ $^
    $(OBJDUMP) -S $@ > $*.asm
    $(OBJDUMP) -t $@ | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > $*.sym

_forktest: forktest.o $(ULIB)
    # forktest has less library code linked in - needs to be small
    # in order to be able to max out the proc table.
    $(LD) $(LDFLAGS) -N -e main -Ttext 0 -o _forktest forktest.o ulib.o usys.o
    $(OBJDUMP) -S _forktest > forktest.asm

mkfs: mkfs.c fs.h
    gcc -DVarName=$(VarName) -m32 -Werror -Wall -o mkfs mkfs.c

UPROGS=\
    _cat\
    _echo\
    _forktest\
    _grep\
    _init\
    _kill\
    _ln\
    _ls\
    _mkdir\
    _rm\
    _sh\
    _stressfs\
    _usertests\
    _wc\
    _zombie\
    _main\

fs.img: mkfs README $(UPROGS)
    ./mkfs fs.img README $(UPROGS)

-include *.d

clean: 
    rm -f *.tex *.dvi *.idx *.aux *.log *.ind *.ilg \
    *.o *.d *.asm *.sym vectors.S bootblock entryother \
    initcode initcode.out kernel xv6.img fs.img kernelmemfs mkfs \
    .gdbinit \
    $(UPROGS)

# make a printout
FILES = $(shell grep -v '^\#' runoff.list)
PRINT = runoff.list runoff.spec README toc.hdr toc.ftr $(FILES)

xv6.pdf: $(PRINT)
    ./runoff
    ls -l xv6.pdf

print: xv6.pdf

# run in emulators

bochs : fs.img xv6.img
    if [ ! -e .bochsrc ]; then ln -s dot-bochsrc .bochsrc; fi
    bochs -q

# try to generate a unique GDB port
GDBPORT = $(shell expr `id -u` % 5000 + 25000)
# QEMU's gdb stub command line changed in 0.11
QEMUGDB = $(shell if $(QEMU) -help | grep -q '^-gdb'; \
    then echo "-gdb tcp::$(GDBPORT)"; \
    else echo "-s -p $(GDBPORT)"; fi)
ifndef CPUS
CPUS := 1
endif
QEMUOPTS = -hdb fs.img xv6.img -smp $(CPUS) -m 512 $(QEMUEXTRA)

qemu: fs.img xv6.img
    $(QEMU) -serial mon:stdio $(QEMUOPTS)

qemu-memfs: xv6memfs.img
    $(QEMU) xv6memfs.img -smp $(CPUS)

qemu-nox: fs.img xv6.img
    $(QEMU) -nographic $(QEMUOPTS)

.gdbinit: .gdbinit.tmpl
    sed "s/localhost:1234/localhost:$(GDBPORT)/" < $^ > $@

qemu-gdb: fs.img xv6.img .gdbinit
    @echo "*** Now run 'gdb'." 1>&2
    $(QEMU) -serial mon:stdio $(QEMUOPTS) -S $(QEMUGDB)

qemu-nox-gdb: fs.img xv6.img .gdbinit
    @echo "*** Now run 'gdb'." 1>&2
    $(QEMU) -nographic $(QEMUOPTS) -S $(QEMUGDB)

# CUT HERE
# prepare dist for students
# after running make dist, probably want to
# rename it to rev0 or rev1 or so on and then
# check in that version.

EXTRA=\
    mkfs.c ulib.c user.h cat.c echo.c forktest.c grep.c kill.c\
    ln.c ls.c mkdir.c rm.c stressfs.c usertests.c wc.c zombie.c\
    printf.c umalloc.c main.c\
    README dot-bochsrc *.pl toc.* runoff runoff1 runoff.list\
    .gdbinit.tmpl gdbutil\

dist:
    rm -rf dist
    mkdir dist
    for i in $(FILES); \
    do \
        grep -v PAGEBREAK $$i >dist/$$i; \
    done
    sed '/CUT HERE/,$$d' Makefile >dist/Makefile
    echo >dist/runoff.spec
    cp $(EXTRA) dist

dist-test:
    rm -rf dist
    make dist
    rm -rf dist-test
    mkdir dist-test
    cp dist/* dist-test
    cd dist-test; $(MAKE) print
    cd dist-test; $(MAKE) bochs || true
    cd dist-test; $(MAKE) qemu

# update this rule (change rev#) when it is time to
# make a new revision.
tar:
    rm -rf /tmp/xv6
    mkdir -p /tmp/xv6
    cp dist/* dist/.gdbinit.tmpl /tmp/xv6
    (cd /tmp; tar cf - xv6) | gzip >xv6-rev5.tar.gz

.PHONY: dist-test dist

thank you

1 Answers1

3

What you need is

make -e VarName=VarValue

This will export the VarName into the makefile where you can use it as a $(VarName) in the gcc compile statement.

So, in the makefile it would be

gcc -DVarName=$(VarName) -c your_source.c -o your_obj.o

For the "#ifdef" situation you either have to change it to "#if", or use this:

make -e SCHED_PR=1

and in the makefile

ifeq ($(SCHED_PR), 1)
mkfs: .....
    gcc -DSCHED_PR=1  ....
else
mkfs: .....
    gcc ....
endif

In the .c file

#if SCHED_PR

...

Viktor Latypov
  • 14,289
  • 3
  • 40
  • 55
  • 1
    i added to my original question my Makefile and i really don't know where to put your commands in there. i tried to put your command in the only place that i saw gcc right after the word gcc and then in the command line i wrote make -e VarName=SCHED_RR but my program didn't print 'SCHED_RR is defined' as i excpected –  May 14 '12 at 20:40
  • So, you have the build rule for mkfs. While compiling the mkfs.c, there will be the 'VarName' symbol defined if you run the "make -e VarName=VarValue" command. – Viktor Latypov May 14 '12 at 20:44
  • Try the echo $(VarName) in the target for mkfs to be sure that the VarName is actually assigned. – Viktor Latypov May 14 '12 at 20:45
  • Excuse me, I haven't noticed your mistake. If you want the SCHED_PR to trigger the #ifdef, then you have to run the "make -e SCHED_PR=1". Is it ok now ? – Viktor Latypov May 14 '12 at 20:46
  • sorry but i didn't understood, i want to run main.c and that when i write make -e VarName=SCHED_RR or any other suggested command, that in main.c will be printed 'SCHED_RR is defined' as my code states at the original question –  May 14 '12 at 20:47
  • I've modified the answer. "VarName" was meant to be "SCHED_PR", not some tricky parameter of 'make'. – Viktor Latypov May 14 '12 at 20:50
  • i wrote what that you have suggested: make -e SCHED_RR=1 but it didn't got inside the ifdef SCHED_RR and didn't printf 'SCHED_RR is defined' and i rewrote the gcc command in the makefile to be gcc -DVarName=$(VarName) -m32 -Werror -Wall -o mkfs mkfs.c but i am not sure that this is what i should do and i dont know how it will solve my problem in main.c –  May 14 '12 at 20:52
  • "gcc -DSCHED_RR=$(SCHED_RR) -m32 -Werror -Wall -o mkfs mkfs.c" will define the preprocessor's symbol SCHED_RR with value 1 (if you use the make -e SCHED_RR=1). So the #ifdef in .c will always work - you have to use just #if there. – Viktor Latypov May 14 '12 at 20:54
  • i did in the makefile: ifeq ($(SCHED_RR), 1) mkfs: mkfs.c fs.h gcc -DSCHED_RR=$(SCHED_RR) -m32 -Werror -Wall -o mkfs mkfs.c else mkfs: mkfs.c fs.h gcc -DSCHED_RR=$(SCHED_PB) -m32 -Werror -Wall -o mkfs mkfs.c endif and in the command line: make -e SCHED_RR=1 and in my main.c i didn't change anything but it still didn't worked and print what i wanted –  May 14 '12 at 21:06
  • I missed once again - try "ifeq ($(SCHED_RR), "1")" (one with the quotes) – Viktor Latypov May 14 '12 at 21:35