Rather cleaner cfile implementation where you just give it a .c and a pile of .h files.
This commit is contained in:
		
							parent
							
								
									8082ef16a7
								
							
						
					
					
						commit
						fcc5a878ae
					
				
					 2 changed files with 29 additions and 25 deletions
				
			
		|  | @ -91,38 +91,40 @@ local function dirnames(collection) | ||||||
| 	return o | 	return o | ||||||
| end | end | ||||||
| 
 | 
 | ||||||
| local function filenamesof(results) | local function filenamesof(targets, pattern) | ||||||
| 	local f = {} | 	local f = {} | ||||||
| 	if results then | 	if targets then | ||||||
| 		for _, r in pairs(results) do | 		for _, r in pairs(targets) do | ||||||
| 			if (type(r) == "string") then | 			if (type(r) == "table") and r.is then | ||||||
| 				f[#f+1] = r | 				if r.outs then | ||||||
| 			elseif (type(r) == "table") then |  | ||||||
| 				if r.is and r.outs then |  | ||||||
| 					for _, o in pairs(r.outs) do | 					for _, o in pairs(r.outs) do | ||||||
|  | 						if not pattern or o:find(pattern) then | ||||||
| 							f[#f+1] = o | 							f[#f+1] = o | ||||||
| 						end | 						end | ||||||
| 					end | 					end | ||||||
| 				end | 				end | ||||||
|  | 			else | ||||||
|  | 				error("list of targets contains something which isn't a target") | ||||||
|  | 			end | ||||||
| 		end | 		end | ||||||
| 	end | 	end | ||||||
| 	return f | 	return f | ||||||
| end | end | ||||||
| 
 | 
 | ||||||
| local function selectof(pattern, targets) | -- Selects all targets containing at least one output file that matches | ||||||
|  | -- the pattern. | ||||||
|  | local function selectof(targets, pattern) | ||||||
| 	local o = {} | 	local o = {} | ||||||
| 	for k, v in pairs(targets) do | 	for k, v in pairs(targets) do | ||||||
| 		if v.is and v.outs then | 		if v.is and v.outs then | ||||||
| 			local targetmatches = nil | 			local matches = false | ||||||
| 			for _, f in pairs(v.outs) do | 			for _, f in pairs(v.outs) do | ||||||
| 				local matches = not not f:find(pattern) | 				if f:find(pattern) then | ||||||
| 				if (targetmatches == nil) then | 					matches = true | ||||||
| 					targetmatches = matches | 					break | ||||||
| 				elseif (targetmatches ~= matches) then |  | ||||||
| 					error("selectof() is matching only part of a target") |  | ||||||
| 				end | 				end | ||||||
| 			end | 			end | ||||||
| 			if targetmatches then | 			if matches then | ||||||
| 				o[#o+1] = v | 				o[#o+1] = v | ||||||
| 			end | 			end | ||||||
| 		end | 		end | ||||||
|  | @ -379,7 +381,7 @@ definerule("simplerule", | ||||||
| 	function (e) | 	function (e) | ||||||
| 		e.environment:rule(filenamesof(e.ins), e.outs) | 		e.environment:rule(filenamesof(e.ins), e.outs) | ||||||
| 		e.environment:label(cwd..":"..e.name, " ", e.label or "") | 		e.environment:label(cwd..":"..e.name, " ", e.label or "") | ||||||
| 		e.environment:mkdirs(dirnames(filenamesof(e.outs))) | 		e.environment:mkdirs(dirnames(e.outs)) | ||||||
| 
 | 
 | ||||||
| 		local vars = { | 		local vars = { | ||||||
| 			ins = e.ins, | 			ins = e.ins, | ||||||
|  | @ -415,6 +417,7 @@ globals = { | ||||||
| 	environment = environment, | 	environment = environment, | ||||||
| 	filenamesof = filenamesof, | 	filenamesof = filenamesof, | ||||||
| 	selectof = selectof, | 	selectof = selectof, | ||||||
|  | 	uniquify = uniquify, | ||||||
| } | } | ||||||
| setmetatable(globals, | setmetatable(globals, | ||||||
| 	{ | 	{ | ||||||
|  |  | ||||||
|  | @ -29,7 +29,6 @@ definerule("normalrule", | ||||||
| definerule("cfile", | definerule("cfile", | ||||||
| 	{ | 	{ | ||||||
| 		srcs = { type="targets" }, | 		srcs = { type="targets" }, | ||||||
| 		hdrs = { type="targets", default={} }, |  | ||||||
| 		commands = { | 		commands = { | ||||||
| 			type="strings", | 			type="strings", | ||||||
| 			default={ | 			default={ | ||||||
|  | @ -38,20 +37,23 @@ definerule("cfile", | ||||||
| 		} | 		} | ||||||
| 	}, | 	}, | ||||||
| 	function (e) | 	function (e) | ||||||
| 		if (#e.srcs ~= 1) then | 		local csrcs = filenamesof(e.srcs, "%.c$") | ||||||
|  | 		if (#csrcs ~= 1) then | ||||||
| 			error("you must have exactly one .c file") | 			error("you must have exactly one .c file") | ||||||
| 		end | 		end | ||||||
| 		 | 		 | ||||||
| 		hdrpaths = {} | 		local htargets = selectof(e.srcs, "%.h$") | ||||||
| 		for _, t in pairs(e.hdrs) do | 		local hdrpaths = {} | ||||||
|  | 		for _, t in pairs(htargets) do | ||||||
| 			hdrpaths[#hdrpaths+1] = "-I"..t.dir | 			hdrpaths[#hdrpaths+1] = "-I"..t.dir | ||||||
| 		end | 		end | ||||||
|  | 		hdrpaths = uniquify(hdrpaths) | ||||||
| 
 | 
 | ||||||
| 		local outleaf = basename(filenamesof(e.srcs)[1]):gsub("%.c$", ".o") | 		local outleaf = basename(csrcs[1]):gsub("%.c$", ".o") | ||||||
| 
 | 
 | ||||||
| 		return normalrule { | 		return normalrule { | ||||||
| 			name = e.name, | 			name = e.name, | ||||||
| 			ins = {e.srcs[1], unpack(e.hdrs)}, | 			ins = {csrcs[1], unpack(htargets)}, | ||||||
| 			outleaves = {outleaf}, | 			outleaves = {outleaf}, | ||||||
| 			label = e.label, | 			label = e.label, | ||||||
| 			commands = e.commands, | 			commands = e.commands, | ||||||
|  | @ -78,8 +80,7 @@ cfile { | ||||||
| 
 | 
 | ||||||
| cfile { | cfile { | ||||||
| 	name = "testfile-bar", | 	name = "testfile-bar", | ||||||
| 	srcs = "bar.c", | 	srcs = {"bar.c", ":mkheader"}, | ||||||
| 	hdrs = ":mkheader", |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| --[[ | --[[ | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue