cross-compiling

Cross compiling for armv7l


I am trying to cross-compiling tsocks for armv7l arachitecture. I installed arm-linux-gnueabi package and tried to compile a simple hello world program, it is working great.

For some reason I can't get tsock's ./configure to use arm-linux-gnueabi-* compiler.

@ubuntu:~/tmp/tsocks-1.8$ ./configure --build x86_64-pc-linux-gnu --host=arm-linux-gnueabi
loading cache ./config.cache
checking host system type... arm-unknown-linux-gnueabi
checking for gcc... (cached) gcc
checking whether the C compiler (gcc  ) works... yes
checking whether the C compiler (gcc  ) is a cross-compiler... no
checking whether we are using GNU C... (cached) yes
checking whether gcc accepts -g... (cached) yes
checking for a BSD compatible install... (cached) /usr/bin/install -c
checking whether ln -s works... (cached) yes
checking if the C compiler accepts -Wall... yes
checking how to run the C preprocessor... (cached) gcc -E
checking for ANSI C header files... (cached) yes
checking for dlfcn.h... (cached) yes
checking for sys/socket.h... (cached) yes
checking for arpa/inet.h... (cached) yes
checking for fcntl.h... (cached) yes
checking for sys/poll.h... (cached) yes
checking for unistd.h... (cached) yes
checking for strcspn... (cached) yes
checking for strdup... (cached) yes
checking for strerror... (cached) yes
checking for strspn... (cached) yes
checking for strtol... (cached) yes
checking for connect in -lc... (cached) yes
checking for socket... (cached) yes
checking for inet_aton... (cached) yes
checking for gethostbyname... (cached) yes
checking for dlsym in -ldl... (cached) yes
checking for RTLD_NEXT from dlfcn.h... no
checking for RTLD_NEXT from dlfcn.h with _GNU_SOURCE... yes
checking for correct select prototype... select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
checking for correct connect prototype... connect(int __fd, const struct sockaddr * __addr, socklen_t __len)
checking for correct close prototype... close(int fd)
checking for correct poll prototype... poll(struct pollfd *ufds, unsigned long nfds, int timeout)
creating ./config.status
creating Makefile
creating config.h
config.h is unchanged

After that I compile code:

@ubuntu:~/tmp/tsocks-1.8$ make
gcc -fPIC  -g -O2 -Wall -I. -c  tsocks.c -o tsocks.o
tsocks.c: In function ‘connect’:
tsocks.c:215:41: warning: pointer targets in passing argument 5 of ‘getsockopt’ differ in signedness [-Wpointer-sign]
  215 |                    (void *) &sock_type, &sock_type_len);
      |                                         ^~~~~~~~~~~~~~
      |                                         |
      |                                         int *
In file included from tsocks.c:39:
/usr/include/x86_64-linux-gnu/sys/socket.h:257:46: note: expected ‘socklen_t * restrict’ {aka ‘unsigned int * restrict’} but argument is of type ‘int *’
  257 |                        socklen_t *__restrict __optlen) __THROW;
      |                        ~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~
tsocks.c:271:62: warning: pointer targets in passing argument 3 of ‘getpeername’ differ in signedness [-Wpointer-sign]
  271 |    if (!getpeername(__fd, (struct sockaddr *) &peer_address, &namelen)) {
      |                                                              ^~~~~~~~
      |                                                              |
      |                                                              int *
In file included from tsocks.c:39:
/usr/include/x86_64-linux-gnu/sys/socket.h:131:47: note: expected ‘socklen_t * restrict’ {aka ‘unsigned int * restrict’} but argument is of type ‘int *’
  131 |                         socklen_t *__restrict __len) __THROW;
      |                         ~~~~~~~~~~~~~~~~~~~~~~^~~~~
tsocks.c: In function ‘select’:
tsocks.c:343:8: warning: variable ‘rc’ set but not used [-Wunused-but-set-variable]
  343 |    int rc = 0;
      |        ^~
