Trying to actually use Native GCC

This is a spinoff of my earlier thread: http://forum.arduino.cc/index.php?topic=269894.0 (I know I kvetched about time constraints, but I fried a critical piece of hardware so I was moth-to-a-flame back to this problem since my project came to a sudden halt)

Here's where I am so far. I went over to my cross-compile virtual machine (which had successfully built the toolchain plus all the Yun packages), and found the equivalent of /usr/include buried in the build tree. I tarballed that up and threw it on the Yun, which got me past the missing string.h error. Would be nice if someone more versed in opkg would make a libc-dev or something that had the appropriate set of headers from there. From what I can see of how the OpenWrt build system works, that would probably be a fair challenge.

But since I'm so fond of brick walls, I immediately hit another. I can't get it to link against /usr/lib/libusb.so. And god knows I've tried. I'm sure there's some magic compiler switch or environment variable I'm missing, but damned if I know what it is.

So what I'm trying to build is a simple (if obscure) command line tool to burn hex files into the MicroChip-family bootloader. This little utility basically builds right out of the box on Debian. The code is on google:

https://code.google.com/p/mphidflash/

It's very simple. No automake or ./configure, just a Makefile and some sources. And the only thing beside libc is that it it does depend on libusb. I simplified the Makefile, and I'll post the relevant portion of it (without the dist, install, tarball, etc targets) in a later message.

And when I try to build it, it won't link against libusb (again, details to follow).

As you will see, "-lusb" is on the linker command line, and it doesn't throw an error about the library being missing. The library is used by other packages, and appears to be sane. I will post a dump from readelf later. All the functions that the linker is complaining about are in fact in the library. Anyone else have a clue? 'cause I sure don't.

Makefile:

VERSION_MAIN = 1
VERSION_SUB  = 6

CC       = gcc
OBJS     = main.o hex.o
EXECPATH = binaries
DISTPATH = dist

ifeq ($(shell uname -s),Darwin)
# Rules for Mac OS X
  OBJS    += usb-osx.o
  CFLAGS   = -fast
  LDFLAGS  = -Wl,-framework,IOKit,-framework,CoreFoundation
  SYSTEM = osx
else
# Rules for Linux, etc.
  OBJS    += usb-libusb.o
  CFLAGS   = -O3 -msoft-float 
  LDFLAGS  = -lusb 
  SYSTEM = linux
endif

CFLAGS += -DVERSION_MAIN=$(VERSION_MAIN) -DVERSION_SUB=$(VERSION_SUB)

all: 
        @echo
        @echo Please make 'mphidflash32' or 'mphidflash64' for 32 or 64 bit version
        @echo

*.o: mphidflash.h

.c.o:
        $(CC) $(CFLAGS) -c $*.c

mphidflash64: EXEC = mphidflash-$(VERSION_MAIN).$(VERSION_SUB)-$(SYSTEM)-64
mphidflash64: mphidflash

mphidflash32: EXEC = mphidflash-$(VERSION_MAIN).$(VERSION_SUB)-$(SYSTEM)-32
mphidflash32: mphidflash

mphidflash: $(OBJS)
        $(CC)  -o $(EXECPATH)/$(EXEC) $(OBJS) $(LDFLAGS)
        strip $(EXECPATH)/$(EXEC)

Failed attempt to build:

