Browse Source

BUILD cmd through build.go. now: let's go port remaining programs :-)

Elbing Miss 8 years ago
parent
commit
94c7532fd9

+ 5 - 199
BUILD

@@ -37,42 +37,6 @@ check_error()
 	fi
 }
 
-### FOR BUILD TESTS PROGRAMS, Provisional ###
-
-#ARGS:
-#  $1 -> test name
-build_a_test()
-{
-	cd ${TEST_DIR}/$1
-	DO_NOTHING=0
-	LDFLAGS_EXTRA=
-	CFLAGS_EXTRA=
-	test_${1} 1
-	if [ $DO_NOTHING -eq 0 ]
-	then
-		echo "$CC $CFLAGS_CMD $CFLAGS_EXTRA $BUILD_DEBUG -c $BUILD_IN"
-		$CC $CFLAGS_CMD $CFLAGS_EXTRA $BUILD_DEBUG -c $BUILD_IN 
-		if [ $? -ne 0 ]
-		then
-			echo "ERROR compiling $1"
-			cd - > /dev/null
-			exit 1
-		fi
-		LD_LIBS=`process_libs_to_link "$LIBS_TO_LINK"`
-		echo $LD $LDFLAGS_EXTRA $LDFLAGS $LD_LIBS -o $BUILD_OUT *.o
-		$LD $LDFLAGS_EXTRA $LDFLAGS -o $BUILD_OUT *.o $LD_LIBS
-		if [ $? -ne 0 ]
-		then
-			echo "ERROR linking $1"
-			cd - > /dev/null
-			exit 1
-		fi
-	fi
-	cd - > /dev/null
-}
-
-##########################
-
 compile_kernel()
 {
 	export HARVEY="$_BUILD_DIR"
@@ -150,162 +114,21 @@ build_klibs()
 
 }
 
-#### FOR BUILD CMD, Provisional!! ####
-
-#ARGS:
-#   $1 -> LIB name
-do_link_lib()
-{
-	AUX=`echo $1 | grep ^lib`
-	_LIB_NAME=
-	if [ -n "$AUX" ]
-	then
-		#Name format is libName
-		_LIB_NAME=`echo $AUX | cut -c 4-`
-		_LIB_NAME="-l$_LIB_NAME"
-	else
-		#Name format is Name
-		_LIB_NAME="-l$1"
-	fi
-	echo $_LIB_NAME
-}
-
-#ARGS:
-#	$1 -> libs list
-process_libs_to_link()
-{
-	_RETURN=
-	for i in $1
-	do
-		_RETURN=${_RETURN}" "`do_link_lib $i`
-	done
-	echo $_RETURN
-}
-
-#ARGS:
-#  $1 -> cmd name
-build_a_cmd()
-{
-	# test if binary has its own subdir
-	if [ -d "${CMD_DIR}/$1" ]
-	then
-		cd ${CMD_DIR}/$1
-	else
-		cd ${CMD_DIR}
-	fi
-	DO_NOTHING=0
-	LDFLAGS_EXTRA=
-	CFLAGS_EXTRA=
-	BUILD_DIR=
-	cmd_${1} 1
-	if [ -n "$BUILD_DIR" ]
-	then
-		cd -
-		cd "$BUILD_DIR"
-	fi
-	if [ $DO_NOTHING -eq 0 ]
-	then
-		echo "$CC $CFLAGS_CMD $CFLAGS_EXTRA $BUILD_DEBUG -c $BUILD_IN"
-		$CC $CFLAGS_CMD $CFLAGS_EXTRA $BUILD_DEBUG -c $BUILD_IN 
-		if [ $? -ne 0 ]
-		then
-			echo "ERROR compiling $1"
-			cd - > /dev/null
-			exit 1
-		fi
-	# If it's a stand alone source don't get all object files
-		if [ -d "${CMD_DIR}/$1" ]
-		then
-			LD_LIBS=`process_libs_to_link "$LIBS_TO_LINK"`
-			echo $LD $LDFLAGS $LDFLAGS_EXTRA $LD_LIBS -o $BUILD_OUT *.o
-			$LD $LDFLAGS_EXTRA $LDFLAGS -o $BUILD_OUT *.o $LD_LIBS
-		elif [ -n "$BUILD_DIR" ] && [ -d `dirname $BUILD_DIR`"/$1" ]
-		then
-			LD_LIBS=`process_libs_to_link "$LIBS_TO_LINK"`
-			echo $LD $LDFLAGS $LDFLAGS_EXTRA $LD_LIBS -o $BUILD_OUT *.o
-			$LD $LDFLAGS_EXTRA $LDFLAGS -o $BUILD_OUT *.o $LD_LIBS
-		else
-			LD_LIBS=`process_libs_to_link "$LIBS_TO_LINK"`
-			echo $LD $LDFLAGS $LDFLAGS_EXTRA $LD_LIBS -o $BUILD_OUT $1.o
-			$LD $LDFLAGS_EXTRA $LDFLAGS -o $BUILD_OUT $1.o $LD_LIBS
-		fi
-		if [ $? -ne 0 ]
-		then
-			echo "ERROR linking $1"
-			cd - > /dev/null
-			exit 1
-		fi
-	fi
-	cd - > /dev/null
-}
-
-#ARGS:
-#   $1 -> cmd name
-clean_a_cmd()
-{
-	if [ -d "${CMD_DIR}/$1" ]
-	then
-		cd ${CMD_DIR}/$1
-	else
-		if [ $1 = ipconfig ]
-		then
-			cd ${CMD_DIR}/ip/$1
-		else
-			cd ${CMD_DIR}
-		fi
-	fi
-	DO_NOTHING=0
-	cmd_${1} 2
-	if [ $DO_NOTHING -eq 0 ]
-	then
-		printf "Cleaning $1 "
-		$CLEAN_COM
-		if [ $? -eq 0 ]
-		then
-			printf "OK\n"
-		else
-			printf "ERROR\n"
-		fi 
-	fi
-}
-
-#ARGS:
-#$1 -> ACTION:
-#      1) Build
-#      2) Clean
 build_cmds()
