Linker problem while retargeting newlib with static library

  Kiến thức lập trình

I can’t get my head around a problem I face (sorry for the long post).

I use a Gnu Arm toolchain with GCC v12.3.

I want to do some retargeting on my stm32. For this, I have a file stdlib_override.cpp :

#include <cerrno>
#include <sys/stat.h>
#include <sys/time.h>
    
extern "C" {
    
    int _gettimeofday(struct timeval *tv, void *) { return 18; }
    
    int _getpid(void) { return 1; }
    
    int _write(int fd, const void *buf, size_t count) { return 0; }
    
    int _read(int /*fd*/, const void *buf, size_t count) { return 0; }
    
    int _kill(int, int)
    {
        errno = EINVAL;
        return -1;
    }
    
    int _close(int) { return -1; }
    
    int _fstat(int, struct stat *st)
    {
        st->st_mode = S_IFCHR;
        return 0;
    }
    
    int _isatty(int) { return 1; }
    
    int _lseek(int, int, int) { return 0; }
    
    int _open(char *, int, ...)
    {
        /* Pretend like we always fail */
        return -1;
    }
    
    int _wait(int *)
    {
        errno = ECHILD;
        return -1;
    }
    
    int _unlink(char *)
    {
        errno = ENOENT;
        return -1;
    }
    
    int _times(struct tms *) { return -1; }
}

My main.cpp is:


#include <cstdio>
#include <sys/time.h>

int main()
{
    timeval tv{};
    std::printf("Hello, World!n");
    std::printf("%dn", gettimeofday(&tv, nullptr));
    return 0;
}

I use CMake as a build system. My CMakeLists.txt is :

cmake_minimum_required(VERSION 3.28)

project(gettimeofday)

set(CMAKE_CXX_STANDARD 17)

add_link_options(
        -mthumb
        -specs=nosys.specs
        -specs=nano.specs
        -Wl,-Map=output.map
        -Wl,--print-memory-usage
        -Wl,--gc-sections
)

add_library(arm STATIC stdlib_override.cpp)

add_executable(gettimeofday main.cpp)

target_link_libraries(gettimeofday PRIVATE arm)

My toolchain file is :

# define main characteristics of the target
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_PROCESSOR ARM)

set(TOOLCHAIN_ROOT_LOCATION "C:/Program Files (x86)/Arm GNU Toolchain arm-none-eabi/12.3 rel1")
set(TOOLCHAIN_PREFIX arm-none-eabi-)

# the path to where toolchain relative includes, libs or bin may be found
set(CMAKE_FIND_ROOT_PATH "${TOOLCHAIN_ROOT_LOCATION}")

set(TOOLCHAIN_COMPLETE "${TOOLCHAIN_ROOT_LOCATION}/bin/${TOOLCHAIN_PREFIX}")

set(CMAKE_C_COMPILER ${TOOLCHAIN_COMPLETE}gcc.exe)
set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER})
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_COMPLETE}g++.exe)
set(CMAKE_OBJCOPY ${TOOLCHAIN_COMPLETE}objcopy.exe CACHE INTERNAL "objcopy tool")
set(CMAKE_SIZE_UTIL ${TOOLCHAIN_COMPLETE}size.exe CACHE INTERNAL "size tool")

# CMake will try to compile using the predefined compiler. STATIC_LIBRARY arg is always needed when cross compiling
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)

# find_program() should never try to find any programs in CMAKE_FIND_ROOT_PATH
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# find_library() should only try to find any library in CMAKE_FIND_ROOT_PATH
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
# find_file() or find_path() should only try to find any file in CMAKE_FIND_ROOT_PATH
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

But the linker seems unable to find functions in stdlib_override.cpp.

