for main, it has dependency list.o and main.o, which both don't exist in directory. 

list.o has dependency list.c and main.o has dependency main.c. Both list.c and main.c are in directory

Why this code does not create main.o before main
typedef struct action_node {
    char **args;  // An array of strings suitable to be passed to execvp
    struct action_node *next_act;
} Action;

typedef struct dep_node {
    struct rule_node *rule;
    struct dep_node *next_dep;
} Dependency;

typedef struct rule_node {
    char *target;
    Dependency *dependencies;
    Action *actions;
    struct rule_node *next_rule;
} Rule;

void execute(Rule *rule) {
    if (rule != NULL) {
        Action *act = rule->actions;
        while (act != NULL) {
            if (execvp((act->args)[0], act->args) == -1) {
                printf("%s executed fail", rule->target);  //
                exit(1);
            } else {
                printf("%s executed success", rule->target);  //
            }
            act = act->next_act;
        }
    }
}

void run_make(char *target, Rule *rules, int pflag) {
    Rule *rule = rules.find_rule(target);
    // evaluate dependency
    Dependency *curr_dep = rule->dependencies;
    if (curr_dep == NULL) {
        execute(rule);
        return;
    }

    int to_execute = 0;
    while (curr_dep != NULL) {
        pid_t pid = fork();
        if (pid == -1) {
            perror("fork");
            exit(1);
        } else if (pid == 0) {                                     // child
            printf("child target: %s\n", curr_dep->rule->target);  //
            run_make(curr_dep->rule->target, rules, pflag);
            exit(0);
        } else {  // parent
            int status;
            pid_t wpid;
            if ((wpid = waitpid(-1, &status, 0)) == -1) {
                perror("waitpid");
            }
            if (WIFEXITED(status) && WEXITSTATUS(status) != 0) {
                exit(WEXITSTATUS(status));
            }

            // target not exist
            if (access(rule->target, F_OK) != -1) {
                to_execute = 1;
            }

            // compare time with dependency
            Dependency *curr_dep1 = rule->dependencies;
            while (curr_dep1 != NULL) {
                if (curr_dep1->rule->time > rule->time) {
                    to_execute = 1;
                    break;
                }
                curr_dep1 = curr_dep1->next_dep;
            }
            if (to_execute == 1) {
                execute(rule);
            }
        }
        curr_dep = curr_dep->next_dep;
    }
}