<commit_before>--
-- make_cpp.lua
-- Generate a C/C++ project makefile.
-- Copyright (c) 2002-2014 <NAME> and the Premake project
--

	local p = premake

	p.make.cpp    = {}

	local make = p.make
	local cpp = p.make.cpp

	local project = p.project
	local config = p.config
	local fileconfig = p.fileconfig


---
-- Add namespace for element definition lists for premake.callarray()
---

	cpp.elements = {}


--
-- Generate a GNU make C++ project makefile, with support for the new platforms API.
--

	cpp.elements.makefile = function(prj)
		return {
			make.header,
			make.phonyRules,
			make.shellType,
			cpp.createRuleTable,
			cpp.outputConfigurationSection,
			cpp.outputPerFileConfigurationSection,
			cpp.createFileTable,
			cpp.outputFilesSection,
			cpp.outputRulesSection,
			cpp.outputFileRuleSection,
			cpp.dependencies,
		}
	end


	function cpp.generate(prj)
		premake.eol("\n")
		premake.callArray(cpp.elements.makefile, prj)

		-- allow the garbage collector to clean things up.
		for cfg in project.eachconfig(prj) do
			cfg._gmake = nil
		end
		prj._gmake = nil
	end


	function cpp.initialize()
		rule 'cpp'
			fileExtension {".cc", ".cpp", ".cxx", ".mm"}
			buildoutputs  {'$(OBJDIR)/%{file.objname}.o'}
			buildmessage  '$(notdir $<)'
			buildcommands {'$(CXX) $(%{premake.make.cpp.fileFlags(cfg, file)}) $(FORCE_INCLUDE) -o "$@" -MF "$(@:%.o=%.d)" -c "$<"'}

		rule 'cc'
			fileExtension {".c", ".s", ".m"}
			buildoutputs  {'$(OBJDIR)/%{file.objname}.o'}
			buildmessage  '$(notdir $<)'
			buildcommands {'$(CC) $(%{premake.make.cpp.fileFlags(cfg, file)}) $(FORCE_INCLUDE) -o "$@" -MF "$(@:%.o=%.d)" -c "$<"'}

		rule 'resource'
			fileExtension ".rc"
			buildoutputs  {'$(OBJDIR)/%{file.objname}.res'}
			buildmessage  '$(notdir $<)'
			buildcommands {'$(RESCOMP) $< -O coff -o "$@" $(ALL_RESFLAGS)'}

		global(nil)
	end


	function cpp.createRuleTable(prj)
		local rules = {}

		local function addRule(extension, rule)
			if type(extension) == 'table' then
				for _, value in ipairs(extension) do
					addRule(value, rule)
				end
			else
				rules[extension] = rule
			end
		end

		-- add all rules.
		local usedRules = table.join({'cpp', 'cc', 'resource'}, prj.rules)
		for _, name in ipairs(usedRules) do
			local rule = premake.global.getRule(name)
			addRule(rule.fileExtension, rule)
		end

		-- create fileset categories.
		local filesets = {
			['.o']   = 'OBJECTS',
			['.obj'] = 'OBJECTS',
			['.cc']  = 'SOURCES',
			['.cpp'] = 'SOURCES',
			['.cxx'] = 'SOURCES',
			['.mm']  = 'SOURCES',
			['.c']   = 'SOURCES',
			['.s']   = 'SOURCES',
			['.m']   = 'SOURCES',
			['.rc']  = 'RESOURCES',
		}

		-- cache the result.
		prj._gmake = prj._gmake or {}
		prj._gmake.rules = rules
		prj._gmake.filesets = filesets
	end


	function cpp.createFileTable(prj)
		for cfg in project.eachconfig(prj) do
			cfg._gmake = cfg._gmake or {}
			cfg._gmake.filesets = {}
			cfg._gmake.fileRules = {}

			local files = table.shallowcopy(prj._.files)
			table.foreachi(files, function(node)
				cpp.addFile(cfg, node)
			end)

			for _, f in pairs(cfg._gmake.filesets) do
				table.sort(f)
			end

			cfg._gmake.kinds = table.keys(cfg._gmake.filesets)
			table.sort(cfg._gmake.kinds)

			prj._gmake.kinds = table.join(prj._gmake.kinds or {}, cfg._gmake.kinds)
		end

		-- we need to reassign object sequences if we generated any files.
		if prj.hasGeneratedFiles and p.project.iscpp(prj) then
			p.oven.assignObjectSequences(prj)
		end

		prj._gmake.kinds = table.unique(prj._gmake.kinds)
		table.sort(prj._gmake.kinds)
	end


	function cpp.addFile(cfg, node)
		local filecfg = fileconfig.getconfig(node, cfg)
		if not filecfg or filecfg.flags.ExcludeFromBuild then
			return
		end

		-- skip generated files, since we try to figure it out manually below.
		if node.generated then
			return
		end

		-- process custom build commands.
		if fileconfig.hasCustomBuildRule(filecfg) then
			local env = table.shallowcopy(filecfg.environ)
			env.PathVars = {
				["file.basename"] = { absolute = false, token = node.basename },
				["file.abspath"]  = { absolute = true,  token = node.abspath },
				["file.relpath"]  = { absolute = false, token = node.relpath },
				["file.name"]     = { absolute = false, token = node.name },
				["file.objname"]  = { absolute = false, token = node.objname },
				["file.path"]     = { absolute = true,  token = node.path },
			}

			local shadowContext = p.context.extent(filecfg, env)

			local buildoutputs = p.project.getrelative(cfg.project, shadowContext.buildoutputs)
			if buildoutputs and #buildoutputs > 0 then
				local file = {
					buildoutputs  = buildoutputs,
					source        = node.relpath,
					buildmessage  = shadowContext.buildmessage,
					buildcommands = shadowContext.buildcommands,
					buildinputs   = p.project.getrelative(cfg.project, shadowContext.buildinputs)
				}
				table.insert(cfg._gmake.fileRules, file)

				for _, output in ipairs(buildoutputs) do<commit_msg>gmake: support more env vars in rules<commit_after>--