root@ArduinoHID:~/hidflash# make clean
rm -f *.o core
root@ArduinoHID:~/hidflash# make mphidflash32
gcc -O3 -msoft-float  -DVERSION_MAIN=1 -DVERSION_SUB=6 -c main.c
gcc -O3 -msoft-float  -DVERSION_MAIN=1 -DVERSION_SUB=6 -c hex.c
hex.c: In function 'issueBlock':
hex.c:249:3: warning: incompatible implicit declaration of built-in function 'memcpy' [enabled by default]
hex.c: In function 'hexWrite':
hex.c:387:24: warning: incompatible implicit declaration of built-in function 'strchr' [enabled by default]
gcc -O3 -msoft-float  -DVERSION_MAIN=1 -DVERSION_SUB=6 -c usb-libusb.c
gcc  -o binaries/mphidflash-1.6-linux-32 main.o hex.o usb-libusb.o -lusb 
usb-libusb.o: In function `usbOpen':
usb-libusb.c:(.text+0xc): undefined reference to `usb_init'
usb-libusb.c:(.text+0x38): undefined reference to `usb_init'
usb-libusb.c:(.text+0x48): undefined reference to `usb_find_busses'
usb-libusb.c:(.text+0x50): undefined reference to `usb_find_busses'
usb-libusb.c:(.text+0x60): undefined reference to `usb_find_devices'
usb-libusb.c:(.text+0x68): undefined reference to `usb_find_devices'
usb-libusb.c:(.text+0x78): undefined reference to `usb_get_busses'
usb-libusb.c:(.text+0x80): undefined reference to `usb_get_busses'
usb-libusb.c:(.text+0xf0): undefined reference to `usb_open'
usb-libusb.c:(.text+0xf8): undefined reference to `usb_open'
usb-libusb.c:(.text+0x10c): undefined reference to `usb_claim_interface'
usb-libusb.c:(.text+0x118): undefined reference to `usb_claim_interface'
usb-libusb.c:(.text+0x128): undefined reference to `usb_detach_kernel_driver_np'
usb-libusb.c:(.text+0x138): undefined reference to `usb_detach_kernel_driver_np'
usb-libusb.c:(.text+0x148): undefined reference to `usb_claim_interface'
usb-libusb.c:(.text+0x150): undefined reference to `usb_claim_interface'
usb-libusb.c:(.text+0x190): undefined reference to `usb_close'
usb-libusb.c:(.text+0x198): undefined reference to `usb_close'
usb-libusb.c:(.text+0x1ac): undefined reference to `usb_strerror'
usb-libusb.c:(.text+0x1b4): undefined reference to `usb_strerror'
usb-libusb.c:(.text+0x200): undefined reference to `usb_strerror'
usb-libusb.c:(.text+0x208): undefined reference to `usb_strerror'
usb-libusb.o: In function `usbWrite':
usb-libusb.c:(.text+0x254): undefined reference to `usb_interrupt_write'
usb-libusb.c:(.text+0x284): undefined reference to `usb_interrupt_write'
usb-libusb.c:(.text+0x2e4): undefined reference to `usb_interrupt_read'
usb-libusb.c:(.text+0x2f0): undefined reference to `usb_interrupt_read'
usb-libusb.o: In function `usbClose':
usb-libusb.c:(.text+0x340): undefined reference to `usb_release_interface'
usb-libusb.c:(.text+0x348): undefined reference to `usb_release_interface'
usb-libusb.c:(.text+0x358): undefined reference to `usb_close'
usb-libusb.c:(.text+0x364): undefined reference to `usb_close'
collect2: ld returned 1 exit status
make: *** [mphidflash] Error 1

The gory details of libusb.so, courtesy of readelf (at the end you see the list of functions contained in the lib):

root@ArduinoHID:~/hidflash# readelf -a /usr/lib/libusb.so 
ELF Header:
  Magic:   7f 45 4c 46 01 02 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF32
  Data:                              2's complement, big endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              DYN (Shared object file)
  Machine:                           MIPS R3000
  Version:                           0x1
  Entry point address:               0xe60
  Start of program headers:          52 (bytes into file)
  Start of section headers:          0 (bytes into file)
  Flags:                             0x70001007, noreorder, pic, cpic, o32, mips32r2
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         6
  Size of section headers:           0 (bytes)
  Number of section headers:         0
  Section header string table index: 0

There are no sections in this file.

There are no sections to group in this file.

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  REGINFO        0x0000f4 0x000000f4 0x000000f4 0x00018 0x00018 R   0x4
  LOAD           0x000000 0x00000000 0x00000000 0x05314 0x05314 R E 0x10000
  LOAD           0x005314 0x00015314 0x00015314 0x00110 0x0155c RW  0x10000
  DYNAMIC        0x00010c 0x0000010c 0x0000010c 0x000d8 0x000d8 RWE 0x4
  GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RWE 0x4
  NULL           0x000000 0x00000000 0x00000000 0x00000 0x00000     0x4

Dynamic section at offset 0x10c contains 22 entries:
  Tag        Type                         Name/Value
 0x00000001 (NEEDED)                     Shared library: [libgcc_s.so.1]
 0x00000001 (NEEDED)                     Shared library: [libc.so.0]
 0x0000000e (SONAME)                     Library soname: [libusb-0.1.so.4]
 0x0000000c (INIT)                       0xde8
 0x0000000d (FINI)                       0x49b0
 0x00000004 (HASH)                       0x1e4
 0x00000005 (STRTAB)                     0x99c
 0x00000006 (SYMTAB)                     0x44c
 0x0000000a (STRSZ)                      1084 (bytes)
 0x0000000b (SYMENT)                     16 (bytes)
 0x00000003 (PLTGOT)                     0x15330
 0x00000011 (REL)                        0xdd8
 0x00000012 (RELSZ)                      16 (bytes)
 0x00000013 (RELENT)                     8 (bytes)
 0x70000001 (MIPS_RLD_VERSION)           1
 0x70000005 (MIPS_FLAGS)                 NOTPOT
 0x70000006 (MIPS_BASE_ADDRESS)          0
 0x7000000a (MIPS_LOCAL_GOTNO)           9
 0x70000011 (MIPS_SYMTABNO)              85
 0x70000012 (MIPS_UNREFEXTNO)            23
 0x70000013 (MIPS_GOTSYM)                0x22
 0x00000000 (NULL)                       0x0

There are no relocations in this file.

There are no unwind sections in this file.

Histogram for bucket list length (total of 67 buckets):
 Length  Number     % of total  Coverage
      0  20         ( 29.9%)
      1  24         ( 35.8%)     28.9%
      2  14         ( 20.9%)     62.7%
      3  6          (  9.0%)     84.3%
      4  2          (  3.0%)     94.0%
      5  1          (  1.5%)    100.0%

No version information found in this file.

Primary GOT:
 Canonical gp value: 0001d320

 Reserved entries:
   Address     Access  Initial Purpose
  00015330 -32752(gp) 00000000 Lazy resolver
  00015334 -32748(gp) 80000000 Module pointer (GNU extension)

 Local entries:
   Address     Access  Initial
  00015338 -32744(gp) 00010000
  0001533c -32740(gp) 00015420
  00015340 -32736(gp) 00015320
  00015344 -32732(gp) 00000000
  00015348 -32728(gp) 00000000
  0001534c -32724(gp) 00000000
  00015350 -32720(gp) 00000000

 Global entries:
   Address     Access  Initial Sym.Val. Type    Ndx Name
  00015354 -32716(gp) 00015454 00015454 OBJECT   18 usb_error_errno
  00015358 -32712(gp) 00004990 00004990 FUNC    UND free
  0001535c -32708(gp) 00004980 00004980 FUNC    UND close
  00015360 -32704(gp) 00000000 00000000 NOTYPE  UND _Jv_RegisterClasses
  00015364 -32700(gp) 00004970 00004970 FUNC    UND closedir
  00015368 -32696(gp) 00004960 00004960 FUNC    UND fputs
  0001536c -32692(gp) 00004950 00004950 FUNC    UND strchr
  00015370 -32688(gp) 00003e68 00003e68 FUNC      8 usb_os_determine_children
  00015374 -32684(gp) 00004940 00004940 FUNC    UND open
  00015378 -32680(gp) 00004930 00004930 FUNC    UND strlen
  0001537c -32676(gp) 00004920 00004920 FUNC    UND atoi
  00015380 -32672(gp) 00004910 00004910 FUNC    UND __errno_location
  00015384 -32668(gp) 00001278 00001278 FUNC      8 usb_close
  00015388 -32664(gp) 00003848 00003848 FUNC      8 usb_os_find_devices
  0001538c -32660(gp) 00000000 00000000 OBJECT  UND stderr
  00015390 -32656(gp) 00002308 00002308 FUNC      8 usb_destroy_configuration
  00015394 -32652(gp) 00004900 00004900 FUNC    UND strcmp
  00015398 -32648(gp) 000010f0 000010f0 FUNC      8 usb_get_string
  0001539c -32644(gp) 00015440 00015440 OBJECT   18 usb_busses
  000153a0 -32640(gp) 000048f0 000048f0 FUNC    UND opendir
  000153a4 -32636(gp) 00001844 00001844 FUNC      8 usb_get_descriptor
  000153a8 -32632(gp) 000048e0 000048e0 FUNC    UND memset
  000153ac -32628(gp) 000048d0 000048d0 FUNC    UND gettimeofday
  000153b0 -32624(gp) 00015450 00015450 OBJECT   18 usb_error_type
  000153b4 -32620(gp) 000012d8 000012d8 FUNC      8 usb_free_dev
  000153b8 -32616(gp) 00001550 00001550 FUNC      8 usb_free_bus
  000153bc -32612(gp) 000048c0 000048c0 FUNC    UND realloc
  000153c0 -32608(gp) 000048b0 000048b0 FUNC    UND strncpy
  000153c4 -32604(gp) 00004138 00004138 FUNC      8 usb_os_init
  000153c8 -32600(gp) 000033b0 000033b0 FUNC      8 usb_control_msg
  000153cc -32596(gp) 000048a0 000048a0 FUNC    UND read
  000153d0 -32592(gp) 00004890 00004890 FUNC    UND fprintf
  000153d4 -32588(gp) 00001058 00001058 FUNC      8 usb_open
  000153d8 -32584(gp) 00015444 00015444 OBJECT   18 usb_debug
  000153dc -32580(gp) 000024c4 000024c4 FUNC      8 usb_fetch_and_parse_descrip
  000153e0 -32576(gp) 00004880 00004880 FUNC    UND readdir
  000153e4 -32572(gp) 00004870 00004870 FUNC    UND select
  000153e8 -32568(gp) 00015458 00015458 OBJECT   18 usb_error_str
  000153ec -32564(gp) 00004860 00004860 FUNC    UND malloc
  000153f0 -32560(gp) 00000000 00000000 FUNC    UND __cxa_finalize
  000153f4 -32556(gp) 00004850 00004850 FUNC    UND memcpy
  000153f8 -32552(gp) 00002e94 00002e94 FUNC      8 usb_os_close
  000153fc -32548(gp) 000018ec 000018ec FUNC      8 usb_parse_descriptor
  00015400 -32544(gp) 00004840 00004840 FUNC    UND getenv
  00015404 -32540(gp) 00000f60 00000f60 FUNC      8 usb_set_debug
  00015408 -32536(gp) 00004830 00004830 FUNC    UND snprintf
  0001540c -32532(gp) 00004820 00004820 FUNC    UND strerror
  00015410 -32528(gp) 00001a80 00001a80 FUNC      8 usb_parse_configuration
  00015414 -32524(gp) 00002e4c 00002e4c FUNC      8 usb_os_open
  00015418 -32520(gp) 00004810 00004810 FUNC    UND ioctl
  0001541c -32516(gp) 000035d0 000035d0 FUNC      8 usb_os_find_busses

It looks to me that there is another library with the missing functions, all you may need to do is to find it and add a -lxxx.o to link it in.

Finding it may not be that easy. A quick try with grep -R usb_get_busses staging_dir/target-mips_r2_uClibc-0.9.33.2/root-ar71xx/usr/lib/*|grep matches only suggests libftdi.so.1 which would only make sense if there is a ftdi on the other side of the USB and may not be correct even if there is.

yun-gcc is definitely a work in progress. There was much frustration involved in getting to where it is now, I was ecstatic when I saw “hello world”.

noblepepper: It looks to me that there is another library with the missing functions, all you may need to do is to find it and add a -lxxx.o to link it in.

Finding it may not be that easy. A quick try with grep -R usb_get_busses staging_dir/target-mips_r2_uClibc-0.9.33.2/root-ar71xx/usr/lib/*|grep matches only suggests libftdi.so.1 which would only make sense if there is a ftdi on the other side of the USB and may not be correct even if there is.

I hear ya, but I'm darn close to 100% certain that it needs libusb.so. That's what it links against in other distros, and the functions that aren't being found are in fact present per the readelf output.

ftdi is of course a USB/CDC chip provider, and thus depends on libusb (and I presume it works!), and it's avrdude that depends on ftdi (yup, I walked that dependency tree by hand).

noblepepper: Finding it may not be that easy. A quick try with grep -R usb_get_busses staging_dir/target-mips_r2_uClibc-0.9.33.2/root-ar71xx/usr/lib/*|grep matches only suggests libftdi.so.1 which would only make sense if there is a ftdi on the other side of the USB and may not be correct even if there is.

yun-gcc is definitely a work in progress. There was much frustration involved in getting to where it is now, I was ecstatic when I saw "hello world".

And kudos to you for the progress you've made. As I've mentioned elsewhere, I couldn't even get the build system to make a hello world package (although rumors abound on the internet that it's possible :) ). I'm sure with infinite time and patience I could make it happen, but at the moment I'm short on both.

So I guess the question is---and you may be a good person to ask---is there any magic gcc command line options we can give it to force it to emit more verbose information about what it's doing? That's about the only thing I can think of that's going to clear this hurdle.

About all I know right now is:

  • The linker can find and make use of libc, since hello world links
  • The linker appears to be finding libusb.so, since it doesn't complain about a missing library
  • If I give the linker a -l with a bogus library name, it will in fact complain that it can't find the non-existant library
  • So libusb.so is in a place where the linker is finding it, and at least according to one tool, it has the functions needed to satisfy the link

Obviously that's not enough to go on, so what other tools are at our disposal to figure out why gcc isn't getting to the finish line?

(as an aside, I'll point out that "nm -D" and "objdump -T" were supposed to also print out the functions exported by the library, but they ranged from claiming to find nothing to outright crashing with a seg fault. but I'm not chasing those gremlins right now)

I believe it is the -v that tells gcc to output what it is doing.

You can also have gcc stop at generating an object file and then use ld manually to link (-c ?).

And most gcc options are well documented https://gcc.gnu.org/onlinedocs/gcc-4.6.4/gcc/

Are you using -fno-use-linker-plugin? I don't remember the errors that caused me to use this or where I found it, but even hello.c won't compile without it.

I had some time to work on this today but I am having trouble finding a set of headers that get me up to the point you are at.

Was it build_dir/toolchain-mips_r2_gcc-4.6-linaro_uClibc-0.9.33.2/uClibc-dev/include/ ?

The biggest problem I have is not finding a header file but a working header file. I can easily add them to the next release of yun-gcc if I can find the right ones.

Ok, I think I'm at the same point as you.

To transfer the headers I did this from the top directory of openwrt-yun -

 scp -r build_dir/toolchain-mips_r2_gcc-4.6-linaro_uClibc-0.9.33.2/uClibc-dev/include/* arduino.local:/usr/include/
scp staging_dir/target-mips_r2_uClibc-0.9.33.2/usr/include/usb.h arduino.local:/usr/include

Now when I try to compile

[code] root@Arduino:~/mphid# make mphidflash32 gcc -O3 -msoft-float -DVERSION_MAIN=1 -DVERSION_SUB=6 -c main.c gcc -O3 -msoft-float -DVERSION_MAIN=1 -DVERSION_SUB=6 -c hex.c gcc -O3 -msoft-float -DVERSION_MAIN=1 -DVERSION_SUB=6 -c usb-libusb.c gcc  -o binaries/mphidflash-1.6-linux-32 main.o hex.o usb-libusb.o -lusb usb-libusb.o: In function usbOpen': usb-libusb.c:(.text+0xc): undefined reference tousb_init' usb-libusb.c:(.text+0x38): undefined reference to usb_init' usb-libusb.c:(.text+0x48): undefined reference tousb_find_busses' usb-libusb.c:(.text+0x50): undefined reference to usb_find_busses' usb-libusb.c:(.text+0x60): undefined reference tousb_find_devices' usb-libusb.c:(.text+0x68): undefined reference to usb_find_devices' usb-libusb.c:(.text+0x78): undefined reference tousb_get_busses' usb-libusb.c:(.text+0x80): undefined reference to usb_get_busses' usb-libusb.c:(.text+0xf0): undefined reference tousb_open' usb-libusb.c:(.text+0xf8): undefined reference to usb_open' usb-libusb.c:(.text+0x10c): undefined reference tousb_claim_interface' usb-libusb.c:(.text+0x118): undefined reference to usb_claim_interface' usb-libusb.c:(.text+0x128): undefined reference tousb_detach_kernel_driver_np' usb-libusb.c:(.text+0x138): undefined reference to usb_detach_kernel_driver_np' usb-libusb.c:(.text+0x148): undefined reference tousb_claim_interface' usb-libusb.c:(.text+0x150): undefined reference to usb_claim_interface' usb-libusb.c:(.text+0x190): undefined reference tousb_close' usb-libusb.c:(.text+0x198): undefined reference to usb_close' usb-libusb.c:(.text+0x1ac): undefined reference tousb_strerror' usb-libusb.c:(.text+0x1b4): undefined reference to usb_strerror' usb-libusb.c:(.text+0x200): undefined reference tousb_strerror' usb-libusb.c:(.text+0x208): undefined reference to usb_strerror' usb-libusb.o: In functionusbWrite': usb-libusb.c:(.text+0x254): undefined reference to usb_interrupt_write' usb-libusb.c:(.text+0x284): undefined reference tousb_interrupt_write' usb-libusb.c:(.text+0x2e4): undefined reference to usb_interrupt_read' usb-libusb.c:(.text+0x2f0): undefined reference tousb_interrupt_read' usb-libusb.o: In function usbClose': usb-libusb.c:(.text+0x340): undefined reference tousb_release_interface' usb-libusb.c:(.text+0x348): undefined reference to usb_release_interface' usb-libusb.c:(.text+0x358): undefined reference tousb_close' usb-libusb.c:(.text+0x364): undefined reference to `usb_close' collect2: ld returned 1 exit status make: *** [mphidflash] Error 1 root@Arduino:~/mphid# [/code]

