ImportError:undefined symbol: fftw_execute

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)
1 Like