-{
-	for i in $BUILD_CMD
-	do
-		if [ $1 -eq 1 ]
-		then
-			build_a_cmd $i
-		else
-			clean_a_cmd $i
-		fi
-	done
-	
-	if [ $1 -eq 1 ]
-	then
-		echo "ALL CMDS COMPILED OK"
-	fi
-}
-
-build_cmds_go()
 {
 	export HARVEY="$_BUILD_DIR"
 	cd "$CMD_DIR"
 	$HARVEY/util/build cmds.json
+	$HARVEY/util/build kcmds.json
 	cd "$PATH_ORI" > /dev/null
 }
-#############################
 
 show_help()
 {
 	printf "\n\nBUILD script for Harvey\n\n"
 	printf "OPTIONS:\n"
 	printf "  all        \tBuild all components\n"
-	printf "  cleanll     \tClean all components\n"
+	printf "  cleanall     \tClean all components\n"
 	printf "  libs       \tBuild the libraries\n"
 	printf "  libs <libname>\tBuild the library <libname>\n"
 	printf "  cleanlibs\tClean the libraries\n"
@@ -363,13 +186,10 @@ else
 					build_go_utils
 					build_libs
 					build_klibs
-					build_cmds 1 ### Provisional
+					build_cmds
 					build_kernel
 					printf "\n\nALL COMPONENTS COMPILED\n\n"
 					;;
-			"cleanall")
-					printf "\n\nALL COMPONENTS ARE CLEANED AT BUILD TIME\n\n"
-					;;
 			"libs")
 					check_lib_dir
 					if [ -z "$2" ]
@@ -384,32 +204,18 @@ else
 						build_klibs
 					fi
 					;;
-			"cleanklibs")
-					printf "\n\nALL COMPONENTS ARE CLEANED AT BUILD TIME\n\n"
-					;;
-			"cleanlibs")
-					printf "\n\nALL COMPONENTS ARE CLEANED AT BUILD TIME\n\n"
-					;;
 			"utils")
 					build_go_utils
 					;;
 			"cmd")
-					if [ -z "$2" ]
-					then
-						build_cmds_go
-					else
-						printf "\n\nALL COMPONENTS ARE CLEANED AT BUILD TIME\n\n"
-					fi
+					build_cmds
 					;;
-			"cleancmd")
+			"cleanall"|"cleancmd"|"cleankernel"|"cleanklibs"|"cleanlibs")
 					printf "\n\nALL COMPONENTS ARE CLEANED AT BUILD TIME\n\n"
 					;;
 			"kernel")
 					build_kernel
 					;;
