Guide to help move from 3.6 to 3.7

Cmake structure for out-of-tree projects

To link against GNU Radio in 3.7:

  • Remove FindGnuradioCore.cmake and FindGruel.cmake,
    Replace with FindGnuradioRuntime.cmake
  • Remove all GRUEL_ references and replace GNURADIO_CORE variables with GNURADIO_RUNTIME
  • Update #include<gruel/attributes.h> to <gnuradio/attributes.h>

Reorganized Blocks

We documented where we moved all blocks from gnuradio-core into their respective components. This can be found in a Google doc:

http://ow.ly/mDplO

Help in documenting where Python modules moved, which we did not track since it was simply a move and not a recoding, would be welcome here.

API Changes in Blocks

gr::filter::freq_xlating_fir_filter_XXX

  • The center_freq argument is now the actual center frequency of the incoming signal.
    • In previous versions of GNU Radio, this was the negative of the center frequency. To fix, just change the sign.

Code structure for out-of-tree modules

The file structure is changing from this format:

gr-modname/include/modname_blockname.h
gr-modname/lib/modname_blockname.cc
...to:
gr-modname/include/modname/blockname.h
gr-modname/lib/blockname_impl.h
gr-modname/lib/blockname_impl.cc
Some things to note:
  • include/modname/blockname.h - This public header file declares an abstract class. Public methods declared here are pure virtual and should be of the form:
    • virtual return_type function_name(arg_list) = 0 since these must be implemented by a subclass (the blockname_impl class will be the concrete class).
  • lib/blockname_impl.h - This private header file declares member variables and concrete implementations of methods declared in the abstract class.
  • lib/blockname_impl.cc - This file defines the member variables and provides the concrete implementations of methods in lib/blockname_impl.h.

Make sure the methods in include/modname/blockname.h are declared pure virtual so that blockname can remain an abstract class. If blockname is not abstract, your code may compile but SWIG will interpret the declaration as the concrete class instead of your blockname_impl class. At runtime this will cause an error like ImportError: [...] undefined symbol when the Python interpreter attempts to load your SWIGged object code. The new coding structure is discussed in great detail here: Blocks Coding Guide.

Recognizing Namespace Changes

All blocks and classes are under namespace in GNU Radio now. So make sure that OOT code understands this.

One big issue to remember is the changes to the class inheritance:

class MODNAME_API classname : public gr_block
class MODNAME_API classname : public gr_sync_block
class MODNAME_API classname : public gr_sync_decimator
class MODNAME_API classname : public gr_sync_interpolator

... becomes:

class MODNAME_API classname : public gr::block
class MODNAME_API classname : public gr::sync_block
class MODNAME_API classname : public gr::sync_decimator
class MODNAME_API classname : public gr::sync_interpolator

Update to the private implementation structure in gnuradio-runtime:

  • Includes will change in form from these examples:
  #include <gr_sync_block.h>
  #include <gr_io_signature.h>
  #include <audio/source.h>
  #include <filter/pfb_decimator_ccf.h>
...to:
#include <gnuradio/sync_block.h>
#include <gnuradio/io_signature.h>
#include <gnuradio/audio/source.h>
#include <gnuradio/filter/pfb_decimator_ccf.h>
  • The C++ classes in the GNU Radio runtime will be accessed through the 'gr' namespace, so class declarations that look like:
class my_foo_block : public gr_sync_block {...};
class my_top_block : public gr_top_block {...};

...will become:

class my_foo_block : public gr::sync_block {...};
class my_top_block : public gr::top_block {...};
  • Finally, creating instances of classes in the runtime will use the static class make() function, instead of calling the separate gr_make_* calls. Thus:
gr_make_io_signature(1, 1, sizeof(gr_complex))
gr_make_io_signature2(1, 1, sizeof(gr_complex))

...becomes:

gr::io_signature::make(1, 1, sizeof(gr::complex))
gr::io_signature::make2(1, 1, sizeof(gr::complex))
  • Python and GRC code won't be affected by this change.

Include Directories

  • As already hinted at above, all headers should be included from the gnuradio directory:
#include <gnuradio/blocks/null_source.h>
  • Include directories in your project should not include gnuradio. You would use /usr/local/include. Do not use /usr/local/include/gnuradio.
    • With the renaming of files, using the include/gnuradio directly could cause name clashes with other projects or standard header files. In particular, #include <math.h> could potentially find gnuradio/math.h instead of the intended system math.h.

Classes, Structs, and Typedefs

Classes and structs are all renamed and under namespaces. So gr_thing becomes gr::thing. This includes gr_tag_t --> gr::tag_t and gr_msg_queue_sptr --> gr::msg_queue::sptr.

However, typedefs have not been changed. This includes:

gr_complex
gr_vector_void_star
gr_vector_const_void_star
gr_vector_int

PMT

  • Import PMT in Python as import pmt (instead of from gruel import pmt).
  • All PMT function names have dropped the pmt_ prefix. So in Python use pmt.to_long instead of pmt.pmt_to_long and in C++ use pmt::to_long instead of pmt::pmt_to_long.

Restructure of GRC Category Names to Help Transition

  • We removed all of the old blocks from the GRC component tree.
  • This does not remove the blocks from GRC, so this does not affect GRC apps already created.
  • The change affects how we find blocks, and the blocks in the category tree are now (almost) all from 3.7.
  • We have changed the category names and reorged all of the blocks, so it might take a little bit of getting used to. But we feel the new categorization is more intuitive.
    • The next section shows the new category names used.
  • When using the component tree, almost all the blocks listed there are the new blocks for 3.7.
  • When opening your GRC files now, if you are using a block that is from 3.6, the name will be: "Block name (old)".
    • This is to make it clear that you are using a pre-3.7 block.
  • The (old) name is to help identify where you can update to a new 3.7 block in your flowgraph.
    • This will help prepare you for the conversion to v3.7
    • A script can help migrating flowgraphs with many old blocks to the 3.7 versions. One attempt with only 15 blocks is at http://nathanwest.us/grc_to_37.sh :
      #!/bin/bash
      # Version 0.1
      # run ./grc_to_37 <appname>.grc
      # this will create a backup copy and attempt to convert the api calls to 3.7
      GRCFILE=$1
      cp $GRCFILE $GRCFILE.pre3.7upgrade_backup # I refuse to take responsibility for breaking your flowgraphs
      # set up a list of partial regexps to change modules
      list_of_block_changes=(
      "gr_peak_detector2_fb/blocks_peak_detector2_fb" 
      "gr_short_to_float/blocks_short_to_float" 
      "gr_diff_phasor_cc/digital_diff_phasor_cc" 
      "blks2_logpwrfft_x/logpwrfft_x" 
      "gr_rms_xx/blocks_rms_xx" 
      "gr_probe_density_b/digital_probe_density_b" 
      "gr_mute_xx/blocks_mute_xx" 
      "gr_agc_xx/analog_agc_xx" 
      "gr_ctcss_squelch_ff/analog_ctcss_squelch_ff" 
      "gr_diff_encoder_bb/digital_diff_encoder_bb" 
      "gr_pll_refout_cc/analog_pll_refout_cc" 
      "gr_uchar_to_float/blocks_uchar_to_float" 
      "gr_interp_fir_filter_xxx/interp_fir_filter_xxx" 
      "gr_udp_sink/blocks_udp_sink" 
      "gr_and_xx/blocks_and_xx" 
      "gr_keep_one_in_n/blocks_keep_one_in_n" 
      "gr_vector_sink_x/blocks_vector_sink_x" 
      "gr_freq_xlating_fir_filter_xxx/freq_xlating_fir_filter_xxx" 
      "gr_float_to_int/blocks_float_to_int" 
      "gr_file_source/blocks_file_source" 
      "gr_float_to_short/blocks_float_to_short" 
      "gr_fft_vxx/fft_vxx" 
      "gr_quadrature_demod_cf/analog_quadrature_demod_cf" 
      "gr_file_sink/blocks_file_sink" 
      "gr_pfb_clock_sync_xxx/digital_pfb_clock_sync_xxx" 
      "gr_multiply_const_vxx/blocks_multiply_const_vxx" 
      "gr_peak_detector_xb/blocks_peak_detector_xb" 
      "gr_noise_source_x/analog_noise_source_x" 
      "gr_simple_framer/digital_simple_framer" 
      "gr_delay/blocks_delay" 
      "gr_pfb_synthesizer_ccf/pfb_synthesizer_ccf" 
      "gr_short_to_char/blocks_short_to_char" 
      "gr_chunks_to_symbols_xx/digital_chunks_to_symbols_xx" 
      "gr_interleaved_short_to_complex/blocks_interleaved_short_to_complex" 
      "gr_frequency_modulator_fc/analog_frequency_modulator_fc" 
      "gr_xor_xx/blocks_xor_xx" 
      "gr_dpll_bb/analog_dpll_bb" 
      "gr_threshold_ff/blocks_threshold_ff" 
      "gr_nop/blocks_nop" 
      "gr_unpack_k_bits_bb/blocks_unpack_k_bits_bb" 
      "gr_max_xx/blocks_max_xx" 
      "gr_int_to_float/blocks_int_to_float" 
      "gr_stream_to_streams/blocks_stream_to_streams" 
      "blks2_wfm_rcv/analog_wfm_rcv" 
      "gr_fractional_interpolator_xx/fractional_interpolator_xx" 
      "gr_conjugate_cc/blocks_conjugate_cc" 
      "blks2_fm_demod_cf/analog_fm_demod_cf" 
      "gr_fir_filter_xxx/fir_filter_xxx" 
      "gr_null_source/blocks_null_source" 
      "gr_complex_to_arg/blocks_complex_to_arg" 
      "gr_pwr_squelch_xx/analog_pwr_squelch_xx" 
      "gr_descrambler_bb/digital_descrambler_bb" 
      "gr_copy/blocks_copy" 
      "gr_complex_to_mag/blocks_complex_to_mag" 
      "gr_throttle/blocks_throttle" 
      "gr_additive_scrambler_bb/digital_additive_scrambler_bb" 
      "gr_wavfile_sink/blocks_wavfile_sink" 
      "gr_vector_source_x/blocks_vector_source_x" 
      "gr_moving_average_xx/blocks_moving_average_xx" 
      "gr_char_to_short/blocks_char_to_short" 
      "blks2_fm_deemph/analog_fm_deemph" 
      "gr_pll_freqdet_cf/analog_pll_freqdet_cf" 
      "gr_or_xx/blocks_or_xx" 
      "blks2_fm_preemph/analog_fm_preemph" 
      "blks2_wfm_tx/analog_wfm_tx" 
      "gr_stream_to_vector/blocks_stream_to_vector" 
      "gr_glfsr_source_x/digital_glfsr_source_x" 
      "gr_map_bb/digital_map_bb" 
      "gr_sig_source_x/analog_sig_source_x" 
      "gr_transcendental/blocks_transcendental" 
      "gr_skiphead/blocks_skiphead" 
      "gr_hilbert_fc/hilbert_fc" 
      "blks2_nbfm_rx/analog_nbfm_rx" 
      "random_source_x/analog_random_source_x" 
      "gr_complex_to_real/blocks_complex_to_real" 
      "gr_null_sink/blocks_null_sink" 
      "gr_float_to_complex/blocks_float_to_complex" 
      "gr_multiply_xx/blocks_multiply_xx" 
      "gr_simple_correlator/digital_simple_correlator" 
      "gr_sample_and_hold_xx/blocks_sample_and_hold_xx" 
      "blks2_pfb_channelizer_ccf/pfb_channelizer_ccf" 
      "gr_goertzel_fc/goertzel_fc" 
      "gr_complex_to_mag_squared/blocks_complex_to_mag_squared" 
      "gr_packed_to_unpacked_xx/blocks_packed_to_unpacked_xx" 
      "blks2_standard_squelch/analog_standard_squelch" 
      "blks2_am_demod_cf/analog_am_demod_cf" 
      "gr_and_const_xx/blocks_and_const_xx" 
      "gr_unpacked_to_packed_xx/blocks_unpacked_to_packed_xx" 
      "gr_probe_avg_mag_sqrd_x/analog_probe_avg_mag_sqrd_x" 
      "gr_channel_model/channels_channel_model" 
      "gr_divide_xx/blocks_divide_xx" 
      "gr_simple_squelch_cc/analog_simple_squelch_cc" 
      "gr_message_source/blocks_message_source" 
      "gr_sub_xx/blocks_sub_xx" 
      "gr_stream_mux/blocks_stream_mux" 
      "gr_burst_tagger/blocks_burst_tagger" 
      "gr_float_to_uchar/blocks_float_to_uchar" 
      "gr_scrambler_bb/digital_scrambler_bb" 
      "gr_streams_to_vector/blocks_streams_to_vector" 
      "gr_add_xx/blocks_add_xx" 
      "gr_feedforward_agc_cc/analog_feedforward_agc_cc" 
      "gr_iir_filter_ffd/iir_filter_ffd" 
      "blks2_stream_to_vector_decimator/blocks_stream_to_vector_decimator" 
      "gr_pn_correlator_cc/digital_pn_correlator_cc" 
      "gr_streams_to_stream/blocks_streams_to_stream" 
      "gr_rational_resampler_base_xxx/rational_resampler_base_xxx" 
      "gr_vector_to_streams/blocks_vector_to_streams" 
      "gr_interleave/blocks_interleave" 
      "gr_add_const_vxx/blocks_add_const_vxx" 
      "gr_message_sink/blocks_message_sink" 
      "gr_complex_to_imag/blocks_complex_to_imag" 
      "gr_vco_f/blocks_vco_f" 
      "gr_deinterleave/blocks_deinterleave" 
      "gr_argmax_xx/blocks_argmax_xx" 
      "gr_not_xx/blocks_not_xx" 
      "gr_udp_source/blocks_udp_source" 
      "gr_nlog10_ff/blocks_nlog10_ff" 
      "gr_diff_decoder_bb/digital_diff_decoder_bb" 
      "gr_phase_modulator_fc/analog_phase_modulator_fc" 
      "gr_complex_to_interleaved_short/blocks_complex_to_interleaved_short" 
      "gr_float_to_char/blocks_float_to_char" 
      "gr_head/blocks_head" 
      "gr_fft_filter_xxx/fft_filter_xxx" 
      "gr_cpfsk_bc/analog_cpfsk_bc" 
      "gr_vector_to_stream/blocks_vector_to_stream" 
      "gr_agc2_xx/analog_agc2_xx" 
      "gr_pll_carriertracking_cc/analog_pll_carriertracking_cc" 
      "gr_repeat/blocks_repeat" 
      "gr_filter_delay_fc/filter_delay_fc" 
      "blks2_rational_resampler_xxx/rational_resampler_xxx" 
      "gr_char_to_float/blocks_char_to_float" 
      "gr_integrate_xx/blocks_integrate_xx" 
      "gr_wavfile_source/blocks_wavfile_source" 
      "gr_complex_to_float/blocks_complex_to_float" 
      "gr_single_pole_iir_filter_xx/single_pole_iir_filter_xx" 
      "blks2_nbfm_tx/analog_nbfm_tx" 
      "blks2_wfm_rcv_pll/analog_wfm_rcv_pll" 
      "const_source_x/analog_const_source_x" 
      "blks2_pfb_arb_resampler_ccf/pfb_arb_resampler_xxx" 
      )
      
      for block in "${list_of_block_changes[@]}" 
      do
          sed --in-place "/<key/s/$block/g" $GRCFILE
          # only replace the keys lines because otherwise
          # block ids can get clobbered if there are 2 of the same block
          # one old, and one new that both use grc generated ids
      done
      
  • The search box will return all blocks found, including the (old) blocks, so you can still get access to these, if you really want.