repeating the last pass with -v gives more information that I don't have enough knowledge to interpret:

[code] root@Arduino:~/mphid# gcc  -o binaries/mphidflash-1.6-linux-32 main.o hex.o usb-libusb.o -lusb -v Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/bin/../libexec/gcc/mips-openwrt-linux-uclibc/4.6.2/lto-wrapper Target: mips-openwrt-linux-uclibc Configured with: ../yun-gcc-4.6.2/configure --host=mips-openwrt-linux-uclibc --target=mips-openwrt-linux-uclibc --prefix=/home/jenkins/jenkins/jobs/yun-openwrt/workspace/staging_dir/target-mips_r2_uClibc-0.9.33.2/yun-gcc --disable-subdir-texinfo MAKEINFO=missing --disable-decimal-float --disable-libquadmath --disable-lto --enable-languages=c,c++ Thread model: posix gcc version 4.6.2 (GCC) COMPILER_PATH=/usr/bin/../libexec/gcc/mips-openwrt-linux-uclibc/4.6.2/:/usr/bin/../libexec/gcc/ LIBRARY_PATH=/usr/bin/../lib/gcc/mips-openwrt-linux-uclibc/4.6.2/:/usr/bin/../lib/gcc/:/usr/bin/../lib/gcc/mips-openwrt-linux-uclibc/4.6.2/../../../:/lib/:/usr/lib/ COLLECT_GCC_OPTIONS='-o' 'binaries/mphidflash-1.6-linux-32 '-v' '-mllsc' '-mno-synci' '-mno-shared' /usr/bin/../libexec/gcc/mips-openwrt-linux-uclibc/4.6.2/collect2 --eh-frame-hdr -EB -dynamic-linker /lib/ld-uClibc.so.0 -o binaries/mphidflash-1.6-linux-32 /usr/bin/../lib/gcc/mips-openwrt-linux-uclibc/4.6.2/../../../crt1.o /usr/bin/../lib/gcc/mips-openwrt-linux-uclibc/4.6.2/../../../crti.o /usr/bin/../lib/gcc/mips-openwrt-linux-uclibc/4.6.2/crtbegin.o -L/usr/bin/../lib/gcc/mips-openwrt-linux-uclibc/4.6.2 -L/usr/bin/../lib/gcc -L/usr/bin/../lib/gcc/mips-openwrt-linux-uclibc/4.6.2/../../.. main.o hex.o usb-libusb.o -lusb -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/bin/../lib/gcc/mips-openwrt-linux-uclibc/4.6.2/crtend.o /usr/bin/../lib/gcc/mips-openwrt-linux-uclibc/4.6.2/../../../crtn.o usb-libusb.o: In function usbOpen': usb-libusb.c:(.text+0xc): undefined reference tousb_init' usb-libusb.c:(.text+0x38): undefined reference to usb_init' usb-libusb.c:(.text+0x48): undefined reference tousb_find_busses' usb-libusb.c:(.text+0x50): undefined reference to usb_find_busses' usb-libusb.c:(.text+0x60): undefined reference tousb_find_devices' usb-libusb.c:(.text+0x68): undefined reference to usb_find_devices' usb-libusb.c:(.text+0x78): undefined reference tousb_get_busses' usb-libusb.c:(.text+0x80): undefined reference to usb_get_busses' usb-libusb.c:(.text+0xf0): undefined reference tousb_open' usb-libusb.c:(.text+0xf8): undefined reference to usb_open' usb-libusb.c:(.text+0x10c): undefined reference tousb_claim_interface' usb-libusb.c:(.text+0x118): undefined reference to usb_claim_interface' usb-libusb.c:(.text+0x128): undefined reference tousb_detach_kernel_driver_np' usb-libusb.c:(.text+0x138): undefined reference to usb_detach_kernel_driver_np' usb-libusb.c:(.text+0x148): undefined reference tousb_claim_interface' usb-libusb.c:(.text+0x150): undefined reference to usb_claim_interface' usb-libusb.c:(.text+0x190): undefined reference tousb_close' usb-libusb.c:(.text+0x198): undefined reference to usb_close' usb-libusb.c:(.text+0x1ac): undefined reference tousb_strerror' usb-libusb.c:(.text+0x1b4): undefined reference to usb_strerror' usb-libusb.c:(.text+0x200): undefined reference tousb_strerror' usb-libusb.c:(.text+0x208): undefined reference to usb_strerror' usb-libusb.o: In functionusbWrite': usb-libusb.c:(.text+0x254): undefined reference to usb_interrupt_write' usb-libusb.c:(.text+0x284): undefined reference tousb_interrupt_write' usb-libusb.c:(.text+0x2e4): undefined reference to usb_interrupt_read' usb-libusb.c:(.text+0x2f0): undefined reference tousb_interrupt_read' usb-libusb.o: In function usbClose': usb-libusb.c:(.text+0x340): undefined reference tousb_release_interface' usb-libusb.c:(.text+0x348): undefined reference to usb_release_interface' usb-libusb.c:(.text+0x358): undefined reference tousb_close' usb-libusb.c:(.text+0x364): undefined reference to `usb_close' collect2: ld returned 1 exit status root@Arduino:~/mphid# [/code]

