代码之家  ›  专栏  ›  技术社区  ›  Gianni Spear

使用Clion IDE对函数的未定义引用

  •  1
  • Gianni Spear  · 技术社区  · 8 年前

    我使用Clion-Jetbrain IDE在linux上用C编写了一个(我的第一个)程序。当我尝试在调试模式下编译时,出现了以下错误消息“undefined reference to”(未定义的引用)引用了我在两个*.c文件(accessory.c和logmanager.c)中编写的函数。

    我试着按照我在网上和stackoverflow上找到的所有指令,尽可能地设置*.c和header*.h文件。

    我想知道在克莱恩设置我的ETCS项目的Cmakelist是否有问题。

    错误:

    /opt/clion-2018.2/bin/cmake/linux/bin/cmake --build /home/alessandro/CLionProjects/ETCS/cmake-build-debug --target ETCS -- -j 1
    Scanning dependencies of target ETCS
    [ 50%] Building C object CMakeFiles/ETCS.dir/serverRCB.c.o
    [100%] Linking C executable ETCS
    CMakeFiles/ETCS.dir/serverRCB.c.o: nella funzione "main":
    /home/alessandro/CLionProjects/ETCS/serverRCB.c:72: undefined reference to "dispaly_array"
    /home/alessandro/CLionProjects/ETCS/serverRCB.c:75: rundefined reference to "dispaly_array"
    /home/alessandro/CLionProjects/ETCS/serverRCB.c:118: undefined reference to "create_logfile"
    /home/alessandro/CLionProjects/ETCS/serverRCB.c:143: rundefined reference to "get_train_name"
    /home/alessandro/CLionProjects/ETCS/serverRCB.c:144: undefined reference to "get_track_name"
    /home/alessandro/CLionProjects/ETCS/serverRCB.c:145: undefined reference to "get_track_name"
    /home/alessandro/CLionProjects/ETCS/serverRCB.c:165: undefined reference to "update_logfileETCS2"
    /home/alessandro/CLionProjects/ETCS/serverRCB.c:195: undefined reference to "update_logfileETCS2"
    /home/alessandro/CLionProjects/ETCS/serverRCB.c:219: undefined reference to "update_logfileETCS2"
    /home/alessandro/CLionProjects/ETCS/serverRCB.c:239: undefined reference to "update_logfileETCS2"
    /home/alessandro/CLionProjects/ETCS/serverRCB.c:263: undefined reference to "update_logfileETCS2"
    /home/alessandro/CLionProjects/ETCS/serverRCB.c:271: undefined reference to "dispaly_array"
    /home/alessandro/CLionProjects/ETCS/serverRCB.c:275: undefined reference to "dispaly_array"
    collect2: error: ld returned 1 exit status
    CMakeFiles/ETCS.dir/build.make:83: set di istruzioni per l'obiettivo "ETCS" non riuscito
    make[3]: *** [ETCS] Errore 1
    CMakeFiles/Makefile2:72: set di istruzioni per l'obiettivo "CMakeFiles/ETCS.dir/all" non riuscito
    make[2]: *** [CMakeFiles/ETCS.dir/all] Errore 2
    CMakeFiles/Makefile2:84: set di istruzioni per l'obiettivo "CMakeFiles/ETCS.dir/rule" non riuscito
    make[1]: *** [CMakeFiles/ETCS.dir/rule] Errore 2
    Makefile:118: set di istruzioni per l'obiettivo "ETCS" non riuscito
    make: *** [ETCS] Errore 2
    

    主要: serverRBC.c

    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netdb.h>
    #include <sys/un.h>
    #include <unistd.h>
    #include <stdlib.h>
    
    #include "accessory.h"
    #include "logfilemanager.h"
    
    
    #define SIZE 256
    
    #define NUMBER_TRAINS 5
    #define NUMBER_TRACKS 16
    #define NUMBER_STATIONS 8
    
    #define SERVER_SOCK_FILE  "servertest"
    #define CLIENT_SOCK_FILE  "clientsocket"
    #define SERVERNAME "RCB"
    
    
    char * train;
    char * actual;
    char * request;
    char name_train[3];
    char name_actual[5];
    char name_request[5];
    
    
    
    int get_actual_index(int fd, int size);
    int get_request_index(int fd, int size);
    int get_train_index(int fd, int size);
    
    
    int main(int argc , char *argv[]) {
    
        int tracks_array[NUMBER_TRACKS];
        int stations_array[NUMBER_STATIONS];
        char server_name[10];
    
        char * logprint;
        char * display_tracks;
        char * display_stations;
    
        int sockfd;
        int clientfd;
        int fdlog;
    
        socklen_t client_len;
        size_t len_socket_structure;
        struct sockaddr_un server_socketaddr;
        struct sockaddr_un client_socketaddr;
    
        client_len = sizeof(client_socketaddr);
    
    
    
        memset(tracks_array, 0, sizeof(display_tracks));
        memset(stations_array, 0, sizeof(stations_array));
        memset(server_name, 0, sizeof(server_name));
    
    
        // AGGIUNGERE INFORMAZIONI RICEVUTE DAL PADRE
    
        /* upddate Stations Array*/
    
    
    
        display_tracks = dispaly_array(tracks_array, NUMBER_TRACKS);
        printf("Tracks: %s - \n", display_tracks);
    
        display_stations = dispaly_array(stations_array, NUMBER_STATIONS);
        printf("Tracks: %s - \n", display_stations);
    
    
        /* Clear address structure */
        memset(&server_socketaddr, 0, sizeof(server_socketaddr));
        memset(&server_socketaddr, 0, sizeof(client_socketaddr));
    
    
        /* first call to socket() function*/
        sockfd = socket(AF_UNIX , SOCK_STREAM , 0);
        if (sockfd == -1) {
            perror("ERROR Server socket");
            exit(1);
        }
        puts("Server socket created");
    
    
        /* Initialize the server_socketaddr socket address. */
        server_socketaddr.sun_family = AF_LOCAL;
        strncpy(server_socketaddr.sun_path, SERVER_SOCK_FILE, sizeof(server_socketaddr.sun_path)-1);
        unlink(server_socketaddr.sun_path);
    
        /* lenght of the structure */
        len_socket_structure = strlen(server_socketaddr.sun_path) + sizeof(server_socketaddr.sun_family);
    
        /* assigning a name to a socket */
        if(bind(sockfd, (struct sockaddr *) &server_socketaddr, len_socket_structure) == -1)
        {
            perror("ERROR Server bind");
            exit(1);
        };
    
        puts("Server binding completed\n");
    
        if(listen(sockfd, NUMBER_TRAINS) == -1){
            perror("ERROR Server listen");
            exit(1);
        };
    
        puts("listening server\n");
    
        strcpy(server_name, SERVERNAME);
        fdlog = create_logfile(server_name, SIZE);
    
    
        while(1)
        {
            clientfd = accept(sockfd, (struct sockaddr *) &client_socketaddr, &client_len);
            while(clientfd == -1)
            {
                perror("ERROR Server accept");
                clientfd = accept(sockfd, (struct sockaddr *) &client_socketaddr, &client_len);
            }
    
            int train_index;
            int actual_index;
            int request_index;
            int status;
    
            memset(name_train, '\0', sizeof(name_train));
            memset(name_actual, '\0', sizeof(name_actual));
            memset(name_request, '\0', sizeof(name_request));
    
            train_index = get_train_index(clientfd, SIZE);
            actual_index = get_actual_index(clientfd, SIZE);
            request_index = get_request_index(clientfd, SIZE);
    
            train = get_train_name(train_index);
            actual = get_track_name(actual_index);
            request = get_track_name(request_index);
    
            strcpy(name_train, train);
            strcpy(name_actual, actual);
            strcpy(name_request, request);
    
            printf("Train %s: from %s to %s\n", name_train, name_actual, name_request);
            fflush(stdout);
    
            /* Server protocol */
    
            if(request_index > 20)
            {
    
                /* From Track to Station */
                printf("Train %s: required authorisation to move in %s\n", name_train, name_request);
                fflush(stdout);
                printf("Server %s: authorisation granted\n", SERVERNAME);
                fflush(stdout);
                write(clientfd, "0", 10);
                logprint = update_logfileETCS2(fdlog, train_index, actual_index, request_index, 0);
                printf("Server %s: %s\n", SERVERNAME, logprint);
                fflush(stdout);
    
                // RISPOSTA da TRENO WHILE
    
    
                printf("Train %s: leaving the track %s\n", name_train, name_actual);
                fflush(stdout);
                tracks_array[actual_index - 1] = 0;
                printf("Train %s: entered in the station %s\n", name_train, name_request);
                fflush(stdout);
                stations_array[request_index - 21] = 1;
    
            } else {
    
                if(actual_index > 20)
                {
                    /* From Station to Track */
                    printf("Train %s: required authorisation to move in %s\n", name_train, name_request);
                    fflush(stdout);
    
                    status = tracks_array[request_index - 1];
    
                    if(status == 0)
                    {
    
                        printf("Server %s: authorisation granted\n", SERVERNAME);
                        fflush(stdout);
                        write(clientfd, "0", 10);
                        logprint = update_logfileETCS2(fdlog, train_index, actual_index, request_index, 0);
                        printf("Server %s: %s\n", SERVERNAME, logprint);
                        fflush(stdout);
    
    
    
                        // RISPOSTA da TRENO WHILE
    
    
    
                        printf("Train %s: leaving the station %s\n", name_train, name_actual);
                        fflush(stdout);
                        stations_array[actual_index - 21] = 0;
    
                        /* update array*/
                        printf("Train %s: entered in the track %s\n", name_train, name_request);
                        fflush(stdout);
                        tracks_array[request_index - 1] = 1;
    
                    } else {
    
                        printf("Server %s: authorisation denied\n", SERVERNAME);
                        fflush(stdout);
                        write(clientfd, "1", 10);
                        logprint = update_logfileETCS2(fdlog, train_index, actual_index, request_index, 1);
                        printf("Server %s: %s\n", SERVERNAME, logprint);
                        fflush(stdout);
    
                    }
    
                } else {
    
                    /* From Track to Track */
                    printf("Train %s: required authorisation to move in %s\n", name_train, name_request);
                    fflush(stdout);
    
                    status = tracks_array[request_index - 1];
    
                    if(status == 0)
                    {
    
                        printf("Server %s: authorisation granted\n", SERVERNAME);
                        fflush(stdout);
                        write(clientfd, "0", 10);
                        logprint = update_logfileETCS2(fdlog, train_index, actual_index, request_index, 0);
                        printf("Server %s: %s\n", SERVERNAME, logprint);
                        fflush(stdout);
    
    
    
                        // RISPOSTA da TRENO WHILE
    
    
    
                        printf("Train %s: leaving the track %s\n", name_train, name_actual);
                        fflush(stdout);
                        tracks_array[actual_index - 21] = 0;
    
                        /* update array*/
                        printf("Train %s: entered in the track %s\n", name_train, name_request);
                        fflush(stdout);
                        tracks_array[request_index - 1] = 1;
    
                    } else {
    
                        printf("Server %s: authorisation denied\n", SERVERNAME);
                        fflush(stdout);
                        write(clientfd, "1", 10);
                        logprint = update_logfileETCS2(fdlog, train_index, actual_index, request_index, 1);
                        printf("Server %s: %s\n", SERVERNAME, logprint);
                        fflush(stdout);
    
                    }
                }
            }
    
            display_tracks = dispaly_array(tracks_array, NUMBER_TRACKS);
            printf("Tracks: %s - \n", display_tracks);
            fflush(stdout);
    
            display_stations = dispaly_array(stations_array, NUMBER_STATIONS);
            printf("Tracks: %s - \n", display_stations);
            fflush(stdout);
    
            printf("Server %s is closed connection with %s\n", SERVERNAME, name_train);
            fflush(stdout);
            close(clientfd);
    
        } /* end of while*/
    }
    
    
    int get_actual_index(int fd, int size)
    {
        int track_index;
        char buffer[size];
        size_t nbytes;
        ssize_t bytes_read;
    
        memset(buffer, '\0', sizeof(buffer));
        nbytes = sizeof(buffer);
    
        bytes_read = read(fd, buffer, nbytes);
        if(bytes_read < 0)
        {
            perror("ERROR reading from get_current_index()");
            exit(1);
        }
        track_index = atoi(buffer);
        return track_index;
    }
    
    
    int get_request_index(int fd, int size)
    {
        int track_index;
        char buffer[size];
        size_t nbytes;
        ssize_t bytes_read;
    
        memset(buffer, '\0', sizeof(buffer));
        nbytes = sizeof(buffer);
    
        bytes_read = read(fd, buffer, nbytes);
        if(bytes_read < 0)
        {
            perror("ERROR reading from get_request_index()");
            exit(1);
        }
        track_index = atoi(buffer);
        return track_index;
    }
    
    
    int get_train_index(int fd, int size)
    {
        int train_index;
        char buffer[size];
        size_t nbytes;
        ssize_t bytes_read;
    
        memset(buffer, '\0', sizeof(buffer));
        nbytes = sizeof(buffer);
    
        bytes_read = read(fd, buffer, nbytes);
        if(bytes_read < 0)
        {
            perror("ERROR reading from get_train_index()");
            exit(1);
        }
        train_index = atoi(buffer);
        return train_index;
    }
    

    附件.h

    char * get_cwd(int size);
    char * get_file_name(char *name, char *ext, int size);
    void create_track_file(char *name, char *ext, int size);
    int map_index(char *name, char *prefix);
    char * get_track_name(int index);
    char * get_train_name(int index);
    char * read_file(char *name, char *ext, int size);
    int count_elements(char *line);
    int get_suffix(char *string, char *prefix);
    int * get_route(char *name, char *ext, int size);
    int check_track_file(int n_tracks, int size);
    void print_route(char *name, int *route);
    void print_create_file(char *name, int i, int n);
    char * dispaly_array(int array[], int len);
    

    附件c

    #include <unistd.h>
    #include <malloc.h>
    #include <string.h>
    #include <stdlib.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <dirent.h>
    
    #include "accessory.h"
    
    
    char * get_cwd(int size){
        char *file_path = malloc(sizeof(char)*size + 1);
        char cwd[size];
        if(getcwd(cwd, sizeof(cwd)) == NULL)
            perror("getcwd() error");
        strcpy(file_path, cwd);
        return file_path;
    }
    
    // reach the limit of Stackoverflow ///
    .........
    .........
    

    //达到堆垛溢出极限///

    char * dispaly_array(int array[], int len)
    {
        char * input_print = calloc(256, sizeof(char));
        char value_char[5];
    
        int value_int;
    
        memset(value_char, '\0', sizeof(value_char));
    
        strcpy(input_print, "[ ");
    
        for(int i = 0; i < len-1; i++)
        {
            value_int = array[i];
            sprintf(value_char, "%d", value_int);
            strcat(value_char, ", ");
            strcat(input_print, value_char);
            memset(value_char, '\0', sizeof(value_char));
        }
    
        value_int = array[len-1];
        sprintf(value_char, "%d", value_int);
        strcat(value_char, "]");
        strcat(input_print, value_char);
        return input_print;
    }
    

    日志管理器.h

    int create_logfile(char *name, int size);
    char * update_logfileETCS1(int fd, int step, int *route);
    char * update_logfileETCS2(int fd, int train_index, int actual_index, int request_index, int authorisation);
    

    日志管理器c

    #include <stdio.h>
    #include <malloc.h>
    #include <memory.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <stdlib.h>
    #include <time.h>
    
    #include "accessory.c"
    #include "logfilemanager.h"
    
    
    int create_logfile(char *name, int size)
    {
        char * file_name = get_file_name(name, ".log", size);
        umask(0);
        int fd = open(file_name, O_WRONLY | O_CREAT | O_APPEND | O_TRUNC, 0777);
        if (fd == -1)
        {
            perror("STATUS");
            exit(1);
        }
        return fd;
    }
    
    char * get_data_time()
    {
        char months_of_year[12][9+1] = {
                "Gennaio",
                "Febbraio",
                "Marzo",
                "Aprile",
                "Maggio",
                "Giugno",
                "Luglio",
                "Agosto",
                "Settembre",
                "Ottobre",
                "Novembre",
                "Dicembre"
        };
    
        char * data_time_string = malloc(sizeof(char)*50 + 1);
    
        time_t current_time;
        struct tm *local_time;
    
        current_time = time(NULL); // get current time
        local_time = localtime (&current_time); // Convert to local time format
    
        char day[2];
        char month[9];
        char year[4];
        char hour[2];
        char minute[2];
        char second[2];
    
        sprintf(day, "%d", (local_time -> tm_mday));
        strcpy(month, months_of_year[local_time -> tm_mon]);
        sprintf(year, "%d", ((local_time -> tm_year) + 1900));
        sprintf(hour, "%d", (local_time -> tm_hour));
        sprintf(minute, "%d", (local_time -> tm_min));
        sprintf(second, "%d", (local_time -> tm_sec));
    
        strcpy(data_time_string, day);
        strcat(data_time_string, " ");
        strcat(data_time_string, month);
        strcat(data_time_string, " ");
        strcat(data_time_string, year);
        strcat(data_time_string, " ");
        strcat(data_time_string, hour);
        strcat(data_time_string, ":");
        strcat(data_time_string, minute);
        strcat(data_time_string, ":");
        strcat(data_time_string, second);
    
        return data_time_string;
    }
    
    
    char * update_logfileETCS1(int fd, int step, int *route)
    {
        char * input_print = calloc(256, sizeof(char));
        char * actual;
        char * next;
        char * time_date;
        char name_actual[5];
        char name_next[5];
        char first[20];
        char second[20];
        char third[20];
    
        memset(name_actual, '\0', sizeof(name_actual));
        memset(name_next, '\0', sizeof(name_next));
        memset(first, '\0', sizeof(first));
        memset(second, '\0', sizeof(second));
        memset(third, '\0', sizeof(third));
    
        actual = get_track_name(route[step]);
        strcpy(name_actual, actual);
        strcpy(name_next, "--");
        if(step < route[0])
        {
            next = get_track_name(route[step+1]);
            strcpy(name_next, next);
        }
        first[20] = "[Attuale: ";
        second[20] = "], [Next: ";
        third[20] = "], ";
        strcpy(input_print, first);
        strcat(input_print, name_actual);
        strcat(input_print, second);
        strcat(input_print, name_next);
        strcat(input_print, third);
        time_date = get_data_time();
        strcat(input_print, time_date);
        strcat(input_print,"\n");
        write(fd, input_print, strlen(input_print));
        return input_print;
    }
    
    
    
    char * update_logfileETCS2(int fd, int train_index, int actual_index, int request_index, int authorisation)
    {
        char * input_print = calloc(256, sizeof(char));
        char * train;
        char * actual;
        char * request;
        char * t_date;
        char name_train[3];
        char name_actual[5];
        char name_request[5];
        char time_date[20];
        char first[20];
        char second[20];
        char third[20];
        char fourth[20];
        char fifth[20];
        char sixth[20];
    
        memset(name_train, '\0', sizeof(name_train));
        memset(name_actual, '\0', sizeof(name_actual));
        memset(name_request, '\0', sizeof(name_request));
        memset(time_date, '\0', sizeof(time_date));
        memset(first, '\0', sizeof(first));
        memset(second, '\0', sizeof(second));
        memset(third, '\0', sizeof(third));
        memset(fourth, '\0', sizeof(fourth));
        memset(fifth, '\0', sizeof(fifth));
        memset(sixth, '\0', sizeof(sixth));
    
        first[20] = "[TRENO RICHIEDENTE AUTORIZZAZIONE: ";
        second[20] = "], [SEGMENTO ATTUALE: ";
        third[20] = "], [SEGMENTO RICHIESTO: ";
        fourth[20] = "], [AUTORIZZATO: ";
        fifth[20] = "], [DATA: ";
        sixth[20] = "]\n";
    
        actual = get_track_name(actual_index);
        strcpy(name_actual, actual);
        strcpy(name_request, "--");
        if(request_index > 0)
        {
            request = get_track_name(request_index);
            strcpy(name_request, request);
        }
    
        train = get_train_name(train_index);
        strcpy(name_train, train);
        strcpy(input_print, first);
        strcat(input_print, name_train);
        strcat(input_print, second);
        strcat(input_print, name_actual);
        strcat(input_print, third);
        strcat(input_print, name_request);
        strcat(input_print, fourth);
        if(authorisation > 0)
        {
            strcat(input_print, "NO");
        } else {
            strcat(input_print, "SI");
        }
        strcat(input_print, fifth);
    
        t_date = get_data_time();
        strcpy(time_date, t_date);
        strcat(input_print, time_date);
    
        strcat(input_print, time_date);
        strcat(input_print, sixth);
        write(fd, input_print, strlen(input_print));
        return input_print;
    }
    

    Cmakelist公司

    cmake_minimum_required(VERSION 3.12)
    project(ETCS C)
    
    set(CMAKE_C_STANDARD 99)
    
    add_executable(ETCS serverRCB.c)
    
    1 回复  |  直到 8 年前
        1
  •  2
  •   Soner from The Ottoman Empire    8 年前

    您的add可执行文件没有其他源和头。应该是,

    add_executable(ETCS serverRBC.c accessory.h accessory.c logmanager.h logmanager.c)
    

    但是,你的主播的名字必须是 main.c . 如果你的 main() 方法处于 serverRBC.c ,您必须将其名称更改为 主c . 决赛 add_executable 应该是,

    add_executable(ETCS main.c accessory.h accessory.c logmanager.h logmanager.c)