C:/PROGRA~2/GNUARM~1/13/bin/../lib/gcc/arm-none-eabi/13.3.1/../../../../arm-none-eabi/bin/ld.exe: C:/PROGRA~2/GNUARM~1/13/bin/../lib/gcc/arm-none-eabi/13.3.1/thumb/nofplibg_nano.a(libc_a-closer.o): in function `_close_r':
closer.c:(.text._close_r+0xc): warning: _close is not implemented and will always fail
C:/PROGRA~2/GNUARM~1/13/bin/../lib/gcc/arm-none-eabi/13.3.1/../../../../arm-none-eabi/bin/ld.exe: C:/PROGRA~2/GNUARM~1/13/bin/../lib/gcc/arm-none-eabi/13.3.1/thumb/nofplibg_nano.a(libc_a-fstatr.o): in function `_fstat_r':
fstatr.c:(.text._fstat_r+0xe): warning: _fstat is not implemented and will always fail
C:/PROGRA~2/GNUARM~1/13/bin/../lib/gcc/arm-none-eabi/13.3.1/../../../../arm-none-eabi/bin/ld.exe: C:/PROGRA~2/GNUARM~1/13/bin/../lib/gcc/arm-none-eabi/13.3.1/thumb/nofplibg_nano.a(libc_a-signalr.o): in function `_getpid_r':
signalr.c:(.text._getpid_r+0x2): warning: _getpid is not implemented and will always fail
C:/PROGRA~2/GNUARM~1/13/bin/../lib/gcc/arm-none-eabi/13.3.1/../../../../arm-none-eabi/bin/ld.exe: C:/PROGRA~2/GNUARM~1/13/bin/../lib/gcc/arm-none-eabi/13.3.1/thumb/nofplibg_nano.a(libc_a-gettimeofdayr.o): in function `_gettimeofday_r':
gettimeofdayr.c:(.text._gettimeofday_r+0xe): warning: _gettimeofday is not implemented and will always fail
C:/PROGRA~2/GNUARM~1/13/bin/../lib/gcc/arm-none-eabi/13.3.1/../../../../arm-none-eabi/bin/ld.exe: C:/PROGRA~2/GNUARM~1/13/bin/../lib/gcc/arm-none-eabi/13.3.1/thumb/nofplibg_nano.a(libc_a-isattyr.o): in function `_isatty_r':
isattyr.c:(.text._isatty_r+0xc): warning: _isatty is not implemented and will always fail
C:/PROGRA~2/GNUARM~1/13/bin/../lib/gcc/arm-none-eabi/13.3.1/../../../../arm-none-eabi/bin/ld.exe: C:/PROGRA~2/GNUARM~1/13/bin/../lib/gcc/arm-none-eabi/13.3.1/thumb/nofplibg_nano.a(libc_a-signalr.o): in function `_kill_r':
signalr.c:(.text._kill_r+0xe): warning: _kill is not implemented and will always fail
C:/PROGRA~2/GNUARM~1/13/bin/../lib/gcc/arm-none-eabi/13.3.1/../../../../arm-none-eabi/bin/ld.exe: C:/PROGRA~2/GNUARM~1/13/bin/../lib/gcc/arm-none-eabi/13.3.1/thumb/nofplibg_nano.a(libc_a-lseekr.o): in function `_lseek_r':
lseekr.c:(.text._lseek_r+0x10): warning: _lseek is not implemented and will always fail
C:/PROGRA~2/GNUARM~1/13/bin/../lib/gcc/arm-none-eabi/13.3.1/../../../../arm-none-eabi/bin/ld.exe: C:/PROGRA~2/GNUARM~1/13/bin/../lib/gcc/arm-none-eabi/13.3.1/thumb/nofplibg_nano.a(libc_a-readr.o): in function `_read_r':
readr.c:(.text._read_r+0x10): warning: _read is not implemented and will always fail
C:/PROGRA~2/GNUARM~1/13/bin/../lib/gcc/arm-none-eabi/13.3.1/../../../../arm-none-eabi/bin/ld.exe: C:/PROGRA~2/GNUARM~1/13/bin/../lib/gcc/arm-none-eabi/13.3.1/thumb/nofplibg_nano.a(libc_a-writer.o): in function `_write_r':
writer.c:(.text._write_r+0x10): warning: _write is not implemented and will always fail

It finds them if I don’t use a static libray (using add_executable(gettimeofday main.cpp stdlib_override.cpp)).

I think there is an order problem between newlib and my lib, but how can I control that?

Theme wordpress giá rẻ Theme wordpress giá rẻ Thiết kế website

LEAVE A COMMENT