Vendor-fetch download to lib directory specified in project.json (#1422) (#1441)

Vendor-fetch download default destination set to dependency-search-path in project.json Add fetched libraries in the project configuration file dependency entry.
This commit is contained in:
Brian Sinquin
2024-09-19 23:44:05 +02:00
committed by GitHub
parent 2fec1c83a4
commit 8a9834cac0
6 changed files with 114 additions and 8 deletions

View File

@@ -13,6 +13,7 @@
#define MAX_THREADS 0xFFFF
#define DEFAULT_SYMTAB_SIZE (256 * 1024)
#define DEFAULT_SWITCHRANGE_MAX_SIZE (256)
#define DEFAULT_PATH "."
typedef enum
{
@@ -433,6 +434,7 @@ typedef struct BuildOptions_
const char *project_name;
const char *target_select;
const char *path;
const char *vendor_download_path;
const char *template;
LinkerType linker_type;
const char *custom_linker_path;

View File

@@ -1237,7 +1237,8 @@ BuildOptions parse_arguments(int argc, const char *argv[])
}
BuildOptions build_options = {
.path = ".",
.path = DEFAULT_PATH,
.vendor_download_path = DEFAULT_PATH,
.emit_llvm = false,
.optsetting = OPT_SETTING_NOT_SET,
.debug_info_override = DEBUG_INFO_NOT_SET,

6
src/build/project.h Normal file
View File

@@ -0,0 +1,6 @@
#pragma once
#include "../utils/json.h"
const char** get_project_dependency_directories();
void add_libraries_to_project_file(const char** libs, const char* target_name);

View File

@@ -1,4 +1,5 @@
#include "build_internal.h"
#include "project.h"
#define PRINTFN(string, ...) fprintf(stdout, string "\n", ##__VA_ARGS__) // NOLINT
#define PRINTF(string, ...) fprintf(stdout, string, ##__VA_ARGS__) // NOLINT
@@ -22,6 +23,18 @@ static JSONObject *read_project(const char **file_used)
return json;
}
const char** get_project_dependency_directories()
{
const char *filename;
JSONObject *json = read_project(&filename);
const char *target = NULL;
const char **deps_dirs = NULL;
get_list_append_strings(filename, target, json, &deps_dirs, "dependency-search-paths", "dependency-search-paths-override", "dependency-search-paths-add");
return deps_dirs;
}
static void print_vec(const char *header, const char **vec, bool opt)
{
if (opt && !vec) return;
@@ -239,6 +252,56 @@ static void view_target(const char *filename, const char *name, JSONObject *targ
TARGET_VIEW_BOOL("Return structs on the stack", "x86-stack-struct-return");
}
void add_libraries_to_project_file(const char** libs, const char* target_name) {
if (!file_exists(PROJECT_JSON5) && !file_exists(PROJECT_JSON)) return;
//TODO! Target name option not implemented
const char *filename;
JSONObject *project_json = read_project(&filename);
// TODO! check if target is specified and exists (NULL at the moment)
JSONObject *libraries_json = json_obj_get(project_json, "dependencies");
const char** dependencies = NULL;
for(int i = 0; i < libraries_json->array_len; i++)
{
vec_add(dependencies, libraries_json->elements[i]->str);
}
// check if libraries are already present
FOREACH(const char*, lib, libs)
{
if (str_findlist(lib, vec_size(dependencies), dependencies)!=-1) continue;
vec_add(dependencies, lib);
}
JSONObject** elements = NULL;
FOREACH(const char*, dep, dependencies)
{
JSONObject* obj = json_new_object(&malloc_arena, J_STRING);
obj->str = dep;
vec_add(elements, obj);
}
// TODO fancier functions for altering JSON file (quite cumbersome at the moment)
// TODO! check if "dependency" entry exists in the project.json file.
// Apply changes to JSON object
libraries_json->elements = elements;
libraries_json->array_len = vec_size(dependencies);
// write to project json file
FILE *file = fopen(filename, "w");
print_json_to_file(project_json, file);
fclose(file);
}
void add_target_project(BuildOptions *build_options)
{
const char *filename;

View File

@@ -3,6 +3,7 @@
// a copy of which can be found in the LICENSE file.
#include "compiler_internal.h"
#include "../build/project.h"
#include <compiler_tests/benchmark.h>
#include "../utils/whereami.h"
#if PLATFORM_POSIX
@@ -862,25 +863,55 @@ static void setup_bool_define(const char *id, bool value)
}
}
#if FETCH_AVAILABLE
const char * vendor_fetch_single(const char* lib, const char* path)
{
const char *resource = str_printf("/c3lang/vendor/releases/download/latest/%s.c3l", lib);
const char *destination = file_append_path(path, str_printf("%s.c3l", lib));
const char *error = download_file("https://github.com", resource, destination);
return error;
}
void vendor_fetch(BuildOptions *options)
{
unsigned count = 0;
if (str_eq(options->path, DEFAULT_PATH))
{
// check if there is a project JSON file
if (file_exists(PROJECT_JSON5) || file_exists(PROJECT_JSON))
{
const char** deps_dirs = get_project_dependency_directories();
int num_lib = vec_size(deps_dirs);
if (num_lib > 0) options->vendor_download_path = deps_dirs[0];
}
}
const char** fetched_libraries = NULL;
FOREACH(const char *, lib, options->libraries_to_fetch)
{
const char *resource = str_printf("/c3lang/vendor/releases/download/latest/%s.c3l", lib);
//TODO : Implement progress bar in the download_file function.
printf("Fetching library '%s'...", lib);
fflush(stdout);
const char *error = download_file("https://github.com", resource, str_printf("%s.c3l", lib));
const char *error = vendor_fetch_single(lib, options->vendor_download_path);
if (!error)
{
puts("ok.");
puts("finished.");
vec_add(fetched_libraries, lib);
count++;
}
else
{
printf("FAILED: '%s'\n", error);
printf("Failed: '%s'\n", error);
}
}
// add fetched library to the dependency list
add_libraries_to_project_file(fetched_libraries, options->project_options.target_name);
if (count == 0) error_exit("Error: Failed to download any libraries.");
if (count < vec_size(options->libraries_to_fetch)) error_exit("Error: Only some libraries were downloaded.");
}

View File

@@ -8,7 +8,6 @@ JSONObject error = { .type = J_ERROR };
JSONObject true_val = { .type = J_BOOL, .b = true };
JSONObject false_val = { .type = J_BOOL, .b = false };
JSONObject zero_val = { .type = J_NUMBER, .f = 0.0 };
JSONObject empty_array_val = { .type = J_ARRAY, .array_len = 0 };
JSONObject empty_obj_val = { .type = J_OBJECT, .member_len = 0 };
#define CONSUME(token_) do { if (!consume(parser, token_)) { json_error(parser, "Unexpected character encountered."); return &error; } } while(0)
@@ -275,7 +274,12 @@ static inline bool consume(JsonParser *parser, JSONTokenType token)
JSONObject *json_parse_array(JsonParser *parser)
{
CONSUME(T_LBRACKET);
if (consume(parser, T_RBRACKET)) return &empty_array_val;
if (consume(parser, T_RBRACKET))
{
JSONObject *array = json_new_object(parser->allocator, J_ARRAY);
array->array_len = 0;
return array;
}
size_t capacity = 16;
JSONObject *array = json_new_object(parser->allocator, J_ARRAY);
@@ -440,7 +444,6 @@ bool is_freable(JSONObject *obj)
if (obj == &true_val) return false;
if (obj == &false_val) return false;
if (obj == &zero_val) return false;
if (obj == &empty_array_val) return false;
if (obj == &empty_obj_val) return false;
return true;
}