tsocks.c: In function ‘poll’:
tsocks.c:526:8: warning: variable ‘rc’ set but not used [-Wunused-but-set-variable]
  526 |    int rc = 0, i;
      |        ^~
gcc -fPIC  -g -O2 -Wall -I. -c  common.c -o common.o
gcc -fPIC  -g -O2 -Wall -I. -c  parser.c -o parser.o
parser.c: In function ‘handle_path’:
parser.c:210:22: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
  210 |                 if (((int) (newserver = (struct serverent *) malloc(sizeof(struct serverent)))) == -1)
      |                      ^
gcc -fPIC  -g -O2 -Wall -I. -nostdlib -shared -o libtsocks.so.1.8 tsocks.o common.o parser.o  -ldl  -lc
ln -sf libtsocks.so.1.8 libtsocks.so
gcc -fPIC  -g -O2 -Wall -I. -static -o saveme saveme.c
gcc -fPIC  -g -O2 -Wall -I. -o inspectsocks inspectsocks.c common.o -lc 
gcc -fPIC  -g -O2 -Wall -I. -o validateconf validateconf.c common.o parser.o -lc

When I check the compiled file, I see that it was compiled for the original architecture, not for armv7l:

@ubuntu:~/tmp/tsocks-1.8$ file libtsocks.so.1.8
libtsocks.so.1.8: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=e1928585546b975b439d280bba97f0c85ed2d89c, with debug_info, not stripped

