Reputation: 83
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
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:
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.
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).
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