Bring in the threaded signal handler design that I experimented with in the Kevux Tools project.
This works by creating a thread that waits for the signal and nothing else.
The threaded design avoids the signal check and therefore avoids period calls to kernel space.
When thread support is diabled, this falls back to the traditional approach.
This will be done for other programs as well.
build_sources_program fll/level_2/print.c
build_sources_program fll/level_2/program.c fll/level_2/program/common.c fll/level_2/program/print.c fll/level_2/private-program.c
-build_sources_program program/fake/main/build.c program/fake/main/clean.c program/fake/main/common.c program/fake/main/fake.c program/fake/main/make.c program/fake/main/print/common.c program/fake/main/print/context.c program/fake/main/print/error.c program/fake/main/print/message.c program/fake/main/print/operation.c program/fake/main/print/warning.c program/fake/main/print/verbose.c program/fake/main/skeleton.c
+build_sources_program program/fake/main/build.c program/fake/main/clean.c program/fake/main/common.c program/fake/main/fake.c program/fake/main/make.c program/fake/main/print/common.c program/fake/main/print/context.c program/fake/main/print/error.c program/fake/main/print/message.c program/fake/main/print/operation.c program/fake/main/print/warning.c program/fake/main/print/verbose.c program/fake/main/signal.c program/fake/main/skeleton.c program/fake/main/thread.c
build_sources_program program/fake/main/build/enumeration.c program/fake/main/build/library.c program/fake/main/build/load.c program/fake/main/build/object.c program/fake/main/build/objects.c program/fake/main/build/print/compile.c program/fake/main/build/print/error.c program/fake/main/build/print/message.c program/fake/main/build/print/verbose.c program/fake/main/build/print/warning.c program/fake/main/build/program.c program/fake/main/build/skeleton.c program/fake/main/build/string.c
build_sources_program program/fake/main/common/define.c program/fake/main/common/enumeration.c program/fake/main/common/print.c program/fake/main/common/string.c program/fake/main/common/type.c
build_sources_program program/fake/main/fake/path_generate.c
if (!data || !data->main) return;
if (data->main->setting.state.status == F_child) return;
if (F_status_is_error(data->main->setting.state.status) || f_file_exists(file_stage, F_true) == F_true) return;
+ if (fake_signal_check(data->main)) return;
fake_main_t * const main = data->main;
- if (!((++main->program.signal_check) % fake_signal_check_d)) {
- if (fll_program_standard_signal_received(&main->program)) {
- fll_program_print_signal_received(&main->program.warning, main->program.signal_received);
-
- main->setting.state.status = F_status_set_error(F_interrupt);
-
- return;
- }
- }
-
f_directory_statuss_t failures = f_directory_statuss_t_initialize;
f_string_dynamic_t path_source = f_string_dynamic_t_initialize; // @todo move this to a shared buffer.
f_string_dynamic_t destination_file = f_string_dynamic_t_initialize;
main->setting.state.status = fll_execute_program(main->cache_argument, main->cache_arguments, ¶meter, 0, (void *) &return_code);
- if (!((++main->program.signal_check) % fake_signal_check_d) && fll_program_standard_signal_received(&main->program)) {
- fll_program_print_signal_received(&main->program.warning, main->program.signal_received);
+ if (fake_signal_check(main)) return return_code;
- main->setting.state.status = F_status_set_error(F_interrupt);
- }
- else if (main->setting.state.status != F_child) {
+ if (main->setting.state.status != F_child) {
if (F_status_is_error(main->setting.state.status)) {
if (F_status_set_fine(main->setting.state.status) == F_failure) {
fake_print_error_failure_script(&main->program.error, main->cache_argument);
void fake_build_operate(fake_data_t * const data, const f_string_statics_t * const build_arguments, const bool process_pipe) {
if (!data || !data->main) return;
+ if (fake_signal_check(data->main)) return;
fake_main_t * const main = data->main;
- if (!((++main->program.signal_check) % fake_signal_check_d)) {
- if (fll_program_standard_signal_received(&main->program)) {
- fll_program_print_signal_received(&main->program.warning, main->program.signal_received);
-
- main->setting.state.status = F_status_set_error(F_interrupt);
-
- return;
- }
- }
-
main->setting.state.status = F_none;
f_mode_t mode = f_mode_t_initialize;
if (!data || !data->main) return;
if (F_status_is_error(data->main->setting.state.status)) return;
+ if (fake_signal_check(data->main)) return;
fake_main_t * const main = data->main;
- if (!((++main->program.signal_check) % fake_signal_check_d)) {
- if (fll_program_standard_signal_received(&main->program)) {
- fll_program_print_signal_received(&main->program.warning, main->program.signal_received);
-
- main->setting.state.status = F_status_set_error(F_interrupt);
-
- return;
- }
- }
-
f_mode_t mode = f_mode_t_initialize;
macro_f_mode_t_set_default_umask(mode, main->program.umask);
if (!data || !data->main || !setting) return;
if (F_status_is_error(data->main->setting.state.status)) return;
+ if (fake_signal_check(data->main)) return;
fake_main_t * const main = data->main;
- if (!((++main->program.signal_check) % fake_signal_check_d)) {
- if (fll_program_standard_signal_received(&main->program)) {
- fll_program_print_signal_received(&main->program.warning, main->program.signal_received);
-
- main->setting.state.status = F_status_set_error(F_interrupt);
-
- return;
- }
- }
-
// Strip the build settings name from the build arguments to generate a list of modes.
f_string_statics_t modes_custom = f_string_statics_t_initialize;
modes_custom.used = build_arguments && build_arguments->used > 1 ? build_arguments->used - 1 : 0;
if (!data || !data->main || !setting) return;
if (F_status_is_error(data->main->setting.state.status) && buffer.used) return;
+ if (fake_signal_check(data->main)) return;
fake_main_t * const main = data->main;
- if (!((++main->program.signal_check) % fake_signal_check_d)) {
- if (fll_program_standard_signal_received(&main->program)) {
- fll_program_print_signal_received(&main->program.warning, main->program.signal_received);
-
- main->setting.state.status = F_status_set_error(F_interrupt);
-
- return;
- }
- }
-
bool error_printed = F_false;
f_string_dynamics_t build_compiler = f_string_dynamics_t_initialize;
if (!data || !data->main || !stage) return;
if (F_status_is_error(data->main->setting.state.status)) return;
+ if (fake_signal_check(data->main)) return;
fake_main_t * const main = data->main;
- if (!((++main->program.signal_check) % fake_signal_check_d)) {
- if (fll_program_standard_signal_received(&main->program)) {
- fll_program_print_signal_received(&main->program.warning, main->program.signal_received);
-
- main->setting.state.status = F_status_set_error(F_interrupt);
-
- return;
- }
- }
-
const f_string_static_t names[] = {
fake_build_stage_library_script_s,
fake_build_stage_library_shared_s,
for (j = 0; j < directorys[i].used; ++j) {
if (f_path_separator_s.used && directorys[i].string[j] != f_path_separator_s.string[0]) continue;
-
- if (!((++main->program.signal_check) % fake_signal_check_d)) {
- if (fll_program_standard_signal_received(&main->program)) {
- fll_program_print_signal_received(&main->program.warning, main->program.signal_received);
-
- main->setting.state.status = F_status_set_error(F_interrupt);
-
- return;
- }
- }
+ if (fake_signal_check(data->main)) return;
directorys[i].string[j] = 0;
* The program signal defines.
*
* fake_signal_*_d:
- * - check: Number of iterations before performing signal check in non-threaded signal handling.
- * - check_tiny: The tiny check.
- * - check_short: The short signal check.
+ * - check: Number of iterations before performing signal check in non-threaded signal handling.
+ * - check_failsafe: When using threads, how many consecutive failures to check signal before aborting (as a recursion failsafe).
+ * - check_tiny: The tiny check.
+ * - check_short: The short signal check.
*/
#ifndef _di_fake_signal_d_
- #define fake_signal_check_d 500000
- #define fake_signal_check_tiny_d 4
- #define fake_signal_check_short_d 16
+ #define fake_signal_check_d 500000
+ #define fake_signal_check_failsafe_d 20000
+ #define fake_signal_check_tiny_d 4
+ #define fake_signal_check_short_d 16
#endif // _di_fake_signal_d_
/**
"f_account_group_id_by_name",
"f_account_id_by_name",
"f_array_lengths_increase",
+ "f_compare_dynamic_partial",
"f_console_parameter_prioritize_right",
"f_console_parameter_process",
"f_conversion_number_signed_to_string",
"f_string_dynamics_increase_by",
"f_string_dynamics_resize",
"f_string_map_multis_resize",
+ "f_thread_create",
"f_uint8s_increase",
"f_uint8s_increase_by",
"f_utf_is_word_dash_plus",
"fl_environment_load_name",
"fl_environment_load_names",
"fl_iki_read",
- "f_compare_dynamic_partial",
"fll_execute_arguments_add",
"fll_execute_arguments_add_parameter_set",
"fll_execute_program",
"fake_make_assure_inside_project",
"fake_make_get_id",
"fake_make_get_id_mode",
- "fake_make_get_id",
"fake_make_operate_expand_build",
"fake_make_operate_expand_context",
"fake_make_operate_expand_environment",
fake_f_f_account_group_id_by_name_e,
fake_f_f_account_id_by_name_e,
fake_f_f_array_lengths_increase_e,
+ fake_f_f_compare_dynamic_partial_e,
fake_f_f_console_parameter_prioritize_right_e,
fake_f_f_console_parameter_process_e,
fake_f_f_conversion_number_signed_to_string_e,
fake_f_f_string_dynamics_increase_by_e,
fake_f_f_string_dynamics_resize_e,
fake_f_f_string_map_multis_resize_e,
+ fake_f_f_thread_create_e,
fake_f_f_uint8s_increase_e,
fake_f_f_uint8s_increase_by_e,
fake_f_f_utf_is_word_dash_plus_e,
fake_f_fl_environment_load_name_e,
fake_f_fl_environment_load_names_e,
fake_f_fl_iki_read_e,
- fake_f_f_compare_dynamic_partial_e,
fake_f_fll_execute_arguments_add_e,
fake_f_fll_execute_arguments_add_parameter_set_e,
fake_f_fll_execute_program_e,
*
* flag: Flags passed to the main function.
*
- * state: The state data used when processing the FSS data.
+ * status_thread: A status used eclusively by the threaded signal handler.
+ * state: The state data used when processing the FSS data.
*
* build: The build directory.
* data: The data directory.
typedef struct {
uint32_t flag;
+ f_status_t status_thread;
f_state_t state;
f_string_dynamic_t build;
#define fake_setting_t_initialize \
{ \
0, \
+ F_none, \
f_state_t_initialize, \
f_string_dynamic_t_initialize, \
f_string_dynamic_t_initialize, \
fl_execute_parameter_t parameter = macro_fl_execute_parameter_t_initialize(0, 0, &environment, &signals, 0);
main->setting.state.status = fll_execute_program(program, main->cache_arguments, ¶meter, 0, (void *) &return_code);
-
- if (!((++main->program.signal_check) % fake_signal_check_d)) {
- if (fll_program_standard_signal_received(&main->program)) {
- fll_program_print_signal_received(&main->program.warning, main->program.signal_received);
-
- main->setting.state.status = F_status_set_error(F_interrupt);
-
- return 0;
- }
- }
-
+ if (fake_signal_check(data->main)) return return_code;
if (main->setting.state.status == F_child) return return_code;
}
else {
void fake_file_buffer(fake_data_t * const data, const f_string_static_t path_file, const bool required, f_string_dynamic_t * const buffer) {
if (!data || !data->main || !buffer) return;
+ if (fake_signal_check(data->main)) return;
fake_main_t * const main = data->main;
- if (!((++main->program.signal_check) % fake_signal_check_d)) {
- if (fll_program_standard_signal_received(&main->program)) {
- fll_program_print_signal_received(&main->program.warning, main->program.signal_received);
-
- main->setting.state.status = F_status_set_error(F_interrupt);
-
- return;
- }
- }
-
main->setting.state.status = f_file_exists(path_file, F_true);
if (F_status_is_error(main->setting.state.status)) {
clearerr(F_type_input_d);
do {
- if (!((++main->program.signal_check) % fake_signal_check_d)) {
- if (fll_program_standard_signal_received(&main->program)) {
- fll_program_print_signal_received(&main->program.warning, main->program.signal_received);
-
- main->setting.state.status = F_status_set_error(F_interrupt);
-
- return;
- }
- }
+ if (fake_signal_check(main)) return;
main->setting.state.status = f_file_stream_read_block(file, buffer);
void fake_validate_parameter_paths(fake_data_t * const data) {
if (!data || !data->main) return;
+ if (fake_signal_check(data->main)) return;
fake_main_t * const main = data->main;
- if (!((++main->program.signal_check) % fake_signal_check_d)) {
- if (fll_program_standard_signal_received(&main->program)) {
- fll_program_print_signal_received(&main->program.warning, main->program.signal_received);
-
- main->setting.state.status = F_status_set_error(F_interrupt);
-
- return;
- }
- }
-
const f_string_static_t names[] = {
fake_long_build_s,
fake_long_data_s,
#include <program/fake/main/print/operation.h>
#include <program/fake/main/print/verbose.h>
#include <program/fake/main/print/warning.h>
+#include <program/fake/main/signal.h>
#include <program/fake/main/skeleton.h>
+#include <program/fake/main/thread.h>
#ifdef __cplusplus
extern "C" {
f_file_umask_get(&data.program.umask);
- {
- const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize(argc, argv, envp);
+ #ifdef _di_thread_support_
+ {
+ const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize(argc, argv, envp);
- fake_setting_load(arguments, &data);
- }
+ fake_setting_load(arguments, &data);
+ }
+
+ fake_main(&data);
+ #else
+ {
+ f_thread_id_t id_signal;
+
+ memset(&id_signal, 0, sizeof(f_thread_id_t));
+
+ data.setting.state.status = f_thread_create(0, &id_signal, &fake_thread_signal, (void *) &data);
+
+ if (F_status_is_error(data.setting.state.status)) {
+ fake_print_error(&data.program.error, macro_fake_f(f_thread_create));
+ }
+ else {
+ {
+ const f_console_arguments_t arguments = macro_f_console_arguments_t_initialize(argc, argv, envp);
+
+ fake_setting_load(arguments, &data);
+ }
+
+ if (!fake_signal_check(&data)) {
+ fake_main(&data);
+ }
- fake_main(&data);
+ f_thread_cancel(id_signal);
+ f_thread_join(id_signal, 0);
+ }
+ }
+ #endif // _di_thread_support_
fake_main_delete(&data);
void fake_make_operate(fake_data_t * const data) {
if (!data || !data->main) return;
+ if (fake_signal_check(data->main)) return;
fake_main_t * const main = data->main;
- if (!((++main->program.signal_check) % fake_signal_check_d)) {
- if (fll_program_standard_signal_received(&main->program)) {
- fll_program_print_signal_received(&main->program.warning, main->program.signal_received);
-
- main->setting.state.status = F_status_set_error(F_interrupt);
-
- return;
- }
- }
-
fake_make_print_message_now_making(&main->program.message, main->setting.fakefile);
f_array_lengths_t section_stack = f_array_lengths_t_initialize;
--- /dev/null
+#include "fake.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(_di_fake_signal_check_) && defined(_di_thread_support_)
+ f_status_t fake_signal_check(fake_main_t * const main) {
+
+ if (!main) return F_false;
+ if (main->program.signal.id == -1) return F_false;
+
+ if (!((++main->program.signal_check) % fake_signal_check_d)) {
+ if (fll_program_standard_signal_received(&main->program)) {
+ fll_program_print_signal_received(&main->program.warning, main->program.signal_received);
+
+ main->setting.state.status = F_status_set_error(F_interrupt);
+
+ return F_true;
+ }
+
+ main->program.signal_check = 0;
+ }
+
+ return F_false;
+ }
+#endif // !defined(_di_fake_signal_check_) && defined(_di_thread_support_)
+
+#if !defined(_di_fake_signal_check_) && !defined(_di_thread_support_)
+ f_status_t fake_signal_check(fake_main_t * const main) {
+
+ if (!main) return F_false;
+ if (main->program.signal.id == -1) return F_false;
+
+ if (main->program.signal_received) {
+ fll_program_print_signal_received(&main->program.warning, main->program.signal_received);
+
+ main->setting.state.status = F_status_set_error(F_interrupt);
+
+ return F_true;
+ }
+
+ return F_false;
+ }
+#endif // !defined(_di_fake_signal_check_) && !defined(_di_thread_support_)
+
+#if !defined(_di_fake_signal_handler_) && !defined(_di_thread_support_)
+ void fake_signal_handler(fake_main_t * const main) {
+
+ if (!main) return;
+
+ siginfo_t information;
+ f_array_length_t failsafe = 0;
+
+ memset(&information, 0, sizeof(siginfo_t));
+
+ main->program.signal_received = 0;
+
+ f_signal_set_empty(&main->program.signal.set);
+ f_signal_set_add(F_signal_abort, &main->program.signal.set);
+ f_signal_set_add(F_signal_broken_pipe, &main->program.signal.set);
+ f_signal_set_add(F_signal_hangup, &main->program.signal.set);
+ f_signal_set_add(F_signal_interrupt, &main->program.signal.set);
+ f_signal_set_add(F_signal_quit, &main->program.signal.set);
+ f_signal_set_add(F_signal_termination, &main->program.signal.set);
+
+ if (main->program.signal.id == -1) {
+ main->setting.status_thread = f_signal_open(&main->program.signal);
+
+ if (F_status_is_error(main->setting.status_thread)) {
+ main->program.signal_received = F_signal_abort;
+
+ return;
+ }
+ }
+
+ do {
+ memset(&information, 0, sizeof(siginfo_t));
+
+ main->setting.status_thread = f_signal_wait(&main->program.signal.set, &information);
+
+ if (F_status_is_error(main->setting.status_thread) && F_status_set_fine(main->setting.status_thread) != F_interrupt) {
+ if (++failsafe >= fake_signal_check_failsafe_d) break;
+ }
+
+ switch (information.si_signo) {
+ case F_signal_abort:
+ case F_signal_broken_pipe:
+ case F_signal_hangup:
+ case F_signal_interrupt:
+ case F_signal_quit:
+ case F_signal_termination:
+ main->program.signal_received = information.si_signo;
+
+ break;
+ }
+
+ failsafe = 0;
+ main->setting.status_thread = F_none;
+
+ } while (!main->program.signal_received);
+
+ f_signal_close(&main->program.signal);
+
+ if (F_status_is_error(main->setting.status_thread)) {
+ main->program.signal_received = F_signal_abort;
+ }
+ }
+#endif // !defined(_di_fake_signal_handler_) && !defined(_di_thread_support_)
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 3
+ *
+ * Project: Featureless Make
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Provides signal functionality.
+ *
+ * This is auto-included and should not need to be explicitly included.
+ */
+#ifndef _fake_signal_h
+#define _fake_signal_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Check to see if a signal is received.
+ *
+ * If main.signal is non-zero, then this handles the following signals:
+ * - F_signal_abort
+ * - F_signal_broken_pipe
+ * - F_signal_hangup
+ * - F_signal_interrupt
+ * - F_signal_quit
+ * - F_signal_termination
+ *
+ * There is a threaded and a non-threaded version of this.
+ * The non-threaded version checks periodically using fake_signal_check_d and updates main->signal_check as needed.
+ * The threaded version checks the flag state which is set by a separate thread that is blocking until signal is received.
+ *
+ * @param main
+ * The main program and settings data.
+ *
+ * This does not alter main.setting.state.status.
+ *
+ * @return
+ * F_true on signal received.
+ * F_false otherwise.
+ *
+ * @see fake_signal_handler()
+ *
+ * @see fll_program_standard_signal_received()
+ */
+#ifndef _di_fake_signal_check_
+ extern f_status_t fake_signal_check(fake_main_t * const main);
+#endif // _di_fake_signal_check_
+
+/**
+ * Signal handler for signals/interrupts.
+ *
+ * This blocks until an expected signal is recieved.
+ * When an expected signal is received it then sets the
+ *
+ * If main.signal is non-zero, then this handles the following signals:
+ * - F_signal_abort
+ * - F_signal_broken_pipe
+ * - F_signal_hangup
+ * - F_signal_interrupt
+ * - F_signal_quit
+ * - F_signal_termination
+ *
+ * @param main
+ * The main program and settings data.
+ *
+ * This alters main.program.signal_received, setting it to a received signal.
+ *
+ * This alters setting.status:
+ * Errors with (error bit set) from: f_signal_open()
+ * Errors with (error bit set) from: f_signal_wait()
+ *
+ * @see f_signal_close()
+ * @see f_signal_open()
+ * @see f_signal_wait()
+ */
+#if !defined(_di_fake_signal_handler_) && !defined(_di_thread_support_)
+ extern void fake_signal_handler(fake_main_t * const main);
+#endif // !defined(_di_fake_signal_handler_) && !defined(_di_thread_support_)
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _fake_signal_h
--- /dev/null
+#include "fake.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(_di_fake_thread_signal_) && !defined(_di_thread_support_)
+ void * fake_thread_signal(void * const main) {
+
+ f_thread_cancel_state_set(PTHREAD_CANCEL_DEFERRED, 0);
+
+ if (main) {
+ fake_signal_handler((fake_main_t *) main);
+ }
+
+ return 0;
+ }
+#endif // !defined(_di_fake_thread_signal_) && !defined(_di_thread_support_)
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 3
+ *
+ * Project: Featureless Make
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Provides thread functionality.
+ *
+ * This is auto-included and should not need to be explicitly included.
+ */
+#ifndef _fake_thread_h
+#define _fake_thread_h
+
+/**
+ * Thread handler for signals/interrupts.
+ *
+ * If main.signal is non-zero, then this handles the following signals:
+ * - F_signal_abort
+ * - F_signal_broken_pipe
+ * - F_signal_hangup
+ * - F_signal_interrupt
+ * - F_signal_quit
+ * - F_signal_termination
+ *
+ * @param main
+ * The program and settings data.
+ *
+ * Must be of type fake_main_t.
+ *
+ * @return
+ * 0, always.
+ *
+ * @see f_thread_cancel_state_set()
+ *
+ * @see fake_signal_handler()
+ */
+#if !defined(_di_fake_thread_signal_) && !defined(_di_thread_support_)
+ extern void * fake_thread_signal(void * const main);
+#endif // !defined(_di_fake_thread_signal_) && !defined(_di_thread_support_)
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _fake_thread_h
# fss-0000
_di_libcap_ Disable libcap support, allow for compiling and linking without libcap (-lcap).
+_di_thread_support_ Disables thread support.
_libcap_legacy_only_ Disable functionality provided by later versions of libcap (2.43 and later).
_pthread_attr_unsupported_ Disable non-portable functionality associated with pthread_attr.
build_libraries-level -lfll_2 -lfll_1 -lfll_0
build_libraries-monolithic -lfll
-build_sources_library main/build.c main/clean.c main/common.c main/fake.c main/make.c main/print/common.c main/print/context.c main/print/error.c main/print/message.c main/print/operation.c main/print/warning.c main/print/verbose.c main/skeleton.c
+build_sources_library main/build.c main/clean.c main/common.c main/fake.c main/make.c main/print/common.c main/print/context.c main/print/error.c main/print/message.c main/print/operation.c main/print/warning.c main/print/verbose.c main/signal.c main/skeleton.c main/thread.c
build_sources_library main/build/enumeration.c main/build/library.c main/build/load.c main/build/object.c main/build/objects.c main/build/print/compile.c main/build/print/error.c main/build/print/message.c main/build/print/verbose.c main/build/print/warning.c main/build/program.c main/build/skeleton.c main/build/string.c
build_sources_library main/common/define.c main/common/enumeration.c main/common/print.c main/common/string.c main/common/type.c
build_sources_library main/fake/path_generate.c
build_sources_program main/main.c
-build_sources_headers main/build.h main/clean.h main/common.h main/fake.h main/make.h main/print/common.h main/print/context.h main/print/error.h main/print/message.h main/print/operation.h main/print/warning.h main/print/verbose.h main/skeleton.h
+build_sources_headers main/build.h main/clean.h main/common.h main/fake.h main/make.h main/print/common.h main/print/context.h main/print/error.h main/print/message.h main/print/operation.h main/print/warning.h main/print/verbose.h main/signal.h main/skeleton.h main/thread.h
build_sources_headers main/build/enumeration.h main/build/library.h main/build/load.h main/build/object.h main/build/objects.h main/build/print/compile.h main/build/print/error.h main/build/print/message.h main/build/print/verbose.h main/build/print/warning.h main/build/program.h main/build/skeleton.h main/build/string.h
build_sources_headers main/common/define.h main/common/enumeration.h main/common/print.h main/common/string.h main/common/type.h
build_sources_headers main/fake/path_generate.h