aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2018-01-07 12:04:20 +0100
committerdec05eba <dec05eba@protonmail.com>2018-01-07 12:04:24 +0100
commit0bb8fff4d481f5076639d28b55daf76dd2b2ea0f (patch)
tree07ef3c879ed94d50237e026de74910fa9e69d684
parent82df40bd1fc82958ef90e7c917ce3eec382d4309 (diff)
Add c/c++ language version option, compile c/cc files with c compiler
-rw-r--r--backend/ninja/Ninja.cpp129
-rw-r--r--include/Conf.hpp32
-rw-r--r--packages.json7
-rw-r--r--src/Conf.cpp76
4 files changed, 219 insertions, 25 deletions
diff --git a/backend/ninja/Ninja.cpp b/backend/ninja/Ninja.cpp
index 4e94fcf..6d871fd 100644
--- a/backend/ninja/Ninja.cpp
+++ b/backend/ninja/Ninja.cpp
@@ -159,6 +159,57 @@ namespace backend
}
return result;
}
+
+ string getLanguageVersionFlag(Compiler compiler, CVersion cVersion)
+ {
+ switch (compiler)
+ {
+ case Compiler::GCC:
+ {
+ switch(cVersion)
+ {
+ case CVersion::C89: return "-std=c89 -pedantic";
+ case CVersion::C99: return "-std=c99 -pedantic";
+ case CVersion::C11: return "-std=c11 -pedantic";
+ }
+ }
+ case Compiler::MSVC:
+ {
+ // TODO: Is it possible to specify c version in msvc?
+ return "";
+ }
+ }
+ assert(false);
+ return "";
+ }
+
+ string getLanguageVersionFlag(Compiler compiler, CPPVersion cppVersion)
+ {
+ switch (compiler)
+ {
+ case Compiler::GCC:
+ {
+ switch(cppVersion)
+ {
+ case CPPVersion::CPP11: return "-std=c++11 -pedantic";
+ case CPPVersion::CPP14: return "-std=c++14 -pedantic";
+ case CPPVersion::CPP17: return "-std=c++17 -pedantic";
+ }
+ }
+ case Compiler::MSVC:
+ {
+ switch(cppVersion)
+ {
+ // Use /Za flag?
+ case CPPVersion::CPP11: return "/std=c++11";
+ case CPPVersion::CPP14: return "/std=c++14";
+ case CPPVersion::CPP17: return "/std=c++17";
+ }
+ }
+ }
+ assert(false);
+ return "";
+ }
const char* getObjectFileExtension(Compiler compiler)
{
@@ -296,6 +347,12 @@ namespace backend
return GlobalLib::getLibs(globalLibDependencies, config, globalLibDir, staticLinkerFlagCallbackFunc, dynamicLinkerFlagCallback, globalIncludeDirCallback);
}
+
+ enum class SourceFileLanguage
+ {
+ C,
+ CPP
+ };
Result<bool> Ninja::build(const SibsConfig &config, const _tinydir_char_t *savePath, LinkerFlagCallbackFunc staticLinkerFlagCallbackFunc, LinkerFlagCallbackFunc dynamicLinkerFlagCallback, GlobalIncludeDirCallbackFunc globalIncludeDirCallback)
{
@@ -429,17 +486,6 @@ namespace backend
}
#endif
- string compilerName;
- switch (config.getCompiler())
- {
- case Compiler::GCC:
- compilerName = "ccache c++";
- break;
- case Compiler::MSVC:
- compilerName = "cl.exe";
- break;
- }
-
string buildJob;
switch(libraryType)
{
@@ -454,6 +500,9 @@ namespace backend
result += "rule cpp_BUILD_EXEC\n";
result += " command = ccache c++ $ARGS -o $out $in $LINK_ARGS $aliasing\n\n";
+
+ result += "rule c_COMPILER\n";
+ result += " command = ccache cc $ARGS -c $in -o $out\n\n";
break;
}
case Compiler::MSVC:
@@ -463,6 +512,9 @@ namespace backend
result += "rule cpp_BUILD_EXEC\n";
result += " command = cl.exe $ARGS $in /Fe$out $LINK_ARGS\n\n";
+
+ result += "rule c_COMPILER\n";
+ result += " command = cl.exe $ARGS /c $in /Fo$out\n\n";
break;
}
}
@@ -484,6 +536,9 @@ namespace backend
result += config.getPackageName();
result += ".a";
result += " $in\n\n";
+
+ result += "rule c_COMPILER\n";
+ result += " command = ccache cc $ARGS -c -fPIC $in -o $out\n\n";
break;
}
case Compiler::MSVC:
@@ -493,6 +548,9 @@ namespace backend
result += "rule cpp_BUILD_STATIC\n";
result += " command = lib.exe /OUT:$out $in\n\n";
+
+ result += "rule c_COMPILER\n";
+ result += " command = cl.exe $ARGS /c $in /Fo$out\n\n";
break;
}
}
@@ -512,6 +570,9 @@ namespace backend
// --whole-archive
result += "rule cpp_BUILD_DYNAMIC\n";
result += " command = ccache c++ $in -shared -o $out $LINK_ARGS $aliasing\n\n";
+
+ result += "rule c_COMPILER\n";
+ result += " command = ccache cc $ARGS -c -fPIC $in -o $out\n\n";
break;
}
case Compiler::MSVC:
@@ -524,6 +585,9 @@ namespace backend
result += "rule cpp_BUILD_DYNAMIC\n";
result += " command = lib.exe /OUT:$out $in\n\n";
+
+ result += "rule c_COMPILER\n";
+ result += " command = cl.exe $ARGS /c $in /Fo$out\n\n";
break;
}
}
@@ -580,27 +644,58 @@ namespace backend
objectNames.reserve(sourceFiles.size());
for(const string &sourceFile : sourceFiles)
{
- string sourceFileLanguage = "c++";
- if(endsWith(sourceFile, ".c"))
- sourceFileLanguage = "c";
+ SourceFileLanguage sourceFileLanguage = SourceFileLanguage::CPP;
+ if(endsWith(sourceFile, ".c") || endsWith(sourceFile, ".cc"))
+ sourceFileLanguage = SourceFileLanguage::C;
+
+ const char *buildTarget;
+ switch(sourceFileLanguage)
+ {
+ case SourceFileLanguage::C:
+ buildTarget = "c_COMPILER";
+ break;
+ case SourceFileLanguage::CPP:
+ buildTarget = "cpp_COMPILER";
+ break;
+ }
+
//string sourceFileEncoded = sourceFile;
//replace(sourceFileEncoded, '/', '@');
string objectName = config.getPackageName() + "@exe/" + sourceFile;
objectName += getObjectFileExtension(config.getCompiler());
result += "build ";
result += objectName;
- result += ": cpp_COMPILER ../../";
+ result += ": ";
+ result += buildTarget;
+ result += " ../../";
result += sourceFile;
result += "\n";
result += " ARGS = $globalIncDir ";
if(!defines.empty())
result += defines;
+
+ result += " ";
+ switch(sourceFileLanguage)
+ {
+ case SourceFileLanguage::C:
+ result += getLanguageVersionFlag(config.getCompiler(), config.getCversion());
+ break;
+ case SourceFileLanguage::CPP:
+ result += getLanguageVersionFlag(config.getCompiler(), config.getCppVersion());
+ break;
+ }
+
switch (config.getCompiler())
{
case Compiler::GCC:
{
// -Werror
- result += " '-I" + config.getPackageName() + "@exe' " + cflags + " '-I..' -Wall -Wextra -Werror=return-type -fexceptions -fdiagnostics-show-option '-fdiagnostics-color=always' '-pipe' '-D_FILE_OFFSET_BITS=64' '-Winvalid-pch' '-Wnon-virtual-dtor' " + optimizationFlags;
+ result += " '-I" + config.getPackageName() + "@exe' " + cflags + " '-I..' -Wall -Wextra -Werror=return-type -fdiagnostics-show-option '-fdiagnostics-color=always' '-pipe' '-D_FILE_OFFSET_BITS=64' '-Winvalid-pch' -fstack-protector " + optimizationFlags;
+ if(sourceFileLanguage == SourceFileLanguage::CPP)
+ {
+ result += " -fexceptions -Wnon-virtual-dtor";
+ }
+
switch (config.getOptimizationLevel())
{
case OPT_LEV_DEBUG:
@@ -616,7 +711,7 @@ namespace backend
{
result += " ";
result += optimizationFlags;
- result += " /EHsc ";
+ result += " /EHsc /W3 ";
result += cflags;
switch (config.getOptimizationLevel())
{
diff --git a/include/Conf.hpp b/include/Conf.hpp
index 950b25a..3dd409d 100644
--- a/include/Conf.hpp
+++ b/include/Conf.hpp
@@ -110,6 +110,20 @@ namespace sibs
PLATFORM_WIN64
};
+ enum class CVersion
+ {
+ C89, // aka ansi
+ C99,
+ C11
+ };
+
+ enum class CPPVersion
+ {
+ CPP11,
+ CPP14,
+ CPP17
+ };
+
const StringView CONFIGS[] = {
"config.win32",
"config.win32.static.debug",
@@ -180,7 +194,9 @@ namespace sibs
optimizationLevel(_optimizationLevel),
finishedProcessing(false),
useCmake(false),
- buildTests(_buildTests)
+ buildTests(_buildTests),
+ cVersion(CVersion::C11),
+ cppVersion(CPPVersion::CPP11)
{
cmakeDirGlobal = projectPath;
cmakeDirStatic = cmakeDirGlobal;
@@ -313,6 +329,16 @@ namespace sibs
return result;
}
+ CVersion getCversion() const
+ {
+ return cVersion;
+ }
+
+ CPPVersion getCppVersion() const
+ {
+ return cppVersion;
+ }
+
bool shouldUseCmake() const
{
return useCmake;
@@ -342,6 +368,8 @@ namespace sibs
void failInvalidFieldUnderObject(const StringView &fieldName) const;
void validatePackageTypeDefined() const;
private:
+ void parseCLang(const StringView &fieldName, const ConfigValue &fieldValue);
+ void parseCppLang(const StringView &fieldName, const ConfigValue &fieldValue);
void parsePlatformConfigs(const StringView &fieldName, const ConfigValue &fieldValue);
void parsePlatformConfig(const StringView &fieldName, const ConfigValue &fieldValue);
void parsePlatformConfigStaticDebug(const StringView &fieldName, const ConfigValue &fieldValue);
@@ -370,6 +398,8 @@ namespace sibs
std::string cmakeArgsGlobal;
std::string cmakeArgsStatic;
std::string cmakeArgsDynamic;
+ CVersion cVersion;
+ CPPVersion cppVersion;
bool useCmake;
bool buildTests;
bool finishedProcessing;
diff --git a/packages.json b/packages.json
deleted file mode 100644
index 3196663..0000000
--- a/packages.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "xxhash": {
- "0.1.0": {
- "urls": ["https://gateway.ipfs.io/ipfs/QmVJH2p3Y28iQ6te5wR6bCDnzDYzDFvEqJDuLf4Ykn2d3Z"]
- }
- }
-}
diff --git a/src/Conf.cpp b/src/Conf.cpp
index f8b53e3..9f63833 100644
--- a/src/Conf.cpp
+++ b/src/Conf.cpp
@@ -792,6 +792,14 @@ namespace sibs
{
parseCmake(name, value, cmakeDirDynamic, cmakeArgsDynamic);
}
+ else if(currentObject.equals("lang.c"))
+ {
+ parseCLang(name, value);
+ }
+ else if(currentObject.equals("lang.cpp"))
+ {
+ parseCppLang(name, value);
+ }
else
{
string errMsg = "Invalid config object \"";
@@ -801,6 +809,74 @@ namespace sibs
}
}
+ void SibsConfig::parseCLang(const StringView &fieldName, const ConfigValue &fieldValue)
+ {
+ if(fieldName.equals("version"))
+ {
+ // TODO: Support several versions (a list of versions where the latest possible version is used)?
+ if(fieldValue.isSingle())
+ {
+ const StringView &cVersionStr = fieldValue.asSingle();
+ if(cVersionStr.equals("c89") || cVersionStr.equals("ansi"))
+ {
+ cVersion = CVersion::C89;
+ }
+ else if(cVersionStr.equals("c99"))
+ {
+ cVersion = CVersion::C99;
+ }
+ else if(cVersionStr.equals("c11"))
+ {
+ cVersion = CVersion::C11;
+ }
+ else
+ {
+ string errMsg = "Expected lang.c.version to be c89, c99 or c11, was ";
+ errMsg += string(cVersionStr.data, cVersionStr.size);
+ throw ParserException(errMsg);
+ }
+ }
+ else
+ throw ParserException("Expected lang.c.version to be a single value, was a list");
+ }
+ else
+ failInvalidFieldUnderObject(fieldName);
+ }
+
+ void SibsConfig::parseCppLang(const StringView &fieldName, const ConfigValue &fieldValue)
+ {
+ if(fieldName.equals("version"))
+ {
+ // TODO: Support several versions (a list of versions where the latest possible version is used)?
+ if(fieldValue.isSingle())
+ {
+ const StringView &cppVersionStr = fieldValue.asSingle();
+ if(cppVersionStr.equals("c++11"))
+ {
+ cppVersion = CPPVersion::CPP11;
+ }
+ else if(cppVersionStr.equals("c++14"))
+ {
+ cppVersion = CPPVersion::CPP14;
+ }
+ else if(cppVersionStr.equals("c++17"))
+ {
+ cppVersion = CPPVersion::CPP17;
+ }
+ else
+ {
+ string errMsg = "Expected lang.cpp.version to be c89, c99 or c11, was ";
+ errMsg += string(cppVersionStr.data, cppVersionStr.size);
+ throw ParserException(errMsg);
+ }
+ }
+ else
+ throw ParserException("Expected lang.cpp.version to be a single value, was a list");
+ }
+ else
+ failInvalidFieldUnderObject(fieldName);
+ }
+
void SibsConfig::parsePlatformConfigs(const StringView &fieldName, const ConfigValue &fieldValue)
{
for(int i = 0; i < NUM_CONFIGS; ++i)