-- make_cpp.lua
-- Generate a C/C++ project makefile.
-- Copyright (c) 2002-2014 <NAME> and the Premake project
--

	local p = premake

	p.make.cpp    = {}

	local make = p.make
	local cpp = p.make.cpp

	local project = p.project
	local config = p.config
	local fileconfig = p.fileconfig


---
-- Add namespace for element definition lists for premake.callarray()
---

	cpp.elements = {}


--
-- Generate a GNU make C++ project makefile, with support for the new platforms API.
--

	cpp.elements.makefile = function(prj)
		return {
			make.header,
			make.phonyRules,
			make.shellType,
			cpp.createRuleTable,
			cpp.outputConfigurationSection,
			cpp.outputPerFileConfigurationSection,
			cpp.createFileTable,
			cpp.outputFilesSection,
			cpp.outputRulesSection,
			cpp.outputFileRuleSection,
			cpp.dependencies,
		}
	end


	function cpp.generate(prj)
		premake.eol("\n")
		premake.callArray(cpp.elements.makefile, prj)

		-- allow the garbage collector to clean things up.
		for cfg in project.eachconfig(prj) do
			cfg._gmake = nil
		end
		prj._gmake = nil
	end


	function cpp.initialize()
		rule 'cpp'
			fileExtension {".cc", ".cpp", ".cxx", ".mm"}
			buildoutputs  {'$(OBJDIR)/%{file.objname}.o'}
			buildmessage  '$(notdir $<)'
			buildcommands {'$(CXX) $(%{premake.make.cpp.fileFlags(cfg, file)}) $(FORCE_INCLUDE) -o "$@" -MF "$(@:%.o=%.d)" -c "$<"'}

		rule 'cc'
			fileExtension {".c", ".s", ".m"}
			buildoutputs  {'$(OBJDIR)/%{file.objname}.o'}
			buildmessage  '$(notdir $<)'
			buildcommands {'$(CC) $(%{premake.make.cpp.fileFlags(cfg, file)}) $(FORCE_INCLUDE) -o "$@" -MF "$(@:%.o=%.d)" -c "$<"'}

		rule 'resource'
			fileExtension ".rc"
			buildoutputs  {'$(OBJDIR)/%{file.objname}.res'}
			buildmessage  '$(notdir $<)'
			buildcommands {'$(RESCOMP) $< -O coff -o "$@" $(ALL_RESFLAGS)'}

		global(nil)
	end


	function cpp.createRuleTable(prj)
		local rules = {}

		local function addRule(extension, rule)
			if type(extension) == 'table' then
				for _, value in ipairs(extension) do
					addRule(value, rule)
				end
			else
				rules[extension] = rule
			end
		end

		-- add all rules.
		local usedRules = table.join({'cpp', 'cc', 'resource'}, prj.rules)
		for _, name in ipairs(usedRules) do
			local rule = premake.global.getRule(name)
			addRule(rule.fileExtension, rule)
		end

		-- create fileset categories.
		local filesets = {
			['.o']   = 'OBJECTS',
			['.obj'] = 'OBJECTS',
			['.cc']  = 'SOURCES',
			['.cpp'] = 'SOURCES',
			['.cxx'] = 'SOURCES',
			['.mm']  = 'SOURCES',
			['.c']   = 'SOURCES',
			['.s']   = 'SOURCES',
			['.m']   = 'SOURCES',
			['.rc']  = 'RESOURCES',
		}

		-- cache the result.
		prj._gmake = prj._gmake or {}
		prj._gmake.rules = rules
		prj._gmake.filesets = filesets
	end


	function cpp.createFileTable(prj)
		for cfg in project.eachconfig(prj) do
			cfg._gmake = cfg._gmake or {}
			cfg._gmake.filesets = {}
			cfg._gmake.fileRules = {}

			local files = table.shallowcopy(prj._.files)
			table.foreachi(files, function(node)
				cpp.addFile(cfg, node)
			end)

			for _, f in pairs(cfg._gmake.filesets) do
				table.sort(f)
			end

			cfg._gmake.kinds = table.keys(cfg._gmake.filesets)
			table.sort(cfg._gmake.kinds)

			prj._gmake.kinds = table.join(prj._gmake.kinds or {}, cfg._gmake.kinds)
		end

		-- we need to reassign object sequences if we generated any files.
		if prj.hasGeneratedFiles and p.project.iscpp(prj) then
			p.oven.assignObjectSequences(prj)
		end

		prj._gmake.kinds = table.unique(prj._gmake.kinds)
		table.sort(prj._gmake.kinds)
	end


	function cpp.addFile(cfg, node)
		local filecfg = fileconfig.getconfig(node, cfg)
		if not filecfg or filecfg.flags.ExcludeFromBuild then
			return
		end

		-- skip generated files, since we try to figure it out manually below.
		if node.generated then
			return
		end

		-- process custom build commands.
		if fileconfig.hasCustomBuildRule(filecfg) then
			local env = table.shallowcopy(filecfg.environ)
			env.PathVars = {
				["file.basename"]     = { absolute = false, token = node.basename },
				["file.abspath"]      = { absolute = true,  token = node.abspath },
				["file.relpath"]      = { absolute = false, token = node.relpath },
				["file.name"]         = { absolute = false, token = node.name },
				["file.objname"]      = { absolute = false, token = node.objname },
				["file.path"]         = { absolute = true,  token = node.path },
				["file.directory"]    = { absolute = true,  token = path.getdirectory(node.abspath) },
				["file.reldirectory"] = { absolute = false, token = path.getdirectory(node.relpath) },
			}

			local shadowContext = p.context.extent(filecfg, env)

			local buildoutputs = p.project.getrelative(cfg.project, shadowContext.buildoutputs)
			if buildoutputs and #buildoutputs > 0 then
				local file = {
					buildoutputs  = buildoutputs,
					source        = node.relpath,
					buildmessage  = shadowContext.buildmessage,
					buildcommands = shadowContext.buildcommands,
					buildinputs   = p.project.getrelative(cfg.project, shadowContext.buildinputs)
				}
				table.insert(cfg._gmake.fileRules, file)

				for _, output in ipairs(buildoutputs) do
{'fraction_non_alphanumeric': 0.15093780848963476, 'fraction_numerical': 0.0017769002961500495, 'mean_word_length': 3.1233211233211233, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4486529', 'n_tokens_mistral': 4128, 'n_tokens_neox': 3498, 'n_words': 811}