Compare commits

...

10 Commits

Author SHA1 Message Date
Thraix b112ab4501 Fix relative paths being put in the wrong intermediate directory 2026-01-20 23:24:27 +01:00
Thraix 1edcfb570b Fix project compilation failure
- Fix project compilation failure when the project contains two files
  with the same name, causing the intermediate file to be in the same
  directory with the same name
- Fix small print errors in makegen --help
2026-01-20 22:27:42 +01:00
Thraix 7c68a839fc Format code based on clang format 2025-11-26 22:06:55 +01:00
Thraix 6976d330fc Add --target=<target> flag
- Used to compile using a specific target, without the need of modifying
  the makegen.xml file
2025-08-05 20:45:36 +02:00
Thraix 658d6df8a5 Add includedirexcldep makgen.xml flag
- New flag is used to add include directories without making them part
  of the include dependency graph.
- Can be used to remove dependency graphs for include directories that
  aren't generally modified, like operating system library include
  directories
2025-06-04 22:20:09 +02:00
Thraix aa0b390379 Fix simple flag and excludesource
- Fix simple flag not generating the correct Makefile
- Fix excludesource not excluding the correct files
2025-06-04 22:09:33 +02:00
Thraix d3c334dc79 Fix absolute paths causing Makefile errors 2025-06-04 21:31:33 +02:00
Thraix f6caefb078 Add sourcefile as makegen.xml option
- sourcefile will add additional individual files. Useful for when the
  user needs to manually specify files from existing repositories. If
  those repositories contain multiple files for different platforms