But if you transfer the static library using this from the top directory:

scp staging_dir/target-mips_r2_uClibc-0.9.33.2/usr/lib/libusb.a arduino.local:/usr/lib

And add -static to the linker flags in the Makefile:

  LDFLAGS  = -static -lusb

Then you get a staticly linked executable:

root@Arduino:~/mphid# make mphidflash32
gcc -O3 -msoft-float -DVERSION_MAIN=1 -DVERSION_SUB=6 -c main.c
gcc -O3 -msoft-float -DVERSION_MAIN=1 -DVERSION_SUB=6 -c hex.c
gcc -O3 -msoft-float -DVERSION_MAIN=1 -DVERSION_SUB=6 -c usb-libusb.c
gcc  -o binaries/mphidflash-1.6-linux-32 main.o hex.o usb-libusb.o -lusb 
strip binaries/mphidflash-1.6-linux-32
root@Arduino:~/mphid# ls -lh binaries/
-rwxr-xr-x    1 root     root       32.3K Oct  5 13:47 mphidflash-1.6-linux-32

I don't know why it won't link against the shared libraries but least a executable is produced and it even runs:

root@Arduino:~/mphid# binaries/mphidflash-1.6-linux-32 
binaries/mphidflash-1.6-linux-32 Error: Device not found (is device attached and in Bootloader mode?)