Note. Not all GRC blocks were converted this way on master. A lot of the hierarchical blocks that had a GRC component were not necessarily moved over to the new components on the master branch. So you might still find a few problems when opening up old GRC files in 3.7.

To see the list of blocks that are still being pulled in the old way, you can look at grc/blocks/block_tree.xml in the source code, or it is installed into ${prefix}/share/gnuradio/blocks/block_tree.xml.

This should really help with transitioning your work to 3.7 when you need to and in the meantime will not affect your current, running systems in anyway but looks.

GRC and Doxygen Components

We have completely overhauled the category naming scheme in both the Doxygen manual and in GRC.

Click Here for a spreadsheet listing all of the blocks and which categories they are in

The following categories (and the Doxygen \ingroup group name for markup) are:

Category Name Doxygen Group
Audio audio_blk
Boolean Operators boolean_operators_blk
Byte Operators byte_operators_blk
Channel models channel_models_blk
Channelizers channelizers_blk
Coding coding_blk
Debug Tools debug_tool_blk
Deprecated deprecated_blk
Equalizers equalizers_blk
Error Coding error_coding_blk
FCD fcd_blk
File Operators file_operators_blk
Filters filter_blk
Fourier Analysis fourier_analysis_blk
Widgets / QT qtgui_blk
Widgets / WX wxgui_blk
Instrumentation / QT instrumentation_blk
Instrumentation / WX instrumentation_blk
Level Controllers level_controllers_blk
Math Operators math_operators_blk
Measurement Tools measurement_tools_blk
Message Tools message_tools_blk
Misc misc_blk
Modulators modulators_blk
Networking Tools networking_tool_blk
NOAA noaa_blk
OFDM ofdm_blk
Packet Operators packet_operators_blk
Pager pager_blk
Peak Detectors peak_detectors_blk
Resamplers resamplers_blk
Stream Operators stream_operators_blk
Stream Tag Tools
Symbol Coding symbol_coding_blk
Synchronizers synchronizers_blk
Trellis Coding trellis_coding_blk
Type Converters type_converters_blk
UHD uhd_blk
Variables
Waveform Generators waveform_generators_blk

VOLK Changes

We have updated the VOLK directory structure to help in the automating of tests and building of new VOLK kernels, including the use of out-of-tree libraries of VOLK functions.

Also, a handful of the original VOLK kernels used num_bytes as the parameter while most used num_items. This inconsistency made it difficult to automate some tests, and it made it more difficult to work with VOLK if you didn't know which style you were working with. The VOLK in 3.7 has updated this so that all blocks now use num_items.

The affected kernels due to the 's/num_bytes/num_items/g' change are:

volk_16i_max_star_16i_a.h
volk_16i_max_star_horizontal_16i_a.h
volk_16i_permute_and_scalar_add_a.h
volk_16i_x4_quad_max_star_16i_a.h
volk_16i_x5_add_quad_16i_x4_a.h
volk_32f_x3_sum_of_poly_32f_a.h
volk_32fc_index_max_16u_a.h
volk_32fc_x2_conjugate_dot_prod_32fc_a.h
volk_32fc_x2_conjugate_dot_prod_32fc_u.h
volk_32fc_x2_dot_prod_32fc_a.h
volk_32fc_x2_s32f_square_dist_scalar_mult_32f_a.h
volk_32fc_x2_square_dist_32f_a.h