I'm working with a device that provides conio.h, conio.c
. In my c++ code, whenever I call getch()
, I get these errors
/usr/bin/ld: CMakeFiles/hello.dir/main.cpp.o: undefined reference to symbol '_Z5getchv'
//usr/lib/libPhantomIOLib42.so: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
CMakeFiles/hello.dir/build.make:96: recipe for target 'hello' failed
make[2]: *** [hello] Error 1
CMakeFiles/Makefile2:82: recipe for target 'CMakeFiles/hello.dir/all' failed
make[1]: *** [CMakeFiles/hello.dir/all] Error 2
Makefile:90: recipe for target 'all' failed
make: *** [all] Error 2
I know conio
is not standard but it seems the company addresses the OS issue by
#if defined(WIN32)
#include <windows.h>
#include <conio.h>
#else
#include "conio.h"
#include <string.h"
#endif
where conio.h
is
#ifndef __CONIO_H_
#define __CONIO_H_
#ifdef _cplusplus
extern "C" {
#endif // _cplusplus
int _kbhit();
int getch();
#ifdef _cplusplus
}
#endif // _cplusplus
#endif // __CONIO_H
and conio.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/poll.h>
#include <termios.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
static struct termios term_attribs, term_attribs_old;
static void restore_term(void)
{
if(tcsetattr(STDIN_FILENO, TCSAFLUSH, &term_attribs_old) < 0)
{
perror("tcsetattr: ");
exit(-1);
}
}
int _kbhit()
{
static int initialized;
fd_set rfds;
struct timeval tv;
int retcode;
if(!initialized)
{
if(tcgetattr(STDIN_FILENO, &term_attribs) < 0)
{
perror("tcgetattr: ");
exit(-1);
}
term_attribs_old = term_attribs;
if(atexit(restore_term))
{
perror("atexit: ");
exit(-1);
}
term_attribs.c_lflag &= ~(ECHO | ICANON | ISIG | IEXTEN);
term_attribs.c_iflag &= ~(IXON | BRKINT | INPCK | ICRNL | ISTRIP);
term_attribs.c_cflag &= ~(CSIZE | PARENB);
term_attribs.c_cflag |= CS8;
term_attribs.c_cc[VTIME] = 0;
term_attribs.c_cc[VMIN] = 0;
if(tcsetattr(STDIN_FILENO, TCSANOW, &term_attribs) < 0)
{
perror("tcsetattr: ");
exit(-1);
}
initialized = 1;
}
FD_ZERO(&rfds);
FD_SET(STDIN_FILENO, &rfds);
memset(&tv, 0, sizeof(tv));
retcode = select(1, &rfds, NULL, NULL, &tv);
if(retcode == -1 && errno == EINTR)
{
return 0;
}
else if(retcode < 0)
{
perror("select: ");
exit(-1);
}
else if(FD_ISSET(STDIN_FILENO, &rfds))
{
return retcode;
}
return 0;
}
int getch()
{
fd_set rfds;
int retcode;
FD_ZERO(&rfds);
FD_SET(STDIN_FILENO, &rfds);
retcode = select(1, &rfds, NULL, NULL, NULL);
if(retcode == -1 && errno == EINTR)
{
return 0;
}
else if(retcode < 0)
{
perror("select: ");
exit(-1);
}
return getchar();
}
My CMakeLists.txt
is
cmake_minimum_required(VERSION 3.10)
project(project2 VERSION 0.1.0 LANGUAGES CXX)
set(CMAKE_CXX_FLAGS "-W -O2 -DNDEBUG -Dlinux")
add_executable(hello main.cpp conio.c conio.h)
target_link_libraries(hello HDU HD rt ncurses stdc++ m)
From the conio.
, I see _cplusplus
which should address the c++ code. Why there an error and to fix it? My OS is ubuntu 18.04. One of the Makefiles provided by the company is
CXX=g++
CXXFLAGS+=-W -fexceptions -O2 -DNDEBUG -Dlinux -Iinclude
LIBS = -lHDU -lHD -lrt -lncurses -lstdc++ -lm
TARGET=ServoLoopDutyCycle
HDRS=include/StatsSampler.h
SRCS=src/ServoLoopDutyCycle.cpp \
src/StatsSampler.cpp \
src/conio.c
OBJS=$(patsubst %.cpp,%.o,$(patsubst %.c,%.o,$(SRCS)))
.PHONY: all
all: $(TARGET)
$(TARGET): $(SRCS)
$(CXX) $(CXXFLAGS) -o $@ $(SRCS) $(LIBS)
.PHONY: clean
clean:
-rm -f $(OBJS) $(TARGET)