Commit f33f46ed authored by Manolis Surligas's avatar Manolis Surligas

Add libfec as external project

The CMake build system will first try to locate libfec in the system. if
it is not available, it will start building the libfec that is part of
the gr-satnogs source code. During the installation libfec is installed
in the system, thus future builds will make use of it and will not
rebuild from source.
parent 02801c9a
......@@ -131,7 +131,6 @@ find_package(Volk REQUIRED)
find_package(OggVorbis REQUIRED)
find_package(PNG REQUIRED)
find_package(png++ REQUIRED)
find_package(Fec REQUIRED)
########################################################################
# Include or not into the module blocks for debugging
......@@ -150,6 +149,45 @@ if(${INCLUDE_DEBUG_BLOCKS})
endif()
endif()
########################################################################
# Search for the libfec if it is already installed in the system
# If not, install the internal one.
########################################################################
find_package(Fec)
if(NOT FEC_FOUND)
message(WARNING "libfec is not installed. The internal libfec will be automatically build and install.")
include(ExternalProject)
ExternalProject_Add(FEC_EXTERNAL
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libfec
BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/libfec
CMAKE_ARGS "-DCMAKE_C_FLAGS=${CMAKE_C_FLAGS}"
"-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}"
"-DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}"
INSTALL_COMMAND ""
)
ExternalProject_Get_Property(FEC_EXTERNAL binary_dir)
add_library(fec SHARED IMPORTED)
set_property(TARGET fec PROPERTY IMPORTED_LOCATION ${install_dir}/libfec.so)
add_dependencies(fec FEC_EXTERNAL)
set(FEC_LIBRARIES "${binary_dir}/libfec.so")
set(FEC_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/libfec")
# Install the header and the library in the standard places
install(FILES
"${FEC_INCLUDE_DIRS}/fec.h"
DESTINATION "include"
)
install(FILES
${FEC_LIBRARIES}
DESTINATION lib${LIB_SUFFIX}
)
else()
add_library(fec INTERFACE)
endif()
# Search for GNU Radio and its components and versions. Add any
# components required to the list of GR_REQUIRED_COMPONENTS (in all
# caps such as FILTER or FFT) and change the version to the minimum
......
This diff is collapsed.
# this module will be imported in the into your flowgraph
def append_dev_args(device, dev_args):
if(len(dev_args) == 0):
return 0
......@@ -22,4 +22,4 @@ FIND_LIBRARY(
)
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(FEC DEFAULT_MSG FEC_LIBRARIES FEC_INCLUDE_DIRS)
\ No newline at end of file
FIND_PACKAGE_HANDLE_STANDARD_ARGS(FEC DEFAULT_MSG FEC_LIBRARIES FEC_INCLUDE_DIRS)
......@@ -81,6 +81,9 @@ if(NOT satnogs_sources)
endif(NOT satnogs_sources)
add_library(gnuradio-satnogs SHARED ${satnogs_sources})
add_dependencies(gnuradio-satnogs fec)
target_link_libraries(gnuradio-satnogs
${Boost_LIBRARIES}
${GNURADIO_ALL_LIBRARIES}
......
########################################################################
# Project setup
########################################################################
cmake_minimum_required(VERSION 2.8)
project(libfec ASM C)
option(BUILD_32BIT_ON_64BIT "Build a 32-bit library on a 64-bit system" OFF)
# 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 "")
list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Modules)
if(NOT LIB_INSTALL_DIR)
set(LIB_INSTALL_DIR lib)
endif()
########################################################################
# Version information
########################################################################
set(VERSION_INFO_MAJOR 3)
set(VERSION_INFO_MINOR 0)
set(VERSION_INFO_PATCH 0)
if(NOT DEFINED VERSION_INFO_EXTRA)
set(VERSION_INFO_EXTRA "git")
endif()
include(Version)
if(NOT DEFINED VERSION)
#set(VERSION "\"${VERSION_INFO_MAJOR}.${VERSION_INFO_MINOR}.${VERSION_INFO_PATCH}\"")
set(VERSION "\"${VERSION_INFO}\"")
endif()
########################################################################
# Compiler specific setup
########################################################################
if(BUILD_32BIT_ON_64BIT)
set(CMAKE_SYSTEM_PROCESSOR "i386")
set(CMAKE_SIZEOF_VOID_P 4)
set(CMAKE_C_FLAGS -m32)
set(CMAKE_CXX_FLAGS -m32)
add_definitions(-m32)
endif()
if((CMAKE_SYSTEM_PROCESSOR MATCHES "i386|i686|x86|AMD64") AND (CMAKE_SIZEOF_VOID_P EQUAL 4))
set(TARGET_ARCH "x86")
elseif((CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|AMD64") AND (CMAKE_SIZEOF_VOID_P EQUAL 8))
set(TARGET_ARCH "x64")
elseif((CMAKE_SYSTEM_PROCESSOR MATCHES "i386") AND (CMAKE_SIZEOF_VOID_P EQUAL 8) AND (APPLE))
# Mac is weird like that.
set(TARGET_ARCH "x64")
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm*")
set(TARGET_ARCH "ARM")
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)64le")
set(TARGET_ARCH "ppc64" "ppc64le")
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)64")
set(TARGET_ARCH "ppc64" "ppc")
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)")
set(TARGET_ARCH "ppc")
endif()
if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANGCC)
add_definitions(-Wall)
add_definitions(-Wno-unused)
if(TARGET_ARCH MATCHES "x64")
add_definitions(-fPIC)
add_definitions(-msse2)
elseif(TARGET_ARCH MATCHES "x86")
add_definitions(-mmmx)
add_definitions(-msse)
add_definitions(-msse2)
elseif(TARGET_ARCH MATCHES "ppc|ppc64")
add_definitions(-fno-common)
add_definitions(-faltivec)
endif()
endif()
########################################################################
# Find build dependencies
########################################################################
# libm
find_library(M_LIB m REQUIRED)
########################################################################
# config.h
########################################################################
#add_definitions(-DHAVE_CONFIG_H)
# Checks for includes
include(CheckIncludeFile)
check_include_file("getopt.h" HAVE_GETOPT_H)
check_include_file("stdio.h" HAVE_STDIO_H)
check_include_file("stdlib.h" HAVE_STDLIB_H)
check_include_file("memory.h" HAVE_MEMORY_H)
check_include_file("string.h" HAVE_STRING_H)
# Checks for functions
include(CheckFunctionExists)
check_function_exists("getopt_long" HAVE_GETOPT_LONG)
check_function_exists("memset" HAVE_MEMSET)
check_function_exists("memmove" HAVE_MEMMOVE)
########################################################################
# Setup apps
########################################################################
if(TARGET_ARCH MATCHES "x64")
list(APPEND libfec_sources
dotprod_port.c
peakval_port.c
sumsq.c
sumsq_port.c
cpu_mode_x86_64.c
##asm
#sse2bfly27-64.s
#sse2bfly29-64.s
)
elseif(TARGET_ARCH MATCHES "x86")
list(APPEND libfec_sources
viterbi27_mmx.c
viterbi27_sse.c
viterbi27_sse2.c
viterbi29_mmx.c
viterbi29_sse.c
viterbi29_sse2.c
viterbi39_sse2.c
viterbi39_sse.c
viterbi39_mmx.c
viterbi615_mmx.c
viterbi615_sse.c
viterbi615_sse2.c
dotprod_mmx.c
dotprod_sse2.c
#peakval_mmx.c
#peakval_sse.c
#peakval_sse2.c
sumsq.c
sumsq_port.c
sumsq_sse2.c
sumsq_mmx.c
cpu_mode_x86.c
#asm
cpu_features.s
dotprod_mmx_assist.s
dotprod_sse2_assist.s
mmxbfly27.s
mmxbfly29.s
peak_mmx_assist.s
peak_sse2_assist.s
peak_sse_assist.s
peakval_mmx_assist.s
peakval_sse2_assist.s
peakval_sse_assist.s
sse2bfly27.s
sse2bfly29.s
ssebfly27.s
ssebfly29.s
sumsq_mmx_assist.s
sumsq_sse2_assist.s
)
elseif(TARGET_ARCH MATCHES "ppc|ppc64")
list(APPEND libfec_sources
viterbi27_av.c
viterbi29_av.c
viterbi39_av.c
viterbi615_av.c
encode_rs_av.c
dotprod_av.c
sumsq_av.c
peakval_av.c
cpu_mode_ppc.c
)
else()
list(APPEND libfec_sources
cpu_mode_generic.c
)
endif()
list(APPEND libfec_sources
fec.c
sim.c
viterbi27.c
viterbi27_port.c
viterbi29.c
viterbi29_port.c
viterbi39.c
viterbi39_port.c
viterbi615.c
viterbi615_port.c
encode_rs_char.c
encode_rs_int.c
encode_rs_8.c
decode_rs_char.c
decode_rs_int.c
decode_rs_8.c
init_rs_char.c
init_rs_int.c
encode_rs_ccsds.c
decode_rs_ccsds.c
dotprod.c
dotprod_port.c
peakval.c
peakval_port.c
sumsq.c
sumsq_port.c
ccsds_tab.c
ccsds_tal.c
)
################################################################################
# Generate pkg-config file
################################################################################
foreach(inc ${LIBFEC_INCLUDE_DIR})
list(APPEND LIBFEC_PC_CFLAGS "-I${inc}")
endforeach()
foreach(lib ${LIBFEC_LIBRARY_DIRS})
list(APPEND LIBFEC_PC_PRIV_LIBS "-L${lib}")
endforeach()
set(LIBFEC_PC_PREFIX ${CMAKE_INSTALL_PREFIX})
set(LIBFEC_PC_EXEC_PREFIX \${prefix})
set(LIBFEC_PC_LIBDIR \${exec_prefix}/${LIB_INSTALL_DIR})
set(LIBFEC_PC_INCLUDEDIR \${prefix}/include)
set(LIBFEC_PC_VERSION ${VERSION})
set(LIBFEC_PC_LIBS "-lfec")
# Use space-delimiter in the .pc file, rather than CMake's semicolon separator
string(REPLACE ";" " " LIBFEC_PC_CFLAGS "${LIBFEC_PC_CFLAGS}")
string(REPLACE ";" " " LIBFEC_PC_LIBS "${LIBFEC_PC_LIBS}")
# Unset these to avoid hard-coded paths in a cross-environment
if(CMAKE_CROSSCOMPILING)
unset(LIBFEC_PC_CFLAGS)
unset(LIBFEC_PC_LIBS)
endif()
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/libfec.pc.in
${CMAKE_CURRENT_BINARY_DIR}/libfec.pc
@ONLY
)
install(
FILES ${CMAKE_CURRENT_BINARY_DIR}/libfec.pc
DESTINATION ${LIB_INSTALL_DIR}/pkgconfig/
)
########################################################################
# Setup libraries
########################################################################
# generate ccsds_tab.c
add_executable(gen_ccsds gen_ccsds.c init_rs_char.c)
add_custom_command(
OUTPUT ${CMAKE_BINARY_DIR}/ccsds_tab.c
COMMAND ${CMAKE_BINARY_DIR}/gen_ccsds > ccsds_tab.c
DEPENDS gen_ccsds
)
# generate ccsds_tal.c
add_executable(gen_ccsds_tal gen_ccsds_tal.c)
add_custom_command(
OUTPUT ${CMAKE_BINARY_DIR}/ccsds_tal.c
COMMAND ${CMAKE_BINARY_DIR}/gen_ccsds_tal > ccsds_tal.c
DEPENDS gen_ccsds_tal
)
# libfec
add_library(libfec_shared SHARED ${libfec_sources})
set_target_properties(libfec_shared PROPERTIES OUTPUT_NAME fec)
target_link_libraries(libfec_shared ${M_LIB})
install(TARGETS libfec_shared
DESTINATION ${LIB_INSTALL_DIR})
install(FILES "${PROJECT_SOURCE_DIR}/fec.h"
DESTINATION include)
########################################################################
# Create uninstall target
########################################################################
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
IMMEDIATE @ONLY)
add_custom_target(uninstall
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
########################################################################
# Print Summary
########################################################################
message(STATUS "")
message(STATUS "##########################################################")
message(STATUS "## Building for version: ${VERSION}")
message(STATUS "## Target Architecture: ${TARGET_ARCH}")
message(STATUS "## Using install prefix: ${CMAKE_INSTALL_PREFIX}")
message(STATUS "##########################################################")
message(STATUS "")
INSTALLATION INSTRUCTIONS
CMake-based build:
Works on most platforms. Do
mkdir build
cd build
cmake ..
make
If that fails, try the older automake-based build:
./bootstrap
./configure
make
make test (optional)
make install (as root)
By default, "make install" puts the libfec libraries in
/usr/local/lib, the include files in /usr/local/include, and the
manual page in /usr/local/man.
You may have an old version of the GNU assembler that cannot handle
the relatively new SSE2 mnemonics. Update your version of the GNU
"binutils" package.
You may obtain the latest binutils package through your normal
distribution channels or from:
http://sources.redhat.com/binutils/
TESTING THE FEC LIBRARY
After running the ./configure script, optional tests can be built and
run as follows:
make test
"make test" tests each routine, using the SIMD versions as
appropriate, verifying correct operation and estimating Viterbi
decoding speeds. These tests should always succeed unless something is
broken.
28 Mar 2004
Phil Karn, karn@ka9q.net
3 Jan 2014
Matthias P. Braendli, matthias@mpb.li
This diff is collapsed.
COPYRIGHT
This package is copyright 2006 by Phil Karn, KA9Q. It may be used
under the terms of the GNU Lesser General Public License (LGPL). See
the file "lesser.txt" in this package for license details.
It has been modified by Matthias P. Braendli, HB9EGM, so that it
compiles for x86_64 and for arm.
For installation instructions, please see INSTALL
INTRODUCTION
This package provides a set of functions that implement several
popular forward error correction (FEC) algorithms and several low-level routines
useful in modems implemented with digital signal processing (DSP).
The following routines are provided:
1. Viterbi decoders for the following convolutional codes:
r=1/2 k=7 ("Voyager" code, now a widely used industry standard)
r=1/2 k=9 (Used on the IS-95 CDMA forward link)
r=1/6 k=15 ("Cassini" code, used by several NASA/JPL deep space missions)
2. Reed-Solomon encoders and decoders for any user-specified code.
3. Optimized encoder and decoder for the CCSDS-standard (255,223)
Reed-Solomon code, with and without the CCSDS-standard "dual basis"
symbol representation.
4. Compute dot product between a 16-bit buffer and a set of 16-bit
coefficients. This is the basic DSP primitive for digital filtering
and correlation.
4. Compute sum of squares of a buffer of 16-bit signed integers. This is
useful in DSP for finding the total energy in a signal.
5. Find peak value in a buffer of 16-bit signed integers, useful for
scaling a signal to prevent overflow.
SIMD SUPPORT
This package automatically makes use of various SIMD (Single
Instruction stream, Multiple Data stream) instruction sets, when
available: MMX, SSE and SSE2 on the IA-32 (Intel) architecture, and
Altivec on the PowerPC G4 and G5 used by Power Macintoshes.
"Altivec" is a Motorola trademark; Apple calls it "Velocity Engine",
and IBM calls it "VMX". Altivec is roughly comparable to SSE2 on the
IA-32.
Many of the SIMD versions run more than an order of
magnitude faster than their portable C versions. The available SIMD
instruction sets, if any, are determined at run time and the proper
version of each routine is automatically selected. If no SIMD
instructions are available, the portable C version is invoked by
default. On targets other than IA-32 and PPC, only the portable C
version is built.
The SIMD-assisted versions generally produce the same results as the C
versions, with a few minor exceptions. The Viterbi decoders in C have
a very slightly greater Eb/No performance due to their use of 32-bit
path metrics. On the other hand, the SIMD versions use the
"saturating" arithmetic available in these instructions to avoid the
integer wraparounds that can occur in C when argument ranges are not
properly constrained. This applies primarily to the "dotprod" (dot
product) function.
The MMX (MultiMedia eXtensions) instruction set was introduced on
later Pentium CPUs; it is also implemented on the Pentium II and most
AMD CPUs starting with the K6. SSE (SIMD Streaming Extensions) was
introduced in the Pentium III; AMD calls it "3D Now! Professional".
Intel introduced SSE2 on the Pentium 4, and it has been picked up by
later AMD CPUs. SSE support implies MMX support, while SSE2 support
implies both SSE and MMX support.
The latest IA-32 SIMD instruction set, SSE3 (also known as "Prescott
New Instructions") was introduced in early 2004 with the latest
("Prescott") revision of the Pentium 4. Relatively little was
introduced with SSE3, and this library currently makes no use of it.
See the various manual pages for details on how to use the library
routines.
Copyright 2006, Phil Karn, KA9Q
karn@ka9q.net
http://www.ka9q.net/
This software may be used under the terms of the GNU Lesser General
Public License (LGPL); see the file lesser.txt for details.
Revision history:
Version 1.0 released 29 May 2001
Version 2.0 released 3 Dec 2001:
Restructured to add support for shared libraries.
Version 2.0.1 released 8 Dec 2001:
Includes autoconf/configure script
Version 2.0.2 released 4 Feb 2002:
Add SIMD version override options
Test for lack of SSE2 mnemonic support in 'as'
Build only selected version
Version 2.0.3 released 6 Feb 2002:
Fix to parityb function in parity.h
feclib version 1.0 released November 2003
Merged SIMD-Viterbi, RS and DSP libraries
Changed SIMD Viterbi decoder to detect SSE2/SSE/MMX at runtime rather than build time
feclib version 2.0 (unreleased) Mar 2004
General speedups and cleanups
Switch from 4 to 8-bit input symbols on all Viterbi decoders
Support for Altivec on PowerPC
Support for k=15 r=1/6 Cassini/Mars Pathfinder/Mars Exploration Rover/STEREO code
Changed license to GNU Lesser General Public License (LGPL)
feclib version 2.1 June 5 2006
Added error checking, fixed alignment bug in SSE2 versions of Viterbi decoders causing segfaults
feclib version 2.1.1 June 6 2006
Fix test/benchmark time measurement on Linux
This library has been modified to compile natively on x86-64.
An attempt has been made to adapt the assembly code, but due to unsolved issues with
the fact that shared libraries on x86-64 have to be compiled with PIC, this approach is
not finished.
This code therefore only uses the portable C implementation, which is certainly slower than
the assembly SSE2 that could ideally be used.
It could be said that we trade performance against the possibility to compile on x86-64.
feb, 2012
Matthias P. Braendli, HB9EGM
#!/bin/bash
aclocal && \
autoheader && \
autoconf
typedef unsigned char data_t;
extern unsigned char Taltab[],Tal1tab[];
#define NN 255
#define NROOTS 32
/* Stuff specific to the 8-bit symbol version of the general purpose RS codecs
*
* Copyright 2003, Phil Karn, KA9Q
* May be used under the terms of the GNU Lesser General Public License (LGPL)
*/
typedef unsigned char data_t;
#define MODNN(x) modnn(rs,x)
#define MM (rs->mm)
#define NN (rs->nn)
#define ALPHA_TO (rs->alpha_to)
#define INDEX_OF (rs->index_of)
#define GENPOLY (rs->genpoly)
#define NROOTS (rs->nroots)
#define FCR (rs->fcr)
#define PRIM (rs->prim)
#define IPRIM (rs->iprim)
#define PAD (rs->pad)
#define A0 (NN)
# Portions of this file have been borrowed from and/or inspired by
# the Version.cmake from the rtl-sdr project.
# http://sdr.osmocom.org/trac/wiki/rtl-sdr
#
# Provides:
# ${VERSION_INFO_BASE} - Major.Minor.Patch
# ${VERSION_INFO} - Major.minor.Patch[-git_info]
#
# Requires values for:
# ${VERSION_INFO_MAJOR} - Increment on API compatibility changes.
# ${VERSION_INFO_MINOR} - Increment when adding features.
# ${VERSION_INFO_PATCH} - Increment for bug and documentation changes.
#
# Optional:
# ${VERSION_INFO_EXTRA} - Set to "git" to append git info. This is
# intended only for non-versioned development
# builds
# ${VERSION_INFO_OVERRIDE} - Set to a non-null value to override the
# VERSION_INFO_EXTRA logic. This is intended
# for automated snapshot builds from exported
# trees, to pass in the git revision info.
#
if(DEFINED __INCLUDED_TOOLAME-DAB_VERSION_CMAKE)
return()
endif()
set(__INCLUDED_TOOLAME-DAB_VERSION_CMAKE TRUE)
################################################################################
# Gather up variables provided by parent script
################################################################################
if(NOT DEFINED VERSION_INFO_MAJOR)
message(FATAL_ERROR "VERSION_INFO_MAJOR is not defined")
else()
set(VER_MAJ ${VERSION_INFO_MAJOR})
endif()
if(NOT DEFINED VERSION_INFO_MINOR)
message(FATAL_ERROR "VERSION_INFO_MINOR is not defined")
else()
set(VER_MIN ${VERSION_INFO_MINOR})
endif()
if(NOT DEFINED VERSION_INFO_PATCH)
message(FATAL_ERROR "VERSION_INFO_PATCH is not defined")
else()
set(VER_PAT ${VERSION_INFO_PATCH})
endif()
################################################################################
# Craft version number, using git, if needed
################################################################################
find_package(Git QUIET)
if(GIT_FOUND)
execute_process(
COMMAND ${GIT_EXECUTABLE} rev-parse --
ERROR_QUIET
RESULT_VARIABLE NOT_GIT_REPOSITORY
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)
if(NOT_GIT_REPOSITORY)
set(GIT_INFO "-unknown")
else()
execute_process(
COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD --
OUTPUT_VARIABLE GIT_REV OUTPUT_STRIP_TRAILING_WHITESPACE
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)