aboutsummaryrefslogtreecommitdiff
path: root/backend/ninja/Ninja.cpp
blob: 7006d30561d8263982b44394a8b0d94dfd8afd37 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include <cstring>
#include "Ninja.hpp"
#include "../../include/FileUtil.hpp"

using namespace std;

namespace backend
{
    string join(const vector<string> &list, const char *joinStr)
    {
        if(list.empty()) return "";
        string result;
        long stringSize = 0;
        long joinStrLen = strlen(joinStr);
        int i = 0;
        for(const string &str : list)
        {
            stringSize += str.size();
            if(!str.empty() && i > 0)
                stringSize += joinStrLen;
            ++i;
        }

        result.reserve(stringSize);

        i = 0;
        for(const string &str : list)
        {
            if(i > 0);
                result += joinStr;
            result += str;
            ++i;
        }

        return move(result);
    }

    void Ninja::addSourceFile(const char *filepath)
    {
        if(filepath && !containsSourceFile(filepath))
            sourceFiles.emplace_back(filepath);
    }

    bool Ninja::containsSourceFile(const char *filepath) const
    {
        for(const string &sourceFile : sourceFiles)
        {
            if(sourceFile == filepath)
                return true;
        }
        return false;
    }

    void Ninja::build(const std::string &packageName, const char *savePath)
    {
        if(sourceFiles.empty()) return;
        printf("Package name: %s\n", packageName.c_str());

        string result;
        result.reserve(16384);

        result += "cflags = -Wall -Werror\n\n";

        result += "rule cpp_COMPILER\n";
        result += "  command = ccache c++ $ARGS -c $in -o $out\n\n";

        result += "rule cpp_LINKER\n";
        result += "  command = ccache c++ $ARGS -o $out $in $LINK_ARGS $aliasing\n\n";

        vector<string> objectNames;
        for(const string &sourceFile : sourceFiles)
        {
            //string sourceFileEncoded = sourceFile;
            //replace(sourceFileEncoded, '/', '@');
            string objectName = packageName + "@exe/" + sourceFile + ".o";
            result += "build ";
            result += objectName;
            result += ": cpp_COMPILER ../../";
            result += sourceFile;
            result += "\n";
            result += "  ARGS = '-I" + packageName + "@exe' '-I.' '-I..' '-fdiagnostics-color=always' '-pipe' '-D_FILE_OFFSET_BITS=64' '-Wall' '-Winvalid-pch' '-Wnon-virtual-dtor' '-O0' '-g'\n\n";
            objectNames.emplace_back(objectName);
        }

        result += "build ";
        result += packageName;
        result += ": cpp_LINKER ";
        result += join(objectNames, " ");
        result += "\n";
        result += "  LINK_ARGS = '-Wl,--no-undefined' '-Wl,--as-needed'\n\n";

        sibs::fileOverwrite(savePath, sibs::StringView(result.data(), result.size()));
        printf("Created ninja build file: %s\n", savePath);
    }
}