-			"cleankernel")
-					printf "\n\nALL COMPONENTS ARE CLEANED AT BUILD TIME\n\n"
-					;;
 			*)
 				echo "Invalid option <$1>"
 				exit 1

+ 0 - 147
BUILD.conf

@@ -30,150 +30,3 @@ NM=nm
 DATE=$(date +%s)
 EXTKERNDATE="-DKERNDATE=${DATE}"
 KERNEL_CONF="k8cpu"
-
-### CMD Provisional!!! ###
-#BUILD_CMD="rc bind mount cat cp echo ls ipconfig ps mkdir pwd chmod rio date dd vga ping telnet dhcpclient srv testalarm"
-# Now essentials are included in build.go
-BUILD_CMD=""
-
-
-### functions ###
-test_hello()
-{
-	BUILD_IN="hello.c"
-	BUILD_OUT="hello"
-	CLEAN_COM="rm -f *.elf.* *.o"
-	LIBS_TO_LINK="stdio c"
-	LDFLAGS_EXTRA="-static -e_main"
-}
-
-test_to_fork()
-{
-	BUILD_IN="to_fork.c"
-	BUILD_OUT="to_fork"
-	CLEAN_COM="rm -f *.elf.* *.o"
-	LIBS_TO_LINK="stdio c"
-	LDFLAGS_EXTRA="-static -e_main"
-}
-
-test_saymyname()
-{
-	BUILD_IN="say.c"
-	BUILD_OUT="say"
-	CLEAN_COM="rm -f *.elf.* *.o"
-	LIBS_TO_LINK="stdio c"
-	LDFLAGS_EXTRA="-static -e_main"
-}
-cmd_dd()
-{
-	BUILD_IN="dd.c"
-	BUILD_OUT="dd.elf.out"
-	CLEAN_COM="rm -f *.elf.* *.o"
-	LIBS_TO_LINK="libc"
-	LDFLAGS_EXTRA="-static -e_main"
-}
-
-cmd_chmod()
-{
-	BUILD_IN="chmod.c"
-	BUILD_OUT="chmod.elf.out"
-	CLEAN_COM="rm -f *.elf.* *.o"
-	LIBS_TO_LINK="libc"
-	LDFLAGS_EXTRA="-static -e_main"
-}
-
-cmd_pwd()
-{
-	BUILD_IN="pwd.c"
-	BUILD_OUT="pwd.elf.out"
-	CLEAN_COM="rm -f *.elf.* *.o"
-	LIBS_TO_LINK="libc"
-	LDFLAGS_EXTRA="-static -e_main"
-}
-
-cmd_mkdir()
-{
-	BUILD_IN="mkdir.c"
-	BUILD_OUT="mkdir.elf.out"
-	CLEAN_COM="rm -f *.elf.* *.o"
-	LIBS_TO_LINK="libc"
-	LDFLAGS_EXTRA="-static -e_main"
-}
-
-cmd_rio()
-{
-	BUILD_IN="data.c  fsys.c  rio.c  scrl.c  time.c  util.c  wctl.c  wind.c  xfid.c"
-	BUILD_OUT="rio.elf.out"
-	CLEAN_COM="rm -f *.elf.* *.o"
-	LIBS_TO_LINK="libcomplete libframe libdraw  libthread libplumb libc"
-	LDFLAGS_EXTRA="-static -e_main"
-}
-
-cmd_vga()
-{
-	BUILD_DIR=${CMD_DIR}/aux/vga
-	BUILD_IN="3dfx.c       bt485.c     ct65540.c    error.c       i81x.c      ics534x.c  mach64xx.c  neomagic.c  radeon.c    s3928.c      sc15025.c   trio64.c        tvp3026.c       vga.c        vision968.c \
-			ark2000pv.c  ch9294.c    cyber938x.c  et4000.c      ibm8514.c   io.c       main.c      nvidia.c    rgb524.c    s3clock.c    stg1702.c   tvp3020.c       tvp3026clock.c  virge.c      vmware.c \
-			att20c49x.c  clgd542x.c  data.c       et4000hwgc.c  icd2061a.c  mach32.c   mga2164w.c  palette.c   rgb524mn.c  s3generic.c  t2r4.c      tvp3025.c       vesa.c          vision864.c  w30c516.c \
-			att21c498.c  clgd546x.c  db.c         hiqvideo.c    ics2494.c   mach64.c   mga4xx.c    pci.c       s3801.c     s3hwgc.c     template.c  tvp3025clock.c  vesadb.c        vision964.c"
-	BUILD_OUT="vga.elf.out"
-	CLEAN_COM="rm -f *.elf.* *.o"
-	LIBS_TO_LINK="ndb bio libc"
-	LDFLAGS_EXTRA="-static -e_main"
-}
-
-cmd_telnet()
-{
-	BUILD_DIR=${CMD_DIR}/ip
-	BUILD_IN="telnet.c"
-	BUILD_OUT="telnet.elf.out"
-	CLEAN_COM="rm -f *.elf.* *.o"
-	LIBS_TO_LINK="bio ip libc"
-	LDFLAGS_EXTRA="-static -e_main"
-}
-
-cmd_ping()
-{
-	BUILD_DIR=${CMD_DIR}/ip
-	BUILD_IN="ping.c"
-	BUILD_OUT="ping.elf.out"
-	CLEAN_COM="rm -f *.elf.* *.o"
-	LIBS_TO_LINK="ndb bio ip libc"
-	LDFLAGS_EXTRA="-static -e_main"
-}
-
-cmd_ps()
-{
-	BUILD_IN="ps.c"
-	BUILD_OUT="ps.elf.out"
-	CLEAN_COM="rm -f *.elf.* *.o"
-	LIBS_TO_LINK="bio libc"
-	LDFLAGS_EXTRA="-static -e_main"
-}
-
-cmd_cp()
-{
-	BUILD_IN="cp.c"
-	BUILD_OUT="cp.elf.out"
-	CLEAN_COM="rm -f *.elf.* *.o"
-	LIBS_TO_LINK="libc"
-	LDFLAGS_EXTRA="-static -e_main"
-}
-
-cmd_testalarm()
-{
-	BUILD_IN="testalarm.c"
-	BUILD_OUT="testalarm.elf.out"
-	CLEAN_COM="rm -f *.elf.* *.o"
-	LIBS_TO_LINK="libc"
-	LDFLAGS_EXTRA="-static -e_main"
-}
-
-cmd_cat()
-{
-	BUILD_IN="cat.c"
-	BUILD_OUT="cat.elf.out"
-	CLEAN_COM="rm -f *.elf.* *.o"
-	LIBS_TO_LINK="libc"
-	LDFLAGS_EXTRA="-static -e_main"
-}

