Libusb error on Mac OS X when building uhd driver

Hi,
I just updated to the latest uhd driver sources from the git
repo, and I get the following error on Mac OS X 10.6.4.

In file included from
/Users/elvis/Tool/ettus/uhd/host/lib/transport/libusb1_base.hpp:23,
from
/Users/elvis/Tool/ettus/uhd/host/lib/transport/libusb1_control.cpp:18:
/usr/local/include/libusb-1.0/libusb.h: In function ‘void
libusb_fill_control_setup(unsigned char*, uint8_t, uint8_t, uint16_t,
uint16_t, uint16_t)’:
/usr/local/include/libusb-1.0/libusb.h:886: error: ISO C++ forbids
braced-groups within expressions
/usr/local/include/libusb-1.0/libusb.h:887: error: ISO C++ forbids
braced-groups within expressions
/usr/local/include/libusb-1.0/libusb.h:888: error: ISO C++ forbids
braced-groups within expressions
/usr/local/include/libusb-1.0/libusb.h: In function ‘void
libusb_fill_control_transfer(libusb_transfer*, libusb_device_handle*,
unsigned char*, void ()(libusb_transfer), void*, unsigned int)’:
/usr/local/include/libusb-1.0/libusb.h:936: error: ISO C++ forbids
braced-groups within expressions
make[2]: *** [lib/CMakeFiles/uhd.dir/transport/libusb1_control.cpp.o]
Error 1
make[1]: *** [lib/CMakeFiles/uhd.dir/all] Error 2
make: *** [all] Error 2

I have libusb-1.0.8 installed from

This must be happening since the UHD driver added support for USRP1 with
USB support.

Best regards,

Elvis

Hello,

I had the same problem, the host configuration for the mac seems broken
when it come to libusb. There is a
#if defined(STDC_VERSION) && (STDC_VERSION >= 199901L)
and it seems the compiler takes the wrong branch.

Anyway, these errors are actually warnings (non-standard C++) that are
turned to errors by the “pedantic” compiler flag used for UHD.

As a workaround, you can edit uhd/host/CMakeLists.txt, just edit line 62
ADD_DEFINITIONS(-pedantic)
by commenting this line out. Then it will compile.

I’m not so sure if this is a great idea, however, but it will work.

Matthias

Am 05.09.2010 um 09:37 schrieb Elvis D.:

Hi,
More specifically, there is a problem with calls to
libusb_cpu_to_le16(x) in libusb.h

/** \def libusb_cpu_to_le16

  • \ingroup misc
  • Convert a 16-bit value from host-endian to little-endian format. On
  • little endian systems, this function does nothing. On big endian
    systems,
  • the bytes are swapped.
  • \param x the host-endian value to convert
  • \returns the value in little-endian byte order
    */
    #define libusb_cpu_to_le16(x) ({
    union {
    uint8_t b8[2];
    uint16_t b16;
    } _tmp;
    uint16_t _tmp2 = (uint16_t)(x);
    _tmp.b8[1] = _tmp2 >> 8;
    _tmp.b8[0] = _tmp2 & 0xff;
    _tmp.b16;
    })

This is called 4 times at line number 886,887,888 and 936 in libusb.h. I
just commented it in the following code fragments , which allowed me to
complete the build:

static inline void libusb_fill_control_setup(unsigned char *buffer,
uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t
wIndex,
uint16_t wLength)
{
struct libusb_control_setup *setup = (struct libusb_control_setup *)
buffer;
setup->bmRequestType = bmRequestType;
setup->bRequest = bRequest;
// setup->wValue = libusb_cpu_to_le16(wValue);
// setup->wIndex = libusb_cpu_to_le16(wIndex);
// setup->wLength = libusb_cpu_to_le16(wLength);
}

static inline void libusb_fill_control_transfer(
struct libusb_transfer *transfer, libusb_device_handle *dev_handle,
unsigned char *buffer, libusb_transfer_cb_fn callback, void
*user_data,
unsigned int timeout)
{
struct libusb_control_setup *setup = (struct libusb_control_setup *)
buffer;
transfer->dev_handle = dev_handle;
transfer->endpoint = 0;
transfer->type = LIBUSB_TRANSFER_TYPE_CONTROL;
transfer->timeout = timeout;
transfer->buffer = buffer;
if (setup) {
// transfer->length = LIBUSB_CONTROL_SETUP_SIZE
// + libusb_le16_to_cpu(setup->wLength);
}
transfer->user_data = user_data;
transfer->callback = callback;
}

The gcc compiler version is the default one supplied with the latest
version of xcode (3.2.3)

i686-apple-darwin10-gcc-4.2.1:

Best regards,

Elvis

On 09/05/2010 04:11 AM, Elvis D. wrote:

Hi,
More specifically, there is a problem with calls to libusb_cpu_to_le16(x) in libusb.h

/** \def libusb_cpu_to_le16

  • \ingroup misc
  • Convert a 16-bit value from host-endian to little-endian format. On
  • little endian systems, this function does nothing. On big endian systems,
  • the bytes are swapped.
  • \param x the host-endian value to convert
  • \returns the value in little-endian byte order
    */
    #define libusb_cpu_to_le16(x) ({
    union {
    uint8_t b8[2];
    uint16_t b16;
    } _tmp;
    uint16_t _tmp2 = (uint16_t)(x);
    _tmp.b8[1] = _tmp2>> 8;
    _tmp.b8[0] = _tmp2& 0xff;
    _tmp.b16;
    })

That seems horrendous, is that even valid c code? Its better defined as
a function, or maybe a preprocessor conditional byteswap… Is it fixed
in the libusb10 repo at least?

-Josh

On Sun, Sep 5, 2010 at 1:24 PM, Josh B. [email protected] wrote:

On 09/05/2010 04:11 AM, Elvis D. wrote:

Hi,
More specifically, there is a problem with calls to
libusb_cpu_to_le16(x) in libusb.h

/** \def libusb_cpu_to_le16

  • \ingroup misc
  • Convert a 16-bit value from host-endian to little-endian format. On
  • little endian systems, this function does nothing. On big endian
    systems,
  • the bytes are swapped.
  • \param x the host-endian value to convert
  • \returns the value in little-endian byte order
    */
    #define libusb_cpu_to_le16(x) ({
    union {
    uint8_t b8[2];
    uint16_t b16;
    } _tmp;
    uint16_t _tmp2 = (uint16_t)(x);
    _tmp.b8[1] = _tmp2>> 8;
    _tmp.b8[0] = _tmp2& 0xff;
    _tmp.b16;
    })

That seems horrendous, is that even valid c code? Its better defined as a
function, or maybe a preprocessor conditional byteswap… Is it fixed in the
libusb10 repo at least?

In libusb, the macro was converted with commit
7ba92cff94bbba19284749c614c26141d3023f37

libusb_cpu_to_le16: macro->static inline function

The error has been reported with Windows and gcc-4.4, which led to the
patch. I’m not sure exactly what caused it to surface in this case.
Oddly enough, the purpose of that macro to begin with was for OSX
support in making “endianness macros endian-independent”. Apparently,
cross-compiling issues prevent a preprocessor conditional
implementation.

Elvis, you can either rebuild libusb from git or wait for the v1.0.9
libusb release.

Tom

Hi Matthias,

On Sep 6, 2010, at 11:51 AM, Matthias W. wrote:

As a workaround, you can edit uhd/host/CMakeLists.txt, just edit line 62
ADD_DEFINITIONS(-pedantic)
by commenting this line out. Then it will compile.

Thanks for the solution. Commenting that entry allowed libusb to compile
on Mac OS 10.6.4.

Best regards,

Elvis D.