aboutsummaryrefslogtreecommitdiff
path: root/src/main.cpp
blob: f9fbd826f1e8dc56eef4122e95e507bc0369595a (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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include <cstdio>
#include "../include/FileUtil.hpp"
#include "../include/Conf.hpp"
#include "../include/Dependency.hpp"
#include "../backend/ninja/Ninja.hpp"
#include <string>
#include <cassert>

using namespace std;
using namespace sibs;

void usage()
{
    printf("Simple build system for native languages\n");
    printf("usage:\n");
    printf("    sibs <project path>\n");
    printf("option:\n");
    printf("    project path: Path containing project.conf\n");
    printf("examples:\n");
    printf("    sibs myProject");
    exit(1);
}

void validateDirectoryPath(const char *projectPath)
{
    FileType projectPathFileType = getFileType(projectPath);
    if(projectPathFileType == FileType::FILE_NOT_FOUND)
    {
        perror(projectPath);
        exit(2);
    }
    else if(projectPathFileType == FileType::REGULAR)
    {
        printf("Expected project path (%s) to be a directory, was a file", projectPath);
        exit(3);
    }
}

void validateFilePath(const char *projectConfPath)
{
    FileType projectConfFileType = getFileType(projectConfPath);
    if(projectConfFileType == FileType::FILE_NOT_FOUND)
    {
        perror(projectConfPath);
        exit(4);
    }
    else if(projectConfFileType == FileType::DIRECTORY)
    {
        printf("Expected project path (%s) to be a file, was a directory", projectConfPath);
        exit(5);
    }
}

const char *sourceFileExtensions[] = { "cc", "cpp", "cxx" };
bool isSourceFile(tinydir_file *file)
{
    if(!file->is_reg)
        return false;

    for(const char *sourceFileExtension : sourceFileExtensions)
    {
        if(_tinydir_strcmp(sourceFileExtension, file->extension) == 0)
            return true;
    }

    return false;
}

int main(int argc, const char **argv)
{
    if(argc != 2)
        usage();

    string projectPath = argv[1];
    validateDirectoryPath(projectPath.c_str());
    if(projectPath.back() != '/')
        projectPath += "/";

    string projectConfFilePath = projectPath;
    projectConfFilePath += "/project.conf";
    validateFilePath(projectConfFilePath.c_str());

    SibsConfig sibsConfig;
    Result<bool> result = Config::readFromFile(projectConfFilePath.c_str(), sibsConfig);
    if(result.isErr())
    {
        printf("Failed to read config: %s\n", result.getErrMsg().c_str());
        exit(6);
    }

    if(sibsConfig.getPackageName().empty())
    {
        printf("project.conf is missing required field package.name\n");
        exit(10);
    }

    //string projectSrcPath = projectPath + "/src";
    //validateDirectoryPath(projectSrcPath.c_str());

    backend::Ninja ninja;
    walkDirFilesRecursive(projectPath.c_str(), [&ninja, &projectPath](tinydir_file *file)
    {
        if (isSourceFile(file))
        {
            printf("Adding source file: %s\n", file->path + projectPath.size());
            ninja.addSourceFile(file->path + projectPath.size());
        } else
        {
            //printf("Ignoring non-source file: %s\n", file->path + projectPath.size());
        }
    });

    // TODO: Create build path if it doesn't exist
    string debugBuildPath = projectPath + "/build/debug";
    Result<bool> buildFileResult = ninja.createBuildFile(sibsConfig.getPackageName(), sibsConfig.getDependencies(), debugBuildPath.c_str());
    if(buildFileResult.isErr())
    {
        printf("Failed to build ninja file: %s\n", buildFileResult.getErrMsg().c_str());
        exit(7);
    }

    Result<bool> buildResult = ninja.build(debugBuildPath.c_str());
    if(buildResult.isErr())
    {
        exit(8);
    }

    return 0;
}