+ 10 - 18
sys/src/9/k10/k8cpu.json

@@ -3,40 +3,32 @@
     "Program": "9k8cpu",
     "Include":["core.json", "../386/386.json", "../ip/ip.json", "../port/port.json"], 
 	"Projects": [
-	"/sys/src/cmd/rc/kernel.json",
-	"/sys/src/cmd/ip/ipconfig/kernel.json",
-	"/sys/src/cmd/bind.json",
-	"/sys/src/cmd/mount.json",
-	"/sys/src/cmd/date.json",
-	"/sys/src/cmd/srv.json",
-	"/sys/src/cmd/echo.json",
-	"/sys/src/cmd/ls.json"
+	"/sys/src/cmd/kcmds.json"
 	],
     "Pre": [
-	"cp ../../../../rc/lib/rcmain rcmain",
-	"data2c _rc_lib_rcmain rcmain >> k8cpu.root.c",
-	"mv ../../cmd/rc/rc.elf.out rc.elf.out",
+	"data2c _rc_lib_rcmain ../../../../rc/lib/rcmain >> k8cpu.root.c",
+	"cp /amd64/bin/rc rc.elf.out",
 	"strip rc.elf.out",
 	"data2c _amd64_bin_rc rc.elf.out >> k8cpu.root.c",
-	"mv ../../cmd/bind.elf.out bind.elf.out",
+	"cp /amd64/bin/bind bind.elf.out",
 	"strip bind.elf.out",
 	"data2c _amd64_bin_bind bind.elf.out>> k8cpu.root.c",
-	"mv ../../cmd/mount.elf.out mount.elf.out",
+	"cp /amd64/bin/mount mount.elf.out",
 	"strip mount.elf.out",
 	"data2c _amd64_bin_mount mount.elf.out>> k8cpu.root.c",
-	"mv ../../cmd/echo.elf.out echo.elf.out",
+	"cp /amd64/bin/echo echo.elf.out",
 	"strip echo.elf.out",
 	"data2c _amd64_bin_echo echo.elf.out>> k8cpu.root.c",
-	"mv ../../cmd/ip/ipconfig/ipconfig.elf.out ipconfig.elf.out",
+	"cp /amd64/bin/ip/ipconfig ipconfig.elf.out",
 	"strip ipconfig.elf.out",
 	"data2c _amd64_bin_ipconfig ipconfig.elf.out>> k8cpu.root.c",
-	"mv ../../cmd/srv.elf.out srv.elf.out",
+	"cp /amd64/bin/srv srv.elf.out",
 	"strip srv.elf.out",
 	"data2c _amd64_bin_srv srv.elf.out>> k8cpu.root.c",
-	"mv ../../cmd/date.elf.out date.elf.out",
+	"cp /amd64/bin/date date.elf.out",
 	"strip date.elf.out",
 	"data2c _amd64_bin_date date.elf.out>> k8cpu.root.c",
-	"mv ../../cmd/ls.elf.out ls.elf.out",
+	"cp /amd64/bin/ls ls.elf.out",
 	"strip ls.elf.out",
 	"data2c _amd64_bin_ls ls.elf.out>> k8cpu.root.c"
     ],

