Browse Source

`compile_file_plan` cleanup

default_compile_flags
vector-of-bool 5 years ago
parent
commit
748fc75429
2 changed files with 70 additions and 13 deletions
  1. +3
    -1
      src/dds/build/plan/compile_file.cpp
  2. +67
    -12
      src/dds/build/plan/compile_file.hpp

+ 3
- 1
src/dds/build/plan/compile_file.cpp View File

} }


fs::path compile_file_plan::calc_object_file_path(const build_env& env) const noexcept { fs::path compile_file_plan::calc_object_file_path(const build_env& env) const noexcept {
// `relpath` is just the path from the root of the source directory to the source file.
auto relpath = fs::relative(_source.path, _source.basis_path); auto relpath = fs::relative(_source.path, _source.basis_path);
auto ret = env.output_root / _subdir / relpath;
// The full output directory is prefixed by `_subdir`
auto ret = env.output_root / _subdir / relpath;
ret.replace_filename(relpath.filename().string() + env.toolchain.object_suffix()); ret.replace_filename(relpath.filename().string() + env.toolchain.object_suffix());
return fs::weakly_canonical(ret); return fs::weakly_canonical(ret);
} }

+ 67
- 12
src/dds/build/plan/compile_file.hpp View File



namespace dds { namespace dds {


/**
* Exception thrown to indicate a compile failure
*/
struct compile_failure : std::runtime_error { struct compile_failure : std::runtime_error {
using runtime_error::runtime_error; using runtime_error::runtime_error;
}; };


/**
* Because we may have many files in a library, we store base file compilation
* parameters in a single object that implements shared semantics. Copying the
* object is cheap, and updates propagate between all copies. Distinct copies
* can be made via the `clone()` method.
*/
class shared_compile_file_rules { class shared_compile_file_rules {
/// The attributes we track
struct rules_impl { struct rules_impl {
std::vector<fs::path> inc_dirs; std::vector<fs::path> inc_dirs;
std::vector<std::string> defs; std::vector<std::string> defs;
bool enable_warnings = false; bool enable_warnings = false;
}; };


/// The actual PIMPL.
std::shared_ptr<rules_impl> _impl = std::make_shared<rules_impl>(); std::shared_ptr<rules_impl> _impl = std::make_shared<rules_impl>();


public: public:
shared_compile_file_rules() = default;

/**
* Create a detached copy of these rules. Updates to the copy do not affect the original.
*/
auto clone() const noexcept { auto clone() const noexcept {
auto cp = *this; auto cp = *this;
cp._impl = std::make_shared<rules_impl>(*_impl); cp._impl = std::make_shared<rules_impl>(*_impl);
return cp; return cp;
} }


/**
* Access the include directories for these rules
*/
auto& include_dirs() noexcept { return _impl->inc_dirs; } auto& include_dirs() noexcept { return _impl->inc_dirs; }
auto& include_dirs() const noexcept { return _impl->inc_dirs; } auto& include_dirs() const noexcept { return _impl->inc_dirs; }


/**
* Access the preprocessor definitions for these rules
*/
auto& defs() noexcept { return _impl->defs; } auto& defs() noexcept { return _impl->defs; }
auto& defs() const noexcept { return _impl->defs; } auto& defs() const noexcept { return _impl->defs; }


/**
* A boolean to toggle compile warnings for the associated compiles
*/
auto& enable_warnings() noexcept { return _impl->enable_warnings; } auto& enable_warnings() noexcept { return _impl->enable_warnings; }
auto& enable_warnings() const noexcept { return _impl->enable_warnings; } auto& enable_warnings() const noexcept { return _impl->enable_warnings; }
}; };


/**
* Represents the parameters to compile an individual file. This includes the
* original source file path, and the shared compile rules as defined
* by `shared_compile_file_rules`.
*/
class compile_file_plan { class compile_file_plan {
/// The shared rules
shared_compile_file_rules _rules; shared_compile_file_rules _rules;
source_file _source;
std::string _qualifier;
fs::path _subdir;
/// The source file object that we are compiling
source_file _source;
/// A "qualifier" to be shown in log messages (not otherwise significant)
std::string _qualifier;
/// The subdirectory in which the object file will be generated
fs::path _subdir;


public: public:
/**
* Create a new instance.
* @param rules The base compile rules
* @param sf The source file that will be compiled
* @param qual An arbitrary qualifier for the source file, shown in log output
* @param subdir The subdirectory where the object file will be generated
*/
compile_file_plan(shared_compile_file_rules rules, compile_file_plan(shared_compile_file_rules rules,
source_file sf, source_file sf,
std::string_view qual, std::string_view qual,
, _qualifier(qual) , _qualifier(qual)
, _subdir(subdir) {} , _subdir(subdir) {}


/**
* The `source_file` object for this plan.
*/
const source_file& source() const noexcept { return _source; } const source_file& source() const noexcept { return _source; }
path_ref source_path() const noexcept { return _source.path; }
auto& rules() const noexcept { return _rules; }
auto& qualifier() const noexcept { return _qualifier; }

fs::path calc_object_file_path(build_env_ref env) const noexcept;
compile_command_info generate_compile_command(build_env_ref) const noexcept;
std::optional<deps_info> compile(build_env_ref) const;
/**
* The path to the source file
*/
path_ref source_path() const noexcept { return _source.path; }
/**
* The shared rules for this compilation
*/
auto& rules() const noexcept { return _rules; }
/**
* The arbitrary qualifier for this compilation
*/
auto& qualifier() const noexcept { return _qualifier; }

/**
* Generate the path that will be the destination of this compile output
*/
fs::path calc_object_file_path(build_env_ref env) const noexcept;
/**
* Generate a concrete compile command object for this source file for the given build
* environment.
*/
compile_command_info generate_compile_command(build_env_ref) const noexcept;
}; };


} // namespace dds } // namespace dds

Loading…
Cancel
Save