c - 使用 Clion IDE 对函数的 undefined reference

标签 c debugging clion

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

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

我想知道在 Clion 中设置 Cmakelist insede 我的 ETCS 项目是否有问题。

错误:

/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 ///
.........
.........

//达到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;
}

生成列表

cmake_minimum_required(VERSION 3.12)
project(ETCS C)

set(CMAKE_C_STANDARD 99)

add_executable(ETCS serverRCB.c)

最佳答案

您添加的可执行文件没有其他源和 header 。应该是,

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

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

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

关于c - 使用 Clion IDE 对函数的 undefined reference ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51770560/

相关文章:

CLion 2022.1 : In template: call to '__builtin_operator_delete' selects non-usual deallocation function in

c - 我已经使用 Geforce GT 540M 分析了 Visual Studio 2010 和 CUDA 4.0,但 IDE 不知道一些关键字

c - 微型 C 编译器 (TCC) 和 winsock?

debugging - 是否应该修复不重要的错误,以免分散开发人员的注意力?

debugging - 如何更改编译器包含在二进制文件的 DWARF 信息中的调试路径

c++ - CMake 错误 "Expected a command name"

Clion 不打印到控制台

c# - 将具有零字符元素的字符数组转换为 C# 字符串

c - Linux API 确定进程拥有的套接字

perl - 具有可读子例程参数的堆栈跟踪