Sorry for the dead air, I was away over the weekend dealing with a client last-minute panic deadline, and before that was prepping for that particular death march.

But thank you for looking more closely at that. At a glance it looks like you found the same header files I did, but I'll double check when I have time later.

Based on the fact that you had success with static linking (which is awesome, I may yet be able to use the Yun for the one-off portable tool I need for a client), I'd say the header files were likely not the problem. More that somehow the native GCC just doesn't like the shared libs.

I ran the same "-v" you did and gleaned similar lack of insight into the problem. What's curious from the -v is that the linker seems to be ok linking with the shared lib version of libc (several of them, from that I can see), but not the libusb.so.

rfd_arduino: But thank you for looking more closely at that. At a glance it looks like you found the same header files I did, but I'll double check when I have time later.

Looks like I used the same header files, I just copied them to /usr/include on my yun rather than /usr/lib.

Yes I put the headers in /usr/include and the static lib in /usr/lib.

Working on a new yun-gcc package, it should be available (at least in a unofficial form) soon...

Interestingly, I still can't link, even following your steps in copying the .a over and modifying the Makefile. In fact it gets worse---the linker errors used to only affect libusb.c, but now main.c also complains:

[code] root@ArduinoHID:~/hidflash# make mphidflash32 gcc  -o binaries/mphidflash-1.6-linux-32 main.o hex.o -static -lusb main.o: In function main': main.c:(.text.startup+0x250): undefined reference tousbOpen' main.c:(.text.startup+0x25c): undefined reference to usbOpen' main.c:(.text.startup+0x278): undefined reference tousbBuf' main.c:(.text.startup+0x290): undefined reference to usbWrite' main.c:(.text.startup+0x29c): undefined reference tousbWrite' main.c:(.text.startup+0x644): undefined reference to usbWrite' main.c:(.text.startup+0x650): undefined reference tousbWrite' main.c:(.text.startup+0x6a8): undefined reference to usbClose' main.c:(.text.startup+0x6b0): undefined reference tousbClose' main.c:(.text.startup+0x6e8): undefined reference to usbWrite' main.c:(.text.startup+0x6f4): undefined reference tousbWrite' main.c:(.text.startup+0x708): undefined reference to usbWrite' main.c:(.text.startup+0x714): undefined reference tousbWrite' main.c:(.text.startup+0x758): undefined reference to usbClose' main.c:(.text.startup+0x760): undefined reference tousbClose' main.c:(.text.startup+0x864): undefined reference to usbWrite' main.c:(.text.startup+0x870): undefined reference tousbWrite' main.c:(.text.startup+0x880): undefined reference to usbClose' main.c:(.text.startup+0x888): undefined reference tousbClose' hex.o: In function issueBlock': hex.c:(.text+0x140): undefined reference tousbBuf' hex.c:(.text+0x188): undefined reference to usbWrite' hex.c:(.text+0x198): undefined reference tousbWrite' hex.c:(.text+0x288): undefined reference to usbWrite' hex.c:(.text+0x290): undefined reference tousbWrite' hex.c:(.text+0x2c8): undefined reference to usbBuf' hex.c:(.text+0x2dc): undefined reference tousbWrite' hex.c:(.text+0x2f8): undefined reference to usbWrite' hex.o: In functionhexWrite': hex.c:(.text+0x99c): undefined reference to usbBuf' hex.c:(.text+0x9a0): undefined reference tousbWrite' hex.c:(.text+0x9b4): undefined reference to `usbWrite' collect2: ld returned 1 exit status make: *** [mphidflash] Error 1 [/code]