+ 0 - 10
sys/src/cmd/bind.json

@@ -1,10 +0,0 @@
-{
-    "Name": "Kernelbind",
-    "Program": "bind.elf.out",
-    "Include": ["kernel.json"],
-    "Pre": [
-	],
-    "SourceFiles": [
-	"bind.c"
-	]
-}

+ 11 - 0
sys/src/cmd/cmds.json

@@ -24,5 +24,16 @@
 	"chmod.c",
 	"date.c",
 	"dd.c"
+	],
+	"Post": [
+	"mv cat ../../../amd64/bin/",
+	"mv cp ../../../amd64/bin/",
+	"mv ls ../../../amd64/bin/",
+	"mv ps ../../../amd64/bin/",
+	"mv mkdir ../../../amd64/bin/",
+	"mv pwd ../../../amd64/bin/",
+	"mv chmod ../../../amd64/bin/",
+	"mv date ../../../amd64/bin/",
+	"mv dd ../../../amd64/bin/"
 	]
 }

+ 0 - 10
sys/src/cmd/date.json

@@ -1,10 +0,0 @@
-{
-    "Name": "Kerneldate",
-    "Program": "date.elf.out",
-    "Include": ["kernel.json"],
-    "Pre": [
-	],
-    "SourceFiles": [
-	"date.c"
-	]
-}

+ 0 - 10
sys/src/cmd/echo.json

@@ -1,10 +0,0 @@
-{
-    "Name": "Kernelecho",
-    "Program": "echo.elf.out",
-    "Include": ["kernel.json"],
-    "Pre": [
-	],
-    "SourceFiles": [
-	"echo.c"
-	]
-}

+ 13 - 0
sys/src/cmd/ip/dhcpclient.json

@@ -0,0 +1,13 @@
+{
+    "Name": "dhcpclient",
+    "Program": "dhcpclient",
+    "Include": ["../kernel.json"],
+    "Pre": [
+	],
+    "SourceFiles": [
+	"dhcpclient.c"
+	],
+	"Post": [
+	"mv dhcpclient ../../../../amd64/bin/ip/"
+	]
+}

+ 16 - 0
sys/src/cmd/ip/ipconfig/ipconfig.json

@@ -0,0 +1,16 @@
+{
+    "Name": "ipconfig",
+    "Program": "ipconfig",
+    "Include": ["../../kernel.json"],
+    "Pre": [
+	],
+    "SourceFiles": [
+	"ipv6.c",
+	"main.c",
+	"ppp.c"
+	],
+	"Post": [
+	"[ -d ../../../../../amd64/bin/ip ] || mkdir ../../../../../amd64/bin/ip",
+	"mv ipconfig ../../../../../amd64/bin/ip/ipconfig"
+	]
+}

+ 0 - 12
sys/src/cmd/ip/ipconfig/kernel.json

