fa7eme
fa7eme

Reputation: 83

undefined reference to c header file's

I want to make a library for testing and for this purpose, I wanna make a c program just returning some char*. I have built it based on cmake. this is my cmake file:

cmake_minimum_required(VERSION 2.8)
project(smc)
add_executable(${PROJECT_NAME} "main.c" "info.cpp")
target_link_libraries(${PROJECT_NAME}
    -lssh
    )
set(HDRS
    ${NMEA_HDRS}
    info.h
    )

header:

#ifndef INFO_H
#define INFO_H

int sshConnection();
char* getcpuusage();

#endif // INFO_H

source:

#include "info.h"
#include <libssh/libssh.h>
#include <stdio.h>
int sshConnection()
{
    ssh_session my_ssh_session = ssh_new();
    const void* ip = "localhost";
    if( my_ssh_session == NULL ) {
            printf( "Error creating ssh session" );
            return 1;
    }
    ssh_options_set(my_ssh_session, SSH_OPTIONS_HOST, "localhost");
    ssh_options_set(my_ssh_session, SSH_OPTIONS_USER, "heydari.f");
    int rc = ssh_connect(my_ssh_session);
    if( rc != SSH_OK ) {
            printf("Error with connecting" );
            ssh_free(my_ssh_session);
            return -1;
    }

    rc = ssh_userauth_password(my_ssh_session, NULL, "heydari@linux");
    if( rc != SSH_AUTH_SUCCESS) {
            printf("Error with authorization %c " , ssh_get_error(my_ssh_session) );
            ssh_disconnect(my_ssh_session);
            ssh_free(my_ssh_session);
            return -1;
    }

}
char *getcpuusage()
{
    sshConnection();
    char * usage = "44%";
    return usage;
}

when I use this header file in my main.cpp:

#include <stdio.h>
#include "info.h"
int main()
{
    char* f = getcpuusage();
    return 0;
}

I got this error:

.../projects/smc/smc/main.c:-1: error: undefined reference to `getcpuusage'

am I wrong in making cmake?

Upvotes: 3

Views: 2234

Answers (1)

hyde
hyde

Reputation: 62777

First of all, the error message comes from linker, it does not find symbol getcpuusage.

The reason for this is, your info.cpp is C++ source file, while main.c is C source file. By default (to allow for example function overloading) C++ does so called name-mangling to all C++ functions, basically combining function name with its parameter types to create symbol name (which looks mangled and messy to a human). The file names of your source files matter, because cmake determines how to compile the file from that, so in this case it compiles one with C compiler and other with C++ compiler.

There are 3 direct solutions:

  1. Use only C++, in other words rename main.c to main.cpp. It would be good to use C++ headers and library in that case, so don't use for example stdio.h either, prefer C++ libraries.

  2. Use only C, in other words rename info.cpp to info.c (and remove any C++ code from it, but in this case it doesn't have any).

  3. Tell C++ compiler to not do name mangling. This can be done using extern "c" when declaring the function (and then you must not use overloads):

info.h:


#ifndef INFO_H
#define INFO_H

#ifdef __cplusplus
// when included in C++ file, let compiler know these are C functions
extern "C" {
#endif

int sshConnection();
char* getcpuusage();

#ifdef __cplusplus
}
#endif

#endif // INFO_H

Upvotes: 3

Related Questions