Solution

  • The important line in the messages displayed while executing configure is:
    checking whether the C compiler (gcc ) is a cross-compiler... no

    You need to explicitly specify which compiler you want to use by setting the CC environment variable, passing the correct argument using the --host option is not enough:

    Example using arm-none-linux-gnueabihf-gcc located in my /opt/arm/12/arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-linux-gnueabihf/bin/ directory:

    CC=/opt/arm/12/arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-linux-gnueabihf/bin/arm-none-linux-gnueabihf-gcc ./confi--host=arm-none-linux-gnueabihfu --host=arm-none-linux-gnueabihf
    loading cache ./config.cache
    checking host system type... arm-none-linux-gnueabihf
    checking for gcc... /opt/arm/12/arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-linux-gnueabihf/bin/arm-none-linux-gnueabihf-gcc
    checking whether the C compiler (/opt/arm/12/arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-linux-gnueabihf/bin/arm-none-linux-gnueabihf-gcc  ) works... yes
    checking whether the C compiler (/opt/arm/12/arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-linux-gnueabihf/bin/arm-none-linux-gnueabihf-gcc  ) is a cross-compiler... yes
    checking whether we are using GNU C... yes
    checking whether /opt/arm/12/arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-linux-gnueabihf/bin/arm-none-linux-gnueabihf-gcc accepts -g... yes
    checking for a BSD compatible install... /usr/bin/install -c
    checking whether ln -s works... yes
    checking if the C compiler accepts -Wall... yes
    checking how to run the C preprocessor... /opt/arm/12/arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-linux-gnueabihf/bin/arm-none-linux-gnueabihf-gcc -E
    checking for ANSI C header files... yes
    checking for dlfcn.h... yes
    checking for sys/socket.h... yes
    checking for arpa/inet.h... yes
    checking for fcntl.h... yes
    checking for sys/poll.h... yes
    checking for unistd.h... yes
    checking for strcspn... yes
    checking for strdup... yes
    checking for strerror... yes
    checking for strspn... yes
    checking for strtol... yes
    checking for connect in -lc... yes
    checking for socket... yes
    checking for inet_aton... yes
    checking for gethostbyname... yes
    checking for dlsym in -ldl... yes
    checking for RTLD_NEXT from dlfcn.h... yes
    checking for correct select prototype... select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
    checking for correct connect prototype... connect(int __fd, const struct sockaddr * __addr, socklen_t __len)
    checking for correct close prototype... close(int fd)
    checking for correct poll prototype... poll(struct pollfd *ufds, unsigned long nfds, int timeout)
    updating cache ./config.cache
    creating ./config.status
    creating Makefile
    creating config.h
    

    Compiling:

    /opt/arm/12/arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-linux-gnueabihf/bin/arm-none-linux-gnueabihf-gcc -fPIC  -g -O2 -Wall -I. -c  tsocks.c -o tsocks.o
    tsocks.c: In function ‘connect’:
    tsocks.c:215:41: warning: pointer targets in passing argument 5 of ‘getsockopt’ differ in signedness [-Wpointer-sign]
      215 |                    (void *) &sock_type, &sock_type_len);
          |                                         ^~~~~~~~~~~~~~
          |                                         |
          |                                         int *
    In file included from tsocks.c:39:
    /opt/arm/12/arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-linux-gnueabihf/arm-none-linux-gnueabihf/libc/usr/include/sys/socket.h:257:46: note: expected ‘socklen_t * restrict’ {aka ‘unsigned int * restrict’} but argument is of type ‘int *’
      257 |                        socklen_t *__restrict __optlen) __THROW;
          |                        ~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~
    tsocks.c:271:62: warning: pointer targets in passing argument 3 of ‘getpeername’ differ in signedness [-Wpointer-sign]
      271 |    if (!getpeername(__fd, (struct sockaddr *) &peer_address, &namelen)) {
          |                                                              ^~~~~~~~
          |                                                              |
          |                                                              int *
    /opt/arm/12/arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-linux-gnueabihf/arm-none-linux-gnueabihf/libc/usr/include/sys/socket.h:131:47: note: expected ‘socklen_t * restrict’ {aka ‘unsigned int * restrict’} but argument is of type ‘int *’
      131 |                         socklen_t *__restrict __len) __THROW;
          |                         ~~~~~~~~~~~~~~~~~~~~~~^~~~~
    tsocks.c: In function ‘select’:
    tsocks.c:343:8: warning: variable ‘rc’ set but not used [-Wunused-but-set-variable]
      343 |    int rc = 0;
          |        ^~
    tsocks.c: In function ‘poll’:
    tsocks.c:526:8: warning: variable ‘rc’ set but not used [-Wunused-but-set-variable]
      526 |    int rc = 0, i;
          |        ^~
    /opt/arm/12/arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-linux-gnueabihf/bin/arm-none-linux-gnueabihf-gcc -fPIC  -g -O2 -Wall -I. -c  common.c -o common.o
    /opt/arm/12/arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-linux-gnueabihf/bin/arm-none-linux-gnueabihf-gcc -fPIC  -g -O2 -Wall -I. -c  parser.c -o parser.o
    /opt/arm/12/arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-linux-gnueabihf/bin/arm-none-linux-gnueabihf-gcc -fPIC  -g -O2 -Wall -I. -nostdlib -shared -o libtsocks.so.1.8 tsocks.o common.o parser.o  -ldl  -lc
    ln -sf libtsocks.so.1.8 libtsocks.so
    /opt/arm/12/arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-linux-gnueabihf/bin/arm-none-linux-gnueabihf-gcc -fPIC  -g -O2 -Wall -I. -static -o saveme saveme.c
    /opt/arm/12/arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-linux-gnueabihf/bin/arm-none-linux-gnueabihf-gcc -fPIC  -g -O2 -Wall -I. -o inspectsocks inspectsocks.c common.o -lc 
    /opt/arm/12/arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-linux-gnueabihf/bin/arm-none-linux-gnueabihf-gcc -fPIC  -g -O2 -Wall -I. -o validateconf validateconf.c common.o parser.o -lc
    

    Checking artifacts where built for the correct architecture:

    file libtsocks.so.1.8
    libtsocks.so.1.8: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, with debug_info, not stripped
    

    You should be able to find the exact path for your cross compiler by executing the following command:

    which  arm-linux-gnueabi-gcc