Skip to content

Commit

Permalink
support pch
Browse files Browse the repository at this point in the history
  • Loading branch information
annacrombie committed Feb 7, 2025
1 parent da2b076 commit 5d9435d
Show file tree
Hide file tree
Showing 12 changed files with 170 additions and 61 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ information.

Things missing include:

- build optimizations like pch and unity
- build optimizations like unity
- some `b_` options
- dependencies with a custom configuration tool
- some modules
Expand Down
5 changes: 2 additions & 3 deletions include/backend/common_args.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,8 @@ void ca_get_option_link_args(struct workspace *wk,
const struct obj_build_target *tgt,
obj args);

obj ca_build_target_joined_args(struct workspace *wk,
const struct project *proj,
const struct obj_build_target *tgt);
obj ca_build_target_joined_args(struct workspace *wk, obj processed_args);

bool
ca_prepare_target_linker_args(struct workspace *wk,
struct obj_compiler *comp,
Expand Down
4 changes: 3 additions & 1 deletion include/compilers.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,9 @@ typedef const struct args *((*compiler_get_arg_func_ns)(TOOLCHAIN_SIG_ns));
_(deps_type, compiler, TOOLCHAIN_PARAMS_0) \
_(coverage, compiler, TOOLCHAIN_PARAMS_0) \
_(std_supported, compiler, TOOLCHAIN_PARAMS_1s) \
_(permissive, compiler, TOOLCHAIN_PARAMS_0)
_(permissive, compiler, TOOLCHAIN_PARAMS_0) \
_(include_pch, compiler, TOOLCHAIN_PARAMS_1s) \
_(winvalid_pch, compiler, TOOLCHAIN_PARAMS_0)

#define FOREACH_LINKER_ARG(_) \
_(lib, linker, TOOLCHAIN_PARAMS_1s) \
Expand Down
2 changes: 2 additions & 0 deletions include/lang/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -249,12 +249,14 @@ struct obj_build_target {
obj src; // obj_array
obj objects; // obj_array
obj args; // obj_dict
obj processed_args_pch; // obj_dict
obj processed_args; // obj_dict
obj link_depends; // obj_array
obj generated_pc; // obj_string
obj override_options; // obj_array
obj required_compilers; // obj_dict
obj extra_files; // obj_array
obj pch; // obj_dict
obj callstack; // obj_array

struct build_dep dep;
Expand Down
3 changes: 3 additions & 0 deletions include/lang/workspace.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ struct project {

bool not_ok; // set by failed subprojects
bool initialized;

// ninja-specific
obj generic_rules[machine_kind_count];
};

struct workspace {
Expand Down
28 changes: 26 additions & 2 deletions src/backend/common_args.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "args.h"
#include "backend/common_args.h"
#include "error.h"
#include "functions/build_target.h"
#include "lang/object_iterators.h"
#include "log.h"
#include "options.h"
Expand Down Expand Up @@ -140,6 +141,10 @@ ca_get_warning_args(struct workspace *wk,
}

push_args(wk, args_id, toolchain_compiler_warning_lvl(wk, comp, lvl));

if (tgt->pch && lvl >= 1) {
push_args(wk, args_id, toolchain_compiler_winvalid_pch(wk, comp));
}
}

static void
Expand Down Expand Up @@ -379,6 +384,9 @@ ca_prepare_target_args(struct workspace *wk, const struct project *proj, struct
assert(!tgt->processed_args);

make_obj(wk, &tgt->processed_args, obj_dict);
if (tgt->pch) {
make_obj(wk, &tgt->processed_args_pch, obj_dict);
}

if (tgt->flags & build_tgt_generated_include) {
const char *private_path = get_cstr(wk, tgt->private_path);
Expand Down Expand Up @@ -456,20 +464,36 @@ ca_prepare_target_args(struct workspace *wk, const struct project *proj, struct
push_args(wk, args, toolchain_compiler_visibility(wk, comp, tgt->visibility));
}

if (tgt->pch) {
obj pch;
if (obj_dict_geti(wk, tgt->pch, lang, &pch)) {
obj args_dup;
obj_array_dup(wk, args, &args_dup);
obj_dict_seti(wk, tgt->processed_args_pch, lang, args_dup);

SBUF(dest_path);
if (!tgt_src_to_object_path(wk, tgt, pch, true, &dest_path)) {
return 0;
}

push_args(wk, args, toolchain_compiler_include_pch(wk, comp, dest_path.buf));
}
}

obj_dict_seti(wk, tgt->processed_args, lang, args);
}

return true;
}

obj
ca_build_target_joined_args(struct workspace *wk, const struct project *proj, const struct obj_build_target *tgt)
ca_build_target_joined_args(struct workspace *wk, obj processed_args)
{
obj joined;
make_obj(wk, &joined, obj_dict);

obj lang, v;
obj_dict_for(wk, tgt->processed_args, lang, v) {
obj_dict_for(wk, processed_args, lang, v) {
obj_dict_seti(wk, joined, lang, join_args_shell_ninja(wk, v));
}

Expand Down
117 changes: 79 additions & 38 deletions src/backend/ninja/build_target.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,76 +11,67 @@
#include "backend/ninja/build_target.h"
#include "error.h"
#include "functions/build_target.h"
#include "lang/object_iterators.h"
#include "lang/workspace.h"
#include "log.h"
#include "platform/assert.h"
#include "platform/filesystem.h"
#include "platform/path.h"

struct write_tgt_iter_ctx {
struct write_tgt_source_ctx {
FILE *out;
const struct obj_build_target *tgt;
const struct project *proj;
struct build_dep args;
obj joined_args;
obj joined_args_pch;
obj object_names;
obj order_deps;
obj implicit_deps;
bool have_order_deps;
bool have_link_language;
};

static enum iteration_result
add_tgt_objects_iter(struct workspace *wk, void *_ctx, obj val)
{
struct write_tgt_iter_ctx *ctx = _ctx;
const char *src = get_file_path(wk, val);

SBUF(path);
path_relative_to(wk, &path, wk->build_root, src);
obj_array_push(wk, ctx->object_names, sbuf_into_str(wk, &path));
return ir_cont;
}
enum write_tgt_src_flag {
write_tgt_src_flag_pch = 1 << 0,
};

static enum iteration_result
write_tgt_sources_iter(struct workspace *wk, void *_ctx, obj val)
static obj
write_tgt_source(struct workspace *wk, struct write_tgt_source_ctx *ctx, enum compiler_language lang, obj val, enum write_tgt_src_flag flags)
{
struct write_tgt_iter_ctx *ctx = _ctx;
const char *src = get_file_path(wk, val);

enum compiler_language lang;
if (!filename_to_compiler_language(src, &lang)) {
UNREACHABLE;
}

/* build paths */
SBUF(dest_path);
if (!tgt_src_to_object_path(wk, ctx->tgt, val, true, &dest_path)) {
return ir_err;
return 0;
}

obj dest = sbuf_into_str(wk, &dest_path);

if (!(flags & write_tgt_src_flag_pch)) {
obj_array_push(wk, ctx->object_names, dest);
}

SBUF(src_path);
path_relative_to(wk, &src_path, wk->build_root, src);

obj_array_push(wk, ctx->object_names, sbuf_into_str(wk, &dest_path));

/* build rules and args */

obj rule_name, specialized_rule;
{
if (flags & write_tgt_src_flag_pch) {
if (!obj_dict_geti(wk, ctx->proj->generic_rules[ctx->tgt->machine], lang, &rule_name)) {
UNREACHABLE;
}
specialized_rule = 0;
} else {
obj rule_name_arr;
if (!obj_dict_geti(wk, ctx->tgt->required_compilers, lang, &rule_name_arr)) {
UNREACHABLE;
}

obj_array_index(wk, rule_name_arr, 0, &rule_name);
obj_array_index(wk, rule_name_arr, 1, &specialized_rule);

if (!specialized_rule) {
if (!ctx->joined_args) {
ctx->joined_args = ca_build_target_joined_args(wk, ctx->proj, ctx->tgt);
}
}
}

SBUF(esc_dest_path);
Expand All @@ -100,16 +91,29 @@ write_tgt_sources_iter(struct workspace *wk, void *_ctx, obj val)
fputc('\n', ctx->out);

if (!specialized_rule) {
obj *joined_args, processed_args;
if (flags & write_tgt_src_flag_pch) {
processed_args = ctx->tgt->processed_args_pch;
joined_args = &ctx->joined_args_pch;
} else {
processed_args = ctx->tgt->processed_args;
joined_args = &ctx->joined_args;
}

if (!*joined_args) {
*joined_args = ca_build_target_joined_args(wk, processed_args);
}

obj args;
if (!obj_dict_geti(wk, ctx->joined_args, lang, &args)) {
if (!obj_dict_geti(wk, *joined_args, lang, &args)) {
LOG_E("No compiler defined for language %s", compiler_language_to_s(lang));
return ir_err;
return 0;
}

fprintf(ctx->out, " ARGS = %s\n", get_cstr(wk, args));
}

return ir_cont;
return dest;
}

bool
Expand All @@ -125,7 +129,7 @@ ninja_write_build_tgt(struct workspace *wk, obj tgt_id, struct write_tgt_ctx *wc
ninja_escape(wk, &esc_path, rel_build_path.buf);
}

struct write_tgt_iter_ctx ctx = {
struct write_tgt_source_ctx ctx = {
.tgt = tgt,
.proj = wctx->proj,
.out = wctx->out,
Expand All @@ -135,6 +139,8 @@ ninja_write_build_tgt(struct workspace *wk, obj tgt_id, struct write_tgt_ctx *wc

ctx.args = tgt->dep_internal;

obj implicit_deps = 0;

bool have_custom_order_deps = false;
{ /* order deps */
if ((ctx.have_order_deps = (get_obj_array(wk, ctx.args.order_deps)->len > 0))) {
Expand All @@ -148,19 +154,54 @@ ninja_write_build_tgt(struct workspace *wk, obj tgt_id, struct write_tgt_ctx *wc
esc_path.buf,
get_cstr(wk, order_deps));
ctx.have_order_deps = false;
ctx.implicit_deps = make_strf(wk, "%s-order_deps", esc_path.buf);
make_obj(wk, &implicit_deps, obj_array);
obj_array_push(wk, implicit_deps, make_strf(wk, "%s-order_deps", esc_path.buf));
have_custom_order_deps = true;
} else {
ctx.order_deps = order_deps;
}
}
}

if (implicit_deps) {
ctx.implicit_deps = join_args_ninja(wk, implicit_deps);
}

if (tgt->pch) { /* pch */
obj k, v;
(void)k;
obj_dict_for(wk, tgt->pch, k, v) {
enum compiler_language lang = k;

if (!implicit_deps) {
make_obj(wk, &implicit_deps, obj_array);
}
obj_array_push(wk, implicit_deps, write_tgt_source(wk, &ctx, lang, v, write_tgt_src_flag_pch));
}

ctx.implicit_deps = join_args_ninja(wk, implicit_deps);
}

{ /* sources */
obj_array_foreach(wk, tgt->objects, &ctx, add_tgt_objects_iter);
obj v;
obj_array_for(wk, tgt->objects, v)
{
const char *src = get_file_path(wk, v);

SBUF(path);
path_relative_to(wk, &path, wk->build_root, src);
obj_array_push(wk, ctx.object_names, sbuf_into_str(wk, &path));
}

if (!obj_array_foreach(wk, tgt->src, &ctx, write_tgt_sources_iter)) {
return false;
obj_array_for(wk, tgt->src, v) {
enum compiler_language lang;
if (!filename_to_compiler_language(get_file_path(wk, v), &lang)) {
UNREACHABLE;
}

if (!write_tgt_source(wk, &ctx, lang, v, 0)) {
return false;
}
}
}

Expand Down
14 changes: 6 additions & 8 deletions src/backend/ninja/rules.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ struct write_compiler_rule_ctx {
FILE *out;
struct project *proj;
struct obj_build_target *tgt;
obj args[machine_kind_count], generic_rules[machine_kind_count];
obj args[machine_kind_count];
};

static void
Expand Down Expand Up @@ -240,7 +240,7 @@ write_compiler_rule_tgt_iter(struct workspace *wk, void *_ctx, obj tgt_id)

ctx->tgt = get_obj_build_target(wk, tgt_id);

ctx->args[ctx->tgt->machine] = ca_build_target_joined_args(wk, ctx->proj, ctx->tgt);
ctx->args[ctx->tgt->machine] = ca_build_target_joined_args(wk, ctx->tgt->processed_args);

if (!obj_dict_foreach(wk, ctx->proj->toolchains[ctx->tgt->machine], ctx, write_compiler_rule_iter)) {
goto ret;
Expand Down Expand Up @@ -338,9 +338,8 @@ ninja_write_rules(FILE *out, struct workspace *wk, struct project *main_proj, bo
uniqify_name(wk, rule_prefix_arr, sbuf_into_str(wk, &pre), &proj->rule_prefix);
}

obj generic_rules[machine_kind_count];
for (enum machine_kind machine = 0; machine < machine_kind_count; ++machine) {
make_obj(wk, &generic_rules[machine], obj_dict);
make_obj(wk, &proj->generic_rules[machine], obj_dict);
}

{ // Name all rules
Expand Down Expand Up @@ -374,7 +373,7 @@ ninja_write_rules(FILE *out, struct workspace *wk, struct project *main_proj, bo
obj name = sbuf_into_str(wk, &rule_name_buf);
uniqify_name(wk, compiler_rule_arr, name, &rule_name);
} else {
if (!obj_dict_geti(wk, generic_rules[tgt->machine], l, &rule_name)) {
if (!obj_dict_geti(wk, proj->generic_rules[tgt->machine], l, &rule_name)) {
sbuf_pushf(wk,
&rule_name_buf,
"%s_%s_%s_compiler",
Expand All @@ -385,7 +384,7 @@ ninja_write_rules(FILE *out, struct workspace *wk, struct project *main_proj, bo
escape_rule(&rule_name_buf);
obj name = sbuf_into_str(wk, &rule_name_buf);
uniqify_name(wk, compiler_rule_arr, name, &rule_name);
obj_dict_seti(wk, generic_rules[tgt->machine], l, rule_name);
obj_dict_seti(wk, proj->generic_rules[tgt->machine], l, rule_name);
}
}

Expand All @@ -407,7 +406,6 @@ ninja_write_rules(FILE *out, struct workspace *wk, struct project *main_proj, bo
struct write_compiler_rule_ctx ctx = {
.out = out,
.proj = proj,
.generic_rules = { generic_rules[0], generic_rules[1] },
};

struct obj_clear_mark mk;
Expand All @@ -426,7 +424,7 @@ ninja_write_rules(FILE *out, struct workspace *wk, struct project *main_proj, bo

{ // generic compiler rules
obj rule_name;
if (obj_dict_geti(wk, generic_rules[machine], l, &rule_name)) {
if (obj_dict_geti(wk, proj->generic_rules[machine], l, &rule_name)) {
write_compiler_rule(
wk, out, make_str(wk, "$ARGS"), rule_name, l, comp_id);
}
Expand Down
Loading

0 comments on commit 5d9435d

Please sign in to comment.