mirror of
https://git.sr.ht/~lattis/muon
synced 2026-01-30 03:14:36 +00:00
Adds support for using msvc, as well as a proper detection step for linkers. Static and shared linkers are both tied to the compiler object for now.
592 lines
14 KiB
C
592 lines
14 KiB
C
/*
|
|
* SPDX-FileCopyrightText: Stone Tickle <lattis@mochiro.moe>
|
|
* SPDX-FileCopyrightText: illiliti <illiliti@dimension.sh>
|
|
* SPDX-License-Identifier: GPL-3.0-only
|
|
*/
|
|
|
|
#ifndef MUON_LANG_OBJECT_H
|
|
#define MUON_LANG_OBJECT_H
|
|
|
|
#include "compat.h"
|
|
|
|
#include <stdarg.h>
|
|
#include <stdio.h>
|
|
|
|
#include "compilers.h"
|
|
#include "datastructures/bucket_arr.h"
|
|
#include "datastructures/hash.h"
|
|
#include "datastructures/iterator.h"
|
|
#include "lang/types.h"
|
|
|
|
enum language_mode {
|
|
language_external,
|
|
language_internal,
|
|
language_opts,
|
|
language_mode_count,
|
|
|
|
language_extended,
|
|
};
|
|
|
|
enum obj_type {
|
|
/* singleton object types */
|
|
obj_null,
|
|
obj_meson,
|
|
obj_disabler,
|
|
obj_machine, // this won't be a singleton object when cross compilaton is implemented
|
|
|
|
/* simple object types */
|
|
obj_bool,
|
|
obj_file,
|
|
obj_feature_opt,
|
|
|
|
/* complex object types */
|
|
_obj_aos_start,
|
|
obj_number = _obj_aos_start,
|
|
obj_string,
|
|
obj_array,
|
|
obj_dict,
|
|
obj_compiler,
|
|
obj_build_target,
|
|
obj_custom_target,
|
|
obj_subproject,
|
|
obj_dependency,
|
|
obj_external_program,
|
|
obj_python_installation,
|
|
obj_run_result,
|
|
obj_configuration_data,
|
|
obj_test,
|
|
obj_module,
|
|
obj_install_target,
|
|
obj_environment,
|
|
obj_include_directory,
|
|
obj_option,
|
|
obj_generator,
|
|
obj_generated_list,
|
|
obj_alias_target,
|
|
obj_both_libs,
|
|
obj_source_set,
|
|
obj_source_configuration,
|
|
|
|
/* muon-specific objects */
|
|
obj_func,
|
|
obj_typeinfo,
|
|
|
|
obj_type_count,
|
|
};
|
|
|
|
/* start of object structs */
|
|
|
|
struct obj_typeinfo {
|
|
type_tag type, subtype;
|
|
};
|
|
|
|
struct obj_func {
|
|
const char *name;
|
|
struct ast *ast;
|
|
enum language_mode lang_mode;
|
|
uint32_t args_id, block_id, nargs, nkwargs;
|
|
obj kwarg_defaults, src, scope_stack;
|
|
type_tag return_type;
|
|
};
|
|
|
|
enum tgt_type {
|
|
tgt_executable = 1 << 0,
|
|
tgt_static_library = 1 << 1,
|
|
tgt_dynamic_library = 1 << 2,
|
|
tgt_shared_module = 1 << 3,
|
|
};
|
|
enum tgt_type_count { tgt_type_count = 4, }; // keep in sync
|
|
|
|
enum feature_opt_state {
|
|
feature_opt_auto,
|
|
feature_opt_enabled,
|
|
feature_opt_disabled,
|
|
};
|
|
|
|
enum module {
|
|
module_fs,
|
|
module_keyval,
|
|
module_pkgconfig,
|
|
module_python,
|
|
module_python3,
|
|
module_sourceset,
|
|
|
|
// unimplemented
|
|
module_unimplemented_separator,
|
|
module_cmake = module_unimplemented_separator,
|
|
module_dlang,
|
|
module_gnome,
|
|
module_hotdoc,
|
|
module_i18n,
|
|
module_java,
|
|
module_modtest,
|
|
module_qt,
|
|
module_qt4,
|
|
module_qt5,
|
|
module_qt6,
|
|
module_unstable_cuda,
|
|
module_unstable_external_project,
|
|
module_unstable_icestorm,
|
|
module_unstable_rust,
|
|
module_unstable_simd,
|
|
module_unstable_wayland,
|
|
module_windows,
|
|
|
|
module_count,
|
|
};
|
|
|
|
enum str_flags {
|
|
str_flag_big = 1 << 0,
|
|
str_flag_mutable = 1 << 1,
|
|
};
|
|
|
|
struct str {
|
|
const char *s;
|
|
uint32_t len;
|
|
enum str_flags flags;
|
|
};
|
|
|
|
struct obj_internal {
|
|
enum obj_type t;
|
|
uint32_t val;
|
|
};
|
|
|
|
struct obj_subproject {
|
|
uint32_t id;
|
|
bool found;
|
|
};
|
|
|
|
struct obj_module {
|
|
enum module module;
|
|
bool found, has_impl;
|
|
obj exports;
|
|
};
|
|
|
|
struct obj_array {
|
|
obj val; // any
|
|
obj next; // obj_array
|
|
obj tail; // obj_array
|
|
uint32_t len;
|
|
bool have_next;
|
|
};
|
|
|
|
enum obj_dict_flags {
|
|
obj_dict_flag_big = 1 << 0,
|
|
obj_dict_flag_int_key = 1 << 1,
|
|
obj_dict_flag_dont_expand = 1 << 2,
|
|
};
|
|
|
|
struct obj_dict_elem {
|
|
uint32_t next;
|
|
obj key, val;
|
|
};
|
|
|
|
struct obj_dict {
|
|
uint32_t data, len;
|
|
obj tail;
|
|
enum obj_dict_flags flags;
|
|
};
|
|
|
|
enum build_tgt_flags {
|
|
build_tgt_flag_export_dynamic = 1 << 0,
|
|
build_tgt_flag_pic = 1 << 1,
|
|
build_tgt_generated_include = 1 << 2,
|
|
build_tgt_flag_build_by_default = 1 << 3,
|
|
build_tgt_flag_visibility = 1 << 4,
|
|
build_tgt_flag_installed = 1 << 5,
|
|
build_tgt_flag_pie = 1 << 6,
|
|
};
|
|
|
|
struct build_dep {
|
|
enum compiler_language link_language;
|
|
|
|
obj link_whole; // obj_array
|
|
|
|
obj link_with; // obj_array
|
|
obj link_with_not_found; // obj_array
|
|
|
|
obj link_args; // obj_array
|
|
obj compile_args; // obj_array
|
|
|
|
obj include_directories; // obj_array
|
|
|
|
obj sources; // obj_array
|
|
obj objects; // obj_array
|
|
|
|
obj order_deps; // obj_array
|
|
obj rpath; // obj_array
|
|
|
|
struct {
|
|
obj deps;
|
|
obj link_with;
|
|
obj link_whole;
|
|
} raw;
|
|
};
|
|
|
|
struct obj_build_target {
|
|
obj name; // obj_string
|
|
obj build_name; // obj_string
|
|
obj build_path; // obj_string
|
|
obj private_path; // obj_string
|
|
obj cwd; // obj_string
|
|
obj build_dir; // obj_string
|
|
obj soname; // obj_string
|
|
obj src; // obj_array
|
|
obj objects; // obj_array
|
|
obj args; // obj_dict
|
|
obj link_depends; // obj_array
|
|
obj generated_pc; // obj_string
|
|
obj override_options; // obj_array
|
|
obj required_compilers; // obj_dict
|
|
|
|
struct build_dep dep;
|
|
struct build_dep dep_internal;
|
|
|
|
enum compiler_visibility_type visibility;
|
|
enum build_tgt_flags flags;
|
|
enum tgt_type type;
|
|
};
|
|
|
|
struct obj_both_libs {
|
|
obj static_lib; // obj_build_target
|
|
obj dynamic_lib; // obj_build_target
|
|
};
|
|
|
|
enum custom_target_flags {
|
|
custom_target_capture = 1 << 0,
|
|
custom_target_build_always_stale = 1 << 1,
|
|
custom_target_build_by_default = 1 << 2,
|
|
custom_target_feed = 1 << 3,
|
|
custom_target_console = 1 << 4,
|
|
};
|
|
|
|
struct obj_custom_target {
|
|
obj name; // obj_string
|
|
obj args; // obj_array
|
|
obj input; // obj_array
|
|
obj output; // obj_array
|
|
obj depends; // obj_array
|
|
obj private_path; // obj_string
|
|
obj env; // str | list[str] | dict[str] | env
|
|
obj depfile; // str
|
|
enum custom_target_flags flags;
|
|
};
|
|
|
|
struct obj_alias_target {
|
|
obj name; // obj_string
|
|
obj depends; // obj_array
|
|
};
|
|
|
|
enum dependency_type {
|
|
dependency_type_declared,
|
|
dependency_type_pkgconf,
|
|
dependency_type_threads,
|
|
dependency_type_external_library,
|
|
dependency_type_appleframeworks,
|
|
dependency_type_not_found,
|
|
};
|
|
|
|
enum dep_flags {
|
|
dep_flag_found = 1 << 0,
|
|
};
|
|
|
|
enum include_type {
|
|
include_type_preserve,
|
|
include_type_system,
|
|
include_type_non_system,
|
|
};
|
|
|
|
struct obj_dependency {
|
|
obj name; // obj_string
|
|
obj version; // obj_string
|
|
obj variables; // obj_dict
|
|
|
|
struct build_dep dep;
|
|
|
|
enum dep_flags flags;
|
|
enum dependency_type type;
|
|
enum include_type include_type;
|
|
};
|
|
|
|
struct obj_external_program {
|
|
bool found, guessed_ver;
|
|
obj cmd_array;
|
|
obj ver;
|
|
};
|
|
|
|
struct obj_python_installation {
|
|
obj prog;
|
|
|
|
obj language_version;
|
|
obj sysconfig_paths;
|
|
obj sysconfig_vars;
|
|
};
|
|
|
|
enum run_result_flags {
|
|
run_result_flag_from_compile = 1 << 0,
|
|
run_result_flag_compile_ok = 1 << 1,
|
|
};
|
|
|
|
struct obj_run_result {
|
|
obj out;
|
|
obj err;
|
|
int32_t status;
|
|
enum run_result_flags flags;
|
|
};
|
|
|
|
struct obj_configuration_data {
|
|
obj dict; // obj_dict
|
|
};
|
|
|
|
enum test_category {
|
|
test_category_test,
|
|
test_category_benchmark,
|
|
};
|
|
|
|
enum test_protocol {
|
|
test_protocol_exitcode,
|
|
test_protocol_tap,
|
|
test_protocol_gtest,
|
|
test_protocol_rust,
|
|
};
|
|
|
|
struct obj_test {
|
|
obj name; // obj_string
|
|
obj exe; // obj_string
|
|
obj args; // obj_array
|
|
obj env; // obj_array
|
|
obj suites; // obj_array
|
|
obj workdir; // obj_string
|
|
obj depends; // obj_array of obj_string
|
|
obj timeout; // obj_number
|
|
obj priority; // obj_number
|
|
bool should_fail, is_parallel, verbose;
|
|
enum test_category category;
|
|
enum test_protocol protocol;
|
|
};
|
|
|
|
struct obj_compiler {
|
|
obj cmd_arr;
|
|
obj linker_cmd_arr;
|
|
obj static_linker_cmd_arr;
|
|
obj ver;
|
|
obj libdirs;
|
|
enum compiler_type type;
|
|
enum linker_type linker_type;
|
|
enum static_linker_type static_linker_type;
|
|
enum compiler_language lang;
|
|
};
|
|
|
|
enum install_target_type {
|
|
install_target_default,
|
|
install_target_subdir,
|
|
install_target_symlink,
|
|
install_target_emptydir,
|
|
};
|
|
|
|
struct obj_install_target {
|
|
obj src;
|
|
obj dest;
|
|
bool has_perm;
|
|
uint32_t perm;
|
|
obj exclude_directories; // obj_array of obj_string
|
|
obj exclude_files; // obj_array of obj_string
|
|
enum install_target_type type;
|
|
bool build_target;
|
|
};
|
|
|
|
struct obj_environment {
|
|
obj actions; // array
|
|
};
|
|
|
|
struct obj_include_directory {
|
|
obj path;
|
|
bool is_system;
|
|
};
|
|
|
|
enum build_option_type {
|
|
op_string,
|
|
op_boolean,
|
|
op_combo,
|
|
op_integer,
|
|
op_array,
|
|
op_feature,
|
|
build_option_type_count,
|
|
};
|
|
|
|
enum build_option_kind {
|
|
build_option_kind_default,
|
|
build_option_kind_prefixed_dir,
|
|
};
|
|
|
|
enum option_value_source {
|
|
option_value_source_unset,
|
|
option_value_source_default,
|
|
option_value_source_environment,
|
|
option_value_source_yield,
|
|
option_value_source_default_options,
|
|
option_value_source_subproject_default_options,
|
|
option_value_source_override_options,
|
|
option_value_source_deprecated_rename,
|
|
option_value_source_commandline,
|
|
};
|
|
|
|
struct obj_option {
|
|
obj name;
|
|
obj val;
|
|
obj choices;
|
|
obj max;
|
|
obj min;
|
|
obj deprecated;
|
|
obj description;
|
|
enum option_value_source source;
|
|
enum build_option_type type;
|
|
enum build_option_kind kind;
|
|
bool yield, builtin;
|
|
};
|
|
|
|
struct obj_generator {
|
|
obj output;
|
|
obj raw_command;
|
|
obj depfile;
|
|
obj depends;
|
|
bool capture;
|
|
bool feed;
|
|
};
|
|
|
|
struct obj_generated_list {
|
|
obj generator; // obj_generator
|
|
obj input; // obj_array of obj_file
|
|
obj extra_arguments; // obj_array of obj_string
|
|
obj preserve_path_from; // obj_string
|
|
};
|
|
|
|
struct obj_source_set {
|
|
obj rules;
|
|
bool frozen;
|
|
};
|
|
|
|
struct obj_source_configuration {
|
|
obj sources, dependencies;
|
|
};
|
|
|
|
/* end of object structs */
|
|
|
|
struct obj_clear_mark {
|
|
uint32_t obji;
|
|
struct bucket_arr_save objs, chrs;
|
|
struct bucket_arr_save obj_aos[obj_type_count - _obj_aos_start];
|
|
};
|
|
|
|
void make_obj(struct workspace *wk, obj *id, enum obj_type type);
|
|
enum obj_type get_obj_type(struct workspace *wk, obj id);
|
|
|
|
void obj_set_clear_mark(struct workspace *wk, struct obj_clear_mark *mk);
|
|
void obj_clear(struct workspace *wk, const struct obj_clear_mark *mk);
|
|
|
|
bool get_obj_bool(struct workspace *wk, obj o);
|
|
void set_obj_bool(struct workspace *wk, obj o, bool v);
|
|
int64_t get_obj_number(struct workspace *wk, obj o);
|
|
void set_obj_number(struct workspace *wk, obj o, int64_t v);
|
|
obj *get_obj_file(struct workspace *wk, obj o);
|
|
const char *get_file_path(struct workspace *wk, obj o);
|
|
const struct str *get_str(struct workspace *wk, obj s);
|
|
enum feature_opt_state get_obj_feature_opt(struct workspace *wk, obj fo);
|
|
void set_obj_feature_opt(struct workspace *wk, obj fo, enum feature_opt_state state);
|
|
|
|
#define OBJ_GETTER(type) struct type *get_ ## type(struct workspace *wk, obj o)
|
|
|
|
OBJ_GETTER(obj_array);
|
|
OBJ_GETTER(obj_dict);
|
|
OBJ_GETTER(obj_compiler);
|
|
OBJ_GETTER(obj_build_target);
|
|
OBJ_GETTER(obj_custom_target);
|
|
OBJ_GETTER(obj_subproject);
|
|
OBJ_GETTER(obj_dependency);
|
|
OBJ_GETTER(obj_external_program);
|
|
OBJ_GETTER(obj_python_installation);
|
|
OBJ_GETTER(obj_run_result);
|
|
OBJ_GETTER(obj_configuration_data);
|
|
OBJ_GETTER(obj_test);
|
|
OBJ_GETTER(obj_module);
|
|
OBJ_GETTER(obj_install_target);
|
|
OBJ_GETTER(obj_environment);
|
|
OBJ_GETTER(obj_include_directory);
|
|
OBJ_GETTER(obj_option);
|
|
OBJ_GETTER(obj_generator);
|
|
OBJ_GETTER(obj_generated_list);
|
|
OBJ_GETTER(obj_alias_target);
|
|
OBJ_GETTER(obj_both_libs);
|
|
OBJ_GETTER(obj_typeinfo);
|
|
OBJ_GETTER(obj_func);
|
|
OBJ_GETTER(obj_source_set);
|
|
OBJ_GETTER(obj_source_configuration);
|
|
|
|
#undef OBJ_GETTER
|
|
|
|
struct sbuf;
|
|
|
|
const char *obj_type_to_s(enum obj_type t);
|
|
bool s_to_type_tag(const char *s, type_tag *t);
|
|
void obj_to_s(struct workspace *wk, obj o, struct sbuf *sb);
|
|
bool obj_equal(struct workspace *wk, obj left, obj right);
|
|
bool obj_clone(struct workspace *wk_src, struct workspace *wk_dest, obj val, obj *ret);
|
|
|
|
#define LO(...) if (log_should_print(log_debug)) { char buf[4096]; log_print_prefix(log_debug, buf, ARRAY_LEN(buf)); log_plain("%s", buf); obj_fprintf(wk, log_file(), __VA_ARGS__); }
|
|
#define LOBJ(object_id) LO("%s: %o\n", #object_id, object_id)
|
|
|
|
bool obj_vasprintf(struct workspace *wk, struct sbuf *sb, const char *fmt, va_list ap);
|
|
bool obj_asprintf(struct workspace *wk, struct sbuf *sb, const char *fmt, ...)
|
|
MUON_ATTR_FORMAT(printf, 3, 4);
|
|
bool obj_vfprintf(struct workspace *wk, FILE *f, const char *fmt, va_list ap)
|
|
MUON_ATTR_FORMAT(printf, 3, 0);
|
|
bool obj_fprintf(struct workspace *wk, FILE *f, const char *fmt, ...)
|
|
MUON_ATTR_FORMAT(printf, 3, 4);
|
|
bool obj_printf(struct workspace *wk, const char *fmt, ...)
|
|
MUON_ATTR_FORMAT(printf, 2, 3);
|
|
void obj_inspect(struct workspace *wk, FILE *out, obj val);
|
|
|
|
typedef enum iteration_result (*obj_array_iterator)(struct workspace *wk, void *ctx, obj val);
|
|
void obj_array_push(struct workspace *wk, obj arr, obj child);
|
|
void obj_array_prepend(struct workspace *wk, obj *arr, obj val);
|
|
bool obj_array_foreach(struct workspace *wk, obj arr, void *ctx, obj_array_iterator cb);
|
|
bool obj_array_foreach_flat(struct workspace *wk, obj arr, void *usr_ctx, obj_array_iterator cb);
|
|
bool obj_array_in(struct workspace *wk, obj arr, obj val);
|
|
bool obj_array_index_of(struct workspace *wk, obj arr, obj val, uint32_t *idx);
|
|
void obj_array_index(struct workspace *wk, obj arr, int64_t i, obj *res);
|
|
void obj_array_extend(struct workspace *wk, obj arr, obj arr2);
|
|
void obj_array_extend_nodup(struct workspace *wk, obj arr, obj arr2);
|
|
void obj_array_dup(struct workspace *wk, obj arr, obj *res);
|
|
bool obj_array_join(struct workspace *wk, bool flat, obj arr, obj join, obj *res);
|
|
void obj_array_tail(struct workspace *wk, obj arr, obj *res);
|
|
void obj_array_set(struct workspace *wk, obj arr, int64_t i, obj v);
|
|
void obj_array_del(struct workspace *wk, obj arr, int64_t i);
|
|
void obj_array_dedup(struct workspace *wk, obj arr, obj *res);
|
|
void obj_array_dedup_in_place(struct workspace *wk, obj *arr);
|
|
bool obj_array_flatten_one(struct workspace *wk, obj val, obj *res);
|
|
typedef int32_t (*obj_array_sort_func)(struct workspace *wk, void *_ctx, obj a, obj b);
|
|
int32_t obj_array_sort_by_str(struct workspace *wk, void *_ctx, obj a, obj b);
|
|
void obj_array_sort(struct workspace *wk, void *usr_ctx, obj arr, obj_array_sort_func func, obj *res);
|
|
obj obj_array_slice(struct workspace *wk, obj arr, int64_t i0, int64_t i1);
|
|
obj obj_array_get_tail(struct workspace *wk, obj arr);
|
|
obj obj_array_pop(struct workspace *wk, obj arr);
|
|
|
|
typedef enum iteration_result (*obj_dict_iterator)(struct workspace *wk, void *ctx, obj key, obj val);
|
|
bool obj_dict_foreach(struct workspace *wk, obj dict, void *ctx, obj_dict_iterator cb);
|
|
bool obj_dict_in(struct workspace *wk, obj dict, obj key);
|
|
bool obj_dict_index(struct workspace *wk, obj dict, obj key, obj *res);
|
|
bool obj_dict_index_strn(struct workspace *wk, obj dict, const char *str, uint32_t len, obj *res);
|
|
bool obj_dict_index_str(struct workspace *wk, obj dict, const char *str, obj *res);
|
|
void obj_dict_set(struct workspace *wk, obj dict, obj key, obj val);
|
|
void obj_dict_dup(struct workspace *wk, obj dict, obj *res);
|
|
void obj_dict_merge(struct workspace *wk, obj dict, obj dict2, obj *res);
|
|
void obj_dict_merge_nodup(struct workspace *wk, obj dict, obj dict2);
|
|
void obj_dict_seti(struct workspace *wk, obj dict, uint32_t key, obj val);
|
|
bool obj_dict_geti(struct workspace *wk, obj dict, uint32_t key, obj *val);
|
|
void obj_dict_del(struct workspace *wk, obj dict, obj key);
|
|
void obj_dict_del_str(struct workspace *wk, obj dict, const char *str);
|
|
void obj_dict_del_strn(struct workspace *wk, obj dict, const char *str, uint32_t len);
|
|
|
|
bool obj_iterable_foreach(struct workspace *wk, obj dict_or_array, void *ctx, obj_dict_iterator cb);
|
|
#endif
|