@@ -1,12 +0,0 @@
-{
-    "Name": "Kernelipconfig",
-    "Program": "ipconfig.elf.out",
-    "Include": ["../../kernel.json"],
-    "Pre": [
-	],
-    "SourceFiles": [
-	"ipv6.c",
-	"main.c",
-	"ppp.c"
-	]
-}

+ 0 - 10
sys/src/cmd/ip/kernel.json

@@ -1,10 +0,0 @@
-{
-    "Name": "Kernelipconfig",
-    "Program": "dhcpclient.elf.out",
-    "Include": ["../kernel.json"],
-    "Pre": [
-	],
-    "SourceFiles": [
-	"dhcpclient.c"
-	]
-}

+ 35 - 0
sys/src/cmd/kcmds.json

@@ -0,0 +1,35 @@
+{
+	"Name": "Kcmds",
+	"Programs": [
+	"bind",
+	"mount",
+	"date",
+	"srv",
+	"echo",
+	"ls"
+	],
+	"Projects": [
+	"/sys/src/cmd/rc/rc.json",
+	"/sys/src/cmd/ip/ipconfig/ipconfig.json",
+	"/sys/src/cmd/ip/dhcpclient.json"
+	],
+	"Include": ["kernel.json"],
+	"Pre": [
+	],
+	"SourceFilesCmd": [
+	"bind.c",
+	"mount.c",
+	"date.c",
+	"srv.c",
+	"echo.c",
+	"ls.c"
+	],
+	"Post": [
+	"mv bind ../../../amd64/bin/",
+	"mv mount ../../../amd64/bin/",
+	"mv date ../../../amd64/bin/",
+	"mv srv ../../../amd64/bin/",
+	"mv echo ../../../amd64/bin/",
+	"mv ls ../../../amd64/bin/"
+	]
+}

+ 0 - 10
sys/src/cmd/ls.json

@@ -1,10 +0,0 @@
-{
-    "Name": "Kernelipconfig",
-    "Program": "ls.elf.out",
-    "Include": ["kernel.json"],
-    "Pre": [
-	],
-    "SourceFiles": [
-	"ls.c"
-	]
-}

+ 0 - 10
sys/src/cmd/mount.json

@@ -1,10 +0,0 @@
-{
-    "Name": "Kernelmount",
-    "Program": "mount.elf.out",
-    "Include": ["kernel.json"],
-    "Pre": [
-	],
-    "SourceFiles": [
-	"mount.c"
-	]
-}

+ 5 - 2
sys/src/cmd/rc/kernel.json → sys/src/cmd/rc/rc.json

@@ -1,6 +1,6 @@
 {
-    "Name": "Kernelrc",
-    "Program": "rc.elf.out",
+    "Name": "rc",
+    "Program": "rc",
     "Include": ["../kernel.json"],
     "Pre": [
 	"yacc -d syn.y",
@@ -24,5 +24,8 @@
 	"tree.c",
 	"var.c",
 	"y.tab.c"
+	],
+	"Post":[
+	"mv rc ../../../../amd64/bin/"
 	]
 }

+ 0 - 10
sys/src/cmd/srv.json

@@ -1,10 +0,0 @@
-{
-    "Name": "Kernelipconfig",
-    "Program": "srv.elf.out",
-    "Include": ["kernel.json"],
-    "Pre": [
-	],
-    "SourceFiles": [
-	"srv.c"
-	]
-}

+ 64 - 34
util/build.go

