I am trying to build a sink block with FFT and Kurtosis capability using gr_modtool.
The code itself can be compiled without error.
But when I run the flow graph in GRC, it produces following error message.
Question: How to solve this error?
I am passing the fftw3f
path through, but I am getting an error.
Thank you in advance for any guidance you may be able to provide.
Generating: '/home/nomo/gr-Kurtosis/kurtosis.py'
Executing: /usr/bin/python3 -u /home/nomo/gr-Kurtosis/kurtosis.py
Traceback (most recent call last):
File "/home/nomo/gr-Kurtosis/kurtosis.py", line 34, in <module>
import Kurtosis
File "/usr/local/lib/python3/dist-packages/Kurtosis/__init__.py", line 30, in <module>
from .Kurtosis_swig import *
File "/usr/local/lib/python3/dist-packages/Kurtosis/Kurtosis_swig.py", line 13, in <module>
from . import _Kurtosis_swig
ImportError: /usr/local/lib/x86_64-linux-gnu/libgnuradio-Kurtosis.so.1.0.0git: undefined symbol: fftw_execute
Below is the implmentation source file:
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <gnuradio/io_signature.h>
#include "Kurtosis_c_impl.h"
namespace gr {
namespace Kurtosis {
Kurtosis_c::sptr
Kurtosis_c::make(int fftsize)
{
return gnuradio::get_initial_sptr
(new Kurtosis_c_impl(fftsize));
}
/*
* The private constructor
*/
Kurtosis_c_impl::Kurtosis_c_impl(int fftsize)
: gr::sync_block("Kurtosis_c",
gr::io_signature::make(1, 1, sizeof(gr_complex)),
gr::io_signature::make(0, 0, 0)),
d_N(fftsize)
{
d_input = (fftw_complex*)fftw_malloc(sizeof(gr_complex) * d_N);
K = (fftw_complex*)fftw_malloc(sizeof(gr_complex) * d_N);
d_plan = fftw_plan_dft_1d(d_N, d_input, d_input, FFTW_BACKWARD, FFTW_ESTIMATE);
}
/*
* Our virtual destructor.
*/
Kurtosis_c_impl::~Kurtosis_c_impl()
{
}
int
Kurtosis_c_impl::work(int noutput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items)
{
const gr_complex *in = (const gr_complex*) input_items[0];
for(int k = 0; k < noutput_items; k++)
{
for(int j = 0; j < M; j++)
{
for(int i = 0; i < d_N; i++)
{
d_input[i][0] = in[i].real();
d_input[i][1] = in[i].imag();
}
fftw_execute(d_plan);
M = 29296;
for(int i = 0; i < d_N; i++)
{
S1[i][0] = S1[i][0] + d_input[i][0];
S1[i][1] = S1[i][1] + d_input[i][1];
S2[i][0] = S2[i][0] + d_input[i][0] * d_input[i][0];
S2[i][1] = S2[i][1] + d_input[i][1] * d_input[i][1];
S3[i][0] = S3[i][0] + d_input[i][0] * d_input[i][0] * d_input[i][0];
S3[i][1] = S3[i][1] + d_input[i][1] * d_input[i][1] * d_input[i][1];
S4[i][0] = S4[i][0] + d_input[i][0] * d_input[i][0] * d_input[i][0] * d_input[i][0];
S4[i][1] = S4[i][1] + d_input[i][1] * d_input[i][1] * d_input[i][1] * d_input[i][1];
dc[i][0] = dc[i][0] + 1;
dc[i][1] = dc[i][1] + 1;
}
for(int i = 0; i < d_N; i++)
{
Myu1[i][0] = S1[i][0] / dc[i][0];
Myu1[i][1] = S1[i][1] / dc[i][1];
Myu2[i][0] = S2[i][0] / dc[i][0];
Myu2[i][1] = S2[i][1] / dc[i][1];
Myu3[i][0] = S3[i][0] / dc[i][0];
Myu3[i][1] = S3[i][1] / dc[i][1];
Myu4[i][0] = S4[i][0] / dc[i][0];
Myu4[i][1] = S4[i][1] / dc[i][1];
}
for(int i = 0; i < d_N; i++)
{
K[i][0] = (Myu4[i][0] - 4 * Myu3[i][0] * Myu1[i][0] + 6 * Myu2[i][0] * Myu1[i][0]
* Myu1[i][0] - 3 * Myu1[i][0] * Myu1[i][0] * Myu1[i][0] * Myu1[i][0]) /
((Myu2[i][0] - Myu1[i][0] * Myu1[i][0]) * (Myu2[i][0] - Myu1[i][0]
* Myu1[i][0]));
K[i][1] = (Myu4[i][1] - 4 * Myu3[i][1] * Myu1[i][1] + 6 * Myu2[i][1] * Myu1[i][1]
* Myu1[i][1] - 3 * Myu1[i][1] * Myu1[i][1] * Myu1[i][1] * Myu1[i][1]) /
((Myu2[i][1] - Myu1[i][1] * Myu1[i][1]) * (Myu2[i][1] - Myu1[i][1]
* Myu1[i][1]));
}
}
}
// Tell runtime system how many output items we produced.
return noutput_items;
}
} /* namespace Kurtosis1 */
} /* namespace gr */
Below is the top-level CMakeLists.txt
file:
########################################################################
# Project setup
########################################################################
cmake_minimum_required(VERSION 3.8)
project(gr-Kurtosis CXX C)
enable_testing()
# Install to PyBOMBS target prefix if defined
if(DEFINED ENV{PYBOMBS_PREFIX})
set(CMAKE_INSTALL_PREFIX $ENV{PYBOMBS_PREFIX})
message(STATUS "PyBOMBS installed GNU Radio. Setting CMAKE_INSTALL_PREFIX to $ENV{PYBOMBS_PREFIX}")
endif()
# Select the release build type by default to get optimization flags
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release")
message(STATUS "Build type not specified: defaulting to release.")
endif(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "")
# Make sure our local CMake Modules path comes first
list(INSERT CMAKE_MODULE_PATH 0 ${CMAKE_SOURCE_DIR}/cmake/Modules)
# Set the version information here
set(VERSION_MAJOR 1)
set(VERSION_API 0)
set(VERSION_ABI 0)
set(VERSION_PATCH git)
cmake_policy(SET CMP0011 NEW)
# Enable generation of compile_commands.json for code completion engines
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
########################################################################
# Compiler specific setup
########################################################################
if((CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR
CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
AND NOT WIN32)
#http://gcc.gnu.org/wiki/Visibility
add_definitions(-fvisibility=hidden)
endif()
IF(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
SET(CMAKE_CXX_STANDARD 11)
ELSEIF(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
SET(CMAKE_CXX_STANDARD 11)
ELSEIF(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
SET(CMAKE_CXX_STANDARD 11)
ELSE()
message(WARNING "C++ standard could not be set because compiler is not GNU, Clang or MSVC.")
ENDIF()
IF(CMAKE_C_COMPILER_ID STREQUAL "GNU")
SET(CMAKE_C_STANDARD 11)
ELSEIF(CMAKE_C_COMPILER_ID MATCHES "Clang")
SET(CMAKE_C_STANDARD 11)
ELSEIF(CMAKE_C_COMPILER_ID STREQUAL "MSVC")
SET(CMAKE_C_STANDARD 11)
ELSE()
message(WARNING "C standard could not be set because compiler is not GNU, Clang or MSVC.")
ENDIF()
########################################################################
# Install directories
########################################################################
find_package(Gnuradio "3.8" REQUIRED)
include(GrVersion)
include(GrPlatform) #define LIB_SUFFIX
find_package(FFTW3f)
if(NOT CMAKE_MODULES_DIR)
set(CMAKE_MODULES_DIR lib${LIB_SUFFIX}/cmake)
endif(NOT CMAKE_MODULES_DIR)
set(GR_INCLUDE_DIR include/Kurtosis)
set(GR_CMAKE_DIR ${CMAKE_MODULES_DIR}/Kurtosis)
set(GR_PKG_DATA_DIR ${GR_DATA_DIR}/${CMAKE_PROJECT_NAME})
set(GR_PKG_DOC_DIR ${GR_DOC_DIR}/${CMAKE_PROJECT_NAME})
set(GR_PKG_CONF_DIR ${GR_CONF_DIR}/${CMAKE_PROJECT_NAME}/conf.d)
set(GR_PKG_LIBEXEC_DIR ${GR_LIBEXEC_DIR}/${CMAKE_PROJECT_NAME})
set(GR_REQUIRED_COMPONENTS RUNTIME FFTW3f)
########################################################################
# On Apple only, set install name and use rpath correctly, if not already set
########################################################################
if(APPLE)
if(NOT CMAKE_INSTALL_NAME_DIR)
set(CMAKE_INSTALL_NAME_DIR
${CMAKE_INSTALL_PREFIX}/${GR_LIBRARY_DIR} CACHE
PATH "Library Install Name Destination Directory" FORCE)
endif(NOT CMAKE_INSTALL_NAME_DIR)
if(NOT CMAKE_INSTALL_RPATH)
set(CMAKE_INSTALL_RPATH
${CMAKE_INSTALL_PREFIX}/${GR_LIBRARY_DIR} CACHE
PATH "Library Install RPath" FORCE)
endif(NOT CMAKE_INSTALL_RPATH)
if(NOT CMAKE_BUILD_WITH_INSTALL_RPATH)
set(CMAKE_BUILD_WITH_INSTALL_RPATH ON CACHE
BOOL "Do Build Using Library Install RPath" FORCE)
endif(NOT CMAKE_BUILD_WITH_INSTALL_RPATH)
endif(APPLE)
########################################################################
# Find gnuradio build dependencies
########################################################################
find_package(Doxygen)
########################################################################
# Setup doxygen option
########################################################################
if(DOXYGEN_FOUND)
option(ENABLE_DOXYGEN "Build docs using Doxygen" ON)
else(DOXYGEN_FOUND)
option(ENABLE_DOXYGEN "Build docs using Doxygen" OFF)
endif(DOXYGEN_FOUND)
########################################################################
# Create uninstall target
########################################################################
configure_file(
${CMAKE_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake
@ONLY)
add_custom_target(uninstall
${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake
)
########################################################################
# Add subdirectories
########################################################################
add_subdirectory(include/Kurtosis)
add_subdirectory(lib)
add_subdirectory(apps)
add_subdirectory(docs)
add_subdirectory(swig)
add_subdirectory(python)
add_subdirectory(grc)
########################################################################
# Install cmake search helper for this library
########################################################################
install(FILES cmake/Modules/KurtosisConfig.cmake
DESTINATION ${CMAKE_MODULES_DIR}/Kurtosis
)
Below is the lib/CMakeLists.txt
file:
########################################################################
# Setup library
########################################################################
include(GrPlatform) #define LIB_SUFFIX
list(APPEND Kurtosis_sources
Kurtosis_c_impl.cc
)
set(Kurtosis_sources "${Kurtosis_sources}" PARENT_SCOPE)
if(NOT Kurtosis_sources)
MESSAGE(STATUS "No C++ sources... skipping lib/")
return()
endif(NOT Kurtosis_sources)
add_library(gnuradio-Kurtosis SHARED ${Kurtosis_sources})
target_link_libraries(gnuradio-Kurtosis PUBLIC ${FFTW3F_LIBRARIES}
gnuradio::gnuradio-runtime fftw3f::fftw3f)
target_include_directories(gnuradio-Kurtosis
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../include>
PUBLIC $<INSTALL_INTERFACE:include>
)
link_directories(${FFTW3F_LIBRARY_DIRS})
set_target_properties(gnuradio-Kurtosis PROPERTIES DEFINE_SYMBOL "gnuradio_Kurtosis_EXPORTS")
if(APPLE)
set_target_properties(gnuradio-Kurtosis PROPERTIES
INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/lib"
)
endif(APPLE)
########################################################################
# Install built library files
########################################################################
include(GrMiscUtils)
GR_LIBRARY_FOO(gnuradio-Kurtosis FFTW3f)
########################################################################
# Print summary
########################################################################
message(STATUS "Using install prefix: ${CMAKE_INSTALL_PREFIX}")
message(STATUS "Building for version: ${VERSION} / ${LIBVER}")
########################################################################
# Build and register unit test
########################################################################
include(GrTest)
include_directories(${CPPUNIT_INCLUDE_DIRS})
# If your unit tests require special include paths, add them here
#include_directories()
# List all files that contain Boost.UTF unit tests here
list(APPEND test_Kurtosis_sources
)
# Anything we need to link to for the unit tests go here
list(APPEND GR_TEST_TARGET_DEPS gnuradio-Kurtosis)
if(NOT test_Kurtosis_sources)
MESSAGE(STATUS "No C++ unit tests... skipping")
return()
endif(NOT test_Kurtosis_sources)
foreach(qa_file ${test_Kurtosis_sources})
GR_ADD_CPP_TEST("Kurtosis_${qa_file}"
${CMAKE_CURRENT_SOURCE_DIR}/${qa_file}
)
endforeach(qa_file)