Start support for multiple build targets.
This commit is contained in:
parent
e3e03dc31f
commit
3dce256213
52 changed files with 1044 additions and 340 deletions
18
bootstrap.sh
18
bootstrap.sh
|
@ -8,8 +8,13 @@ g++ $SOURCE_DIR/main.cpp \
|
|||
$CORE_SRC_DIR/base_types/Error.cpp \
|
||||
$CORE_SRC_DIR/base_types/Index.cpp \
|
||||
$CORE_SRC_DIR/base_types/Char.cpp \
|
||||
$SOURCE_DIR/base/compiler/BuildLibrary.cpp \
|
||||
$SOURCE_DIR/base/compiler/BuildSession.cpp \
|
||||
$SOURCE_DIR/base/compiler/buildsystem/BuildEnvironment.cpp \
|
||||
$SOURCE_DIR/base/compiler/buildsystem/BuildConfig.cpp \
|
||||
$SOURCE_DIR/base/compiler/buildsystem/BuildBinary.cpp \
|
||||
$SOURCE_DIR/base/compiler/buildsystem/BuildTarget.cpp \
|
||||
$SOURCE_DIR/base/compiler/buildsystem/BuildLibrary.cpp \
|
||||
$SOURCE_DIR/base/compiler/buildsystem/BuildExecutable.cpp \
|
||||
$SOURCE_DIR/base/compiler/buildsystem/BuildSession.cpp \
|
||||
$CORE_SRC_DIR/data_structures/String.cpp \
|
||||
$CORE_SRC_DIR/filesystem/FileSystemPath.cpp \
|
||||
$CORE_SRC_DIR/filesystem/File.cpp \
|
||||
|
@ -18,17 +23,24 @@ g++ $SOURCE_DIR/main.cpp \
|
|||
$CORE_SRC_DIR/filesystem/Directory.cpp \
|
||||
$CORE_SRC_DIR/logging/ConsoleLogger.cpp \
|
||||
$CORE_SRC_DIR/logging/Logger.cpp \
|
||||
$CORE_SRC_DIR/serialization/yaml/YamlDocuments.cpp \
|
||||
$CORE_SRC_DIR/serialization/yaml/YamlDocument.cpp \
|
||||
$CORE_SRC_DIR/serialization/yaml/YamlParser.cpp \
|
||||
$CORE_SRC_DIR/streams/FileStream.cpp \
|
||||
$CORE_SRC_DIR/streams/Stream.cpp \
|
||||
$CORE_SRC_DIR/system/process/Process.cpp \
|
||||
$CORE_SRC_DIR/time/Time.cpp \
|
||||
-o builder -g -fno-exceptions -fno-rtti \
|
||||
-I$CORE_SRC_DIR/base_types \
|
||||
-I$SOURCE_DIR/base/compiler \
|
||||
-I$SOURCE_DIR/base/compiler/buildsystem \
|
||||
-I$CORE_SRC_DIR/data_structures \
|
||||
-I$CORE_SRC_DIR/encoding \
|
||||
-I$CORE_SRC_DIR/filesystem \
|
||||
-I$CORE_SRC_DIR/filesystem/posix \
|
||||
-I$CORE_SRC_DIR/logging \
|
||||
-I$CORE_SRC_DIR/memory \
|
||||
-I$CORE_SRC_DIR/serialization/yaml \
|
||||
-I$CORE_SRC_DIR/streams \
|
||||
-I$CORE_SRC_DIR/system/process \
|
||||
-I$CORE_SRC_DIR/time
|
||||
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
#include "BuildLibrary.h"
|
||||
|
||||
#include "Logger.h"
|
||||
#include "Directory.h"
|
||||
|
||||
BuildLibrary::BuildLibrary(const FileSystemPath& build_config)
|
||||
: m_build_config(build_config)
|
||||
{
|
||||
}
|
||||
|
||||
Status BuildLibrary::scan()
|
||||
{
|
||||
LOG_INFO("Scanning build file at: " << m_build_config);
|
||||
const auto search_dir = m_build_config.parent_path();
|
||||
m_name = search_dir.stem().str();
|
||||
|
||||
STATUS_CHECK(Directory::getFilesWithExtension(search_dir,
|
||||
".cpp",
|
||||
m_sources,
|
||||
true), "Error collecting source files")
|
||||
|
||||
m_include_dirs.push_back(search_dir);
|
||||
|
||||
STATUS_CHECK(Directory::getAllSubDirectories(search_dir,
|
||||
m_include_dirs), "Error collecting include dirs")
|
||||
return {};
|
||||
}
|
||||
|
||||
const String& BuildLibrary::get_name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
const Vector<FileSystemPath>& BuildLibrary::get_sources() const
|
||||
{
|
||||
return m_sources;
|
||||
}
|
||||
|
||||
const Vector<FileSystemPath>& BuildLibrary::get_include_dirs() const
|
||||
{
|
||||
return m_include_dirs;
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "FileSystemPath.h"
|
||||
#include "String.h"
|
||||
|
||||
class BuildLibrary
|
||||
{
|
||||
public:
|
||||
BuildLibrary() = default;
|
||||
|
||||
BuildLibrary(const FileSystemPath& build_config);
|
||||
|
||||
const Vector<FileSystemPath>& get_sources() const;
|
||||
|
||||
const Vector<FileSystemPath>& get_include_dirs() const;
|
||||
|
||||
const String& get_name() const;
|
||||
|
||||
Status scan();
|
||||
|
||||
private:
|
||||
FileSystemPath m_build_config;
|
||||
Vector<FileSystemPath> m_sources;
|
||||
Vector<FileSystemPath> m_include_dirs;
|
||||
String m_name;
|
||||
};
|
|
@ -1,131 +0,0 @@
|
|||
#include "BuildSession.h"
|
||||
|
||||
#include "Logger.h"
|
||||
#include "Process.h"
|
||||
#include "Directory.h"
|
||||
|
||||
BuildSession::BuildSession(const String& source_dir,
|
||||
const String& build_dir)
|
||||
: m_source_dir(source_dir)
|
||||
{
|
||||
if (build_dir.empty())
|
||||
{
|
||||
m_build_dir = FileSystemPath::current_dir().value();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_build_dir = build_dir;
|
||||
}
|
||||
const auto build_str = m_build_dir.str() + "/build";
|
||||
m_build_dir = FileSystemPath(build_str);
|
||||
m_compiler_flags.push_back("-g");
|
||||
m_compiler_flags.push_back("-fno-exceptions");
|
||||
m_compiler_flags.push_back("-fno-rtti");
|
||||
}
|
||||
|
||||
Status BuildSession::scan()
|
||||
{
|
||||
LOG_INFO("Scanning sources at:" << m_source_dir);
|
||||
Vector<FileSystemPath> yaml_files;
|
||||
STATUS_CHECK(Directory::getFilesWithExtension(
|
||||
m_source_dir,
|
||||
".yaml",
|
||||
yaml_files,
|
||||
true), "Error looking for build files");
|
||||
|
||||
for(const auto& yaml_file : yaml_files)
|
||||
{
|
||||
if (yaml_file.file_name() == "build")
|
||||
{
|
||||
STATUS_CHECK(add_library(yaml_file),
|
||||
"Error adding library");
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
Status BuildSession::add_library(const FileSystemPath& config_path)
|
||||
{
|
||||
LOG_INFO("Adding library at: " << config_path);
|
||||
BuildLibrary lib(config_path);
|
||||
STATUS_CHECK(lib.scan(), "Error scanning library");
|
||||
m_libraries.push_back(lib);
|
||||
return {};
|
||||
}
|
||||
|
||||
Status BuildSession::build()
|
||||
{
|
||||
LOG_INFO("Creating dir: " << m_build_dir);
|
||||
Directory::create(m_build_dir, true);
|
||||
for(auto& library : m_libraries)
|
||||
{
|
||||
auto run_status = compile_library(library);
|
||||
if (!run_status.ok())
|
||||
{
|
||||
return run_status;
|
||||
}
|
||||
run_status = create_archive(library);
|
||||
if (!run_status.ok())
|
||||
{
|
||||
return run_status;
|
||||
}
|
||||
//break;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
Status BuildSession::compile_library(BuildLibrary& lib)
|
||||
{
|
||||
for(const auto& source : lib.get_sources())
|
||||
{
|
||||
const auto run_status = compile_source_file(source, lib);
|
||||
if (!run_status.ok())
|
||||
{
|
||||
return run_status;
|
||||
}
|
||||
//break;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
Status BuildSession::create_archive(BuildLibrary& lib)
|
||||
{
|
||||
Vector<String> args;
|
||||
args.push_back("rcs");
|
||||
|
||||
auto name = "lib" + lib.get_name() + ".a";
|
||||
args.push_back(name);
|
||||
|
||||
for(const auto& source : lib.get_sources())
|
||||
{
|
||||
const auto output_path = m_build_dir / source.file_name();
|
||||
const auto output_file = output_path.str() + ".o";
|
||||
args.push_back(output_file);
|
||||
}
|
||||
|
||||
LOG_INFO("Archiving " << name);
|
||||
return Process::launch(m_archive_command, args);
|
||||
}
|
||||
|
||||
Status BuildSession::compile_source_file(const FileSystemPath& source,
|
||||
const BuildLibrary& lib)
|
||||
{
|
||||
Vector<String> args = m_compiler_flags;
|
||||
args.push_back("-c");
|
||||
add_include_dirs(args, lib);
|
||||
args.push_back(source.str());
|
||||
|
||||
const auto output_path = m_build_dir / source.file_name();
|
||||
args.push_back("-o");
|
||||
args.push_back(output_path.str() + ".o");
|
||||
LOG_INFO("Compiling " << source.file_name());
|
||||
return Process::launch(m_compiler_command, args);
|
||||
}
|
||||
|
||||
void BuildSession::add_include_dirs(Vector<String>& args, const BuildLibrary& lib)
|
||||
{
|
||||
for(const auto& include_dir : lib.get_include_dirs())
|
||||
{
|
||||
args.push_back(_s("-I") + include_dir.str());
|
||||
}
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "BuildLibrary.h"
|
||||
#include "Error.h"
|
||||
|
||||
class BuildSession
|
||||
{
|
||||
public:
|
||||
BuildSession(const String& source_dir,
|
||||
const String& build_dir = {});
|
||||
|
||||
Status scan();
|
||||
|
||||
Status build();
|
||||
|
||||
Status add_library(const FileSystemPath& config_path);
|
||||
|
||||
private:
|
||||
Status compile_library(BuildLibrary& lib);
|
||||
|
||||
Status compile_source_file(const FileSystemPath& source,
|
||||
const BuildLibrary& lib);
|
||||
|
||||
void add_include_dirs(Vector<String>& args, const BuildLibrary& lib);
|
||||
|
||||
Status create_archive(BuildLibrary& lib);
|
||||
|
||||
String m_compiler_command{"/usr/bin/g++"};
|
||||
String m_archive_command{"/usr/bin/ar"};
|
||||
Vector<String> m_compiler_flags;
|
||||
FileSystemPath m_source_dir;
|
||||
FileSystemPath m_build_dir;
|
||||
Vector<BuildLibrary> m_libraries;
|
||||
};
|
121
src/base/compiler/buildsystem/BuildBinary.cpp
Normal file
121
src/base/compiler/buildsystem/BuildBinary.cpp
Normal file
|
@ -0,0 +1,121 @@
|
|||
#include "BuildBinary.h"
|
||||
|
||||
#include "Directory.h"
|
||||
#include "Logger.h"
|
||||
#include "Process.h"
|
||||
|
||||
BuildBinary::BuildBinary(BuildTargetType binary_type)
|
||||
: BuildTarget(binary_type)
|
||||
{
|
||||
}
|
||||
|
||||
BuildBinary::BuildBinary(Ptr<BuildConfig> config)
|
||||
: BuildTarget(std::move(config))
|
||||
{
|
||||
}
|
||||
|
||||
const Vector<FileSystemPath>& BuildBinary::get_sources() const
|
||||
{
|
||||
return m_sources;
|
||||
}
|
||||
|
||||
Status BuildBinary::populate_sources_dirs()
|
||||
{
|
||||
return Directory::getFilesWithExtension(get_directory(),
|
||||
".cpp",
|
||||
m_sources,
|
||||
true);
|
||||
}
|
||||
|
||||
Status BuildBinary::build()
|
||||
{
|
||||
for(auto target : m_dependencies)
|
||||
{
|
||||
target->build();
|
||||
}
|
||||
|
||||
if (const auto rc = compile_sources(); !rc.ok())
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (const auto rc = create_archive(); !rc.ok())
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
Status BuildBinary::configure(const BuildEnvironment& env)
|
||||
{
|
||||
if(const auto rc = BuildTarget::configure(env); !rc.ok())
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
STATUS_CHECK(populate_sources_dirs(),
|
||||
"Error collecting source files");
|
||||
|
||||
m_compiler_flags = env.get_compiler_flags();
|
||||
m_compiler_command = env.get_compiler_command();
|
||||
m_archive_command = env.get_archive_command();
|
||||
m_build_dir = env.get_build_dir();
|
||||
return {};
|
||||
}
|
||||
|
||||
Status BuildBinary::compile_sources()
|
||||
{
|
||||
for(const auto& src : m_sources)
|
||||
{
|
||||
if (const auto rc = compile_file(src); !rc.ok())
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
void BuildBinary::add_include_dirs(Vector<String>& args)
|
||||
{
|
||||
Vector<FileSystemPath> dirs;
|
||||
get_public_include_dirs(dirs);
|
||||
for(const auto& dir : dirs)
|
||||
{
|
||||
args.push_back("-I" + dir.str());
|
||||
}
|
||||
}
|
||||
|
||||
Status BuildBinary::compile_file(const FileSystemPath& source)
|
||||
{
|
||||
Vector<String> args = m_compiler_flags;
|
||||
args.push_back("-c");
|
||||
|
||||
add_include_dirs(args);
|
||||
|
||||
args.push_back(source.str());
|
||||
|
||||
const auto output_path = m_build_dir / source.file_name();
|
||||
args.push_back("-o");
|
||||
args.push_back(output_path.str() + ".o");
|
||||
LOG_INFO("Compiling " << source.file_name());
|
||||
return Process::launch(m_compiler_command, args);
|
||||
}
|
||||
|
||||
Status BuildBinary::create_archive()
|
||||
{
|
||||
Vector<String> args;
|
||||
args.push_back("rcs");
|
||||
|
||||
auto name = "lib" + get_name() + ".a";
|
||||
args.push_back(name);
|
||||
|
||||
for(const auto& src : get_sources())
|
||||
{
|
||||
const auto output_path = m_build_dir / src.file_name();
|
||||
const auto output_file = output_path.str() + ".o";
|
||||
args.push_back(output_file);
|
||||
}
|
||||
|
||||
LOG_INFO("Archiving " << name);
|
||||
return Process::launch(m_archive_command, args);
|
||||
}
|
||||
|
37
src/base/compiler/buildsystem/BuildBinary.h
Normal file
37
src/base/compiler/buildsystem/BuildBinary.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
#pragma once
|
||||
|
||||
#include "BuildTarget.h"
|
||||
|
||||
class BuildBinary : public BuildTarget
|
||||
{
|
||||
public:
|
||||
BuildBinary(BuildTargetType binary_type);
|
||||
|
||||
BuildBinary(Ptr<BuildConfig> config);
|
||||
|
||||
virtual ~BuildBinary() = default;
|
||||
|
||||
Status build() override;
|
||||
|
||||
Status configure(const BuildEnvironment& env) override;
|
||||
|
||||
const Vector<FileSystemPath>& get_sources() const;
|
||||
|
||||
private:
|
||||
void add_include_dirs(Vector<String>& args);
|
||||
|
||||
Status populate_sources_dirs();
|
||||
|
||||
Status create_archive();
|
||||
|
||||
Status compile_sources();
|
||||
|
||||
Status compile_file(const FileSystemPath& source);
|
||||
|
||||
Vector<String> m_compiler_flags;
|
||||
String m_compiler_command;
|
||||
String m_archive_command;
|
||||
FileSystemPath m_build_dir;
|
||||
Vector<String> m_public_header_dependencies;
|
||||
Vector<FileSystemPath> m_sources;
|
||||
};
|
33
src/base/compiler/buildsystem/BuildConfig.cpp
Normal file
33
src/base/compiler/buildsystem/BuildConfig.cpp
Normal file
|
@ -0,0 +1,33 @@
|
|||
#include "BuildConfig.h"
|
||||
|
||||
#include "YamlParser.h"
|
||||
|
||||
BuildConfig::BuildConfig(const FileSystemPath& path)
|
||||
: m_path(path)
|
||||
{
|
||||
}
|
||||
|
||||
Status BuildConfig::load()
|
||||
{
|
||||
YamlParser yaml_parser;
|
||||
if (const auto rc = yaml_parser.parse(m_path, m_content); !rc.ok())
|
||||
{
|
||||
return rc;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
FileSystemPath BuildConfig::get_directory() const
|
||||
{
|
||||
return m_path.parent_path();
|
||||
}
|
||||
|
||||
String BuildConfig::get_directory_name() const
|
||||
{
|
||||
return get_directory().stem().str();
|
||||
}
|
||||
|
||||
BuildTargetType BuildConfig::get_target_type() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
27
src/base/compiler/buildsystem/BuildConfig.h
Normal file
27
src/base/compiler/buildsystem/BuildConfig.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
#pragma once
|
||||
|
||||
#include "FileSystemPath.h"
|
||||
#include "YamlDocuments.h"
|
||||
#include "Error.h"
|
||||
#include "BuildTargetType.h"
|
||||
|
||||
class BuildConfig
|
||||
{
|
||||
public:
|
||||
BuildConfig() = default;
|
||||
|
||||
BuildConfig(const FileSystemPath& path);
|
||||
|
||||
Status load();
|
||||
|
||||
FileSystemPath get_directory() const;
|
||||
|
||||
String get_directory_name() const;
|
||||
|
||||
BuildTargetType get_target_type() const;
|
||||
|
||||
private:
|
||||
BuildTargetType m_type{BuildTargetType::STATIC_LIBRARY};
|
||||
YamlDocuments m_content;
|
||||
FileSystemPath m_path;
|
||||
};
|
46
src/base/compiler/buildsystem/BuildEnvironment.cpp
Normal file
46
src/base/compiler/buildsystem/BuildEnvironment.cpp
Normal file
|
@ -0,0 +1,46 @@
|
|||
#include "BuildEnvironment.h"
|
||||
|
||||
BuildEnvironment::BuildEnvironment(const FileSystemPath& source_dir,
|
||||
const FileSystemPath& build_dir)
|
||||
: m_build_dir(build_dir),
|
||||
m_source_dir(source_dir)
|
||||
{
|
||||
m_compiler_flags.push_back("-g");
|
||||
m_compiler_flags.push_back("-fno-exceptions");
|
||||
m_compiler_flags.push_back("-fno-rtti");
|
||||
}
|
||||
|
||||
const Vector<String>& BuildEnvironment::get_compiler_flags() const
|
||||
{
|
||||
return m_compiler_flags;
|
||||
}
|
||||
|
||||
const String& BuildEnvironment::get_compiler_command() const
|
||||
{
|
||||
return m_compiler_command;
|
||||
}
|
||||
|
||||
const String& BuildEnvironment::get_archive_command() const
|
||||
{
|
||||
return m_archive_command;
|
||||
}
|
||||
|
||||
const FileSystemPath& BuildEnvironment::get_build_dir() const
|
||||
{
|
||||
return m_build_dir;
|
||||
}
|
||||
|
||||
const FileSystemPath& BuildEnvironment::get_source_dir() const
|
||||
{
|
||||
return m_source_dir;
|
||||
}
|
||||
|
||||
FileSystemPath BuildEnvironment::get_test_dir() const
|
||||
{
|
||||
return m_source_dir / "test";
|
||||
}
|
||||
|
||||
void BuildEnvironment::set_build_dir(const FileSystemPath& dir)
|
||||
{
|
||||
m_build_dir = dir;
|
||||
}
|
31
src/base/compiler/buildsystem/BuildEnvironment.h
Normal file
31
src/base/compiler/buildsystem/BuildEnvironment.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
#pragma once
|
||||
|
||||
#include "Vector.h"
|
||||
#include "FileSystemPath.h"
|
||||
|
||||
class BuildEnvironment
|
||||
{
|
||||
public:
|
||||
BuildEnvironment(const FileSystemPath& source_dir, const FileSystemPath& build_dir = {});
|
||||
|
||||
const Vector<String>& get_compiler_flags() const;
|
||||
|
||||
const String& get_compiler_command() const;
|
||||
|
||||
const String& get_archive_command() const;
|
||||
|
||||
const FileSystemPath& get_build_dir() const;
|
||||
|
||||
const FileSystemPath& get_source_dir() const;
|
||||
|
||||
FileSystemPath get_test_dir() const;
|
||||
|
||||
void set_build_dir(const FileSystemPath& dir);
|
||||
|
||||
private:
|
||||
String m_compiler_command{"/usr/bin/g++"};
|
||||
String m_archive_command{"/usr/bin/ar"};
|
||||
Vector<String> m_compiler_flags;
|
||||
FileSystemPath m_build_dir;
|
||||
FileSystemPath m_source_dir;
|
||||
};
|
6
src/base/compiler/buildsystem/BuildExecutable.cpp
Normal file
6
src/base/compiler/buildsystem/BuildExecutable.cpp
Normal file
|
@ -0,0 +1,6 @@
|
|||
#include "BuildExecutable.h"
|
||||
|
||||
BuildExecutable::BuildExecutable(Ptr<BuildConfig> config)
|
||||
: BuildBinary(std::move(config))
|
||||
{
|
||||
}
|
13
src/base/compiler/buildsystem/BuildExecutable.h
Normal file
13
src/base/compiler/buildsystem/BuildExecutable.h
Normal file
|
@ -0,0 +1,13 @@
|
|||
#pragma once
|
||||
|
||||
#include "BuildBinary.h"
|
||||
|
||||
class BuildExecutable : public BuildBinary
|
||||
{
|
||||
public:
|
||||
BuildExecutable() = default;
|
||||
|
||||
BuildExecutable(Ptr<BuildConfig> config);
|
||||
|
||||
virtual ~BuildExecutable() = default;
|
||||
};
|
17
src/base/compiler/buildsystem/BuildLibrary.cpp
Normal file
17
src/base/compiler/buildsystem/BuildLibrary.cpp
Normal file
|
@ -0,0 +1,17 @@
|
|||
#include "BuildLibrary.h"
|
||||
|
||||
BuildLibrary::BuildLibrary(BuildTargetType lib_type)
|
||||
: BuildBinary(lib_type)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
BuildLibrary::BuildLibrary(Ptr<BuildConfig> config)
|
||||
: BuildBinary(std::move(config))
|
||||
{
|
||||
}
|
||||
|
||||
Status BuildLibrary::build()
|
||||
{
|
||||
return BuildBinary::build();
|
||||
}
|
15
src/base/compiler/buildsystem/BuildLibrary.h
Normal file
15
src/base/compiler/buildsystem/BuildLibrary.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
#pragma once
|
||||
|
||||
#include "BuildBinary.h"
|
||||
|
||||
class BuildLibrary : public BuildBinary
|
||||
{
|
||||
public:
|
||||
BuildLibrary(BuildTargetType lib_type);
|
||||
|
||||
BuildLibrary(Ptr<BuildConfig> config);
|
||||
|
||||
virtual ~BuildLibrary() = default;
|
||||
|
||||
Status build() override;
|
||||
};
|
86
src/base/compiler/buildsystem/BuildSession.cpp
Normal file
86
src/base/compiler/buildsystem/BuildSession.cpp
Normal file
|
@ -0,0 +1,86 @@
|
|||
#include "BuildSession.h"
|
||||
|
||||
#include "Logger.h"
|
||||
#include "Directory.h"
|
||||
|
||||
BuildSession::BuildSession(const FileSystemPath& source_dir,
|
||||
const FileSystemPath& build_dir)
|
||||
: m_build_environment(source_dir)
|
||||
{
|
||||
auto working_build_dir = build_dir;
|
||||
if (working_build_dir.is_empty().value())
|
||||
{
|
||||
working_build_dir = FileSystemPath::current_dir().value();
|
||||
}
|
||||
m_build_environment.set_build_dir(working_build_dir / "build");
|
||||
}
|
||||
|
||||
Status BuildSession::configure()
|
||||
{
|
||||
LOG_INFO("Configuring project at:" << m_build_environment.get_source_dir());
|
||||
Vector<FileSystemPath> yaml_files;
|
||||
STATUS_CHECK(Directory::getFilesWithExtension(
|
||||
m_build_environment.get_source_dir(),
|
||||
".yaml",
|
||||
yaml_files,
|
||||
true), "Error looking for build files");
|
||||
for(const auto& yaml_file : yaml_files)
|
||||
{
|
||||
if (yaml_file.file_name() == "build")
|
||||
{
|
||||
STATUS_CHECK(add_target(yaml_file),
|
||||
"Error adding target at: " + yaml_file.stem().str());
|
||||
}
|
||||
}
|
||||
return configure_tests();
|
||||
}
|
||||
|
||||
Status BuildSession::add_target(const FileSystemPath& config_path)
|
||||
{
|
||||
LOG_INFO("Adding target at: " << config_path);
|
||||
auto target = BuildTarget::create(config_path);
|
||||
STATUS_CHECK(target->configure(m_build_environment), "Error configuring target");
|
||||
m_targets.push_back(std::move(target));
|
||||
return {};
|
||||
}
|
||||
|
||||
Status BuildSession::configure_tests()
|
||||
{
|
||||
const auto test_dir = m_build_environment.get_test_dir();
|
||||
LOG_INFO("Scanning test files at:" << test_dir);
|
||||
Vector<FileSystemPath> candidate_test_files;
|
||||
STATUS_CHECK(Directory::getFilesWithExtension(
|
||||
test_dir,
|
||||
".cpp",
|
||||
candidate_test_files,
|
||||
true), "Error looking for test files");
|
||||
|
||||
Vector<FileSystemPath> test_files;
|
||||
for(const auto& test_file : candidate_test_files)
|
||||
{
|
||||
if (test_file.stem().starts_with("Test"))
|
||||
{
|
||||
if (test_file.contains("core"))
|
||||
{
|
||||
LOG_INFO("Adding " << test_file);
|
||||
test_files.push_back(test_file);
|
||||
}
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
Status BuildSession::build()
|
||||
{
|
||||
LOG_INFO("Starting build at: " << m_build_environment.get_build_dir());
|
||||
Directory::create(m_build_environment.get_build_dir(), true);
|
||||
for(auto& target : m_targets)
|
||||
{
|
||||
auto run_status = target->build();
|
||||
if (!run_status.ok())
|
||||
{
|
||||
return run_status;
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
26
src/base/compiler/buildsystem/BuildSession.h
Normal file
26
src/base/compiler/buildsystem/BuildSession.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
#pragma once
|
||||
|
||||
#include "BuildEnvironment.h"
|
||||
#include "BuildTarget.h"
|
||||
#include "FileSystemPath.h"
|
||||
#include "Error.h"
|
||||
#include "Pointer.h"
|
||||
|
||||
class BuildSession
|
||||
{
|
||||
public:
|
||||
BuildSession(const FileSystemPath& source_dir,
|
||||
const FileSystemPath& build_dir = {});
|
||||
|
||||
Status build();
|
||||
|
||||
Status configure();
|
||||
|
||||
private:
|
||||
Status add_target(const FileSystemPath& config_path);
|
||||
|
||||
Status configure_tests();
|
||||
|
||||
BuildEnvironment m_build_environment;
|
||||
Vector<Ptr<BuildTarget> > m_targets;
|
||||
};
|
105
src/base/compiler/buildsystem/BuildTarget.cpp
Normal file
105
src/base/compiler/buildsystem/BuildTarget.cpp
Normal file
|
@ -0,0 +1,105 @@
|
|||
#include "BuildTarget.h"
|
||||
|
||||
#include "Logger.h"
|
||||
#include "Directory.h"
|
||||
#include "YamlParser.h"
|
||||
|
||||
#include "BuildLibrary.h"
|
||||
#include "BuildExecutable.h"
|
||||
|
||||
Ptr<BuildTarget> BuildTarget::create(const FileSystemPath& build_config_path)
|
||||
{
|
||||
auto build_config = Ptr<BuildConfig>::create(build_config_path);
|
||||
build_config->load();
|
||||
auto build_type = build_config->get_target_type();
|
||||
if (build_type == BuildTargetType::SHARED_LIBRARY || build_type == BuildTargetType::SHARED_LIBRARY)
|
||||
{
|
||||
Ptr<BuildTarget> target_type;
|
||||
target_type = Ptr<BuildLibrary>::create(std::move(build_config));
|
||||
return std::move(target_type);
|
||||
}
|
||||
else
|
||||
{
|
||||
Ptr<BuildTarget> target_type;
|
||||
target_type = Ptr<BuildExecutable>::create(std::move(build_config));
|
||||
return std::move(target_type);
|
||||
}
|
||||
}
|
||||
|
||||
BuildTarget::BuildTarget(BuildTargetType target_type)
|
||||
: m_type(target_type)
|
||||
{
|
||||
}
|
||||
|
||||
BuildTarget::BuildTarget(Ptr<BuildConfig> config)
|
||||
: m_build_config(std::move(config)),
|
||||
m_type(m_build_config->get_target_type())
|
||||
{
|
||||
}
|
||||
|
||||
void BuildTarget::add_dependency(BuildTarget* dependency)
|
||||
{
|
||||
m_dependencies.push_back(dependency);
|
||||
}
|
||||
|
||||
BuildTargetType BuildTarget::get_type() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
const Vector<BuildTarget*>& BuildTarget::get_dependencies() const
|
||||
{
|
||||
return m_dependencies;
|
||||
}
|
||||
|
||||
const Vector<String>& BuildTarget::get_dependency_names() const
|
||||
{
|
||||
return m_dependency_names;
|
||||
}
|
||||
|
||||
const String& BuildTarget::get_name() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
void BuildTarget::get_public_include_dirs(Vector<FileSystemPath>& dirs) const
|
||||
{
|
||||
dirs.extend(m_include_dirs);
|
||||
for(auto target : m_dependencies)
|
||||
{
|
||||
target->get_public_include_dirs(dirs);
|
||||
}
|
||||
}
|
||||
|
||||
Status BuildTarget::load_config()
|
||||
{
|
||||
STATUS_CHECK(m_build_config->load(), "Failed to load build config.");
|
||||
m_name = m_build_config->get_directory_name();
|
||||
return {};
|
||||
}
|
||||
|
||||
FileSystemPath BuildTarget::get_directory() const
|
||||
{
|
||||
return m_build_config->get_directory();
|
||||
}
|
||||
|
||||
Status BuildTarget::populate_include_dirs()
|
||||
{
|
||||
const auto search_dir = get_directory();
|
||||
m_include_dirs.push_back(search_dir);
|
||||
return Directory::getAllSubDirectories(search_dir, m_include_dirs);
|
||||
}
|
||||
|
||||
Status BuildTarget::configure(const BuildEnvironment& env)
|
||||
{
|
||||
for(auto target : m_dependencies)
|
||||
{
|
||||
target->configure(env);
|
||||
}
|
||||
|
||||
const auto search_dir = get_directory();
|
||||
LOG_INFO("Scanning build file at: " << search_dir);
|
||||
|
||||
STATUS_CHECK(populate_include_dirs(), "Error populating include dirs");
|
||||
return {};
|
||||
}
|
52
src/base/compiler/buildsystem/BuildTarget.h
Normal file
52
src/base/compiler/buildsystem/BuildTarget.h
Normal file
|
@ -0,0 +1,52 @@
|
|||
#pragma once
|
||||
|
||||
#include "BuildConfig.h"
|
||||
#include "FileSystemPath.h"
|
||||
#include "String.h"
|
||||
#include "Vector.h"
|
||||
|
||||
#include "BuildEnvironment.h"
|
||||
|
||||
class BuildTarget
|
||||
{
|
||||
public:
|
||||
BuildTarget(BuildTargetType target_type);
|
||||
|
||||
BuildTarget(Ptr<BuildConfig> config);
|
||||
|
||||
static Ptr<BuildTarget> create(const FileSystemPath& build_config_path);
|
||||
|
||||
virtual ~BuildTarget() = default;
|
||||
|
||||
virtual Status build() = 0;
|
||||
|
||||
void add_dependency(BuildTarget* dependency);
|
||||
|
||||
virtual Status configure(const BuildEnvironment& env);
|
||||
|
||||
BuildTargetType get_type() const;
|
||||
|
||||
void get_public_include_dirs(Vector<FileSystemPath>& dirs) const;
|
||||
|
||||
const String& get_name() const;
|
||||
|
||||
const Vector<BuildTarget*>& get_dependencies() const;
|
||||
|
||||
const Vector<String>& get_dependency_names() const;
|
||||
|
||||
protected:
|
||||
FileSystemPath get_directory() const;
|
||||
|
||||
Vector<BuildTarget*> m_dependencies;
|
||||
|
||||
private:
|
||||
Status populate_include_dirs();
|
||||
|
||||
Status load_config();
|
||||
|
||||
Vector<String> m_dependency_names;
|
||||
Ptr<BuildConfig> m_build_config;
|
||||
Vector<FileSystemPath> m_include_dirs;
|
||||
String m_name;
|
||||
BuildTargetType m_type{BuildTargetType::UNSET};
|
||||
};
|
9
src/base/compiler/buildsystem/BuildTargetType.h
Normal file
9
src/base/compiler/buildsystem/BuildTargetType.h
Normal file
|
@ -0,0 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
enum class BuildTargetType
|
||||
{
|
||||
UNSET,
|
||||
SHARED_LIBRARY,
|
||||
STATIC_LIBRARY,
|
||||
EXECUTABLE
|
||||
};
|
|
@ -1,27 +0,0 @@
|
|||
set(MODULE_NAME compression)
|
||||
|
||||
list(APPEND SOURCES
|
||||
StreamCompressor.cpp
|
||||
huffman/HuffmanEncoder.cpp
|
||||
huffman/HuffmanStream.cpp
|
||||
huffman/HuffmanCodeLengthTable.cpp
|
||||
huffman/HuffmanTree.cpp
|
||||
RunLengthEncoder.cpp
|
||||
ZlibEncoder.cpp
|
||||
deflate/DeflateEncoder.cpp
|
||||
deflate/DeflateBlock.cpp
|
||||
Lz77Encoder.cpp
|
||||
CyclicRedundancyChecker.cpp
|
||||
)
|
||||
|
||||
add_library(${MODULE_NAME} SHARED ${SOURCES})
|
||||
|
||||
target_include_directories(${MODULE_NAME} PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/deflate
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/huffman
|
||||
)
|
||||
|
||||
target_link_libraries(${MODULE_NAME} PUBLIC core)
|
||||
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER src/base)
|
||||
set_target_properties( ${MODULE_NAME} PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON )
|
|
@ -47,4 +47,16 @@ const Error& Status::error() const
|
|||
bool Status::ok() const
|
||||
{
|
||||
return m_ok;
|
||||
}
|
||||
|
||||
String Status::str() const
|
||||
{
|
||||
if (!m_ok)
|
||||
{
|
||||
return m_error.msg();
|
||||
}
|
||||
else
|
||||
{
|
||||
return {};
|
||||
}
|
||||
}
|
|
@ -48,14 +48,16 @@ public:
|
|||
|
||||
Status(const Error& err);
|
||||
|
||||
const Error& error() const;
|
||||
|
||||
static Status with_errno(const String& prefix_msg);
|
||||
|
||||
void on_errno(const String& prefix_msg);
|
||||
|
||||
const Error& error() const;
|
||||
|
||||
bool ok() const;
|
||||
|
||||
String str() const;
|
||||
|
||||
private:
|
||||
Error m_error;
|
||||
bool m_ok{true};
|
||||
|
|
|
@ -25,6 +25,37 @@ String::String(const char* data)
|
|||
append(data);
|
||||
}
|
||||
|
||||
bool String::contains(const String& term) const
|
||||
{
|
||||
if (empty() || term.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (term.size() > size())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t match_idx{0};
|
||||
for(std::size_t idx=0; idx<size();idx++)
|
||||
{
|
||||
if (term[match_idx] == m_data[idx])
|
||||
{
|
||||
match_idx++;
|
||||
if (match_idx == term.size())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
match_idx = 0;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
String String::fmt(const char* fmt, ...)
|
||||
{
|
||||
String ret;
|
||||
|
@ -297,6 +328,26 @@ void String::split(Vector<String>& output, char delimiter) const
|
|||
}
|
||||
}
|
||||
|
||||
bool String::starts_with(const String& prefix) const
|
||||
{
|
||||
if (size() < prefix.size())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (prefix.empty() && (!empty()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
for(size_t idx=0; idx<prefix.size();idx++)
|
||||
{
|
||||
if (prefix[idx] != m_data[idx])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
String String::to_string(size_t input)
|
||||
{
|
||||
String conv;
|
||||
|
|
|
@ -22,6 +22,8 @@ public:
|
|||
|
||||
void append(const Vector<Byte>& data);
|
||||
|
||||
bool contains(const String& term) const;
|
||||
|
||||
const Vector<char>& data() const;
|
||||
|
||||
bool empty() const;
|
||||
|
@ -51,6 +53,8 @@ public:
|
|||
|
||||
void split(Vector<String>& output, char delimiter = ' ') const;
|
||||
|
||||
bool starts_with(const String& prefix) const;
|
||||
|
||||
static String to_string(size_t input);
|
||||
|
||||
void to_bytes(Vector<Byte>& bytes) const;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "Stream.h"
|
||||
#include "IOStream.h"
|
||||
#include "Byte.h"
|
||||
#include "Error.h"
|
||||
|
||||
|
|
|
@ -14,6 +14,12 @@ FileSystemPath::FileSystemPath(const String& path)
|
|||
{
|
||||
}
|
||||
|
||||
FileSystemPath::FileSystemPath(const char* path)
|
||||
: m_path(path)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
const String& FileSystemPath::str() const
|
||||
{
|
||||
return m_path;
|
||||
|
@ -139,6 +145,16 @@ FileSystemPath FileSystemPath::stem() const
|
|||
}
|
||||
}
|
||||
|
||||
bool FileSystemPath::starts_with(const String& prefix) const
|
||||
{
|
||||
return m_path.starts_with(prefix);
|
||||
}
|
||||
|
||||
bool FileSystemPath::contains(const String& term) const
|
||||
{
|
||||
return m_path.contains(term);
|
||||
}
|
||||
|
||||
String FileSystemPath::file_name() const
|
||||
{
|
||||
String name_and_ext;
|
||||
|
|
|
@ -10,6 +10,8 @@ public:
|
|||
|
||||
FileSystemPath(const String& path);
|
||||
|
||||
FileSystemPath(const char* path);
|
||||
|
||||
const String& str() const;
|
||||
|
||||
static Result<FileSystemPath> current_dir();
|
||||
|
@ -38,6 +40,10 @@ public:
|
|||
|
||||
FileSystemPath stem() const;
|
||||
|
||||
bool contains(const String& term) const;
|
||||
|
||||
bool starts_with(const String& prefix) const;
|
||||
|
||||
FileSystemPath operator/ (const char* body) const
|
||||
{
|
||||
String ret = m_path;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "FileSystemPath.h"
|
||||
#include "Stream.h"
|
||||
#include "IOStream.h"
|
||||
#include "JsonDocument.h"
|
||||
|
||||
class JsonParser
|
||||
|
|
|
@ -1,6 +1,14 @@
|
|||
#pragma once
|
||||
|
||||
#include "Dictionary.h"
|
||||
#include "Pointer.h"
|
||||
|
||||
class YamlDocument
|
||||
{
|
||||
public:
|
||||
YamlDocument()
|
||||
{
|
||||
}
|
||||
|
||||
Ptr<Dictionary> m_root;
|
||||
};
|
11
src/base/core/serialization/yaml/YamlDocuments.cpp
Normal file
11
src/base/core/serialization/yaml/YamlDocuments.cpp
Normal file
|
@ -0,0 +1,11 @@
|
|||
#include "YamlDocuments.h"
|
||||
|
||||
void YamlDocuments::add_document(Ptr<YamlDocument> doc)
|
||||
{
|
||||
m_documents.push_back(std::move(doc));
|
||||
}
|
||||
|
||||
const Vector<Ptr<YamlDocument> >& YamlDocuments::get_documents() const
|
||||
{
|
||||
return m_documents;
|
||||
}
|
17
src/base/core/serialization/yaml/YamlDocuments.h
Normal file
17
src/base/core/serialization/yaml/YamlDocuments.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
#pragma once
|
||||
|
||||
#include "Vector.h"
|
||||
#include "Pointer.h"
|
||||
#include "YamlDocument.h"
|
||||
|
||||
class YamlDocuments
|
||||
{
|
||||
public:
|
||||
|
||||
void add_document(Ptr<YamlDocument> doc);
|
||||
|
||||
const Vector<Ptr<YamlDocument> >& get_documents() const;
|
||||
|
||||
private:
|
||||
Vector<Ptr<YamlDocument> > m_documents;
|
||||
};
|
|
@ -0,0 +1,14 @@
|
|||
#include "YamlParser.h"
|
||||
|
||||
#include "FileStream.h"
|
||||
|
||||
Status YamlParser::parse(const FileSystemPath& path, YamlDocuments& result)
|
||||
{
|
||||
InputFileStream f(path);
|
||||
return parse(f, result);
|
||||
}
|
||||
|
||||
Status YamlParser::parse(InputStream<Byte>& input, YamlDocuments& result)
|
||||
{
|
||||
return {};
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
#pragma once
|
||||
|
||||
#include "IOStream.h"
|
||||
#include "YamlDocuments.h"
|
||||
#include "FileSystemPath.h"
|
||||
|
||||
class YamlParser
|
||||
{
|
||||
public:
|
||||
Status parse(const FileSystemPath& path, YamlDocuments& result);
|
||||
|
||||
Status parse(InputStream<Byte>& input, YamlDocuments& result);
|
||||
};
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
#include "Bits.h"
|
||||
|
||||
Optional<Byte> BinaryStream::getNextByte(InputStream<Byte>& stream)
|
||||
bool BinaryStream::getNextByte(InputStream<Byte>& stream, Byte& ret)
|
||||
{
|
||||
return stream.get();
|
||||
return stream.get(ret);
|
||||
}
|
||||
|
||||
bool BinaryStream::getNextNBytes(InputStream<Byte>& stream, Byte* buffer, size_t number)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "Stream.h"
|
||||
#include "IOStream.h"
|
||||
#include "String.h"
|
||||
#include "Optional.h"
|
||||
#include "Byte.h"
|
||||
|
@ -8,7 +8,6 @@
|
|||
class BinaryStream
|
||||
{
|
||||
public:
|
||||
|
||||
template<typename T>
|
||||
static bool write(OutputStream<Byte>* stream, T data)
|
||||
{
|
||||
|
@ -16,7 +15,7 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
static Optional<Byte> getNextByte(InputStream<Byte>& stream);
|
||||
static bool getNextByte(InputStream<Byte>& stream, Byte& ret);
|
||||
|
||||
static bool getNextNBytes(InputStream<Byte>& stream, Byte* buffer, size_t numBytes);
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "Stream.h"
|
||||
#include "IOStream.h"
|
||||
#include "String.h"
|
||||
|
||||
using OutputByteStream = OutputByteStream<Byte>;
|
||||
|
|
58
src/base/core/streams/FileStream.cpp
Normal file
58
src/base/core/streams/FileStream.cpp
Normal file
|
@ -0,0 +1,58 @@
|
|||
#include "FileStream.h"
|
||||
|
||||
InputFileStream::InputFileStream(const FileSystemPath& path)
|
||||
: m_file(path),
|
||||
m_buffer(Vector<Byte>(m_buffer_size))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool InputFileStream::finished() const
|
||||
{
|
||||
return m_end_of_stream == true;
|
||||
}
|
||||
|
||||
bool InputFileStream::get(Byte& item)
|
||||
{
|
||||
if (m_buffer_offset >= m_buffer_current_size)
|
||||
{
|
||||
if (m_end_of_file)
|
||||
{
|
||||
m_end_of_stream = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_buffer_offset = 0;
|
||||
if (const auto rc = m_file.read(m_buffer); !rc.ok())
|
||||
{
|
||||
on_error(rc);
|
||||
return false;
|
||||
}
|
||||
m_buffer_current_size = m_buffer.size();
|
||||
if (m_buffer_current_size < m_buffer_size)
|
||||
{
|
||||
m_end_of_file = true;
|
||||
}
|
||||
if (m_buffer_current_size == 0)
|
||||
{
|
||||
m_end_of_stream = true;
|
||||
return false;
|
||||
}
|
||||
item = m_buffer[m_buffer_offset];
|
||||
m_buffer_offset++;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
item = m_buffer[m_buffer_offset];
|
||||
m_buffer_offset++;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool InputFileStream::good() const
|
||||
{
|
||||
return !m_end_of_stream && Stream::good();
|
||||
}
|
||||
|
||||
|
|
@ -1,32 +1,29 @@
|
|||
#pragma once
|
||||
|
||||
#include "Byte.h"
|
||||
#include "Stream.h"
|
||||
#include "IOStream.h"
|
||||
#include "FileSystemPath.h"
|
||||
#include "File.h"
|
||||
#include "Vector.h"
|
||||
|
||||
class InputFileStream : public InputStream<Byte>
|
||||
{
|
||||
public:
|
||||
InputFileStream(const FileSystemPath& path)
|
||||
: File(path)
|
||||
{
|
||||
InputFileStream(const FileSystemPath& path);
|
||||
|
||||
}
|
||||
bool finished() const;
|
||||
|
||||
bool good() const override
|
||||
{
|
||||
return
|
||||
}
|
||||
bool good() const override;
|
||||
|
||||
bool get(T& item) = 0;
|
||||
bool get(Byte& item);
|
||||
|
||||
private:
|
||||
void finished()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
File mFile;
|
||||
File m_file;
|
||||
bool m_end_of_file{false};
|
||||
bool m_end_of_stream{false};
|
||||
size_t m_buffer_offset{0};
|
||||
size_t m_buffer_current_size{0};
|
||||
size_t m_buffer_size{4096};
|
||||
Vector<Byte> m_buffer;
|
||||
Status mStatus;
|
||||
};
|
41
src/base/core/streams/IOStream.h
Normal file
41
src/base/core/streams/IOStream.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
#pragma once
|
||||
|
||||
#include "Vector.h"
|
||||
#include "Stream.h"
|
||||
|
||||
template<typename T>
|
||||
class InputStream : public Stream
|
||||
{
|
||||
public:
|
||||
virtual bool get(T& item) = 0;
|
||||
|
||||
virtual int get(Vector<T>& items)
|
||||
{
|
||||
size_t count = 0;
|
||||
T item;
|
||||
while(good() && count < items.size())
|
||||
{
|
||||
if (const auto ok = get(item); !ok)
|
||||
{
|
||||
break;
|
||||
}
|
||||
items[count] = item;
|
||||
count++;
|
||||
}
|
||||
if (has_error())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return count;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class OutputStream : public Stream
|
||||
{
|
||||
public:
|
||||
virtual int write(T* data, size_t size) = 0;
|
||||
};
|
|
@ -20,8 +20,7 @@ bool InputBitStream::readNextByte(Byte& buffer)
|
|||
{
|
||||
if (mStream->good())
|
||||
{
|
||||
buffer = static_cast<Byte>(mStream->get());
|
||||
return true;
|
||||
return mStream->get(buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "BitStream.h"
|
||||
#include "Stream.h"
|
||||
#include "IOStream.h"
|
||||
#include "Byte.h"
|
||||
|
||||
class InputBitStream : public BitStream
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "BitStream.h"
|
||||
#include "Stream.h"
|
||||
#include "IOStream.h"
|
||||
#include "Byte.h"
|
||||
|
||||
class OutputBitStream : public BitStream
|
||||
|
|
23
src/base/core/streams/Stream.cpp
Normal file
23
src/base/core/streams/Stream.cpp
Normal file
|
@ -0,0 +1,23 @@
|
|||
#include "Stream.h"
|
||||
|
||||
bool Stream::good() const
|
||||
{
|
||||
return m_has_error;
|
||||
}
|
||||
|
||||
const Status& Stream::get_last_error() const
|
||||
{
|
||||
return m_last_error;
|
||||
}
|
||||
|
||||
void Stream::on_error(const String& msg)
|
||||
{
|
||||
m_has_error = true;
|
||||
m_last_error = Status(Error(msg));
|
||||
}
|
||||
|
||||
void Stream::on_error(const Status& status)
|
||||
{
|
||||
m_has_error = true;
|
||||
m_last_error = status;
|
||||
}
|
|
@ -1,34 +1,25 @@
|
|||
#pragma once
|
||||
|
||||
#include "Optional.h"
|
||||
#include <cstddef>
|
||||
#include "Error.h"
|
||||
|
||||
template<typename T>
|
||||
class Stream
|
||||
{
|
||||
public:
|
||||
virtual bool good() const = 0;
|
||||
};
|
||||
const Status& get_last_error() const;
|
||||
|
||||
template<typename T>
|
||||
class InputStream : public Stream<T>
|
||||
{
|
||||
public:
|
||||
Optional<T> get()
|
||||
virtual bool good() const;
|
||||
|
||||
bool has_error() const
|
||||
{
|
||||
T item;
|
||||
if (get(item))
|
||||
{
|
||||
return {item};
|
||||
}
|
||||
return {};
|
||||
return m_has_error;
|
||||
}
|
||||
virtual bool get(T& item) = 0;
|
||||
|
||||
protected:
|
||||
void on_error(const String& msg);
|
||||
|
||||
void on_error(const Status& status);
|
||||
|
||||
bool m_has_error{false};
|
||||
Status m_last_error;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class OutputStream : public Stream<T>
|
||||
{
|
||||
public:
|
||||
virtual void write(T* data, size_t size) = 0;
|
||||
};
|
32
src/base/core/streams/StringStream.cpp
Normal file
32
src/base/core/streams/StringStream.cpp
Normal file
|
@ -0,0 +1,32 @@
|
|||
#include "StringStream.h"
|
||||
|
||||
StringStream::StringStream(const String& str)
|
||||
{
|
||||
str.to_bytes(m_buffer);
|
||||
}
|
||||
|
||||
bool StringStream::finished() const
|
||||
{
|
||||
return m_end_of_stream;
|
||||
}
|
||||
|
||||
bool StringStream::good() const
|
||||
{
|
||||
return !m_end_of_stream && InputStream<Byte>::good();
|
||||
}
|
||||
|
||||
bool StringStream::get(Byte& item)
|
||||
{
|
||||
if (m_end_of_stream)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (m_offset >= m_buffer.size())
|
||||
{
|
||||
m_end_of_stream = true;
|
||||
return false;
|
||||
}
|
||||
item = m_buffer[m_offset];
|
||||
m_offset++;
|
||||
return true;
|
||||
}
|
21
src/base/core/streams/StringStream.h
Normal file
21
src/base/core/streams/StringStream.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
#pragma once
|
||||
|
||||
#include "IOStream.h"
|
||||
#include "String.h"
|
||||
|
||||
class StringStream : public InputStream<Byte>
|
||||
{
|
||||
public:
|
||||
StringStream(const String& str);
|
||||
|
||||
bool finished() const;
|
||||
|
||||
bool good() const override;
|
||||
|
||||
bool get(Byte& item);
|
||||
|
||||
private:
|
||||
bool m_end_of_stream{false};
|
||||
size_t m_offset{0};
|
||||
VecBytes m_buffer;
|
||||
};
|
16
src/main.cpp
16
src/main.cpp
|
@ -1,26 +1,26 @@
|
|||
#include "BuildSession.h"
|
||||
#include "ConsoleLogger.h"
|
||||
#include "FileSystemPath.h"
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
if (argc == 1)
|
||||
if (argc <= 1)
|
||||
{
|
||||
LOG_ERROR("Missing arg with path to source dir");
|
||||
return -1;
|
||||
}
|
||||
|
||||
BuildSession build(argv[1]);
|
||||
const auto scan_status = build.scan();
|
||||
if (!scan_status.ok())
|
||||
FileSystemPath source_path(argv[1]);
|
||||
BuildSession build(source_path);
|
||||
if (const auto rc = build.configure(); !rc.ok())
|
||||
{
|
||||
LOG_ERROR("Scan failed with " << scan_status.error().msg());
|
||||
LOG_ERROR("Configure failed with " << rc);
|
||||
return -1;
|
||||
}
|
||||
|
||||
const auto build_status = build.build();
|
||||
if (!build_status.ok())
|
||||
if (const auto rc = build.build(); !rc.ok())
|
||||
{
|
||||
LOG_ERROR("Build failed with " << build_status.error().msg());
|
||||
LOG_ERROR("Build failed with " << rc);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -8,14 +8,21 @@ g++ $SCRIPT_DIR/test_runner.cpp \
|
|||
$CORE_SRC_DIR/base_types/Index.cpp \
|
||||
$CORE_SRC_DIR/base_types/Char.cpp \
|
||||
$CORE_SRC_DIR/data_structures/String.cpp \
|
||||
$CORE_SRC_DIR/filesystem/File.cpp \
|
||||
$CORE_SRC_DIR/filesystem/FileSystemPath.cpp \
|
||||
$CORE_SRC_DIR/logging/Logger.cpp \
|
||||
$CORE_SRC_DIR/logging/ConsoleLogger.cpp \
|
||||
$CORE_SRC_DIR/serialization/yaml/YamlDocument.cpp \
|
||||
$CORE_SRC_DIR/serialization/yaml/YamlDocuments.cpp \
|
||||
$CORE_SRC_DIR/serialization/yaml/YamlParser.cpp \
|
||||
$CORE_SRC_DIR/streams/Stream.cpp \
|
||||
$CORE_SRC_DIR/streams/StringStream.cpp \
|
||||
$CORE_SRC_DIR/time/Time.cpp \
|
||||
$SCRIPT_DIR/test_utils/TestCaseRunner.cpp \
|
||||
$SCRIPT_DIR/core/TestFileSystemPath.cpp \
|
||||
$SCRIPT_DIR/core/TestString.cpp \
|
||||
$SCRIPT_DIR/core/TestVector.cpp \
|
||||
$SCRIPT_DIR/core/TestYamlParser.cpp \
|
||||
-o test_runner -g \
|
||||
-I$SCRIPT_DIR/test_utils \
|
||||
-I$CORE_SRC_DIR \
|
||||
|
@ -24,6 +31,8 @@ g++ $SCRIPT_DIR/test_runner.cpp \
|
|||
-I$CORE_SRC_DIR/data_structures \
|
||||
-I$CORE_SRC_DIR/base_types \
|
||||
-I$CORE_SRC_DIR/memory \
|
||||
-I$CORE_SRC_DIR/time \
|
||||
-I$CORE_SRC_DIR/system/process \
|
||||
-I$CORE_SRC_DIR/streams \
|
||||
-I$CORE_SRC_DIR/serialization/yaml \
|
||||
-I$CORE_SRC_DIR/time \
|
||||
-I$CORE_SRC_DIR/filesystem
|
|
@ -1,13 +0,0 @@
|
|||
include(TestTargets)
|
||||
|
||||
unit_tests(
|
||||
MODULE_NAME core
|
||||
FILES
|
||||
TestBits.cpp
|
||||
TestBitStream.cpp
|
||||
TestDataStructures.cpp
|
||||
TestTomlReader.cpp
|
||||
TestStringUtils.cpp
|
||||
DEPENDENCIES
|
||||
core
|
||||
)
|
|
@ -2,8 +2,6 @@
|
|||
|
||||
#include "TestFramework.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
TEST_CASE(TestVectorExtend, "core")
|
||||
{
|
||||
Vector<size_t> vec;
|
||||
|
|
19
test/core/TestYamlParser.cpp
Normal file
19
test/core/TestYamlParser.cpp
Normal file
|
@ -0,0 +1,19 @@
|
|||
#include "TestFramework.h"
|
||||
|
||||
#include "YamlParser.h"
|
||||
#include "StringStream.h"
|
||||
|
||||
TEST_CASE(TestYamlParser, "core")
|
||||
{
|
||||
const auto content = R"(depends:
|
||||
headers:
|
||||
public:
|
||||
- core)";
|
||||
|
||||
StringStream stream(content);
|
||||
|
||||
YamlDocuments yaml_docs;
|
||||
YamlParser parser;
|
||||
const auto status = parser.parse(stream, yaml_docs);
|
||||
REQUIRE(status.ok());
|
||||
}
|
Loading…
Reference in a new issue