diff --git a/.ycm_extra_conf.py b/.ycm_extra_conf.py
old mode 100755
new mode 100644
index b38cf07..a90307b
--- a/.ycm_extra_conf.py
+++ b/.ycm_extra_conf.py
@@ -1,172 +1,139 @@
+# Generated by YCM Generator at 2019-01-29 22:35:09.802732
+
+# This file is NOT licensed under the GPLv3, which is the license for the rest
+# of YouCompleteMe.
+#
+# Here's the license text for this file:
+#
+# This is free and unencumbered software released into the public domain.
+#
+# Anyone is free to copy, modify, publish, use, compile, sell, or
+# distribute this software, either in source code form or as a compiled
+# binary, for any purpose, commercial or non-commercial, and by any
+# means.
+#
+# In jurisdictions that recognize copyright laws, the author or authors
+# of this software dedicate any and all copyright interest in the
+# software to the public domain. We make this dedication for the benefit
+# of the public at large and to the detriment of our heirs and
+# successors. We intend this dedication to be an overt act of
+# relinquishment in perpetuity of all present and future rights to this
+# software under copyright law.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#
+# For more information, please refer to
+
import os
-import os.path
-import fnmatch
-import logging
import ycm_core
-import re
-BASE_FLAGS = [
- '-Wall',
- '-Wuninitialized',
- '-Wextra',
- '-Wno-long-long',
- '-Wno-variadic-macros',
- '-fexceptions',
- '-ferror-limit=10000',
- '-DNDEBUG',
- '-std=c++17',
- '-xc++',
- '-I/usr/lib/',
- '-I/usr/include/',
- ]
-
-SOURCE_EXTENSIONS = [
- '.cpp',
- ]
-
-SOURCE_DIRECTORIES = [
- 'src'
- ]
-
-HEADER_EXTENSIONS = [
- '.h',
- ]
-
-HEADER_DIRECTORIES = [
- ]
-
-def IsHeaderFile(filename):
- extension = os.path.splitext(filename)[1]
- return extension in HEADER_EXTENSIONS
-
-def GetCompilationInfoForFile(database, filename):
- if IsHeaderFile(filename):
- basename = os.path.splitext(filename)[0]
- for extension in SOURCE_EXTENSIONS:
- # Get info from the source files by replacing the extension.
- replacement_file = basename + extension
- if os.path.exists(replacement_file):
- compilation_info = database.GetCompilationInfoForFile(replacement_file)
- if compilation_info.compiler_flags_:
- return compilation_info
- # If that wasn't successful, try replacing possible header directory with possible source directories.
- for header_dir in HEADER_DIRECTORIES:
- for source_dir in SOURCE_DIRECTORIES:
- src_file = replacement_file.replace(header_dir, source_dir)
- if os.path.exists(src_file):
- compilation_info = database.GetCompilationInfoForFile(src_file)
- if compilation_info.compiler_flags_:
- return compilation_info
- return None
- return database.GetCompilationInfoForFile(filename)
-
-def FindNearest(path, target, build_folder):
- candidate = os.path.join(path, target)
- if(os.path.isfile(candidate) or os.path.isdir(candidate)):
- logging.info("Found nearest " + target + " at " + candidate)
- return candidate;
-
- parent = os.path.dirname(os.path.abspath(path));
- if(parent == path):
- raise RuntimeError("Could not find " + target);
-
- if(build_folder):
- candidate = os.path.join(parent, build_folder, target)
- if(os.path.isfile(candidate) or os.path.isdir(candidate)):
- logging.info("Found nearest " + target + " in build folder at " + candidate)
- return candidate;
-
- return FindNearest(parent, target, build_folder)
-
-def MakeRelativePathsInFlagsAbsolute(flags, working_directory):
- if not working_directory:
- return list(flags)
- new_flags = []
- make_next_absolute = False
- path_flags = [ '-isystem', '-I', '-iquote', '--sysroot=' ]
- for flag in flags:
- new_flag = flag
-
- if make_next_absolute:
- make_next_absolute = False
- if not flag.startswith('/'):
- new_flag = os.path.join(working_directory, flag)
-
- for path_flag in path_flags:
- if flag == path_flag:
- make_next_absolute = True
- break
-
- if flag.startswith(path_flag):
- path = flag[ len(path_flag): ]
- new_flag = path_flag + os.path.join(working_directory, path)
- break
-
- if new_flag:
- new_flags.append(new_flag)
- return new_flags
+flags = [
+ '-x',
+ 'c++',
+ '-D_DEBUG',
+ '-std=c++17',
+]
-def FlagsForClangComplete(root):
- try:
- clang_complete_path = FindNearest(root, '.clang_complete')
- clang_complete_flags = open(clang_complete_path, 'r').read().splitlines()
- return clang_complete_flags
- except:
- return None
+# Set this to the absolute path to the folder (NOT the file!) containing the
+# compile_commands.json file to use that instead of 'flags'. See here for
+# more details: http://clang.llvm.org/docs/JSONCompilationDatabase.html
+#
+# You can get CMake to generate this file for you by adding:
+# set( CMAKE_EXPORT_COMPILE_COMMANDS 1 )
+# to your CMakeLists.txt file.
+#
+# Most projects will NOT need to set this to anything; you can just change the
+# 'flags' list of compilation flags. Notice that YCM itself uses that approach.
+compilation_database_folder = ''
-def FlagsForInclude(root):
- try:
- include_path = FindNearest(root, 'include')
- flags = []
- for dirroot, dirnames, filenames in os.walk(include_path):
- for dir_path in dirnames:
- real_path = os.path.join(dirroot, dir_path)
- flags = flags + ["-I" + real_path]
- return flags
- except:
- return None
+if os.path.exists( compilation_database_folder ):
+ database = ycm_core.CompilationDatabase( compilation_database_folder )
+else:
+ database = None
-def FlagsForCompilationDatabase(root, filename):
- try:
- # Last argument of next function is the name of the build folder for
- # out of source projects
- compilation_db_path = FindNearest(root, 'compile_commands.json', 'build')
- compilation_db_dir = os.path.dirname(compilation_db_path)
- logging.info("Set compilation database directory to " + compilation_db_dir)
- compilation_db = ycm_core.CompilationDatabase(compilation_db_dir)
- if not compilation_db:
- logging.info("Compilation database file found but unable to load")
- return None
- compilation_info = GetCompilationInfoForFile(compilation_db, filename)
- if not compilation_info:
- logging.info("No compilation info for " + filename + " in compilation database")
- return None
- return MakeRelativePathsInFlagsAbsolute(
- compilation_info.compiler_flags_,
- compilation_info.compiler_working_dir_)
- except:
- return None
+SOURCE_EXTENSIONS = [ '.C', '.cpp', '.cxx', '.cc', '.c', '.m', '.mm' ]
+
+def DirectoryOfThisScript():
+ return os.path.dirname( os.path.abspath( __file__ ) )
+
+
+def MakeRelativePathsInFlagsAbsolute( flags, working_directory ):
+ if not working_directory:
+ return list( flags )
+ new_flags = []
+ make_next_absolute = False
+ path_flags = [ '-isystem', '-I', '-iquote', '--sysroot=' ]
+ for flag in flags:
+ new_flag = flag
+
+ if make_next_absolute:
+ make_next_absolute = False
+ if not flag.startswith( '/' ):
+ new_flag = os.path.join( working_directory, flag )
+
+ for path_flag in path_flags:
+ if flag == path_flag:
+ make_next_absolute = True
+ break
+
+ if flag.startswith( path_flag ):
+ path = flag[ len( path_flag ): ]
+ new_flag = path_flag + os.path.join( working_directory, path )
+ break
+
+ if new_flag:
+ new_flags.append( new_flag )
+ return new_flags
+
+
+def IsHeaderFile( filename ):
+ extension = os.path.splitext( filename )[ 1 ]
+ return extension in [ '.H', '.h', '.hxx', '.hpp', '.hh' ]
+
+
+def GetCompilationInfoForFile( filename ):
+ # The compilation_commands.json file generated by CMake does not have entries
+ # for header files. So we do our best by asking the db for flags for a
+ # corresponding source file, if any. If one exists, the flags for that file
+ # should be good enough.
+ if IsHeaderFile( filename ):
+ basename = os.path.splitext( filename )[ 0 ]
+ for extension in SOURCE_EXTENSIONS:
+ replacement_file = basename + extension
+ if os.path.exists( replacement_file ):
+ compilation_info = database.GetCompilationInfoForFile(
+ replacement_file )
+ if compilation_info.compiler_flags_:
+ return compilation_info
+ return None
+ return database.GetCompilationInfoForFile( filename )
+
+
+def FlagsForFile( filename, **kwargs ):
+ if database:
+ # Bear in mind that compilation_info.compiler_flags_ does NOT return a
+ # python list, but a "list-like" StringVec object
+ compilation_info = GetCompilationInfoForFile( filename )
+ if not compilation_info:
+ return None
+
+ final_flags = MakeRelativePathsInFlagsAbsolute(
+ compilation_info.compiler_flags_,
+ compilation_info.compiler_working_dir_ )
+
+ else:
+ relative_to = DirectoryOfThisScript()
+ final_flags = MakeRelativePathsInFlagsAbsolute( flags, relative_to )
+
+ return {
+ 'flags': final_flags,
+ 'do_cache': True
+ }
-def FlagsForFile(filename):
- root = os.path.realpath(filename);
- compilation_db_flags = FlagsForCompilationDatabase(root, filename)
- confPath = os.path.dirname(os.path.abspath(__file__))
-
- for dir in HEADER_DIRECTORIES:
- BASE_FLAGS.append('-I'+confPath+'/'+dir)
-
- if compilation_db_flags:
- final_flags = compilation_db_flags
- else:
- final_flags = BASE_FLAGS
- clang_flags = FlagsForClangComplete(root)
- if clang_flags:
- final_flags = final_flags + clang_flags
- include_flags = FlagsForInclude(root)
- if include_flags:
- final_flags = final_flags + include_flags
- return {
- 'flags': final_flags,
- 'do_cache': True
- }
diff --git a/Makefile b/Makefile
index 4d97070..bc1ebb9 100755
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-# This Makefile was generated using MakeGen v1.0.8 made by Tim HÃ¥kansson
+# This Makefile was generated using MakeGen v1.0.9 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++
diff --git a/src/Common.h b/src/Common.h
index 9a6112c..208f21a 100755
--- a/src/Common.h
+++ b/src/Common.h
@@ -12,7 +12,7 @@
// Release , should be backwards compatible with any minor version
#define MAKEGEN_VERSION_RELEASE 0
// Minor changes, should be compatible with any other minor version with same major and release.
-#define MAKEGEN_VERSION_MINOR 8
+#define MAKEGEN_VERSION_MINOR 9
#define MAKEGEN_VERSION ("v" STR(MAKEGEN_VERSION_MAJOR) "." STR(MAKEGEN_VERSION_RELEASE) "." STR(MAKEGEN_VERSION_MINOR))
const static unsigned int FLAG_HELP = BIT(0);
diff --git a/src/ConfigFile.cpp b/src/ConfigFile.cpp
index d8dc51f..34af385 100755
--- a/src/ConfigFile.cpp
+++ b/src/ConfigFile.cpp
@@ -13,7 +13,7 @@ ConfigFile::ConfigFile()
}
-ConfigFile ConfigFile::Load()
+ConfigFile ConfigFile::Load(const std::string& filename)
{
ConfigFile conf;
unsigned int loadFlag = 0;
@@ -22,94 +22,97 @@ ConfigFile ConfigFile::Load()
std::string* s;
bool* b;
- std::ifstream file("makegen.conf");
+ std::ifstream file(filename);
std::string line;
- while(std::getline(file,line))
+ if(file.is_open())
{
- if(line[0]=='#')
+ while(std::getline(file,line))
{
- if(line == "#libs")
+ if(line[0]=='#')
{
- vec = &conf.libs;
- loadFlag = FLAG_VECTOR;
- }
- else if(line == "#libdirs")
- {
- vec = &conf.libdirs;
- loadFlag = FLAG_VECTOR;
- }
- else if(line == "#includedirs")
- {
- vec = &conf.includedirs;
- loadFlag = FLAG_VECTOR;
- }
- else if(line == "#compileflags")
- {
- vec = &conf.flags;
- loadFlag = FLAG_VECTOR;
- }
- else if(line == "#srcdirs")
- {
- vec = &conf.srcdirs;
- loadFlag = FLAG_VECTOR;
- }
- else if(line == "#defines")
- {
- vec = &conf.defines;
- loadFlag = FLAG_VECTOR;
- }
- else if(line == "#outputdir")
- {
- s = &conf.outputdir;
- loadFlag = FLAG_STRING;
- }
- else if(line == "#outputname")
- {
- s = &conf.outputname;
- loadFlag = FLAG_STRING;
- }
- else if(line == "#projectname")
- {
- s = &conf.projectname;
- loadFlag = FLAG_STRING;
- }
- else if(line == "#executable")
- {
- b = &conf.executable;
- loadFlag = FLAG_BOOL;
- }
- else if(line == "#shared")
- {
- b = &conf.shared;
- loadFlag = FLAG_BOOL;
+ if(line == "#libs")
+ {
+ vec = &conf.libs;
+ loadFlag = FLAG_VECTOR;
+ }
+ else if(line == "#libdirs")
+ {
+ vec = &conf.libdirs;
+ loadFlag = FLAG_VECTOR;
+ }
+ else if(line == "#includedirs")
+ {
+ vec = &conf.includedirs;
+ loadFlag = FLAG_VECTOR;
+ }
+ else if(line == "#compileflags")
+ {
+ vec = &conf.flags;
+ loadFlag = FLAG_VECTOR;
+ }
+ else if(line == "#srcdirs")
+ {
+ vec = &conf.srcdirs;
+ loadFlag = FLAG_VECTOR;
+ }
+ else if(line == "#defines")
+ {
+ vec = &conf.defines;
+ loadFlag = FLAG_VECTOR;
+ }
+ else if(line == "#outputdir")
+ {
+ s = &conf.outputdir;
+ loadFlag = FLAG_STRING;
+ }
+ else if(line == "#outputname")
+ {
+ s = &conf.outputname;
+ loadFlag = FLAG_STRING;
+ }
+ else if(line == "#projectname")
+ {
+ s = &conf.projectname;
+ loadFlag = FLAG_STRING;
+ }
+ else if(line == "#executable")
+ {
+ b = &conf.executable;
+ loadFlag = FLAG_BOOL;
+ }
+ else if(line == "#shared")
+ {
+ b = &conf.shared;
+ loadFlag = FLAG_BOOL;
+ }
+ else
+ {
+ LOG_ERROR("Invalid flag: ", line);
+ loadFlag = FLAG_NONE;
+ }
}
else
{
- LOG_ERROR("Invalid flag: ", line);
- loadFlag = FLAG_NONE;
- }
- }
- else
- {
- if(loadFlag == FLAG_STRING)
- {
- *s = line;
- }
- else if(loadFlag == FLAG_VECTOR)
- {
- vec->push_back(line);
- }
- else if(loadFlag == FLAG_BOOL)
- {
- if(line == "true")
- *b = true;
- else
- *b = false;
+ if(loadFlag == FLAG_STRING)
+ {
+ *s = line;
+ }
+ else if(loadFlag == FLAG_VECTOR)
+ {
+ vec->push_back(line);
+ }
+ else if(loadFlag == FLAG_BOOL)
+ {
+ if(line == "true")
+ *b = true;
+ else
+ *b = false;
+ }
}
}
+ return conf;
}
- return conf;
}
void ConfigFile::InputMultiple(const std::string& inputText, std::vector& vec, bool needEnding)
diff --git a/src/ConfigFile.h b/src/ConfigFile.h
index 2a5788c..0b1b9c5 100755
--- a/src/ConfigFile.h
+++ b/src/ConfigFile.h
@@ -21,7 +21,7 @@ class ConfigFile
ConfigFile();
void Save() const;
static ConfigFile Gen();
- static ConfigFile Load();
+ static ConfigFile Load(const std::string& filename);
private:
static void InputMultiple(const std::string& inputText, std::vector& vec, bool needEnding);
};
diff --git a/src/main.cpp b/src/main.cpp
index ecf032f..9a29698 100755
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -11,10 +11,38 @@
#include "Makefile.h"
#include "Timer.h"
-void GenMakefile()
+void PrintHelp()
{
- ConfigFile conf = ConfigFile::Load();
- Makefile::Save(conf);
+ LOG_INFO("Usage: makegen [options]");
+ LOG_INFO(" Options:");
+ LOG_INFO(" --help\tDisplays this information");
+ LOG_INFO(" --conf\tGenerate a config file for the project");
+ LOG_INFO(" --version\tDisplays the version of this program");
+ LOG_INFO(" install\tGenerates a Makefile and runs make install");
+ LOG_INFO(" clean\t\tGenerates a Makefile and runs make clean");
+ LOG_INFO(" rebuild\tGenerates a Makefile and runs make rebuild");
+ LOG_INFO(" If no option is given it will run default make");
+}
+
+bool GenMakefile()
+{
+ std::ifstream f("makegen.conf");
+ if(f.good())
+ {
+ ConfigFile conf = ConfigFile::Load("makegen.conf");
+ Makefile::Save(conf);
+ return true;
+ }
+ f.close();
+ f = std::ifstream("Makefile");
+
+ if(!f.good())
+ {
+ LOG_ERROR("No makegen.conf or Makefile found.");
+ PrintHelp();
+ return false;
+ }
+ return true;
}
unsigned int ReadFlags(int argc, char** argv)
@@ -50,15 +78,7 @@ int main(int argc, char** argv)
unsigned int flags = ReadFlags(argc,argv);
if(flags & FLAG_HELP)
{
- LOG_INFO("Usage: makegen [options]");
- LOG_INFO(" Options:");
- LOG_INFO(" --help\tDisplays this information");
- LOG_INFO(" --conf\tGenerate a config file for the project");
- LOG_INFO(" --version\tDisplays the version of this program");
- LOG_INFO(" install\tGenerates a Makefile and runs make install");
- LOG_INFO(" clean\t\tGenerates a Makefile and runs make clean");
- LOG_INFO(" rebuild\tGenerates a Makefile and runs make rebuild");
- LOG_INFO(" If no option is given it will generate a Makefile and run default make");
+ PrintHelp();
return 0;
}
if(flags & FLAG_VERSION)
@@ -73,7 +93,8 @@ int main(int argc, char** argv)
}
LOG_INFO("Generating Makefile...");
Timer timer;
- GenMakefile();
+ if(!GenMakefile())
+ return 1;
LOG_INFO("Took ", round(timer.Elapsed()*1000.0)/1000.0,"s");
LOG_INFO("Running Makefile...");
for(int i = 1;i