@@ -83,12 +83,15 @@ func process(f string, b *build) {
 	b.Library += build.Library
 	// For each source file, assume we create an object file with the last char replaced
 	// with 'o'. We can get smarter later.
+
 	for _, v := range build.SourceFiles {
 		f := path.Base(v)
 		o := f[:len(f)-1] + "o"
 		b.ObjectFiles = append(b.ObjectFiles, o)
 	}
+
 	b.ObjectFiles = append(b.ObjectFiles, adjust(build.ObjectFiles)...)
+
 	for _, v := range build.Include {
 		wd := path.Dir(f)
 		f := path.Join(wd, v)
@@ -106,39 +109,72 @@ func compile(b *build) {
 	if len(b.SourceFilesCmd) > 0 {
 		for _, i := range b.SourceFilesCmd {
 			log.Printf("compiling program %v\n", i)
-			args = append(args, b.SourceFilesCmd...)
+			argscmd := append(args, []string{i}...)
+			cmd := exec.Command("gcc", argscmd...)
+			cmd.Env = append(os.Environ(), b.Env...)
+			cmd.Stdin = os.Stdin
+			cmd.Stderr = os.Stderr
+			cmd.Stdout = os.Stdout
+			log.Printf("Run %v %v", cmd.Path, cmd.Args)
+			err := cmd.Run()
+			if err != nil {
+				log.Fatalf("%v\n", err)
+			}
+			argscmd = args
 		}
 	} else {
 		args = append(args, b.SourceFiles...)
-	}
-	cmd := exec.Command("gcc", args...)
-	cmd.Env = append(os.Environ(), b.Env...)
-
-	cmd.Stdin = os.Stdin
-	cmd.Stderr = os.Stderr
-	cmd.Stdout = os.Stdout
-	log.Printf("Run %v %v", cmd.Path, cmd.Args)
-	err := cmd.Run()
-	if err != nil {
-		log.Fatalf("%v\n", err)
+		cmd := exec.Command("gcc", args...)
+		cmd.Env = append(os.Environ(), b.Env...)
+
+		cmd.Stdin = os.Stdin
+		cmd.Stderr = os.Stderr
+		cmd.Stdout = os.Stdout
+		log.Printf("Run %v %v", cmd.Path, cmd.Args)
+		err := cmd.Run()
+		if err != nil {
+			log.Fatalf("%v\n", err)
+		}
 	}
 }
 
 func link(b *build) {
-	args := []string{"-o", b.Program}
-	args = append(args, b.Oflags...)
-	args = append(args, b.ObjectFiles...)
-	args = append(args, b.Libs...)
-	cmd := exec.Command("ld", args...)
-	cmd.Env = append(os.Environ(), b.Env...)
-
-	cmd.Stdin = os.Stdin
-	cmd.Stderr = os.Stderr
-	cmd.Stdout = os.Stdout
-	log.Printf("Run %v %v", cmd.Path, cmd.Args)
-	err := cmd.Run()
-	if err != nil {
-		log.Fatalf("%v\n", err)
+	if len(b.Programs) > 0 {
+		for _, n := range b.Programs {
+			args := []string{"-o", n}
+			args = append(args, b.Oflags...)
+			f := path.Base(n)
+			o := f[:len(f)] + ".o"
+			args = append(args, []string{o}...)
+			args = append(args, b.Libs...)
+			cmd := exec.Command("ld", args...)
+			cmd.Env = append(os.Environ(), b.Env...)
+
+			cmd.Stdin = os.Stdin
+			cmd.Stderr = os.Stderr
+			cmd.Stdout = os.Stdout
+			log.Printf("Run %v %v", cmd.Path, cmd.Args)
+			err := cmd.Run()
+			if err != nil {
+				log.Fatalf("%v\n", err)
+			}
+		}
+	} else {
+		args := []string{"-o", b.Program}
+		args = append(args, b.Oflags...)
+		args = append(args, b.ObjectFiles...)
+		args = append(args, b.Libs...)
+		cmd := exec.Command("ld", args...)
+		cmd.Env = append(os.Environ(), b.Env...)
+
+		cmd.Stdin = os.Stdin
+		cmd.Stderr = os.Stderr
+		cmd.Stdout = os.Stdout
+		log.Printf("Run %v %v", cmd.Path, cmd.Args)
+		err := cmd.Run()
+		if err != nil {
+			log.Fatalf("%v\n", err)
+		}
 	}
 }
 
@@ -179,10 +215,7 @@ func project(root string) {
 		compile(b)
 	}
 	if len(b.SourceFilesCmd) > 0 {
-		for _, p := range b.Programs {
-			log.Printf("making project %v\n", p)
-			compile(b)
-		}
+		compile(b)
 	}
 	log.Printf("root %v program %v\n", root, b.Program)
 	if b.Program != "" {
@@ -193,10 +226,7 @@ func project(root string) {
 		log.Printf("\n\n*** Building %v ***\n\n", b.Library)
 	}
 	if len(b.Programs ) > 0 {
-		for _, l := range b.Programs {
-			log.Printf("linking program %v\n", l)
-			link(b)
-		}
+		link(b)
 	}
 	run(b, b.Post)
 }