I don't see usb-libusb.o in there.

Is libusb.a in /usr/lib?

noblepepper: I don't see usb-libusb.o in there.

Is libusb.a in /usr/lib?

Doh! A stray keystroke in vi must have deleted the "S" in "OBJS += usb-libusb.o" in the Makefile.

Links great now, will try it out on real hardware. Though the hardware guy now says that Microchip has three different bootloaders (wtf?). So after all this is might not even work.

rfd_arduino: Links great now, will try it out on real hardware. Though the hardware guy now says that Microchip has three different bootloaders (wtf?). So after all this is might not even work.

Sigh, of course my next brick wall is getting the final binary to actually work as advertised. Googling that turns up a bunch of possibilities (almost none of them related to gcc) that I don't have time to chase at the moment. I tried compiling it on a Pi and ended up with the same behavior as the Yun (writing to the HID device seems to work, but then reading times out with an error).

Along the way I discovered the really cool hack that is VisualGDB. If the Yun had at least most of the gcc toolchain working, that would enable folks to build/debug right on the PC straight over to the Yun.

You mentioned that you were taking another pass at gcc-yun: how's that coming?

As always, thanks to everyone for all their efforts. If I ever get out from under my current workload I'd be happy to give back more than the "hey, it's broke" feedback that I am now.

