kfrlib / kfr

Fast, modern C++ DSP framework, FFT, Sample Rate Conversion, FIR/IIR/Biquad Filters (SSE, AVX, AVX-512, ARM NEON)
https://www.kfrlib.com
GNU General Public License v2.0
1.65k stars 253 forks source link

undefined reference to `kfr::sse2::dft_plan<double>::~dft_plan()' #102

Closed KenSporger closed 3 years ago

KenSporger commented 4 years ago

Hi~ I am writing the programs according to the document tutorial, which includes KFR, DSP, DFT, IO four chapters. When I use the code in KFR, it works well; but if I use the code from the other three chapters, the compiler will report some errors. For examples: I wrote,

#include <kfr/all.hpp>
#include<iostream>
using namespace kfr;

int main()
{
    audio_reader_mp3<float> reader(open_file_for_reading("./wav/music.mp3"));
    univector2d<float> audio = reader.read_channels();
    println("Sample Rate  = ", reader.format().samplerate);
    println("Channels     = ", reader.format().channels);
    println("Length       = ", reader.format().length);
    println("Duration (s) = ", reader.format().length / reader.format().samplerate);
    println("Bit depth    = ", audio_sample_bit_depth(reader.format().type));
}

but an error occurred when compiling,

Executing task: g++ -std=c++17 -static-libgcc /home/ken/Documents/KFR-DSP/basic/io.cpp -o demo -I /usr/local/include -I /usr/local/include/kfr -L /usr/local/lib -l kfr_dft -l kfr_io <

/usr/bin/ld: /usr/local/lib/libkfr_io.a(audiofile-impl.cpp.o): relocation R_X86_64_32S against `.text' can not be used when making a PIE object; recompile with -fPIC
/usr/bin/ld: final link failed: Nonrepresentable section on output
collect2: error: ld returned 1 exit status
The terminal process "g++ '-std=c++17', '-static-libgcc', '/home/ken/Documents/KFR-DSP/basic/io.cpp', '-o', 'demo', '-I', '/usr/local/include', '-I', '/usr/local/include/kfr', '-L', '/usr/local/lib', '-l', 'kfr_dft', '-l', 'kfr_io'" terminated with exit code: 1.

Besides,I wrote,

#include<iostream>
#include <kfr/all.hpp>
using namespace kfr;
int main()
{
    univector<complex<double>, 256> data = cexp(
            linspace(0, c_pi<double, 2>, 256) * make_complex(0, 1));
    univector<complex<double>, 256> freq;
    freq = dft(data);
}

another error occurred,

/usr/local/include/kfr/simd/impl/backend_generic.hpp: In function ‘kfr::sse2::intrinsics::simd<double, 2> kfr::sse2::intrinsics::simd_vec_shuffle(kfr::sse2::intrinsics::simd_t<double, 2>, kfr::sse2::intrinsics::simd<double, 2>&, cometa::csizes_t<I0, I1>) [with long unsigned int I0 = 0; long unsigned int I1 = 0]’:
/usr/local/include/kfr/simd/impl/backend_generic.hpp:1533:12: error: the last argument must be a 2-bit immediate
     return _mm_shuffle_pd(x, x, mask);
            ^
/usr/local/include/kfr/simd/impl/backend_generic.hpp: In function ‘kfr::sse2::intrinsics::simd<double, 2> kfr::sse2::intrinsics::simd_vec_shuffle(kfr::sse2::intrinsics::simd_t<double, 2>, kfr::sse2::intrinsics::simd<double, 2>&, cometa::csizes_t<I0, I1>) [with long unsigned int I0 = 1; long unsigned int I1 = 1]’:
/usr/local/include/kfr/simd/impl/backend_generic.hpp:1533:12: error: the last argument must be a 2-bit immediate
     return _mm_shuffle_pd(x, x, mask);
            ^
/usr/local/include/kfr/simd/impl/backend_generic.hpp: In function ‘kfr::sse2::intrinsics::simd<double, 2> kfr::sse2::intrinsics::simd_vec_shuffle(kfr::sse2::intrinsics::simd_t<double, 2>, kfr::sse2::intrinsics::simd<double, 2>&, cometa::csizes_t<I0, I1>) [with long unsigned int I0 = 1; long unsigned int I1 = 0]’:
/usr/local/include/kfr/simd/impl/backend_generic.hpp:1533:12: error: the last argument must be a 2-bit immediate
     return _mm_shuffle_pd(x, x, mask);

I also try to write an CMakeLists.txt,like this:

cmake_minimum_required(VERSION 3.1)
SET(CMAKE_BUILD_TYPE "Release")
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
project(demo)
set(KFR_DIR /usr/local/include/kfr)
include_directories(${KCF_DIR})
add_executable(demo     fft.cpp)
target_link_libraries(demo kfr_io kfr_dft)

but it turns out an error like first situation,

CMakeFiles/demo.dir/fft.cpp.o: In function `kfr::univector<kfr::complex<double>, 18446744073709551615ul> kfr::sse2::dft<double, 256ul>(kfr::univector<kfr::complex<double>, 256ul> const&)':
fft.cpp:(.text._ZN3kfr4sse23dftIdLm256EEENS_9univectorINS_7complexIT_EELm18446744073709551615EEERKNS2_IS5_XT0_EEE[_ZN3kfr4sse23dftIdLm256EEENS_9univectorINS_7complexIT_EELm18446744073709551615EEERKNS2_IS5_XT0_EEE]+0x115): undefined reference to `void kfr::sse2::dft_initialize<double>(kfr::dft_plan<double>&)'

I suspect that I did not fullyinstall KFR, because I was a little confused about the installation tutorial. I saw that you provided two installation methods under Linux. I tried both of them, and finally obtained libkfr dft. a_ and libkfr io.a_. But examples/ CMakeLists.txt seems to be needed libdft.a and _libusearch.a?

There are my environments: Ubuntu18.04 Gcc 7.5.0 clang version 7.0.0 kfr 4.2.0

Any idea what's going on?

samuelriddle commented 4 years ago

Hi,

For CMake way, try to use the following cmake file (place it in the same directory with you fft.cpp)

cmake_minimum_required(VERSION 3.1)
project(demo CXX)
add_subdirectory(${KFR_DIR} kfr-bin)
add_executable(demo     fft.cpp)
target_link_libraries(demo kfr kfr_io kfr_dft use_arch)

And execute the following commands inside your directory (where fft.cpp is located).

mkdir build
cd build
cmake "-DKFR_DIR=<PATH-TO-KFR-SOURCE>" -DCMAKE_BUILD_TYPE=Release ..
cmake --build .

In this case you do not need to build KFR binaries manually, cmake will do it automatically for you.

use_arch is a virtual target that exists only in cmake environment. It's intended for setting correct arch flags for you own executables, you should not use it in GCC command line.