aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore16
-rw-r--r--CMakeLists.txt24
-rw-r--r--README.md5
-rw-r--r--backend/ninja/Ninja.cpp75
-rw-r--r--backend/ninja/Ninja.hpp5
-rw-r--r--include/Conf.hpp11
-rwxr-xr-xinstall.sh12
-rw-r--r--project.conf8
-rw-r--r--src/Conf.cpp23
-rw-r--r--src/GlobalLib.cpp23
-rw-r--r--src/main.cpp25
-rw-r--r--tests/project.conf2
-rw-r--r--tests/src/confTest/confTest.cpp26
-rw-r--r--tests/src/confTest/project.conf8
-rw-r--r--tests/src/main.cpp2
15 files changed, 167 insertions, 98 deletions
diff --git a/.gitignore b/.gitignore
index f76c38c..2a323e3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,12 +1,4 @@
-CMakeCache.txt
-CMakeFiles
-CMakeScripts
-Testing
-Makefile
-cmake_install.cmake
-install_manifest.txt
-compile_commands.json
-CTestTestfile.cmake
-cmake-build-debug
-.idea
-build
+sibs-build
+.idea/
+.kdev4/
+sibs.kdev4
diff --git a/CMakeLists.txt b/CMakeLists.txt
deleted file mode 100644
index a636daa..0000000
--- a/CMakeLists.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-cmake_minimum_required(VERSION 3.0.2)
-project(sibs)
-
-set(CMAKE_CXX_STANDARD 11)
-
-set(SOURCE_FILES
- external/xxhash.c
- backend/ninja/Ninja.cpp
- src/main.cpp
- src/FileUtil.cpp
- src/Conf.cpp
- src/PkgConfig.cpp
- src/Exec.cpp
- src/GlobalLib.cpp
- src/curl.cpp
- src/Archive.cpp)
-
-find_package(CURL REQUIRED)
-find_package(LibArchive REQUIRED)
-
-add_executable(sibs ${SOURCE_FILES})
-
-include_directories(${CURL_INCLUDE_DIR} ${LibArchive_INCLUDE_DIR})
-target_link_libraries(sibs ${CURL_LIBRARIES} ${LibArchive_LIBRARIES}) \ No newline at end of file
diff --git a/README.md b/README.md
index a77005b..ea1dc3f 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,7 @@
# Simple Build System for Native Languages
sibs can currently create ninja build files from very simple c++ projects. More to be added soon.
+
+# Installation
+Newest version of sibs builds itself. If you don't already have sibs installed, you need to download an old version first: https://github.com/DEC05EBA/sibs/releases/tag/0.1.0
+After you've download release 0.1.0, you can install it by running install.sh
+When you have sibs 0.1.0 installed, you can install latest version of sibs by running install.sh. New install script uses sibs.
diff --git a/backend/ninja/Ninja.cpp b/backend/ninja/Ninja.cpp
index b2a073b..49bda4f 100644
--- a/backend/ninja/Ninja.cpp
+++ b/backend/ninja/Ninja.cpp
@@ -42,7 +42,29 @@ namespace backend
++i;
}
- return move(result);
+ return result;
+ }
+
+ bool endsWith(const string &str, const string &endWithStr)
+ {
+ if(endWithStr.size() > str.size())
+ return false;
+ else
+ return strncmp(&str[str.size() - endWithStr.size()], &endWithStr[0], endWithStr.size()) == 0;
+ }
+
+ Ninja::LibraryType getNinjaLibraryType(PackageType packageType)
+ {
+ switch(packageType)
+ {
+ case PackageType::EXECUTABLE:
+ return Ninja::LibraryType::EXECUTABLE;
+ case PackageType::STATIC:
+ return Ninja::LibraryType::STATIC;
+ case PackageType::DYNAMIC:
+ case PackageType::LIBRARY:
+ return Ninja::LibraryType::DYNAMIC;
+ }
}
string getIncludeOptionFlag(Compiler compiler, const string &filepath)
@@ -117,8 +139,7 @@ namespace backend
}
}
- Ninja::Ninja(LibraryType _libraryType) :
- libraryType(_libraryType)
+ Ninja::Ninja()
{
}
@@ -183,7 +204,7 @@ namespace backend
}
return false;
}
-
+
#if OS_FAMILY == OS_FAMILY_POSIX
Result<bool> validatePkgConfigPackageVersionExists(const Dependency &dependency)
{
@@ -299,6 +320,8 @@ namespace backend
if(createBuildDirResult.isErr())
return createBuildDirResult;
+ LibraryType libraryType = getNinjaLibraryType(config.getPackageType());
+
string savePathUtf8 = toUtf8(savePath);
FileString ninjaBuildFilePath = savePath;
@@ -325,6 +348,19 @@ namespace backend
}
result += "\n\n";
+ string defines;
+ for(const auto &definePair : config.getDefines())
+ {
+ defines += " '-D";
+ defines += definePair.first;
+ defines += "=";
+ defines += definePair.second;
+ defines += "'";
+ }
+
+ if(!defines.empty())
+ printf("Custom define: %s\n", defines.c_str());
+
string compilerName;
switch (config.getCompiler())
{
@@ -431,6 +467,9 @@ namespace backend
objectNames.reserve(sourceFiles.size());
for(const string &sourceFile : sourceFiles)
{
+ string sourceFileLanguage = "c++";
+ if(endsWith(sourceFile, ".c"))
+ sourceFileLanguage = "c";
//string sourceFileEncoded = sourceFile;
//replace(sourceFileEncoded, '/', '@');
string objectName = config.getPackageName() + "@exe/" + sourceFile;
@@ -440,7 +479,9 @@ namespace backend
result += ": cpp_COMPILER ../../";
result += sourceFile;
result += "\n";
- result += " ARGS = $globalIncDir";
+ result += " ARGS = $globalIncDir ";
+ if(!defines.empty())
+ result += defines;
if(config.getCompiler() != Compiler::MSVC)
result += " '-I" + config.getPackageName() + "@exe' '-I..' '-fdiagnostics-color=always' '-pipe' '-D_FILE_OFFSET_BITS=64' '-Wall' '-Winvalid-pch' '-Wnon-virtual-dtor' " + optimizationFlags + " '-g'";
result += "\n\n";
@@ -508,7 +549,7 @@ namespace backend
break;
}
}
-
+
if(!allLinkerFlags.empty())
{
result += allLinkerFlags;
@@ -592,7 +633,7 @@ namespace backend
if(!buildResult)
return buildResult;
- Result<bool> buildTestResult = buildTests(config, projectGeneratedBinary);
+ Result<bool> buildTestResult = buildTests(projectGeneratedBinary, config, savePath);
if(!buildTestResult)
return buildTestResult;
@@ -614,14 +655,24 @@ namespace backend
return false;
}
- Result<bool> Ninja::buildTests(const SibsConfig &parentConfig, const std::string &projectGeneratedBinary)
+ Result<bool> Ninja::buildTests(const std::string &projectGeneratedBinary, const SibsConfig &config, const char *savePath)
{
if(testSourceDirs.empty())
return Result<bool>::Ok(true);
- // TODO: Include executable as dependency??? or compile project as dynamic library even if it's not a library
- if(libraryType == LibraryType::EXECUTABLE)
- return Result<bool>::Err("Unit tests are currently only supported in projects that compile to static/dynamic library");
+ // Tests need parent project as dependency. Executables can't be included as dependency so we build it as dynamic library.
+ // `build` also builds tests
+ if(getNinjaLibraryType(config.getPackageType()) == LibraryType::EXECUTABLE)
+ {
+ SibsConfig parentProjConfigLib = config;
+ parentProjConfigLib.setPackageType(PackageType::DYNAMIC);
+ // HACK: We can build a package that is defined as executable and contains main function by redefining `main`
+ // as something else.
+ // TODO: Do not allow defining `main` in project.conf or as program argument to sibs (when sibs supports defines).
+ // It's ok if `define` fails. It could fail if `main` has already been replaced by other tests somehow.
+ parentProjConfigLib.define("main", "sibs_lib_ignore_main");
+ return build(parentProjConfigLib, savePath, nullptr, nullptr);
+ }
for(const string &testSourceDir : testSourceDirs)
{
@@ -635,7 +686,7 @@ namespace backend
projectConfFilePath += TINYDIR_STRING("/project.conf");
FileType projectConfFileType = getFileType(projectConfFilePath.c_str());
- SibsTestConfig sibsTestConfig(parentConfig.getCompiler(), testSourceDirNative);
+ SibsTestConfig sibsTestConfig(config.getCompiler(), testSourceDirNative);
if(projectConfFileType == FileType::REGULAR)
{
Result<bool> result = Config::readFromFile(projectConfFilePath.c_str(), sibsTestConfig);
diff --git a/backend/ninja/Ninja.hpp b/backend/ninja/Ninja.hpp
index e37a5ca..36a57ff 100644
--- a/backend/ninja/Ninja.hpp
+++ b/backend/ninja/Ninja.hpp
@@ -22,7 +22,7 @@ namespace backend
DYNAMIC,
};
- Ninja(LibraryType libraryType = LibraryType::EXECUTABLE);
+ Ninja();
void addSourceFile(const char *filepath);
void addTestSourceDir(const char *dir);
@@ -30,7 +30,7 @@ namespace backend
const std::vector<std::string>& getSourceFiles() const;
sibs::Result<bool> build(const sibs::SibsConfig &config, const _tinydir_char_t *savePath, sibs::LinkerFlagCallbackFunc staticLinkerFlagCallbackFunc = nullptr, sibs::LinkerFlagCallbackFunc dynamicLinkerFlagCallback = nullptr);
private:
- sibs::Result<bool> buildTests(const sibs::SibsConfig &parentConfig, const std::string &projectGeneratedBinary);
+ sibs::Result<bool> buildTests(const std::string &projectGeneratedBinary, const sibs::SibsConfig &config, const char *savePath);
bool containsSourceFile(const std::string &filepath) const;
bool containsTestSourceDir(const std::string &dir) const;
bool containsDependency(const std::string &dependency) const;
@@ -40,7 +40,6 @@ namespace backend
std::vector<std::string> sourceFiles;
std::vector<std::string> testSourceDirs;
std::vector<std::string> binaryDependencies;
- LibraryType libraryType;
};
}
diff --git a/include/Conf.hpp b/include/Conf.hpp
index 0ad1090..d147fca 100644
--- a/include/Conf.hpp
+++ b/include/Conf.hpp
@@ -8,6 +8,7 @@
#include "Dependency.hpp"
#include "Package.hpp"
#include <vector>
+#include <unordered_map>
#include <cassert>
#include <stdexcept>
@@ -147,6 +148,15 @@ namespace sibs
{
return optimizationLevel;
}
+
+ void setPackageType(PackageType packageType)
+ {
+ this->packageType = packageType;
+ }
+
+ virtual bool isDefined(const std::string &name) const;
+ virtual bool define(const std::string &name, const std::string &value);
+ virtual const std::unordered_map<std::string, std::string>& getDefines() const;
protected:
virtual void processObject(StringView name) override;
virtual void processField(StringView name, const ConfigValue &value) override;
@@ -160,6 +170,7 @@ namespace sibs
PackageType packageType;
std::vector<Dependency> dependencies;
std::vector<std::string> includeDirs;
+ std::unordered_map<std::string, std::string> defines;
OptimizationLevel optimizationLevel;
bool finishedProcessing;
};
diff --git a/install.sh b/install.sh
index ac18bf8..c73d777 100755
--- a/install.sh
+++ b/install.sh
@@ -2,10 +2,8 @@
set -e
-scriptpath="$(dirname "$0")"
-mkdir -p "$scriptpath/build/release"
-cd "$scriptpath/build/release"
-cmake -G Ninja -DCMAKE_BUILD_TYPE=Release ../../
-ninja
-sudo cp sibs /usr/bin/
-echo "Copied $scriptpath/build/release/sibs to /usr/bin/sibs"
+project_dir=`dirname $0`
+sibs build $project_dir --release
+sudo cp "$project_dir/sibs-build/release/sibs" "/usr/bin/sibs"
+echo "Copied $project_dir/sibs-build/release/sibs to /usr/bin/sibs"
+echo "Installation successful!" \ No newline at end of file
diff --git a/project.conf b/project.conf
index 96bb9b9..3f46ea9 100644
--- a/project.conf
+++ b/project.conf
@@ -1,8 +1,10 @@
[package]
name = "sibs"
+type = "executable"
version = "0.1.0"
-authors = ["Aleksi Lindeman <aleksi_888@hotmail.com>"]
+authors = ["DEC05EBA <0xdec05eba@gmail.com>"]
+tests = "tests"
[dependencies]
-sfml-all = "2.4"
-xxhash = "0.1.0" \ No newline at end of file
+libcurl = "7"
+libarchive = "3.3"
diff --git a/src/Conf.cpp b/src/Conf.cpp
index 743942a..5282bb5 100644
--- a/src/Conf.cpp
+++ b/src/Conf.cpp
@@ -339,6 +339,27 @@ namespace sibs
case OPT_LEV_RELEASE: return "release";
}
}
+
+ bool SibsConfig::isDefined(const std::string &name) const
+ {
+ return defines.find(name) != defines.end();
+ }
+
+ bool SibsConfig::define(const std::string &name, const std::string &value)
+ {
+ if(isDefined(name))
+ return false;
+ else
+ {
+ defines[name] = value;
+ return true;
+ }
+ }
+
+ const std::unordered_map<std::string, std::string>& SibsConfig::getDefines() const
+ {
+ return defines;
+ }
void SibsConfig::processObject(StringView name)
{
@@ -497,4 +518,4 @@ namespace sibs
{
finishedProcessing = true;
}
-} \ No newline at end of file
+}
diff --git a/src/GlobalLib.cpp b/src/GlobalLib.cpp
index db85abd..fde7797 100644
--- a/src/GlobalLib.cpp
+++ b/src/GlobalLib.cpp
@@ -138,22 +138,7 @@ namespace sibs
return Result<string>::Err(errMsg);
}
- backend::Ninja::LibraryType libraryType;
- switch(sibsConfig.getPackageType())
- {
- case PackageType::STATIC:
- libraryType = backend::Ninja::LibraryType::STATIC;
- break;
- case PackageType::DYNAMIC:
- case PackageType::LIBRARY:
- libraryType = backend::Ninja::LibraryType::DYNAMIC;
- break;
- default:
- assert(false);
- return Result<string>::Err("Unexpected error");
- }
-
- backend::Ninja ninja(libraryType);
+ backend::Ninja ninja;
FileWalkCallbackFunc collectSourceFiles = [&ninja, &sibsConfig, &collectSourceFiles](tinydir_file *file)
{
if(file->is_reg)
@@ -201,7 +186,7 @@ namespace sibs
buildPath += TINYDIR_STRING("release");
break;
}
-
+
string libPath = toUtf8(buildPath);
switch (sibsConfig.getCompiler())
{
@@ -209,7 +194,7 @@ namespace sibs
{
libPath += "/lib";
libPath += name;
- if (libraryType == backend::Ninja::LibraryType::STATIC)
+ if (sibsConfig.getPackageType() == PackageType::STATIC)
{
libPath += ".a";
string libPathCmd = "'";
@@ -231,7 +216,7 @@ namespace sibs
{
libPath += "/";
libPath += name;
- if (libraryType == backend::Ninja::LibraryType::STATIC)
+ if (sibsConfig.getPackageType() == PackageType::STATIC)
{
libPath += ".lib";
string libPathCmd = "\"";
diff --git a/src/main.cpp b/src/main.cpp
index f49ba59..855b1dc 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,6 +1,7 @@
#include <cstdio>
#include <iostream>
#include <unordered_set>
+#include <chrono>
#include "../include/FileUtil.hpp"
#include "../include/Conf.hpp"
#include "../include/Exec.hpp"
@@ -8,6 +9,7 @@
using namespace std;
using namespace sibs;
+using namespace std::chrono;
// TODO: Fail if multiple versions of the same dependency is used
// as linking will fail because of multiple definitions of the same thing
@@ -20,6 +22,8 @@ using namespace sibs;
// TODO: Places that use PATH_MAX should be modified. A path CAN be longer than PATH_MAX... (does this include replacing tinydir.h?)
+// TODO: Remove install.sh when sibs supports installation of packages (so it can install itself)
+
#if OS_FAMILY == OS_FAMILY_POSIX
#define ferr std::cerr
#else
@@ -207,23 +211,7 @@ int buildProject(int argc, const _tinydir_char_t **argv)
//string projectSrcPath = projectPath + "/src";
//validateDirectoryPath(projectSrcPath.c_str());
- PackageType packageType = sibsConfig.getPackageType();
- backend::Ninja::LibraryType libraryType;
- switch(packageType)
- {
- case PackageType::EXECUTABLE:
- libraryType = backend::Ninja::LibraryType::EXECUTABLE;
- break;
- case PackageType::STATIC:
- libraryType = backend::Ninja::LibraryType::STATIC;
- break;
- case PackageType::DYNAMIC:
- case PackageType::LIBRARY:
- libraryType = backend::Ninja::LibraryType::DYNAMIC;
- break;
- }
-
- backend::Ninja ninja(libraryType);
+ backend::Ninja ninja;
FileWalkCallbackFunc collectSourceFiles = [&ninja, &sibsConfig, &collectSourceFiles](tinydir_file *file)
{
if(file->is_reg)
@@ -263,12 +251,15 @@ int buildProject(int argc, const _tinydir_char_t **argv)
break;
}
+ auto startTime = high_resolution_clock::now();
Result<bool> buildFileResult = ninja.build(sibsConfig, buildPath.c_str());
if(buildFileResult.isErr())
{
ferr << "Failed to build ninja file: " << toFileString(buildFileResult.getErrMsg()) << endl;
exit(7);
}
+ auto elapsedTime = duration_cast<duration<double>>(high_resolution_clock::now() - startTime);
+ printf("Build finished in %fs\n", elapsedTime.count());
return 0;
}
diff --git a/tests/project.conf b/tests/project.conf
new file mode 100644
index 0000000..6a33314
--- /dev/null
+++ b/tests/project.conf
@@ -0,0 +1,2 @@
+[dependencies]
+catch2 = "0.1.0"
diff --git a/tests/src/confTest/confTest.cpp b/tests/src/confTest/confTest.cpp
new file mode 100644
index 0000000..38b4971
--- /dev/null
+++ b/tests/src/confTest/confTest.cpp
@@ -0,0 +1,26 @@
+#include "catch2/0.1.0/catch.hpp"
+#include "../../../include/Conf.hpp"
+
+using namespace sibs;
+
+TEST_CASE("parse config")
+{
+ SibsConfig sibsConfig("tests/src/confTest");
+ Result<bool> result = Config::readFromFile("tests/src/confTest/project.conf", sibsConfig);
+ if(result.isErr())
+ {
+ fprintf(stderr, "%s", result.getErrMsg().c_str());
+ exit(1);
+ }
+ REQUIRE(sibsConfig.getPackageName() == "confTest");
+ REQUIRE(sibsConfig.getPackageType() == PackageType::LIBRARY);
+ REQUIRE(sibsConfig.getDependencies().size() == 2);
+
+ const auto &xxhashDependency = sibsConfig.getDependencies()[0];
+ REQUIRE(xxhashDependency.name == "xxhash");
+ REQUIRE(xxhashDependency.version == "0.1.0");
+
+ const auto &catch2Dependency = sibsConfig.getDependencies()[1];
+ REQUIRE(catch2Dependency.name == "catch2");
+ REQUIRE(catch2Dependency.version == "1.0.0");
+}
diff --git a/tests/src/confTest/project.conf b/tests/src/confTest/project.conf
new file mode 100644
index 0000000..e50ad9c
--- /dev/null
+++ b/tests/src/confTest/project.conf
@@ -0,0 +1,8 @@
+[package]
+name = "confTest"
+version = "0.1.0"
+type = "library"
+
+[dependencies]
+xxhash = "0.1.0"
+catch2 = "1.0.0"
diff --git a/tests/src/main.cpp b/tests/src/main.cpp
new file mode 100644
index 0000000..d29d915
--- /dev/null
+++ b/tests/src/main.cpp
@@ -0,0 +1,2 @@
+#define CATCH_CONFIG_MAIN
+#include "catch2/0.1.0/catch.hpp"