Meanwhile, the PHP scripts I cobbled together last fall to mimic the hardware I'm developing for are working great. Got four Yuns tied down to a piece of plywood running off a couple of 5V/1A wallwarts and they have stayed up for months. Of course, I had to punt and tie them to CAT5 because of the fragility of wifi (which may have gotten better, I just have no time to test it), but besides that they have held up very well.

There is a package at https://www.dropbox.com/s/r36jzl6iqab3ajk/yun-gcc_4.6.2-1a_ar71xx.ipk?dl=0, that has the headers mentioned in the thread along with libusb.a. It should be the same as the setup we arrived at here. Besides learning openwrt I had to learn some git to submit the yun-gcc package, I need to clean up some sloppiness and then I will put a pull request in for an updated yun-gcc

I spend most of my time in linux, VisualGDB looks like a windows tool. I don't know if it will work with OpenWrt which insists on a case sensitive file system.

If you want GDB/GCC on openwrt and have access to a linux box or virtual machine I recommend following this https://downloads.openwrt.org/docs/eclipse.pdf procedure, I haven't used it with latest openwrt-yun but it worked great with the older ones. Full source level debugging once you get it set up to cross compile for the yun. I don't think I want to tackle native compilation with debugging on a host box.

noblepepper:
I spend most of my time in linux, VisualGDB looks like a windows tool. I don’t know if it will work with OpenWrt which insists on a case sensitive file system.

If you want GDB/GCC on openwrt and have access to a linux box or virtual machine I recommend following this https://downloads.openwrt.org/docs/eclipse.pdf procedure, I haven’t used it with latest openwrt-yun but it worked great with the older ones. Full source level debugging once you get it set up to cross compile for the yun. I don’t think I want to tackle native compilation with debugging on a host box.

Yeah, been there done that with Eclipse. And given that (a) Eclipse would be too heavyweight for the Yun, and (b) I had lousy luck with the cross-compile environment, I’d just as soon not go there at the moment.

Most of my day job these days is in Visual Studio, so that’s where the muscle memory is for me right now. You’re correct about file system issues—I had to override VisualGDB’s default directory for precisely that reason. Once I did that it seemed to work well. A very cool hack, and if I can get a little mileage with it will hopefully reduce the headwind with native development. I mean, yeah, I’ve done ./configure and makefiles, but I’m rusty and I’d rather not context switch between the paying work and the playing work.