- Rework IncludeDeps to support sourcefiles
2025-05-25 16:07:32 +02:00
Thraix 61f9c3ee0d Fix relative paths not being included as include dependency 2020-04-26 20:13:52 +02:00
Thraix febfda55cc Release v1.3.0 2020-03-07 22:06:57 +01:00
27 changed files with 1490 additions and 843 deletions
+334
View File
@@ -0,0 +1,334 @@
---
Language: Cpp
AccessModifierOffset: -2
AlignAfterOpenBracket: Align
AlignArrayOfStructures: None
AlignConsecutiveAssignments:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionDeclarations: false
AlignFunctionPointers: false
PadOperators: true
AlignConsecutiveBitFields:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionDeclarations: false
AlignFunctionPointers: false
PadOperators: false
AlignConsecutiveDeclarations:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionDeclarations: true
AlignFunctionPointers: false
PadOperators: false
AlignConsecutiveMacros:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionDeclarations: false
AlignFunctionPointers: false
PadOperators: false
AlignConsecutiveShortCaseStatements:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCaseArrows: false
AlignCaseColons: false
AlignConsecutiveTableGenBreakingDAGArgColons:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionDeclarations: false
AlignFunctionPointers: false
PadOperators: false
AlignConsecutiveTableGenCondOperatorColons:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionDeclarations: false
AlignFunctionPointers: false
PadOperators: false
AlignConsecutiveTableGenDefinitionColons:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionDeclarations: false
AlignFunctionPointers: false
PadOperators: false
AlignEscapedNewlines: Left
AlignOperands: Align
AlignTrailingComments:
Kind: Always
OverEmptyLines: 0
AllowAllArgumentsOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowBreakBeforeNoexceptSpecifier: Never
AllowShortBlocksOnASingleLine: Never
AllowShortCaseExpressionOnASingleLine: true
AllowShortCaseLabelsOnASingleLine: false
AllowShortCompoundRequirementOnASingleLine: true
AllowShortEnumsOnASingleLine: true
AllowShortFunctionsOnASingleLine: false
AllowShortIfStatementsOnASingleLine: Never
AllowShortLambdasOnASingleLine: All
AllowShortLoopsOnASingleLine: true
AllowShortNamespacesOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakBeforeMultilineStrings: true
AttributeMacros:
- __capability
- absl_nonnull
- absl_nullable
- absl_nullability_unknown
BinPackArguments: false
BinPackLongBracedList: true
BinPackParameters: false
BitFieldColonSpacing: Both
BracedInitializerIndentWidth: -1
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: Never
AfterEnum: false
AfterExternBlock: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
BeforeCatch: false
BeforeElse: false
BeforeLambdaBody: false
BeforeWhile: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakAdjacentStringLiterals: true
BreakAfterAttributes: Leave
BreakAfterJavaFieldAnnotations: false
BreakAfterReturnType: None
BreakArrays: true
BreakBeforeBinaryOperators: None
BreakBeforeConceptDeclarations: Always
BreakBeforeBraces: Allman
BreakBeforeInlineASMColon: OnlyMultiline
BreakBeforeTemplateCloser: false
BreakBeforeTernaryOperators: true
BreakBinaryOperations: Never
BreakConstructorInitializers: BeforeColon
BreakFunctionDefinitionParameters: false
BreakInheritanceList: BeforeColon
BreakStringLiterals: true
BreakTemplateDeclarations: Yes
ColumnLimit: 120
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerIndentWidth: 2
ContinuationIndentWidth: 2
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
EmptyLineAfterAccessModifier: Never
EmptyLineBeforeAccessModifier: LogicalBlock
EnumTrailingComma: Leave
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: false
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IfMacros:
- KJ_IF_MAYBE
IncludeBlocks: Regroup
IncludeCategories:
- Regex: '^<ext/.*\.h>'
Priority: 2
SortPriority: 0
CaseSensitive: false
- Regex: '^<.*\.h>'
Priority: 1
SortPriority: 0
CaseSensitive: false
- Regex: '^<.*'
Priority: 2
SortPriority: 0
CaseSensitive: false
- Regex: '.*'
Priority: 3
SortPriority: 0
CaseSensitive: false
IncludeIsMainRegex: '([-_](test|unittest))?$'
IncludeIsMainSourceRegex: ''
IndentAccessModifiers: false
IndentCaseBlocks: false
IndentCaseLabels: true
IndentExportBlock: true
IndentExternBlock: AfterExternBlock
IndentGotoLabels: true
IndentPPDirectives: None
IndentRequiresClause: true
IndentWidth: 2
IndentWrappedFunctionNames: false
InsertBraces: false
InsertNewlineAtEOF: false
InsertTrailingCommas: None
IntegerLiteralSeparator:
Binary: 0
BinaryMinDigits: 0
Decimal: 0
DecimalMinDigits: 0
Hex: 0
HexMinDigits: 0
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLines:
AtEndOfFile: false
AtStartOfBlock: false
AtStartOfFile: true
KeepFormFeed: false
LambdaBodyIndentation: Signature
LineEnding: DeriveLF
MacroBlockBegin: ''
MacroBlockEnd: ''
MainIncludeChar: Quote
MaxEmptyLinesToKeep: 1
NamespaceIndentation: All
ObjCBinPackProtocolList: Never
ObjCBlockIndentWidth: 2
ObjCBreakBeforeNestedBlockParam: true
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
OneLineFormatOffRegex: ''
PackConstructorInitializers: Never
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 1
PenaltyBreakBeforeMemberAccess: 150
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakOpenParenthesis: 0
PenaltyBreakScopeResolution: 500
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyIndentedWhitespace: 0
PenaltyReturnTypeOnItsOwnLine: 200
PointerAlignment: Left
PPIndentWidth: -1
QualifierAlignment: Leave
RawStringFormats:
- Language: Cpp
Delimiters:
- cc
- CC
- cpp
- Cpp
- CPP
- 'c++'
- 'C++'
CanonicalDelimiter: ''
BasedOnStyle: google
- Language: TextProto
Delimiters:
- pb
- PB
- proto
- PROTO
EnclosingFunctions:
- EqualsProto
- EquivToProto
- PARSE_PARTIAL_TEXT_PROTO
- PARSE_TEST_PROTO
- PARSE_TEXT_PROTO
- ParseTextOrDie
- ParseTextProtoOrDie
- ParseTestProto
- ParsePartialTestProto
CanonicalDelimiter: pb
BasedOnStyle: google
ReferenceAlignment: Pointer
ReflowComments: Always
RemoveBracesLLVM: false
RemoveEmptyLinesInUnwrappedLines: false
RemoveParentheses: Leave
RemoveSemicolon: false
RequiresClausePosition: OwnLine
RequiresExpressionIndentation: OuterScope
SeparateDefinitionBlocks: Always
ShortNamespaceLines: 1
SkipMacroDefinitionBody: false
SortIncludes:
Enabled: true
IgnoreCase: false
SortJavaStaticImport: Before
SortUsingDeclarations: LexicographicNumeric
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterOperatorKeyword: false
SpaceAfterTemplateKeyword: true
SpaceAroundPointerQualifiers: Default
SpaceBeforeAssignmentOperators: true
SpaceBeforeCaseColon: false
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeJsonColon: false
SpaceBeforeParens: ControlStatements
SpaceBeforeParensOptions:
AfterControlStatements: true
AfterForeachMacros: true
AfterFunctionDefinitionName: false
AfterFunctionDeclarationName: false
AfterIfMacros: true
AfterNot: false
AfterOverloadedOperator: false
AfterPlacementOperator: true
AfterRequiresInClause: false
AfterRequiresInExpression: false
BeforeNonEmptyParentheses: false
SpaceBeforeRangeBasedForLoopColon: true
SpaceBeforeSquareBrackets: false
SpaceInEmptyBlock: false
SpacesBeforeTrailingComments: 2
SpacesInAngles: Never
SpacesInContainerLiterals: true
SpacesInLineCommentPrefix:
Minimum: 1
Maximum: -1
SpacesInParens: Never
SpacesInParensOptions:
ExceptDoubleParentheses: false
InCStyleCasts: false
InConditionalStatements: false
InEmptyParentheses: false
Other: false
SpacesInSquareBrackets: false
Standard: Auto
StatementAttributeLikeMacros:
- Q_EMIT
StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION
TableGenBreakInsideDAGArg: DontBreak
TabWidth: 2
UseTab: Never
VerilogBreakBetweenInstancePorts: true
WhitespaceSensitiveMacros:
- BOOST_PP_STRINGIZE
- CF_SWIFT_NAME
- NS_SWIFT_NAME
- PP_STRINGIZE
- STRINGIZE
WrapNamespaceBodyWithEmptyLines: Leave
...
+23 -22
View File
@@ -1,4 +1,4 @@
# This Makefile was generated using MakeGen v1.3.0 made by Tim Håkansson
# This Makefile was generated using MakeGen v1.3.8 made by Tim Håkansson
# and is licensed under MIT. Full source of the project can be found at
# https://github.com/Thraix/MakeGen
CC=@g++
@@ -7,59 +7,60 @@ MKDIR_P=mkdir -p
BIN=bin/
OBJPATH=$(BIN)intermediates
INCLUDES=
OBJECTS=$(OBJPATH)/ConfigCLI.o $(OBJPATH)/ConfigFile.o $(OBJPATH)/HFileGen.o $(OBJPATH)/IncludeDeps.o $(OBJPATH)/Makefile.o $(OBJPATH)/Utils.o $(OBJPATH)/ConfigFileConf.o $(OBJPATH)/main.o $(OBJPATH)/XML.o $(OBJPATH)/XMLObject.o
CFLAGS=$(INCLUDES) -std=c++17 -c -D_DEBUG -g3 -w
OBJECTS=$(OBJPATH)/src/ConfigCLI.o $(OBJPATH)/src/ConfigFile.o $(OBJPATH)/src/HFileGen.o $(OBJPATH)/src/IncludeDeps.o $(OBJPATH)/src/Makefile.o $(OBJPATH)/src/Utils.o $(OBJPATH)/src/compatibility/ConfigFileConf.o $(OBJPATH)/src/main.o $(OBJPATH)/src/xml/XML.o $(OBJPATH)/src/xml/XMLObject.o
CFLAGS=$(INCLUDES) -std=c++17 -c
LIBDIR=
LDFLAGS=
LIBS=$(LIBDIR)
OUTPUT=$(BIN)makegen
.PHONY: all directories rebuild clean run
all: directories $(OUTPUT)
directories: $(BIN) $(OBJPATH)
$(BIN):
$(info Creating output directories)
@$(MKDIR_P) $(BIN)
$(OBJPATH):
@$(MKDIR_P) $(OBJPATH)
directories: $(OBJPATH)/src $(OBJPATH)/src/compatibility $(OBJPATH)/src/xml
$(OBJPATH)/src:
@$(MKDIR_P) $@
$(OBJPATH)/src/compatibility:
@$(MKDIR_P) $@
$(OBJPATH)/src/xml:
@$(MKDIR_P) $@
run: all
@./$(OUTPUT)
rebuild: clean all
clean:
$(info Removing intermediates)
rm -rf $(OBJPATH)/*.o
$(info Removing $(OBJPATH))
@rm -rf $(OBJPATH)/
$(OUTPUT): $(OBJECTS)
$(info Generating output file)
$(info Generating output file $(OUTPUT))
$(CO) $(OUTPUT) $(OBJECTS) $(LDFLAGS) $(LIBS)
install: all
$(info Installing MakeGen to /usr/bin/)
@cp $(OUTPUT) /usr/bin/makegen
$(OBJPATH)/ConfigCLI.o : src/ConfigCLI.cpp src/Common.h src/ConfigCLI.h src/ConfigFile.h src/ConfigUtils.h src/FileUtils.h src/Utils.h src/xml/XMLObject.h
$(OBJPATH)/src/ConfigCLI.o: src/ConfigCLI.cpp src/Common.h src/ConfigCLI.h src/ConfigFile.h src/ConfigUtils.h src/FileUtils.h src/Utils.h src/FlagData.h src/xml/XMLObject.h
$(info -[10%]- $<)
$(CC) $(CFLAGS) -o $@ $<
$(OBJPATH)/ConfigFile.o : src/ConfigFile.cpp src/ConfigFile.h src/ConfigUtils.h src/Common.h src/FileUtils.h src/Utils.h src/xml/XMLObject.h src/compatibility/ConfigFileConf.h src/xml/XML.h
$(OBJPATH)/src/ConfigFile.o: src/ConfigFile.cpp src/ConfigFile.h src/ConfigUtils.h src/Common.h src/FileUtils.h src/Utils.h src/FlagData.h src/xml/XMLObject.h src/compatibility/ConfigFileConf.h src/xml/XML.h
$(info -[20%]- $<)
$(CC) $(CFLAGS) -o $@ $<
$(OBJPATH)/HFileGen.o : src/HFileGen.cpp src/FileUtils.h src/Common.h src/Utils.h src/HFileGen.h src/ConfigFile.h src/ConfigUtils.h src/xml/XMLObject.h
$(OBJPATH)/src/HFileGen.o: src/HFileGen.cpp src/FileUtils.h src/Common.h src/Utils.h src/HFileGen.h src/ConfigFile.h src/ConfigUtils.h src/FlagData.h src/xml/XMLObject.h
$(info -[30%]- $<)
$(CC) $(CFLAGS) -o $@ $<
$(OBJPATH)/IncludeDeps.o : src/IncludeDeps.cpp src/Common.h src/IncludeDeps.h src/ConfigFile.h src/ConfigUtils.h src/FileUtils.h src/Utils.h src/xml/XMLObject.h
$(OBJPATH)/src/IncludeDeps.o: src/IncludeDeps.cpp src/Common.h src/IncludeDeps.h src/ConfigFile.h src/ConfigUtils.h src/FileUtils.h src/Utils.h src/FlagData.h src/xml/XMLObject.h
$(info -[40%]- $<)
$(CC) $(CFLAGS) -o $@ $<
$(OBJPATH)/Makefile.o : src/Makefile.cpp src/IncludeDeps.h src/ConfigFile.h src/ConfigUtils.h src/Common.h src/FileUtils.h src/Utils.h src/xml/XMLObject.h src/Makefile.h
$(OBJPATH)/src/Makefile.o: src/Makefile.cpp src/Common.h src/IncludeDeps.h src/ConfigFile.h src/ConfigUtils.h src/FileUtils.h src/Utils.h src/FlagData.h src/xml/XMLObject.h src/Makefile.h
$(info -[50%]- $<)
$(CC) $(CFLAGS) -o $@ $<
$(OBJPATH)/Utils.o : src/Utils.cpp src/ConfigFile.h src/ConfigUtils.h src/Common.h src/FileUtils.h src/Utils.h src/xml/XMLObject.h
$(OBJPATH)/src/Utils.o: src/Utils.cpp src/ConfigFile.h src/ConfigUtils.h src/Common.h src/FileUtils.h src/Utils.h src/FlagData.h src/xml/XMLObject.h
$(info -[60%]- $<)
$(CC) $(CFLAGS) -o $@ $<
$(OBJPATH)/ConfigFileConf.o : src/compatibility/ConfigFileConf.cpp src/compatibility/ConfigFileConf.h
$(OBJPATH)/src/compatibility/ConfigFileConf.o: src/compatibility/ConfigFileConf.cpp src/ConfigFile.h src/ConfigUtils.h src/Common.h src/FileUtils.h src/Utils.h src/FlagData.h src/xml/XMLObject.h src/compatibility/ConfigFileConf.h
$(info -[70%]- $<)
$(CC) $(CFLAGS) -o $@ $<
$(OBJPATH)/main.o : src/main.cpp src/Common.h src/ConfigCLI.h src/ConfigFile.h src/ConfigUtils.h src/FileUtils.h src/Utils.h src/xml/XMLObject.h src/HFileGen.h src/Makefile.h src/Timer.h
$(OBJPATH)/src/main.o: src/main.cpp src/Common.h src/ConfigCLI.h src/ConfigFile.h src/ConfigUtils.h src/FileUtils.h src/Utils.h src/FlagData.h src/xml/XMLObject.h src/HFileGen.h src/Makefile.h src/Timer.h
$(info -[80%]- $<)
$(CC) $(CFLAGS) -o $@ $<
$(OBJPATH)/XML.o : src/xml/XML.cpp src/xml/XML.h src/xml/XMLObject.h src/xml/XMLException.h
$(OBJPATH)/src/xml/XML.o: src/xml/XML.cpp src/xml/XML.h src/xml/XMLObject.h src/xml/XMLException.h
$(info -[90%]- $<)
$(CC) $(CFLAGS) -o $@ $<
$(OBJPATH)/XMLObject.o : src/xml/XMLObject.cpp src/xml/XMLException.h src/xml/XMLObject.h
$(OBJPATH)/src/xml/XMLObject.o: src/xml/XMLObject.cpp src/Common.h src/Utils.h src/xml/XMLException.h src/xml/XMLObject.h
$(info -[100%]- $<)
$(CC) $(CFLAGS) -o $@ $<
+2 -2
View File
@@ -18,6 +18,6 @@
<projectname>MakeGen</projectname>
<srcdir>src/</srcdir>
</configuration>
<target>Debug</target>
<version>v1.3.0</version>
<target>Release</target>
<version>v1.3.8</version>
</makegen>
Executable → Regular
+34 -2
View File
@@ -1,6 +1,8 @@
#pragma once
#include <iostream>
#include <set>
#include <vector>
#define BIT(x) (1 << x)
@@ -12,7 +14,7 @@
// Release, should be backwards compatible with any minor version
#define MAKEGEN_VERSION_RELEASE 3
// Minor changes, generally bug fixes
#define MAKEGEN_VERSION_MINOR 0
#define MAKEGEN_VERSION_MINOR 8
#define MAKEGEN_VERSION ("v" STR(MAKEGEN_VERSION_MAJOR) "." STR(MAKEGEN_VERSION_RELEASE) "." STR(MAKEGEN_VERSION_MINOR))
@@ -27,7 +29,7 @@ const static unsigned int FLAG_SINGLE_THREAD = BIT(7);
const static unsigned int FLAG_DEPENDENCY = BIT(8);
const static unsigned int FLAG_SIMPLE = BIT(9);
const static unsigned int FLAG_CONFIG = BIT(10);
const static unsigned int FLAG_TARGET = BIT(11);
#define LOG_INFO(...) LogHelper(__VA_ARGS__)
#define LOG_WARNING(...) LogHelper(__VA_ARGS__)
@@ -60,3 +62,33 @@ void LogHelper(const T& var, const Ts& ...vars)
Log(vars...);
std::cout << std::endl;
}
template <typename T>
std::ostream& operator<<(std::ostream& ostream, const std::vector<T>& vec)
{
ostream << "[" << std::endl;
for (size_t i = 0; i < vec.size(); i++)
{
if (i != 0)
ostream << ", " << std::endl;
ostream << vec[i];
}
ostream << std::endl << "]";
return ostream;
}
template <typename T>
std::ostream& operator<<(std::ostream& ostream, const std::set<T>& set)
{
ostream << "[" << std::endl;
int i = 0;
for (const auto& elem : set)
{
if (i != 0)
ostream << ", " << std::endl;
ostream << " " << elem;
i++;
}
ostream << std::endl << "]";
return ostream;
}
+3 -6
View File
@@ -3,8 +3,6 @@
#include "Common.h"
#include "ConfigFile.h"
#include <set>
void ConfigCLI::DisplayCLIHelp()
{
LOG_INFO(1 + (char*)R"(
@@ -130,7 +128,6 @@ Valid settings are:
genhfile Specifies if MakeGen should generate a project h-file)");
}
ConfigSetting ConfigCLI::CLIStringToSetting(const std::string& s)
{
static std::map<std::string, ConfigSetting> map{
@@ -174,12 +171,12 @@ int ConfigCLI::Gen(int argc, char** argv)
std::string option = argv[1];
if (option == "prompt")
{
ConfigFile::Gen().Save();
ConfigFile::Gen(FlagData{}).Save();
return 0;
}
if (option == "default")
{
ConfigFile{FileUtils::GetRealPath("."),0}.Save();
ConfigFile{FileUtils::GetRealPath("."), FlagData{}, 0}.Save();
return 0;
}
else
@@ -324,7 +321,7 @@ int ConfigCLI::Main(int argc, char** argv)
DisplayCLIHelp();
return 0;
}
std::optional<ConfigFile> config = ConfigFile::GetConfigFile();
std::optional<ConfigFile> config = ConfigFile::GetConfigFile("./", FlagData{});
std::string command = argv[1];
if (command == "gen")
{
+1 -1
View File
@@ -6,6 +6,7 @@ struct ConfigCLI
{
public:
static int Main(int argc, char** argv);
private:
static void DisplayCLIHelp();
static void DisplayGenHelp();
@@ -21,5 +22,4 @@ struct ConfigCLI
static int Remove(int argc, char** argv, ConfigFile& config);
static int Set(int argc, char** argv, ConfigFile& config);
static int Get(int argc, char** argv, ConfigFile& config);
};
Executable → Regular
+46 -34
View File
@@ -1,13 +1,12 @@
#include "ConfigFile.h"
#include <fstream>
#include "FileUtils.h"
#include "compatibility/ConfigFileConf.h"
#include "xml/XML.h"
#include <algorithm>
#include <fstream>
ConfigFile::ConfigFile(const std::string& path, int)
ConfigFile::ConfigFile(const std::string& path, const FlagData& flagData, int)
: configPath{path}
{
// Converts project name (current directory) to lowercase
@@ -17,6 +16,9 @@ ConfigFile::ConfigFile(const std::string& path, int)
// Version, target and configuration is probably going to be used in the future
makegen.AddXMLObject(XMLObject("version", {}, "v1.3.0"));
if (flagData.flags & FLAG_TARGET)
makegen.AddXMLObject(XMLObject("target", {}, flagData.target));
else
makegen.AddXMLObject(XMLObject("target", {}, "Release"));
XMLObject configuration("configuration", {{"name", "Release"}}, std::map<std::string, std::vector<XMLObject>>{});
@@ -30,22 +32,30 @@ ConfigFile::ConfigFile(const std::string& path, int)
makegen.AddXMLObject(configuration);
config = makegen;
Init();
Init(flagData);
}
ConfigFile::ConfigFile(const std::string& path)
: config{XML::FromFile(path + CONFIG_FILENAME)}, configPath{path}
ConfigFile::ConfigFile(const std::string& path, const FlagData& flagData)
: config{XML::FromFile(path + CONFIG_FILENAME)},
configPath{path}
{
Init();
Init(flagData);
}
ConfigFile::ConfigFile(XMLObject& config, const std::string& path)
: config{config}, configPath{path}
ConfigFile::ConfigFile(XMLObject& config, const std::string& path, const FlagData& flagData)
: config{config},
configPath{path}
{
Init();
Init(flagData);
}
void ConfigFile::Init()
void ConfigFile::Init(const FlagData& flagData)
{
if (flagData.flags & FLAG_TARGET)
{
target = flagData.target;
}
else
{
const std::vector<XMLObject>* targetXml = config.GetObjectPtr("target");
target = "Release";
@@ -54,12 +64,12 @@ void ConfigFile::Init()
LOG_ERROR("No target found in config file. Using target=", target);
return;
}
if (targetXml->size() > 1)
LOG_ERROR("To many targets in config file. Using target=", (*targetXml)[0].GetText());
if (targetXml->size() > 0)
target = (*targetXml)[0].GetText();
}
}
std::string& ConfigFile::GetSettingString(ConfigSetting setting)
{
@@ -86,7 +96,7 @@ std::string& ConfigFile::GetSettingString(ConfigSetting setting)
LOG_ERROR("To many arguments for setting using first: ", (int)setting, "=", (*values)[0].GetText());
}
std::string s = (*values)[0].GetText();
if(ConfigUtils::IsDirectory(setting) && s[s.size()-1] != '/')
if (ConfigUtils::IsDirectory(setting) && !s.empty() && s[s.size() - 1] != '/')
s += '/';
return cache.strings.emplace(sSetting, s).first->second;
}
@@ -310,7 +320,8 @@ XMLObject& ConfigFile::GetConfiguration()
}
}
LOG_ERROR("Couldn\'t find given target in config file. Using target=", (*configurations)[0].HasAttribute("name") ? (*configurations)[0].GetAttribute("name") : "");
LOG_ERROR("Couldn\'t find given target in config file. Using target=",
(*configurations)[0].HasAttribute("name") ? (*configurations)[0].GetAttribute("name") : "");
return (*configurations)[0];
}
@@ -324,13 +335,15 @@ ConfigFile& ConfigFile::GetDependencyConfig(size_t i)
return dependencyConfigs[i];
}
std::optional<ConfigFile> ConfigFile::GetConfigFile(const std::string& filepath)
std::optional<ConfigFile> ConfigFile::GetConfigFile(const std::string& filepath, const FlagData& flagData)
{
std::map<std::string, ConfigFile> loadedConfigs;
return GetConfigFile(filepath, loadedConfigs);
return GetConfigFile(filepath, loadedConfigs, flagData);
}
std::optional<ConfigFile> ConfigFile::GetConfigFile(const std::string& filepath, std::map<std::string, ConfigFile>& loadedConfigs)
std::optional<ConfigFile> ConfigFile::GetConfigFile(const std::string& filepath,
std::map<std::string, ConfigFile>& loadedConfigs,
const FlagData& flagData)
{
std::string realPath = FileUtils::GetRealPath(filepath);
if (realPath == "")
@@ -355,7 +368,7 @@ std::optional<ConfigFile> ConfigFile::GetConfigFile(const std::string& filepath,
if (f.good())
{
f.close();
ConfigFile conf = ConfigFile(filepath);
ConfigFile conf = ConfigFile(filepath, flagData);
if (conf.hasInitError)
return {};
loadedConfigs.emplace(realPath, conf);
@@ -364,7 +377,7 @@ std::optional<ConfigFile> ConfigFile::GetConfigFile(const std::string& filepath,
// Create dependency config files.
for (size_t i = 0; i < dependencies.size(); ++i)
{
std::optional<ConfigFile> dep = GetConfigFile(conf.configPath + dependencies[i], loadedConfigs);
std::optional<ConfigFile> dep = GetConfigFile(conf.configPath + dependencies[i], loadedConfigs, flagData);
if (dep)
{
conf.dependencyConfigs.push_back(*dep);
@@ -426,10 +439,11 @@ void ConfigFile::InputMultiple(const std::string& inputText, std::vector<std::st
}
}
ConfigFile ConfigFile::Gen()
ConfigFile ConfigFile::Gen(const FlagData& flagData)
{
bool executable, shared, generateHFile;
std::vector<std::string> libs, libdirs, includedirs, defines, compileFlags, linkingFlags, dependencies, excludeSources, excludeHeaders;
std::vector<std::string> libs, libdirs, includedirs, defines, compileFlags, linkingFlags, dependencies,
excludeSources, excludeHeaders;
std::string srcdir, outputdir, projectname, outputname, hFile;
InputBoolean("Should it be compiled as an executable? (y/n)", executable);
@@ -462,12 +476,14 @@ ConfigFile ConfigFile::Gen()
InputString("Enter a name for the project:", projectname, false, false);
InputString("Enter a name for the output file:", outputname, false, false);
// Create xml
XMLObject makegen("makegen", {}, std::map<std::string, std::vector<XMLObject>>{});
// Version, target and configuration is probably going to be used in the future
makegen.AddXMLObject(XMLObject("version", {}, "v1.3.0"));
if (flagData.flags & FLAG_TARGET)
makegen.AddXMLObject(XMLObject("target", {}, flagData.target));
else
makegen.AddXMLObject(XMLObject("target", {}, "Release"));
XMLObject configuration("configuration", {{"name", "Release"}}, std::map<std::string, std::vector<XMLObject>>{});
@@ -476,25 +492,21 @@ ConfigFile ConfigFile::Gen()
configuration.AddXMLObject(XMLObject("srcdir", {}, srcdir));
configuration.AddXMLObject(XMLObject("outputdir", {}, outputdir));
configuration.AddXMLObject(XMLObject("hfilename", {}, hFile));
configuration.AddXMLObject(XMLObject("outputtype", {},
executable ? "executable" : (shared ? "sharedlibrary" : "staticlibrary")));
configuration.AddXMLObject(
XMLObject("outputtype", {}, executable ? "executable" : (shared ? "sharedlibrary" : "staticlibrary")));
configuration.AddXMLObject(XMLObject("generatehfile", {}, generateHFile ? "true" : "false"));
for(auto it = libs.begin();it != libs.end(); ++it)
configuration.AddXMLObject({"library",{},*it});
for(auto it = libdirs.begin();it != libdirs.end(); ++it)
configuration.AddXMLObject({"librarydir",{},*it});
for (auto it = libs.begin(); it != libs.end(); ++it) configuration.AddXMLObject({"library", {}, *it});
for (auto it = libdirs.begin(); it != libdirs.end(); ++it) configuration.AddXMLObject({"librarydir", {}, *it});
for (auto it = includedirs.begin(); it != includedirs.end(); ++it)
configuration.AddXMLObject({"includedir", {}, *it});
for(auto it = defines.begin();it != defines.end(); ++it)
configuration.AddXMLObject({"define",{},*it});
for(auto it = compileFlags.begin();it != compileFlags.end(); ++it)
configuration.AddXMLObject({"cflag",{},*it});
for (auto it = defines.begin(); it != defines.end(); ++it) configuration.AddXMLObject({"define", {}, *it});
for (auto it = compileFlags.begin(); it != compileFlags.end(); ++it) configuration.AddXMLObject({"cflag", {}, *it});
for (auto it = dependencies.begin(); it != dependencies.end(); ++it)
configuration.AddXMLObject({"dependency", {}, *it});
makegen.AddXMLObject(configuration);
return ConfigFile{makegen, FileUtils::GetRealPath(".")};
return ConfigFile{makegen, FileUtils::GetRealPath("."), flagData};
}
void ConfigFile::Save() const
Executable → Regular
+15 -10
View File
@@ -1,13 +1,14 @@
#pragma once
#include "ConfigUtils.h"
#include "xml/XMLObject.h"
#include <map>
#include <optional>
#include <string>
#include <vector>
#include "ConfigUtils.h"
#include "FlagData.h"
#include "xml/XMLObject.h"
static const std::string CONFIG_FILENAME = "makegen.xml";
class ConfigFile
@@ -26,9 +27,9 @@ class ConfigFile
public:
// Generates a new default config file
ConfigFile(const std::string& path, int);
ConfigFile(const std::string& path);
ConfigFile(XMLObject& config, const std::string& path);
ConfigFile(const std::string& path, const FlagData& flagData, int);
ConfigFile(const std::string& path, const FlagData& flagData);
ConfigFile(XMLObject& config, const std::string& path, const FlagData& flagData);
void Save() const;
@@ -44,14 +45,18 @@ class ConfigFile
XMLObject& GetConfiguration();
const std::string& GetConfigPath() const;
ConfigFile& GetDependencyConfig(size_t i);
private:
void Init();
void Init(const FlagData& flagData);
public:
static ConfigFile Gen();
static std::optional<ConfigFile> GetConfigFile(const std::string& filepath = "./");
static ConfigFile Gen(const FlagData& flagData);
static std::optional<ConfigFile> GetConfigFile(const std::string& filepath, const FlagData& flagData);
private:
static std::optional<ConfigFile> GetConfigFile(const std::string& filepath, std::map<std::string, ConfigFile>& loadedConfigs);
static std::optional<ConfigFile> GetConfigFile(const std::string& filepath,
std::map<std::string, ConfigFile>& loadedConfigs,
const FlagData& flagData);
static std::optional<ConfigFile> Load(const std::string& filename);
static void InputBoolean(const std::string& inputText, bool& b);
static void InputMultiple(const std::string& inputText, std::vector<std::string>& vec, bool needEnding);
+49 -24
View File
@@ -1,13 +1,14 @@
#pragma once
#include <assert.h>
#include <map>
#include <string>
#include <vector>
#include "Common.h"
#include "FileUtils.h"
#include <assert.h>
#include <map>
#include <vector>
#include <string>
struct ConfigCache
{
std::map<std::string, std::string> strings;
@@ -18,9 +19,26 @@ struct ConfigCache
enum class ConfigSetting
{
// vectors
Library = 0, LibraryDir = 1, IncludeDir = 2, Define = 3, Dependency = 4, CFlag = 5, LFlag = 6, ExcludeSource = 7, ExcludeHeader = 8, ExecPreArgument = 9, ExecArgument = 10,
Library = 0,
LibraryDir = 1,
IncludeDir = 2,
Define = 3,
Dependency = 4,
CFlag = 5,
LFlag = 6,
ExcludeSource = 7,
ExcludeHeader = 8,
ExecPreArgument = 9,
ExecArgument = 10,
SourceFile = 11,
IncludeDirExclDep = 12,
// Strings
SourceDir = 32, OutputDir = 33, OutputName = 34, OutputType = 35, ProjectName = 36, HFileName = 37,
SourceDir = 32,
OutputDir = 33,
OutputName = 34,
OutputType = 35,
ProjectName = 36,
HFileName = 37,
// Bools
GenerateHFile = 64,
// Other
@@ -69,9 +87,14 @@ struct ConfigUtils
return "argument";
case ConfigSetting::GenerateHFile:
return "generatehfile";
case ConfigSetting::SourceFile:
return "sourcefile";
case ConfigSetting::IncludeDirExclDep:
return "includedirexcldep";
case ConfigSetting::Invalid:
return "invalid";
}
return "";
}
static bool IsDirectory(ConfigSetting setting)
@@ -83,6 +106,7 @@ struct ConfigUtils
case ConfigSetting::LibraryDir:
case ConfigSetting::IncludeDir:
case ConfigSetting::Dependency:
case ConfigSetting::IncludeDirExclDep:
return true;
case ConfigSetting::OutputName:
case ConfigSetting::OutputType:
@@ -97,11 +121,11 @@ struct ConfigUtils
case ConfigSetting::ExecPreArgument:
case ConfigSetting::ExecArgument:
case ConfigSetting::GenerateHFile:
case ConfigSetting::SourceFile:
case ConfigSetting::Invalid:
return false;
default:
LOG_ERROR("INVALID ENUM: ", (int)setting);
assert(false);
}
return false;
}
static bool IsStringSetting(ConfigSetting setting)
@@ -127,9 +151,12 @@ struct ConfigUtils
case ConfigSetting::ExecPreArgument:
case ConfigSetting::ExecArgument:
case ConfigSetting::GenerateHFile:
case ConfigSetting::SourceFile:
case ConfigSetting::IncludeDirExclDep:
case ConfigSetting::Invalid:
return false;
}
return false;
}
static bool IsVectorSetting(ConfigSetting setting)
@@ -147,6 +174,8 @@ struct ConfigUtils
case ConfigSetting::ExcludeSource:
case ConfigSetting::ExecPreArgument:
case ConfigSetting::ExecArgument:
case ConfigSetting::SourceFile:
case ConfigSetting::IncludeDirExclDep:
return true;
case ConfigSetting::SourceDir:
case ConfigSetting::OutputDir:
@@ -158,7 +187,9 @@ struct ConfigUtils
case ConfigSetting::Invalid:
return false;
}
return false;
}
static bool IsBoolSetting(ConfigSetting setting)
{
switch (setting)
@@ -182,9 +213,12 @@ struct ConfigUtils
case ConfigSetting::ExcludeSource:
case ConfigSetting::ExecPreArgument:
case ConfigSetting::ExecArgument:
case ConfigSetting::SourceFile:
case ConfigSetting::Invalid:
case ConfigSetting::IncludeDirExclDep:
return false;
}
return false;
}
static std::string GetDefaultSettingString(ConfigSetting setting, const std::string& path)
@@ -209,6 +243,7 @@ struct ConfigUtils
LOG_ERROR("INVALID STRING ENUM: ", (int)setting);
assert(false);
}
return "";
}
static bool GetDefaultSettingBool(ConfigSetting setting)
@@ -232,8 +267,7 @@ struct ConfigUtils
{
std::string projectname = GetDefaultProjectName(path);
std::string outputname;
std::transform(
projectname.begin(),
std::transform(projectname.begin(),
projectname.end(),
std::back_inserter(outputname),
[](unsigned char c)
@@ -242,13 +276,9 @@ struct ConfigUtils
return '_';
return (char)std::tolower(c);
});
auto it = std::remove_if(
outputname.begin(),
auto it = std::remove_if(outputname.begin(),
outputname.end(),
[](unsigned char c)
{
return (c < '0' || c > '9') && (c < 'a' || c > 'z') && c != '_';
});
[](unsigned char c) { return (c < '0' || c > '9') && (c < 'a' || c > 'z') && c != '_'; });
outputname.erase(it, outputname.end());
outputname += ".out";
return outputname;
@@ -258,12 +288,7 @@ struct ConfigUtils
{
std::string hfile = GetDefaultProjectName(path);
auto it = std::remove_if(
hfile.begin(),
hfile.end(),
[](unsigned char c)
{
return (c < 'a' || c > 'z') && (c < 'A' || c > 'Z');
});
hfile.begin(), hfile.end(), [](unsigned char c) { return (c < 'a' || c > 'z') && (c < 'A' || c > 'Z'); });
hfile.erase(it, hfile.end());
hfile += ".h";
return hfile;
+24 -14
View File
@@ -1,17 +1,20 @@
#pragma once
#include <assert.h>
#include <dirent.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
#include <algorithm>
#include <cstring>
#include <filesystem>
#include <fstream>
#include <string>
#include <vector>
#include "Common.h"
#include "Utils.h"
#include <algorithm>
#include <assert.h>
#include <cstring>
#include <dirent.h>
#include <fstream>
#include <sys/stat.h>
#include <stdlib.h>
#include <string>
#include <vector>
#include <unistd.h>
struct FileUtils
{
@@ -112,8 +115,9 @@ struct FileUtils
{
// Find the most common directory
std::string commonPath = Utils::CommonPrefix(from, to);
while(commonPath.back() != '/')
commonPath.pop_back();
if (commonPath.empty())
return "";
while (commonPath.back() != '/') commonPath.pop_back();
commonPath.pop_back();
// Go back to the common directory
@@ -135,8 +139,9 @@ struct FileUtils
{
DIR* dp;
struct dirent* dirp;
if((dp = opendir(folder.c_str())) == NULL){
LOG_ERROR(errno);
if ((dp = opendir(folder.c_str())) == NULL)
{
LOG_ERROR("Failed to open directory: ", folder);
return;
}
while ((dirp = readdir(dp)) != NULL)
@@ -156,4 +161,9 @@ struct FileUtils
}
closedir(dp);
}
static bool FileExists(const std::string& filename)
{
return std::filesystem::exists(filename) && !std::filesystem::is_directory(filename);
}
};
+9
View File
@@ -0,0 +1,9 @@
#pragma once
#include <string>
struct FlagData
{
unsigned int flags{0};
std::string target{""}; // Only set if flags contain FLAG_TARGET
};
+4 -2
View File
@@ -1,8 +1,9 @@
#include "HFileGen.h"
#include "FileUtils.h"
#include <set>
#include "FileUtils.h"
void HFileGen::Create(ConfigFile& conf)
{
std::set<std::string> hFiles;
@@ -17,7 +18,8 @@ void HFileGen::Create(ConfigFile& conf)
if (extensionPos != std::string::npos)
{
std::string filename = it->substr(path.length());
if(Utils::IsHeaderFile(filename) && filename != conf.GetConfigPath() + conf.GetSettingString(ConfigSetting::HFileName))
if (Utils::IsHeaderFile(filename) &&
filename != conf.GetConfigPath() + conf.GetSettingString(ConfigSetting::HFileName))
{
// Make files sorted in alphabetical order
hFiles.emplace(filename);
Executable → Regular
+53 -18
View File
@@ -1,17 +1,27 @@
#include "IncludeDeps.h"
#include <sstream>
#include "Common.h"
std::set<std::string> IncludeDeps::printSet;
int IncludeDeps::printCounter = 0;
IncludeDeps::IncludeDeps(const std::string& filename, const std::string& dir, const std::set<HFile>& files, std::map<std::string, IncludeDeps*>& allDeps)
: IncludeDeps{filename, dir, false, files, allDeps}
{}
IncludeDeps::IncludeDeps(const std::string& filename, const std::string& dir, bool projectHFile, const std::set<HFile>& files, std::map<std::string, IncludeDeps*>& allDeps)
: filepath(dir+filename), projectHFile{projectHFile}
IncludeDeps::IncludeDeps(const std::string& filename,
const std::set<HFile>& files,
std::map<std::string, IncludeDeps*>& allDeps)
: IncludeDeps{filename, false, files, allDeps}
{
}
IncludeDeps::IncludeDeps(const std::string& filename,
bool projectHFile,
const std::set<HFile>& files,
std::map<std::string, IncludeDeps*>& allDeps)
: filepath(filename),
projectHFile{projectHFile}
{
std::filesystem::path path{filepath};
if (Utils::IsHeaderFile(filename))
{
allDeps.emplace(filepath, this);
@@ -20,42 +30,67 @@ IncludeDeps::IncludeDeps(const std::string& filename, const std::string& dir, bo
std::string line;
while (std::getline(file, line))
{
size_t pos = line.find("#include");
if(pos != std::string::npos)
std::string start;
std::stringstream ss{line};
ss >> start;
if (start == "#include")
{
std::string include = GetIncludeFile(line);
std::filesystem::path includeFileRelativeToSource;
if (path.is_absolute())
includeFileRelativeToSource = std::filesystem::relative("/", ".").string() + "/" + include;
else
includeFileRelativeToSource = std::filesystem::relative(path.parent_path(), ".").string() + "/" + include;
// Check if file can be found relative to current file:
if (FileUtils::FileExists(includeFileRelativeToSource.string()))
{
auto itD = allDeps.find(includeFileRelativeToSource.string());
if (itD == allDeps.end())
{
IncludeDeps* inc = new IncludeDeps(includeFileRelativeToSource.string(), false, files, allDeps);
dependencies.emplace(includeFileRelativeToSource, inc);
}
else
{
dependencies.emplace(itD->first, itD->second);
}
}
else
{
std::string include = GetIncludeFile(line, pos, filename);
auto it = files.find({include, "", false});
if (it != files.end())
{
auto itD = allDeps.find(it->filepath);
if (itD == allDeps.end())
{
IncludeDeps* inc = new IncludeDeps(it->filename,it->directory, it->isProjectHFile, files,allDeps);
IncludeDeps* inc = new IncludeDeps(it->filepath, it->isProjectHFile, files, allDeps);
dependencies.emplace(it->filepath, inc);
}else{
}
else
{
dependencies.emplace(itD->first, itD->second);
}
}
}
}
}
}
std::string IncludeDeps::GetIncludeFile(const std::string& line, size_t pos, const std::string& filename)
std::string IncludeDeps::GetIncludeFile(const std::string& line)
{
size_t bracket = line.find('<',pos);
size_t bracket = line.find('<');
if (bracket == std::string::npos)
{
bracket = line.find('\"',pos);
bracket = line.find('\"');
if (bracket == std::string::npos)
{
return "";
}
size_t slash = filename.find_last_of("/");
std::string include = line.substr(bracket + 1, line.find('\"', bracket + 1) - bracket - 1);
if(slash == std::string::npos)
slash = -1;
return filename.substr(0,slash+1)+include;
return include;
}
else
{
Executable → Regular
+24 -11
View File
@@ -1,41 +1,51 @@
#pragma once
#include "ConfigFile.h"
#include "FileUtils.h"
#include <filesystem>
#include <iostream>
#include <map>
#include <set>
#include <string>
#include "ConfigFile.h"
#include "FileUtils.h"
struct CompareIncludeDeps;
class IncludeDeps
{
public:
std::map<std::string, IncludeDeps*> dependencies;
std::string filepath;
std::filesystem::path filepath;
bool projectHFile;
static std::set<std::string> printSet;
static int printCounter;
IncludeDeps(const std::string& filename, const std::string& dir, const std::set<HFile>& files, std::map<std::string, IncludeDeps*>& allDeps);
IncludeDeps(const std::string& filename, const std::set<HFile>& files, std::map<std::string, IncludeDeps*>& allDeps);
IncludeDeps(const std::string& filename, const std::string& dir, bool projectHFile, const std::set<HFile>& files, std::map<std::string, IncludeDeps*>& allDeps);
IncludeDeps(const std::string& filename,
bool projectHFile,
const std::set<HFile>& files,
std::map<std::string, IncludeDeps*>& allDeps);
std::string GetIncludeFile(const std::string& line, size_t pos, const std::string& filename);
std::string GetIncludeFile(const std::string& line);
std::ostream& Output(std::ostream& stream, const ConfigFile& conf)
{
if(printSet.find(filepath) != printSet.end())
std::string filePathInMakeFile = filepath;
if (!filepath.is_absolute())
filePathInMakeFile = std::filesystem::relative(conf.GetConfigPath() + "/" + filepath.string(), "./").string();
if (printSet.find(filePathInMakeFile) != printSet.end())
return stream;
printSet.emplace(filePathInMakeFile);
printCounter++;
printSet.emplace(filepath);
if (!projectHFile)
stream << FileUtils::GetRelativePath(conf.GetConfigPath(), filepath);
{
stream << " " << filePathInMakeFile;
}
for (auto it = dependencies.begin(); it != dependencies.end(); ++it)
{
stream << " ";
(it->second)->Output(stream, conf);
}
printCounter--;
@@ -48,14 +58,17 @@ class IncludeDeps
struct CompareIncludeDeps
{
using is_transparent = void;
bool operator()(const IncludeDeps* d1, const IncludeDeps* d2) const
{
return d1->filepath < d2->filepath;
}
bool operator()(const IncludeDeps* d, const std::string& filepath) const
{
return d->filepath < filepath;
}
bool operator()(const std::string& filepath, const IncludeDeps* d) const
{
return filepath < d->filepath;
+65 -32
View File
@@ -1,11 +1,12 @@
#include "Makefile.h"
#include "IncludeDeps.h"
#include "Utils.h"
#include <fstream>
#include <map>
#include "Common.h"
#include "IncludeDeps.h"
#include "Utils.h"
void Makefile::Save(ConfigFile& conf, unsigned int flags)
{
std::set<HFile> hFiles; // hFile, directory
@@ -16,7 +17,8 @@ void Makefile::Save(ConfigFile& conf, unsigned int flags)
Utils::GetCppAndHFiles(conf, hFiles, cppFiles);
std::ofstream outputFile(conf.GetConfigPath() + "Makefile");
outputFile << "# This Makefile was generated using MakeGen "<< MAKEGEN_VERSION << " made by Tim Håkansson" << std::endl;
outputFile << "# This Makefile was generated using MakeGen " << MAKEGEN_VERSION << " made by Tim Håkansson"
<< std::endl;
outputFile << "# and is licensed under MIT. Full source of the project can be found at" << std::endl;
outputFile << "# https://github.com/Thraix/MakeGen" << std::endl;
outputFile << "CC=@g++" << std::endl;
@@ -40,13 +42,21 @@ void Makefile::Save(ConfigFile& conf, unsigned int flags)
{
outputFile << "-I " << *it << " ";
}
std::vector<std::string>& includedirsexcldep = conf.GetSettingVectorString(ConfigSetting::IncludeDirExclDep);
for (auto it = includedirsexcldep.begin(); it != includedirsexcldep.end(); ++it)
{
outputFile << "-I " << *it << " ";
}
outputFile << std::endl;
outputFile << "OBJECTS=";
for (auto it = cppFiles.begin(); it != cppFiles.end(); ++it)
{
size_t extensionPos = it->find_last_of(".");
size_t slash = it->find_last_of("/")+1;
outputFile << "$(OBJPATH)/" << it->substr(slash, extensionPos - slash) << ".o ";
std::filesystem::path cppFile(*it);
std::filesystem::path oFile = cppFile.replace_extension("o");
std::string oFileStr = oFile.string();
Utils::Replace(oFileStr, "..", "dotdot");
outputFile << "$(OBJPATH)/" << oFileStr << " ";
}
outputFile << std::endl;
if (outputtype == "executable" || outputtype != "sharedlibrary")
@@ -113,16 +123,20 @@ void Makefile::Save(ConfigFile& conf, unsigned int flags)
outputFile << "all: directories $(OUTPUT)" << std::endl;
// Directories
outputFile << "directories: $(BIN) $(OBJPATH)" << std::endl;
std::set<std::string> intermediateDirectories = GetIntermediateDirectories(cppFiles);
outputFile << "directories: ";
for (const auto& intermediateDirectory : intermediateDirectories)
{
outputFile << intermediateDirectory << " ";
}
outputFile << std::endl;
// Bin path
outputFile << "$(BIN):" << std::endl;
outputFile << "\t$(info Creating output directories)" << std::endl;
outputFile << "\t@$(MKDIR_P) $(BIN)" << std::endl;
// Object path
outputFile << "$(OBJPATH):" << std::endl;
outputFile << "\t@$(MKDIR_P) $(OBJPATH)" << std::endl;
// Intermediate directories
for (const auto& intermediateDirectory : intermediateDirectories)
{
outputFile << intermediateDirectory << ":" << std::endl;
outputFile << "\t@$(MKDIR_P) $@" << std::endl;
}
// Run
outputFile << "run: all" << std::endl;
@@ -132,11 +146,9 @@ void Makefile::Save(ConfigFile& conf, unsigned int flags)
std::vector<std::string>& arguments = conf.GetSettingVectorString(ConfigSetting::ExecArgument);
outputFile << "\t@";
for(auto&& preargument : prearguments)
outputFile << preargument << " ";
for (auto&& preargument : prearguments) outputFile << preargument << " ";
outputFile << "./$(OUTPUT)";
for(auto&& argument : arguments)
outputFile << " " << argument;
for (auto&& argument : arguments) outputFile << " " << argument;
outputFile << std::endl;
}
@@ -145,12 +157,12 @@ void Makefile::Save(ConfigFile& conf, unsigned int flags)
// Clean
outputFile << "clean:" << std::endl;
outputFile << "\t$(info Removing intermediates)" << std::endl;
outputFile << "\trm -rf $(OBJPATH)/*.o" << std::endl;
outputFile << "\t$(info Removing $(OBJPATH))" << std::endl;
outputFile << "\t@rm -rf $(OBJPATH)/" << std::endl;
// Output file
outputFile << "$(OUTPUT): $(OBJECTS)" << std::endl;
outputFile << "\t$(info Generating output file)" << std::endl;
outputFile << "\t$(info Generating output file $(OUTPUT))" << std::endl;
if (outputtype == "executable")
outputFile << "\t$(CO) $(OUTPUT) $(OBJECTS) $(LDFLAGS) $(LIBS)" << std::endl;
else
@@ -158,7 +170,8 @@ void Makefile::Save(ConfigFile& conf, unsigned int flags)
// Install
outputFile << "install: all" << std::endl;
outputFile << "\t$(info Installing " << conf.GetSettingString(ConfigSetting::ProjectName) <<" to /usr/bin/)" << std::endl;
outputFile << "\t$(info Installing " << conf.GetSettingString(ConfigSetting::ProjectName) << " to /usr/bin/)"
<< std::endl;
outputFile << "\t@cp $(OUTPUT) /usr/bin/" << conf.GetSettingString(ConfigSetting::OutputName) << std::endl;
std::map<std::string, IncludeDeps*> dependencies;
@@ -166,20 +179,40 @@ void Makefile::Save(ConfigFile& conf, unsigned int flags)
for (auto it = cppFiles.begin(); it != cppFiles.end(); ++it)
{
i++;
std::string& srcdir = conf.GetSettingString(ConfigSetting::SourceDir);
auto itD = dependencies.find(srcdir + *it);
auto itD = dependencies.find(*it);
if (itD == dependencies.end())
{
IncludeDeps* deps = new IncludeDeps(*it, conf.GetConfigPath() + srcdir,hFiles,dependencies);
size_t extensionPos = it->find_last_of(".");
size_t slash = it->find_last_of("/")+1;
std::string oFile = it->substr(slash, extensionPos - slash)+".o ";
outputFile << "$(OBJPATH)/" << oFile << ": ";
std::filesystem::path cppFile(*it);
std::filesystem::path oFile = cppFile.replace_extension("o");
std::string oFileStr = oFile.string();
Utils::Replace(oFileStr, "..", "dotdot");
outputFile << "$(OBJPATH)/" << oFileStr << ":";
if (flags & FLAG_SIMPLE)
{
outputFile << " " << *it;
}
else
{
IncludeDeps* deps = new IncludeDeps(*it, hFiles, dependencies);
deps->Output(outputFile, conf);
}
outputFile << std::endl;
outputFile << "\t$(info -[" << (int)(i / (float)cppFiles.size() * 100) << "%]- $<)" << std::endl;
outputFile << "\t$(CC) $(CFLAGS) -o $@ $<" << std::endl;
}
}
}
std::set<std::string> Makefile::GetIntermediateDirectories(const std::set<std::string>& cppFiles)
{
std::set<std::string> intermediateDirectories;
for (const auto& cppFile : cppFiles)
{
std::filesystem::path cppPath{cppFile};
std::filesystem::path oFile = cppPath.replace_extension("o");
std::string parentPathStr = oFile.parent_path().string();
Utils::Replace(parentPathStr, "..", "dotdot");
intermediateDirectories.emplace("$(OBJPATH)/" + parentPathStr);
}
return intermediateDirectories;
}
Executable → Regular
+3
View File
@@ -6,4 +6,7 @@ class Makefile
{
public:
static void Save(ConfigFile& conf, unsigned int flags);
private:
static std::set<std::string> GetIntermediateDirectories(const std::set<std::string>& cppFiles);
};
Executable → Regular
+7 -2
View File
@@ -6,8 +6,10 @@ class Timer
{
private:
std::chrono::time_point<std::chrono::high_resolution_clock> m_start;
public:
Timer(){
Timer()
{
Reset();
}
@@ -18,6 +20,9 @@ class Timer
float Elapsed()
{
return std::chrono::duration_cast<std::chrono::duration<float,std::milli>>(std::chrono::high_resolution_clock::now() - m_start).count() / 1000.0f;
return std::chrono::duration_cast<std::chrono::duration<float, std::milli>>(
std::chrono::high_resolution_clock::now() - m_start)
.count() /
1000.0f;
}
};
+93 -19
View File
@@ -1,5 +1,7 @@
#include "Utils.h"
#include <filesystem>
#include "ConfigFile.h"
#include "FileUtils.h"
@@ -24,13 +26,33 @@ bool Utils::IsHeaderFile(const std::string& filepath)
size_t pDot = filepath.find_last_of('.');
if (pDot == std::string::npos || (pSlash != std::string::npos && pSlash > pDot))
{
LOG_ERROR("No file extension for file: ", filepath);
return false;
}
extension.remove_prefix(pDot + 1);
return extension == "hpp" || extension == "h" || extension == "hxx";
}
bool Utils::StartsWith(const std::string& str, const std::string& prefix)
{
if (str.size() < prefix.size())
return false;
return str.compare(0, prefix.size(), prefix) == 0;
}
void Utils::Replace(std::string& str, const std::string& from, const std::string& to)
{
if (from.empty())
return;
size_t pos = str.find(from, 0);
while (pos != std::string::npos)
{
str.replace(pos, from.length(), to);
pos = str.find(from, pos + to.length());
}
}
std::string Utils::CommonPrefix(const std::string& s1, const std::string& s2)
{
size_t n = 0;
@@ -48,20 +70,31 @@ std::string Utils::CommonPrefix(const std::string& s1, const std::string& s2)
void Utils::GetCppFiles(ConfigFile& conf, std::set<std::string>& cppFiles)
{
std::vector<std::string> files;
std::string path = conf.GetConfigPath() + conf.GetSettingString(ConfigSetting::SourceDir);
std::string sourceDir = conf.GetSettingString(ConfigSetting::SourceDir);
std::string path = conf.GetConfigPath() + sourceDir;
if (!sourceDir.empty())
{
FileUtils::GetAllFiles(path, files);
}
const std::vector<std::string>& excludeSources = conf.GetSettingVectorString(ConfigSetting::ExcludeSource);
for(auto it = files.begin(); it!=files.end();++it)
for (const auto& sourceFile : conf.GetSettingVectorString(ConfigSetting::SourceFile))
{
std::string filename = it->substr(path.length());
if (FileUtils::FileExists(conf.GetConfigPath() + sourceFile))
cppFiles.emplace(conf.GetConfigPath() + sourceFile);
else
LOG_WARNING("Source file doesn't exist: ", sourceFile);
}
for (auto& filename : files)
{
std::filesystem::path filepath = std::filesystem::relative(filename, "./");
if (IsSourceFile(filename))
{
std::string sourceFile =conf.GetSettingString(ConfigSetting::SourceDir) + filename;
auto it = std::find(excludeSources.begin(), excludeSources.end(), sourceFile);
auto it = std::find(excludeSources.begin(), excludeSources.end(), filename);
if (it == excludeSources.end())
{
cppFiles.emplace(filename);
cppFiles.emplace(filepath.string());
}
}
}
@@ -70,26 +103,49 @@ void Utils::GetCppFiles(ConfigFile& conf, std::set<std::string>& cppFiles)
void Utils::GetCppAndHFiles(ConfigFile& conf, std::set<HFile>& hFiles, std::set<std::string>& cppFiles)
{
std::vector<std::string> files;
std::string path = conf.GetConfigPath() + conf.GetSettingString(ConfigSetting::SourceDir);
FileUtils::GetAllFiles(path,files);
const std::vector<std::string>& excludeSources = conf.GetSettingVectorString(ConfigSetting::ExcludeSource);
// include paramenter with the path of the file
// For example src/graphics/Window.h -> graphics/Window.h if src is a src folder
for(auto it = files.begin(); it!=files.end();++it)
std::string sourceDir = conf.GetSettingString(ConfigSetting::SourceDir);
std::string path = conf.GetConfigPath() + sourceDir;
if (!sourceDir.empty())
{
FileUtils::GetAllFiles(path, files);
}
const std::vector<std::string>& excludeSources = conf.GetSettingVectorString(ConfigSetting::ExcludeSource);
for (const auto& sourceFile : conf.GetSettingVectorString(ConfigSetting::SourceFile))
{
if (FileUtils::FileExists(conf.GetConfigPath() + sourceFile))
cppFiles.emplace(conf.GetConfigPath() + sourceFile);
else
LOG_WARNING("Source file doesn't exist: ", sourceFile);
}
for (const auto& filename : files)
{
std::string filename = it->substr(path.length());
if (IsSourceFile(filename))
{
std::string sourceFile =conf.GetSettingString(ConfigSetting::SourceDir) + filename;
auto it = std::find(excludeSources.begin(), excludeSources.end(), sourceFile);
std::filesystem::path filepath = std::filesystem::relative(filename, "./");
auto it = std::find(excludeSources.begin(), excludeSources.end(), filepath.string());
if (it == excludeSources.end())
{
cppFiles.emplace(filename);
cppFiles.emplace(filepath.string());
}
}
else if (IsHeaderFile(filename))
{
hFiles.emplace(HFile{filename,path,false});
std::filesystem::path path = std::filesystem::relative(filename, sourceDir);
hFiles.emplace(HFile{path.string(), sourceDir, false});
}
}
for (const auto& includePath : conf.GetSettingVectorString(ConfigSetting::IncludeDir))
{
std::vector<std::string> files;
FileUtils::GetAllFiles(includePath, files);
for (const auto& file : files)
{
std::filesystem::path path = std::filesystem::relative(file, includePath);
if (IsHeaderFile(path.string()))
{
hFiles.emplace(HFile{path.string(), includePath, false});
}
}
}
@@ -119,10 +175,28 @@ void Utils::GetHFiles(const std::string& dependencyDir, ConfigFile& conf, std::s
if (IsHeaderFile(*it))
{
std::string filename = it->substr(depSrcDir.length());
hFiles.emplace(HFile{filename, depSrcDir, conf.GetSettingBool(ConfigSetting::GenerateHFile) && filename == conf.GetSettingString(ConfigSetting::HFileName)});
auto it = hFiles.find({filename, "", false});
if (it != hFiles.end())
{
if (filename == conf.GetSettingString(ConfigSetting::HFileName) && !it->isProjectHFile)
{
HFile hfile = *it;
hfile.isProjectHFile = true;
hFiles.erase(it);
hFiles.emplace(hfile);
}
}
else
{
hFiles.emplace(HFile{filename,
depSrcDir,
conf.GetSettingBool(ConfigSetting::GenerateHFile) &&
filename == conf.GetSettingString(ConfigSetting::HFileName)});
}
}
}
}
bool Utils::IsWhiteSpace(char c)
{
return c == '\n' || c == '\t' || c == '\r' || c == ' ' || c == '\t';
+17 -5
View File
@@ -1,25 +1,33 @@
#pragma once
#include <filesystem>
#include <iostream>
#include <set>
#include <string>
struct HFile
{
std::string filename;
std::string directory;
bool isProjectHFile;
std::string filepath;
std::filesystem::path filepath;
HFile(const std::string& filename, const std::string& directory, bool isProjectHFile)
: filename{filename}, directory{directory}, isProjectHFile{isProjectHFile}, filepath{directory+filename}
{}
: filename{filename},
isProjectHFile{isProjectHFile},
filepath{directory + filename}
{
}
friend bool operator<(const HFile& h1, const HFile& h2)
{
return h1.filename < h2.filename;
}
friend std::ostream& operator<<(std::ostream& ostream, const HFile& hFile)
{
return ostream << "filename: " << hFile.filename << "\tfilepath: " << hFile.filepath.string();
}
};
class ConfigFile;
@@ -28,7 +36,11 @@ struct Utils
{
static bool IsSourceFile(const std::string& filepath);
static bool IsHeaderFile(const std::string& filepath);
static std::string CommonPrefix(const std::string& s1, const std::string& s2);
static bool StartsWith(const std::string& str, const std::string& prefix);
static void Replace(std::string& str, const std::string& from, const std::string& to);
static void GetCppFiles(ConfigFile& conf, std::set<std::string>& cppFiles);
static void GetCppAndHFiles(ConfigFile& conf, std::set<HFile>& hFiles, std::set<std::string>& cppFiles);
static void GetHFiles(const std::string& dependencyDir, ConfigFile& conf, std::set<HFile>& hFiles);
+27 -27
View File
@@ -2,24 +2,30 @@
const std::string CONFIG_FILENAME_CONF = "makegen.conf";
#include "../ConfigFile.h"
#include "../FileUtils.h"
#include <algorithm>
#include <fstream>
#include "../ConfigFile.h"
#include "../FileUtils.h"
#define FLAG_NONE 0
#define FLAG_VECTOR 1
#define FLAG_STRING 2
#define FLAG_BOOL 3
ConfigFileConf::ConfigFileConf()
: outputdir("bin/"), srcdir("src/"), outputname(""), projectname(FileUtils::GetCurrentDirectory()), hFile(""), executable(true), shared(true), generateHFile(false)
: outputdir("bin/"),
srcdir("src/"),
outputname(""),
projectname(FileUtils::GetCurrentDirectory()),
hFile(""),
executable(true),
shared(true),
generateHFile(false)
{
// Converts project name (current directory) to lowercase
// and replace whitespace with underscore
std::transform(
projectname.begin(),
std::transform(projectname.begin(),
projectname.end(),
std::back_inserter(outputname),
[](unsigned char c)
@@ -30,13 +36,8 @@ ConfigFileConf::ConfigFileConf()
});
// Removes all other characters
std::remove_if(
outputdir.begin(),
outputdir.end(),
[](unsigned char c)
{
return (c < 'a' || c > 'z') && c != '_';
});
outputdir.erase(std::remove_if(
outputdir.begin(), outputdir.end(), [](unsigned char c) { return (c < 'a' || c > 'z') && c != '_'; }));
// Add suffix
outputname += ".out";
@@ -60,8 +61,7 @@ void ConfigFileConf::CreateXMLFile(const std::string& filepath)
if (file.is_open())
{
// config name, { pointer to memory, isDirectory}
std::map<std::string, std::pair<std::string*, bool>> strings =
{
std::map<std::string, std::pair<std::string*, bool>> strings = {
{"#srcdir", {&conf.srcdir, true}},
{"#outputdir", {&conf.outputdir, true}},
{"#outputname", {&conf.outputname, false}},
@@ -70,18 +70,17 @@ void ConfigFileConf::CreateXMLFile(const std::string& filepath)
};
// config name, { pointer to memory, isDirectory}
std::map<std::string, std::pair<std::vector<std::string>*, bool>> vectors =
{
std::map<std::string, std::pair<std::vector<std::string>*, bool>> vectors = {
{"#libs", {&conf.libs, false}},
{"#libdirs", {&conf.libdirs, true}},
{"#includedirs", {&conf.includedirs, true}},
{"#compileflags", {&conf.flags, false}},
{"#defines", {&conf.defines, false}},
{"#dependencies", {&conf.dependencies, true}},
{"#sourcefiles", {&conf.sourceFiles, false}},
};
std::map<std::string, bool*> booleans =
{
std::map<std::string, bool*> booleans = {
{"#executable", &conf.executable},
{"#shared", &conf.shared},
{"#generatehfile", &conf.generateHFile},
@@ -138,7 +137,8 @@ void ConfigFileConf::CreateXMLFile(const std::string& filepath)
else if (loadFlag == FLAG_VECTOR)
{
if (isDirectory && line[line.size() - 1] != '/')
{;
{
;
line += '/';
}
vec->push_back(line);
@@ -161,7 +161,7 @@ void ConfigFileConf::CreateXMLFile(const std::string& filepath)
XMLObject makegen("makegen", {}, std::map<std::string, std::vector<XMLObject>>{});
// Version, target and configuration is probably going to be used in the future
makegen.AddXMLObject(XMLObject("version", {}, "v1.3.0"));
makegen.AddXMLObject(XMLObject("version", {}, "v1.3.2"));
makegen.AddXMLObject(XMLObject("target", {}, "Release"));
XMLObject configuration("configuration", {{"name", "Release"}}, std::map<std::string, std::vector<XMLObject>>{});
@@ -170,22 +170,22 @@ void ConfigFileConf::CreateXMLFile(const std::string& filepath)
configuration.AddXMLObject(XMLObject("srcdir", {}, conf.srcdir));
configuration.AddXMLObject(XMLObject("outputdir", {}, conf.outputdir));
configuration.AddXMLObject(XMLObject("hfilename", {}, conf.hFile));
configuration.AddXMLObject(XMLObject("outputtype", {},
conf.executable ? "executable" : (conf.shared ? "sharedlibrary" : "staticlibrary")));
configuration.AddXMLObject(
XMLObject("outputtype", {}, conf.executable ? "executable" : (conf.shared ? "sharedlibrary" : "staticlibrary")));
configuration.AddXMLObject(XMLObject("generatehfile", {}, conf.generateHFile ? "true" : "false"));
for(auto it = conf.libs.begin();it != conf.libs.end(); ++it)
configuration.AddXMLObject({"library",{},*it});
for (auto it = conf.libs.begin(); it != conf.libs.end(); ++it) configuration.AddXMLObject({"library", {}, *it});
for (auto it = conf.libdirs.begin(); it != conf.libdirs.end(); ++it)
configuration.AddXMLObject({"librarydir", {}, *it});
for (auto it = conf.includedirs.begin(); it != conf.includedirs.end(); ++it)
configuration.AddXMLObject({"includedir", {}, *it});
for (auto it = conf.defines.begin(); it != conf.defines.end(); ++it)
configuration.AddXMLObject({"define", {}, *it});
for(auto it = conf.flags.begin();it != conf.flags.end(); ++it)
configuration.AddXMLObject({"cflag",{},*it});
for (auto it = conf.flags.begin(); it != conf.flags.end(); ++it) configuration.AddXMLObject({"cflag", {}, *it});
for (auto it = conf.dependencies.begin(); it != conf.dependencies.end(); ++it)
configuration.AddXMLObject({"dependency", {}, *it});
for (auto it = conf.sourceFiles.begin(); it != conf.sourceFiles.end(); ++it)
configuration.AddXMLObject({"sourcefile", {}, *it});
makegen.AddXMLObject(configuration);
std::ofstream xmlFile(conf.configPath + "makegen.xml");
+3
View File
@@ -17,6 +17,7 @@ class ConfigFileConf
std::vector<std::string> defines;
std::vector<std::string> flags;
std::vector<std::string> dependencies;
std::vector<std::string> sourceFiles;
std::string outputdir;
std::string srcdir;
@@ -26,9 +27,11 @@ class ConfigFileConf
bool executable;
bool shared;
bool generateHFile;
public:
ConfigFileConf();
static void CreateXMLFile(const std::string& filename);
private:
};
Executable → Regular
+56 -32
View File
@@ -1,14 +1,16 @@
#include <cmath>
#include <filesystem>
#include <thread>
#include "Common.h"
#include "ConfigCLI.h"
#include "ConfigFile.h"
#include "FileUtils.h"
#include "FlagData.h"
#include "HFileGen.h"
#include "Makefile.h"
#include "Timer.h"
#include <cmath>
#include <thread>
#define RETURN_IF(x, b) \
if (x) \
return b;
@@ -39,12 +41,12 @@ Usage: makegen [options]
-s, single Runs additional makegen options as single thread
(no --jobs=X flag)
--simple Creates a simple Makefile without include dependencies
(no --jobs=X flag)
--target=<target> Run the makegen.xml file with the specified target
If no option is given it will run \"make all\"
If no option is given it will run "make all"
If multiple make options are given it will run in the following order:
clean all install run, rebuild will be translated to \"clean make\")");
clean all install run, rebuild will be translated to "clean make")");
}
void GenMakefile(ConfigFile& conf, unsigned int flags)
@@ -54,11 +56,11 @@ void GenMakefile(ConfigFile& conf, unsigned int flags)
Makefile::Save(conf, flags);
}
unsigned int ReadFlags(int argc, char** argv)
FlagData ReadFlags(int argc, char** argv)
{
if (argc >= 2 && std::string(argv[1]) == "conf")
return FLAG_CONFIG;
unsigned int flags = 0;
return FlagData{FLAG_CONFIG};
FlagData flagData{};
bool make = true;
for (int i = 1; i < argc; i++)
{
@@ -67,52 +69,63 @@ unsigned int ReadFlags(int argc, char** argv)
std::string flag(argv[i]);
if (flag == "-h" || flag == "--help")
{
flags |= FLAG_HELP;
flagData.flags |= FLAG_HELP;
}
else if (flag == "-v" || flag == "--version")
{
flags |= FLAG_VERSION;
flagData.flags |= FLAG_VERSION;
}
else if (flag == "make" || flag == "-m" || flag == "all" || flag == "-a")
{
flags |= FLAG_MAKE;
flagData.flags |= FLAG_MAKE;
}
else if (flag == "clean" || flag == "-c")
{
make = false;
flags |= FLAG_CLEAN;
flagData.flags |= FLAG_CLEAN;
}
else if (flag == "run" || flag == "-e" || flag == "execute")
{
flags |= FLAG_RUN;
flagData.flags |= FLAG_RUN;
}
else if (flag == "install" || flag == "-i")
{
flags |= FLAG_INSTALL;
flagData.flags |= FLAG_INSTALL;
}
else if (flag == "rebuild" || flag == "-r")
{
flags |= FLAG_CLEAN;
flags |= FLAG_MAKE;
flagData.flags |= FLAG_CLEAN;
flagData.flags |= FLAG_MAKE;
}
else if (flag == "single" || flag == "-s")
{
flags |= FLAG_SINGLE_THREAD;
flagData.flags |= FLAG_SINGLE_THREAD;
}
else if (flag == "--simple")
{
flags |= FLAG_SIMPLE;
flagData.flags |= FLAG_SIMPLE;
}
else if (Utils::StartsWith(flag, "--target="))
{
std::string prefix("--target=");
if (flag.size() < prefix.size() + 1)
{
LOG_ERROR("No target specified in --target=<target>");
return FlagData{FLAG_HELP};
}
flagData.flags |= FLAG_TARGET;
flagData.target = flag.substr(std::string("--target=").size());
}
else if (flag != "")
{
LOG_ERROR("Unknown argument ", flag);
return FLAG_HELP;
return FlagData{FLAG_HELP};
}
}
}
if (make)
flags |= FLAG_MAKE;
return flags;
flagData.flags |= FLAG_MAKE;
return flagData;
}
bool RunMake(const std::string& filepath, unsigned int flags, ConfigFile& conf)
@@ -139,20 +152,31 @@ bool RunMake(const std::string& filepath, unsigned int flags, ConfigFile& conf)
return true;
}
bool MakeGen(const std::string& filepath, unsigned int flags, ConfigFile& conf)
bool MakeGen(const std::string& filepath, const FlagData& flagData, ConfigFile& conf)
{
std::vector<std::string>& dependencies = conf.GetSettingVectorString(ConfigSetting::Dependency);
for (size_t i = 0; i < dependencies.size(); ++i)
{
bool success = MakeGen(dependencies[i], flags, conf.GetDependencyConfig(i));
std::filesystem::path currentPath = std::filesystem::current_path();
std::filesystem::current_path(dependencies[i]);
auto conf = ConfigFile::GetConfigFile("./", flagData);
if (conf)
{
bool success = MakeGen("./", flagData, conf.value());
if (!success)
{
std::filesystem::current_path(currentPath);
return success;
}
}
std::filesystem::current_path(currentPath);
}
LOG_INFO("-----------------------------------");
LOG_INFO("Building ", conf.GetSettingString(ConfigSetting::ProjectName));
LOG_INFO("Generating Makefile...");
Timer timer;
GenMakefile(conf, flags);
GenMakefile(conf, flagData.flags);
LOG_INFO("Took ", round(timer.Elapsed() * 1000.0) / 1000.0, "s");
LOG_INFO("Running Makefile...");
@@ -164,31 +188,31 @@ bool MakeGen(const std::string& filepath, unsigned int flags, ConfigFile& conf)
if (!FileUtils::HasPath(intermediatePath))
FileUtils::CreateDirectory(intermediatePath);
}
return RunMake(filepath, flags, conf);
return RunMake(filepath, flagData.flags, conf);
}
int main(int argc, char** argv)
{
unsigned int flags = ReadFlags(argc,argv);
if(flags & FLAG_HELP)
FlagData flagData = ReadFlags(argc, argv);
if (flagData.flags & FLAG_HELP)
{
PrintHelp();
return 0;
}
if(flags & FLAG_VERSION)
if (flagData.flags & FLAG_VERSION)
{
LOG_INFO("MakeGen ", MAKEGEN_VERSION);
return 0;
}
if(flags & FLAG_CONFIG)
if (flagData.flags & FLAG_CONFIG)
{
return ConfigCLI::Main(argc - 1, &argv[1]);
}
std::map<std::string, ConfigFile> files{};
auto conf = ConfigFile::GetConfigFile();
auto conf = ConfigFile::GetConfigFile("./", flagData);
if (conf)
{
bool success = MakeGen("./", flags, *conf);
bool success = MakeGen("./", flagData, *conf);
return success ? 0 : 1;
}
else
+3 -3
View File
@@ -1,9 +1,9 @@
#include "XML.h"
#include "XMLException.h"
#include <fstream>
#include <algorithm>
#include <fstream>
#include "XMLException.h"
XMLObject XML::FromString(const std::string& string, const std::string& filename = "")
{
+10 -4
View File
@@ -1,19 +1,25 @@
#pragma once
#include "XMLObject.h"
#include <exception>
#include <string>
#include "XMLObject.h"
class XMLException : public std::exception
{
private:
std::string m_message;
public:
explicit XMLException(const std::string& message) : m_message("XMLException: " + message) {}
explicit XMLException(const std::string& message)
: m_message("XMLException: " + message)
{
}
explicit XMLException(const std::string& message, const XMLObject::XMLLoadData& data)
: m_message("XMLException(" + data.file + ":" + std::to_string(data.line) + "): " + message)
{}
{
}
virtual const char* what() const throw()
{
+40 -36
View File
@@ -1,9 +1,9 @@
#include "XMLObject.h"
#include <cstring>
#include "../Common.h"
#include "../Utils.h"
#include <cstring>
#include "XMLException.h"
XMLObject::XMLObject(const std::string& string)
@@ -28,16 +28,22 @@ XMLObject::XMLObject(const std::string& string, XMLLoadData& data)
ReadBodyTail(string, data);
}
XMLObject::XMLObject(const std::string& name, const std::map<std::string, std::string>& attributes, const std::string& text)
:name(name), attributes(attributes), text(text)
XMLObject::XMLObject(const std::string& name,
const std::map<std::string, std::string>& attributes,
const std::string& text)
: name(name),
attributes(attributes),
text(text)
{
}
XMLObject::XMLObject(const std::string& name, const std::map<std::string, std::string>& attributes, const std::map<std::string,std::vector<XMLObject>>& objects)
: name(name), attributes(attributes), objects(objects)
XMLObject::XMLObject(const std::string& name,
const std::map<std::string, std::string>& attributes,
const std::map<std::string, std::vector<XMLObject>>& objects)
: name(name),
attributes(attributes),
objects(objects)
{
}
bool XMLObject::HasAttribute(const std::string& property) const
@@ -154,7 +160,6 @@ XMLObject XMLObject::GetStrippedXMLObject() const
// //
////////////////////////////////////////////////////////////
bool XMLObject::ReadHead(const std::string& string, XMLLoadData& data)
{
// Check if the first character is the start of and xml tag.
@@ -179,7 +184,8 @@ bool XMLObject::ReadHead(const std::string& string, XMLLoadData& data)
data.pos++;
ReadWhiteSpace(string, data);
if (string[data.pos] != '>')
throw XMLException((std::string("Invalid character proceeding / in opening XML Tag \"") + string[data.pos] + "\".").c_str(), data);
throw XMLException(
(std::string("Invalid character proceeding / in opening XML Tag \"") + string[data.pos] + "\".").c_str(), data);
data.pos++;
// nothing more to read.
return true;
@@ -187,7 +193,9 @@ bool XMLObject::ReadHead(const std::string& string, XMLLoadData& data)
ReadWhiteSpace(string, data);
if (string[data.pos] != '>')
throw XMLException((std::string("Invalid character proceeding attributes in opening XML Tag \"") + string[data.pos] + "\".").c_str(), data);
throw XMLException(
(std::string("Invalid character proceeding attributes in opening XML Tag \"") + string[data.pos] + "\".").c_str(),
data);
(data.pos)++;
return false;
}
@@ -203,7 +211,8 @@ void XMLObject::ReadName(const std::string& string, XMLLoadData& data)
ReadWhiteSpace(string, data);
if (string[data.pos] != '/' && string[data.pos] != '>' && Utils::IsWhiteSpace(string[data.pos]))
{
throw XMLException((std::string("Invalid character proceeding name in XML Tag \"") + string[data.pos] + "\".").c_str(), data);
throw XMLException(
(std::string("Invalid character proceeding name in XML Tag \"") + string[data.pos] + "\".").c_str(), data);
}
}
@@ -230,7 +239,9 @@ void XMLObject::ReadAttribute(const std::string& string, XMLLoadData& data)
// Read =
if (string[data.pos] != '=')
throw XMLException((std::string("Invalid character proceeding property name in XML Tag \"") + string[data.pos] + "\".").c_str(), data);
throw XMLException(
(std::string("Invalid character proceeding property name in XML Tag \"") + string[data.pos] + "\".").c_str(),
data);
(data.pos)++;
ReadWhiteSpace(string, data);
@@ -256,7 +267,10 @@ void XMLObject::ReadBodyTail(const std::string& string, XMLLoadData& data)
ReadWhiteSpace(string, data);
std::string closeTag = GetClosingTag(string, data);
if (closeTag.length() == 0)
throw XMLException("Tag after XML Test was not a closing tag. XMLObject doesn't support text and other XMLObjects at the same time.", data);
throw XMLException(
"Tag after XML Test was not a closing tag. XMLObject doesn't support text and other XMLObjects at the same "
"time.",
data);
return;
}
// Check if we can read the closing tag.
@@ -279,14 +293,14 @@ void XMLObject::ReadText(const std::string& string, XMLLoadData& data)
void XMLObject::ReadWhiteSpace(const std::string& string, XMLLoadData& data)
{
while (Utils::IsWhiteSpace(string[data.pos])) {
while (Utils::IsWhiteSpace(string[data.pos]))
{
if (string[data.pos] == '\n')
(data.line)++;
(data.pos)++;
}
}
std::string XMLObject::GetClosingTag(const std::string& string, XMLLoadData& data)
{
int startPos = data.pos;
@@ -307,7 +321,8 @@ std::string XMLObject::GetClosingTag(const std::string& string, XMLLoadData& dat
ReadWhiteSpace(string, data);
std::string tag = Utils::GetWord(string, data.pos);
if (tag != name)
throw XMLException((std::string("Closing tag doesn't match opening tag. (\"") + name + "\" != \"" + tag+ "\")").c_str(), data);
throw XMLException(
(std::string("Closing tag doesn't match opening tag. (\"") + name + "\" != \"" + tag + "\")").c_str(), data);
data.pos += tag.length();
ReadWhiteSpace(string, data);
if (string[data.pos] != '>')
@@ -318,14 +333,8 @@ std::string XMLObject::GetClosingTag(const std::string& string, XMLLoadData& dat
void XMLObject::ReplacePredefinedEntities(std::string& string, XMLLoadData& data)
{
std::vector<std::pair<std::string, std::string>> entities
{
{"&quot;","\""},
{"&apos;", "\'"},
{"&lt;", "<"},
{"&gt;",">"},
{"&amp;", "&"}
};
std::vector<std::pair<std::string, std::string>> entities{
{"&quot;", "\""}, {"&apos;", "\'"}, {"&lt;", "<"}, {"&gt;", ">"}, {"&amp;", "&"}};
size_t pos = string.find('&');
while (pos != std::string::npos)
{
@@ -339,25 +348,21 @@ void XMLObject::ReplacePredefinedEntities(std::string& string, XMLLoadData& data
}
}
if (!found)
LOG_ERROR("(" + data.file + ":" + std::to_string(data.line) + "): ""Ampersand found in xml but isn't a predefined entity.");
LOG_ERROR("(" + data.file + ":" + std::to_string(data.line) +
"): "
"Ampersand found in xml but isn't a predefined entity.");
pos = string.find('&', pos + 1);
}
}
std::string XMLObject::ReadXMLName(const std::string& string, XMLLoadData& data)
{
if(!(Utils::IsLetter(string[data.pos]) ||
string[data.pos] == '_' ||
string[data.pos] == ':'))
if (!(Utils::IsLetter(string[data.pos]) || string[data.pos] == '_' || string[data.pos] == ':'))
throw XMLException(std::string("Name doesn't start with a letter."), data);
int endPos = data.pos + 1;
while (endPos < string.length() && (
Utils::IsLetter(string[endPos]) ||
string[endPos] == '_' ||
string[endPos] == '-' ||
string[endPos] == ':' ||
string[endPos] == '.'))
while (endPos < string.length() && (Utils::IsLetter(string[endPos]) || string[endPos] == '_' ||
string[endPos] == '-' || string[endPos] == ':' || string[endPos] == '.'))
endPos++;
return string.substr(data.pos, endPos - data.pos);
}
@@ -403,4 +408,3 @@ std::ostream& XMLObject::WriteToStream(std::ostream& stream, int indent) const
return stream;
}
+11 -3
View File
@@ -1,20 +1,22 @@
#pragma once
#include <string>
#include <map>
#include <set>
#include <string>
#include <vector>
class XMLObject
{
public:
friend class XMLexception;
struct XMLLoadData
{
int pos;
int line;
const std::string& file;
};
private:
std::string name;
std::string text;
@@ -23,12 +25,17 @@ class XMLObject
std::map<std::string, std::vector<XMLObject>> objects;
public:
XMLObject() {}
XMLObject()
{
}
XMLObject(const std::string& string);
XMLObject(const std::string& string, int pos, int line, const std::string& file);
XMLObject(const std::string& string, XMLLoadData& data);
XMLObject(const std::string& name, const std::map<std::string, std::string>& properties, const std::string& text);
XMLObject(const std::string& name, const std::map<std::string, std::string>& properties, const std::map<std::string, std::vector<XMLObject>>& objects);
XMLObject(const std::string& name,
const std::map<std::string, std::string>& properties,
const std::map<std::string, std::vector<XMLObject>>& objects);
bool HasAttribute(const std::string& property) const;
const std::string& GetAttribute(const std::string& property) const;
@@ -53,6 +60,7 @@ class XMLObject
}
std::ostream& WriteToStream(std::ostream& stream, int indent = 0) const;
friend std::ostream& operator<<(std::ostream& stream, const XMLObject& object)
{
return object.WriteToStream(stream);