undefined reference to espeak using cmake - cmake

I am working on this project and this is a related issue
i have replaced the TTS flite engine with Espeak TTs engine so I had to modify the CmakeLists.txt
find_package(Espeak REQUIRED)
include_directories(${Espeak_INCLUDE_DIRS})
set(LIBS ${LIBS} ${Espeak_LIBRARIES})
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR} /cmake/Modules/")
if (NOT Espeak_Found)
message(FATAL_ERROR "Package Espeak required, but not found!")
endif(NOT Espeak_Found)
because of that FindEspeak.cmake isn`t supported by default so I added the file to cmake default module path,compiled the project and get the following error
Linking CXX executable TextReading
CMakeFiles/TextReading.dir/EspeakBridge.cpp.o:(.bss+0x0): multiple definition of `samplerate'
CMakeFiles/TextReading.dir/EspeakTTSWorker.cpp.o:(.bss+0x0): first defined here
CMakeFiles/TextReading.dir/EspeakBridge.cpp.o:(.bss+0x10): multiple definition of `sounddata'
CMakeFiles/TextReading.dir/EspeakTTSWorker.cpp.o:(.bss+0x10): first defined here
CMakeFiles/TextReading.dir/EspeakBridge.cpp.o:(.bss+0x28): multiple definition of `counter'
CMakeFiles/TextReading.dir/EspeakTTSWorker.cpp.o:(.bss+0x28): first defined here
CMakeFiles/TextReading.dir/EspeakBridge.cpp.o:(.bss+0x30): multiple definition of `waves'
CMakeFiles/TextReading.dir/EspeakTTSWorker.cpp.o:(.bss+0x30): first defined here
CMakeFiles/TextReading.dir/EspeakBridge.cpp.o: In function `SynthCallback(short*, int, espeak_EVENT*)':
EspeakBridge.cpp:(.text+0x0): multiple definition of `SynthCallback(short*, int, espeak_EVENT*)'
CMakeFiles/TextReading.dir/EspeakTTSWorker.cpp.o:EspeakTTSWorker.cpp: (.text+0x0): first defined here
CMakeFiles/TextReading.dir/moc_EspeakTTSWorker.cxx.o:(.bss+0x0): multiple definition of `samplerate'
CMakeFiles/TextReading.dir/EspeakTTSWorker.cpp.o:(.bss+0x0): first defined here
CMakeFiles/TextReading.dir/moc_EspeakTTSWorker.cxx.o:(.bss+0x10): multiple definition of `sounddata'
CMakeFiles/TextReading.dir/EspeakTTSWorker.cpp.o:(.bss+0x10): first defined here
CMakeFiles/TextReading.dir/moc_EspeakTTSWorker.cxx.o:(.bss+0x28): multiple definition of `counter'
CMakeFiles/TextReading.dir/EspeakTTSWorker.cpp.o:(.bss+0x28): first defined here
CMakeFiles/TextReading.dir/moc_EspeakTTSWorker.cxx.o:(.bss+0x30): multiple definition of `waves'
CMakeFiles/TextReading.dir/EspeakTTSWorker.cpp.o:(.bss+0x30): first defined here
CMakeFiles/TextReading.dir/moc_EspeakTTSWorker.cxx.o: In function `SynthCallback(short*, int, espeak_EVENT*)':
moc_EspeakTTSWorker.cxx:(.text+0x0): multiple definition of `SynthCallback(short*, int, espeak_EVENT*)'
CMakeFiles/TextReading.dir/EspeakTTSWorker.cpp.o:EspeakTTSWorker.cpp:(.text+0x0): first defined here
CMakeFiles/TextReading.dir/EspeakTTSWorker.cpp.o: In function `EspeakTTSWorker::run()':
EspeakTTSWorker.cpp:(.text+0x118): undefined reference to `espeak_Initialize'
CMakeFiles/TextReading.dir/EspeakBridge.cpp.o: In function `EspeakBridge::init()':
EspeakBridge.cpp:(.text+0x93): undefined reference to `espeak_Initialize'
EspeakBridge.cpp:(.text+0x9d): undefined reference to `espeak_SetVoiceByName'
EspeakBridge.cpp:(.text+0xa7): undefined reference to `espeak_SetSynthCallback'
CMakeFiles/TextReading.dir/EspeakBridge.cpp.o: In function `EspeakBridge::close()':
EspeakBridge.cpp:(.text+0x173): undefined reference to `espeak_Terminate'
CMakeFiles/TextReading.dir/EspeakBridge.cpp.o: In function `EspeakTTSWorker::setText(std::string const&)':
EspeakBridge.cpp:(.text._ZN15EspeakTTSWorker7setTextERKSs[_ZN15EspeakTTSWorker7setTextERKSs]+0x121): undefined reference to `espeak_Synth'
EspeakBridge.cpp:(.text._ZN15EspeakTTSWorker7setTextERKSs[_ZN15EspeakTTSWorker7setTextERKSs]+0x126): undefined reference to `espeak_Synchronize'
collect2: error: ld returned 1 exit status
make[2]: *** [TextReading] Error 1
make[1]: *** [CMakeFiles/TextReading.dir/all] Error 2
make: *** [all] Error 2`
what should I do ?

I just edited Espeak parameters
############ Find ESPEAK TTS ############
find_path(LIBESPEAK_INCLUDE_DIRS
NAMES speak_lib.h
HINTS /usr/include/espeak)
find_library(LIBESPEAK_LIBRARIES
NAMES espeak
HINTS /usr/lib/ /usr/x86_64-linux-gnu/
PATH_SUFFIXES lib)
########################################
add_executable(TextReading
${DAD_SOURCES}
${DAD_HEADERS}
${MY_UI_HDRS}
${MY_MOC_SRCS}
${MY_CUDA_COMPILED_FILES}
${QEXTSERIALPORT_SOURCES} ${QEXTSERIALPORT_HEADERS}
)

Related

Compiling object oriented fortran with gfortran [duplicate]

I'm having trouble trying to compile a simple fortran program which uses a module in the same directory.
I have 2 files: test1.f90 which contains the program and modtest.f90 which contains the module.
This is test1.f90:
program test
use modtest
implicit none
print*,a
end program test
This is modtest.f90:
module modtest
implicit none
save
integer :: a = 1
end module modtest
Both files are in the same directory. I compile modtest.f90 and test.f90 like this:
gfortran -c modtest.f90
gfortran -o test1 test1.f90
But then I get this error:
/tmp/cckqu8c3.o: In function `MAIN__':
test1.f90:(.text+0x50): undefined reference to `__modtest_MOD_a'
collect2: ld returned 1 exit status
Is there something I'm missing?
Thanks for the help
What you're doing is not telling the linker where reference module modtest is so that the your code can use its contents.
This should work:
gfortran -o test1 test1.f90 modtest.o
Some context:
The -o option tells the compiler to put the output of the full build (compile + link) into a program called test1. Then we supply a file that we are to compile (test1.f90). Finally we are telling the compiler to consider a file that contains the compiled output of another build (modtest.o) and to link this to the compiled output of test1.f90, and use the contents of modtest.o when trying to sort out references within the test1.f90 that reference the module modtest (in the statement use modtest in the source code).
So the statement says:
Please compile and subsequently link test1.f90 to modtest.o, and produce a file called test1 as the final output.

Setting cmake variable in command line and comparing it with string

I'm calling my CMakeLists.txt like this:
cmake ../.. -DTARGET=JETSON_NANO
Then, this line:
message(STATUS "------------ TARGET: ${TARGET}")
prints ------------ TARGET: JETSON_NANO
but this line:
if (TARGET STREQUAL JETSON_NANO)
gives error:
if given arguments:
"TARGET" "STREQUAL" "JETSON_NANO"
Why? TARGET is setted!
TARGET is a special keyword for if command. It is used for check whether given target (in CMake sense) exists. Correct usage of this keyword includes two arguments of if:
if(TARGET JETSON_NANO) # Checks whether CMake target JETSON_NANO exists
This is why CMake emits error when you use this keyword with three arguments:
if (TARGET STREQUAL "JETSON_NANO") # Error: 'TARGET' keyword requires two `if` arguments
However, you may swap compared strings in if command:
if ("JETSON_NANO" STREQUAL TARGET) # Compares string "JETSON_NANO" with variable TARGET
See more about if command in its documentation.

Unwanted behavior with CMake+Ninja+Emacs

I am writing a Fortran code using Emacs and CMake with the Ninja generator. If, instead of Ninja I use make as the generator, and there's a coding mistake, I get an error message like
/home/raul/Projects/test/main.f90:54:9:
my_cols = 1
1
Error: Symbol ‘my_cols’ at (1) has no IMPLICIT type
Emacs reports the correct location of the source file along with line and column numbers so that I can quickly jump to the offending code. On the other hand, with Ninja, the error message returned looks something like this:
CMakeFiles/run.dir/main.f90-pp.f90:54:9:
1
Error: Symbol ‘my_cols’ at (1) has no IMPLICIT type
I am pointed to what looks like a preprocessed Fortran source file, not the original source file. The line and column numbers correspond to the original file, and the contents of the error message is slightly different (the line above "1" has gone missing). This is clearly annoying because I need to make any fixes in the original file, not the preprocessed one. Is there any way to change this behavior? I'm not sure whether this has something to do with Emacs, Ninja, Cmake, or Fortran.
EDIT. Minimal example.
# CMakeLists.txt
cmake_minimum_required(VERSION 3.0)
project(test Fortran)
add_executable(main main.f90)
# main.f90
implicit none
a = 5
end program
With gfortran, I get
[3/4] Building Fortran object CMakeFiles/main.dir/main.f90.o
FAILED: CMakeFiles/main.dir/main.f90.o
/usr/bin/f95 -I../ -c CMakeFiles/main.dir/main.f90-pp.f90 -o CMakeFiles/main.dir/main.f90.o
CMakeFiles/main.dir/main.f90-pp.f90:2:3:
# 1 "<built-in>"
1
Error: Symbol ‘a’ at (1) has no IMPLICIT type
ninja: build stopped: subcommand failed.
Interestingly, with the Intel Fortran compiler (ifort) I get
[3/4] Building Fortran object CMakeFiles/main.dir/main.f90.o
FAILED: CMakeFiles/main.dir/main.f90.o
/opt/intel/compilers_and_libraries_2017.4.196/linux/bin/intel64/ifort -I../ -c CMakeFiles/main.dir/main.f90-pp.f90 -o CMakeFiles/main.dir/main.f90.o
../main.f90(2): error #6404: This name does not have a type, and must have an explicit type. [A]
a = 5
--^
compilation aborted for CMakeFiles/main.dir/main.f90-pp.f90 (code 1)
ninja: build stopped: subcommand failed.
The error message is slightly different and now it is able to point to the correct location. (On a more complex project with several subdirectories also ifort gets it wrong.)

CHECK_LIBRARY_EXISTS library with dependencies

I'm using cmake to build my c++-project that uses a library that is located in my "/usr/local/bin/" directory.
The relevant part in the CMakeList.txt reads:
CHECK_INCLUDE_FILES("/usr/local/include/fann.h" HAVE_FANN_HEADER)
CHECK_LIBRARY_EXISTS(fann fann_get_errno "/usr/local/lib/" HAVE_FANN_LIB)
if(${HAVE_FANN_HEADER} AND ${HAVE_FANN_LIB})
the header is found without a problem the while library is not. Looking into the CMakeError.txt shows:
`/usr/bin/cc -DCHECK_FUNCTION_EXISTS=fann_get_errno CMakeFiles/cmTryCompileExec2973046031.dir/CheckFunctionExists.c.o -o cmTryCompileExec2973046031 -L/usr/local/lib -rdynamic -lfann -Wl,-rpath,/usr/local/lib
/usr/local/lib/libfann.so: undefined reference to 'sin'
/usr/local/lib/libfann.so: undefined reference to 'exp'
/usr/local/lib/libfann.so: undefined reference to 'cos'
/usr/local/lib/libfann.so: undefined reference to 'log'
/usr/local/lib/libfann.so: undefined reference to 'pow'
/usr/local/lib/libfann.so: undefined reference to 'sqrt'
/usr/local/lib/libfann.so: undefined reference to 'floor'`
in the subsequent if-statement the second variable is therefore undefined.
I suspect that this is because the test program is not linked with the standard math library. However in my main program the libm.so will be linked.
How do I fix the linking of the cmake test program?
I would be happy about any comments
Thank you
Arne
As per the documentation of CHECK_LIBRARY_EXISTS(), you can set CMAKE_REQUIRED_LIBRARIES to a list of libraries required to link the test before invoking CHECK_LIBRARY_EXISTS(). Like so:
set(CMAKE_REQUIRED_LIBRARIES m)
CHECK_LIBRARY_EXISTS(fann fann_get_errno "/usr/local/lib/" HAVE_FANN_LIB)

set_target_properties called with incorrect number of arguments?

Here is my simple CMakeLists.txt file:
include_directories (${CMAKE_SOURCE_DIR}/common)
find_package(Threads)
add_library (libusbmuxd SHARED libusbmuxd.c sock_stuff.c ${CMAKE_SOURCE_DIR}/common/utils.c)
find_library (PTHREAD pthread)
target_link_libraries (libusbmuxd ${CMAKE_THREAD_LIBS_INIT})
# 'lib' is a UNIXism, the proper CMake target is usbmuxd
# But we can't use that due to the conflict with the usbmuxd daemon,
# so instead change the library output base name to usbmuxd here
set_target_properties(libusbmuxd PROPERTIES OUTPUT_NAME usbmuxd)
set_target_properties(libusbmuxd PROPERTIES VERSION ${LIBUSBMUXD_VERSION})
set_target_properties(libusbmuxd PROPERTIES SOVERSION ${LIBUSBMUXD_SOVERSION})
install(TARGETS libusbmuxd
ARCHIVE DESTINATION lib${LIB_SUFFIX}
LIBRARY DESTINATION lib${LIB_SUFFIX}
)
install(FILES usbmuxd.h usbmuxd-proto.h DESTINATION include)
This gives me an error:
CMake error at CMakeLists.txt:12 (set_target_properties):
set_target_properties called with incorrect number of arguments
CMake error at CMakeLists.txt:13 (set_target_properties):
set_target_properties called with incorrect number of arguments
Those are the second and third set_target_properties. The first set_target_properties never had that problem?
(If you haven't realized already, I'm trying to build usbmuxd-1.0.4)
The format of SET_TARGET_PROPERTIES is:
SET_TARGET_PROPERTIES(
target1 target2 ... targetM
PROPERTIES
prop1 val1 prop2 val2 ... propN valN
)
The reason for your problem is that your variables LIBUSBMUXD_VERSION and LIBUSBMUXD_SOVERSION are undefined, and so the syntax of your command is:
SET_TARGET_PROPERTIES(target PROPERTIES name)
Instead of:
SET_TARGET_PROPERTIES(target PROPERTIES name value)
To fix this, try quoting the variables; using "${LIBUSBMUXD_SOVERSION}" should ensure that it takes on the value of the empty string even if the variable is undefined, thereby adhering to the syntax.