stuff-from-scratch/src/base/compiler/buildsystem/BuildBinary.cpp
2024-01-28 16:28:16 +00:00

121 lines
2.6 KiB
C++

#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);
}