Skip to content

CheckIPOSupported seems t o ignore CMAKE_TRY_COMPILE_TARGET_TYPE

I am using a project, which can also target some embedded devices using newlib, this library cant generally be used "standalone", some stuff like the platform specific output device for printf needs to be hooked in.

its generally expected that you set CMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY to make diverse checks work (or atleast silently pass). This doesnt seem to affect CheckIPOSupported, it will always try to link an executable and fail.

the toolchain itself supports LTO just fine, and could correctly link shared libraries (aswell as executables with some added linker options).

For testing, you could use this Gnu ARM toolchain.

CMakeLists.txt

cmake_minimum_required(VERSION 3.14)
include(CheckIPOSupported)

project(testipo
				LANGUAGES C)

check_ipo_supported(RESULT TEST_IPO_SUPPORTED OUTPUT TEST_IPO_SUPPORTED_FAILURE)
if(NOT TEST_IPO_SUPPORTED)
  message(WARNING "IPO is not supported: ${TEST_IPO_SUPPORTED_FAILURE}")
endif()

used toolchain.cmake, PACKAGE_PREFIX_DIR should point to the root toolchain installation (expects the compiler in bin).

get_filename_component(PACKAGE_PREFIX_DIR "${CMAKE_CURRENT_LIST_DIR}/.." ABSOLUTE)
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR})
set(CMAKE_TOOLCHAIN_REMOVE_MPATH ${CMAKE_CURRENT_LIST_DIR})

set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(CMAKE_SYSTEM_VERSION )

set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
set(CMAKE_INSTALL_SO_NO_EXE 0)

# Generic paths and search settings
set(CMAKE_PROGRAM_PATH "${PACKAGE_PREFIX_DIR}/bin")
set(CMAKE_SYSROOT "${PACKAGE_PREFIX_DIR}/arm-none-eabi")
set(CMAKE_FIND_ROOT_PATH "${CMAKE_SYSROOT}")
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

set(ENV{PKG_CONFIG_PATH} "")
set(ENV{PKG_CONFIG_LIBDIR} "${CMAKE_SYSROOT}/usr/lib/pkgconfig:${CMAKE_SYSROOT}/usr/share/pkgconfig")
set(ENV{PKG_CONFIG_SYSROOT_DIR} "${CMAKE_SYSROOT}")

# Compiler binaries
set(CMAKE_C_COMPILER "${PACKAGE_PREFIX_DIR}/bin/arm-none-eabi-gcc")
set(CMAKE_CXX_COMPILER "${PACKAGE_PREFIX_DIR}/bin/arm-none-eabi-g++")
set(CMAKE_Fortran_COMPILER "${PACKAGE_PREFIX_DIR}/bin/arm-none-eabi-gfortran")
set(CMAKE_OBJC_COMPILER "${PACKAGE_PREFIX_DIR}/bin/arm-none-eabi-gobjc")
set(CMAKE_OBJCXX_COMPILER "${PACKAGE_PREFIX_DIR}/bin/arm-none-eabi-gobjc++")

Output from the example above

CMake Warning at CMakeLists.txt:9 (message):
  IPO is not supported: Change Dir:
  /tmp/pbuild/CMakeFiles/_CMakeLTOTest-C/bin

  

  Run Build Command(s):/usr/bin/gmake -f Makefile && /usr/bin/cmake
  -S/tmp/pbuild/CMakeFiles/_CMakeLTOTest-C/src
  -B/tmp/pbuild/CMakeFiles/_CMakeLTOTest-C/bin --check-build-system
  CMakeFiles/Makefile.cmake 0

  /usr/bin/cmake -E cmake_progress_start
  /tmp/pbuild/CMakeFiles/_CMakeLTOTest-C/bin/CMakeFiles
  /tmp/pbuild/CMakeFiles/_CMakeLTOTest-C/bin//CMakeFiles/progress.marks

  /usr/bin/gmake -f CMakeFiles/Makefile2 all

  gmake[1]: Entering directory '/tmp/pbuild/CMakeFiles/_CMakeLTOTest-C/bin'

  /usr/bin/gmake -f CMakeFiles/foo.dir/build.make CMakeFiles/foo.dir/depend

  gmake[2]: Entering directory '/tmp/pbuild/CMakeFiles/_CMakeLTOTest-C/bin'

  cd /tmp/pbuild/CMakeFiles/_CMakeLTOTest-C/bin && /usr/bin/cmake -E
  cmake_depends "Unix Makefiles" /tmp/pbuild/CMakeFiles/_CMakeLTOTest-C/src
  /tmp/pbuild/CMakeFiles/_CMakeLTOTest-C/src
  /tmp/pbuild/CMakeFiles/_CMakeLTOTest-C/bin
  /tmp/pbuild/CMakeFiles/_CMakeLTOTest-C/bin
  /tmp/pbuild/CMakeFiles/_CMakeLTOTest-C/bin/CMakeFiles/foo.dir/DependInfo.cmake


  Scanning dependencies of target foo

  gmake[2]: Leaving directory '/tmp/pbuild/CMakeFiles/_CMakeLTOTest-C/bin'

  /usr/bin/gmake -f CMakeFiles/foo.dir/build.make CMakeFiles/foo.dir/build

  gmake[2]: Entering directory '/tmp/pbuild/CMakeFiles/_CMakeLTOTest-C/bin'

  [ 25%] Building C object CMakeFiles/foo.dir/foo.c.obj

  /tmp/installWin64/bin/arm-none-eabi-gcc
  --sysroot=/tmp/installWin64/arm-none-eabi -flto -fno-fat-lto-objects -o
  CMakeFiles/foo.dir/foo.c.obj -c
  /tmp/pbuild/CMakeFiles/_CMakeLTOTest-C/src/foo.c

  [ 50%] Linking C static library libfoo.a

  /usr/bin/cmake -P CMakeFiles/foo.dir/cmake_clean_target.cmake

  /usr/bin/cmake -E cmake_link_script CMakeFiles/foo.dir/link.txt --verbose=1

  "/tmp/installWin64/bin/arm-none-eabi-gcc-ar" cr libfoo.a
  CMakeFiles/foo.dir/foo.c.obj

  "/tmp/installWin64/bin/arm-none-eabi-gcc-ranlib" libfoo.a

  gmake[2]: Leaving directory '/tmp/pbuild/CMakeFiles/_CMakeLTOTest-C/bin'

  [ 50%] Built target foo

  /usr/bin/gmake -f CMakeFiles/boo.dir/build.make CMakeFiles/boo.dir/depend

  gmake[2]: Entering directory '/tmp/pbuild/CMakeFiles/_CMakeLTOTest-C/bin'

  cd /tmp/pbuild/CMakeFiles/_CMakeLTOTest-C/bin && /usr/bin/cmake -E
  cmake_depends "Unix Makefiles" /tmp/pbuild/CMakeFiles/_CMakeLTOTest-C/src
  /tmp/pbuild/CMakeFiles/_CMakeLTOTest-C/src
  /tmp/pbuild/CMakeFiles/_CMakeLTOTest-C/bin
  /tmp/pbuild/CMakeFiles/_CMakeLTOTest-C/bin
  /tmp/pbuild/CMakeFiles/_CMakeLTOTest-C/bin/CMakeFiles/boo.dir/DependInfo.cmake


  Scanning dependencies of target boo

  gmake[2]: Leaving directory '/tmp/pbuild/CMakeFiles/_CMakeLTOTest-C/bin'

  /usr/bin/gmake -f CMakeFiles/boo.dir/build.make CMakeFiles/boo.dir/build

  gmake[2]: Entering directory '/tmp/pbuild/CMakeFiles/_CMakeLTOTest-C/bin'

  [ 75%] Building C object CMakeFiles/boo.dir/main.c.obj

  /tmp/installWin64/bin/arm-none-eabi-gcc
  --sysroot=/tmp/installWin64/arm-none-eabi -flto -fno-fat-lto-objects -o
  CMakeFiles/boo.dir/main.c.obj -c
  /tmp/pbuild/CMakeFiles/_CMakeLTOTest-C/src/main.c

  [100%] Linking C executable boo

  /usr/bin/cmake -E cmake_link_script CMakeFiles/boo.dir/link.txt --verbose=1

  /tmp/installWin64/bin/arm-none-eabi-gcc
  --sysroot=/tmp/installWin64/arm-none-eabi -flto -fno-fat-lto-objects
  CMakeFiles/boo.dir/main.c.obj -o boo libfoo.a

  
  /tmp/installWin64/lib/gcc/arm-none-eabi/10/../../../../arm-none-eabi/bin/ld:
  /tmp/installWin64/lib/gcc/arm-none-eabi/10/../../../../arm-none-eabi/lib/libc.a(lib_a-exit.o):
  in function `exit':

  /hugo/src/newlib-333/newlib/libc/stdlib/exit.c:64: undefined reference to
  `_exit'

  
  /tmp/installWin64/lib/gcc/arm-none-eabi/10/../../../../arm-none-eabi/bin/ld:
  /tmp/installWin64/lib/gcc/arm-none-eabi/10/../../../../arm-none-eabi/lib/libc.a(lib_a-sbrkr.o):
  in function `_sbrk_r':

  /hugo/src/newlib-333/newlib/libc/reent/sbrkr.c:51: undefined reference to
  `_sbrk'

  
  /tmp/installWin64/lib/gcc/arm-none-eabi/10/../../../../arm-none-eabi/bin/ld:
  /tmp/installWin64/lib/gcc/arm-none-eabi/10/../../../../arm-none-eabi/lib/libc.a(lib_a-writer.o):
  in function `_write_r':

  /hugo/src/newlib-333/newlib/libc/reent/writer.c:49: undefined reference to
  `_write'

  
  /tmp/installWin64/lib/gcc/arm-none-eabi/10/../../../../arm-none-eabi/bin/ld:
  /tmp/installWin64/lib/gcc/arm-none-eabi/10/../../../../arm-none-eabi/lib/libc.a(lib_a-closer.o):
  in function `_close_r':

  /hugo/src/newlib-333/newlib/libc/reent/closer.c:47: undefined reference to
  `_close'

  
  /tmp/installWin64/lib/gcc/arm-none-eabi/10/../../../../arm-none-eabi/bin/ld:
  /tmp/installWin64/lib/gcc/arm-none-eabi/10/../../../../arm-none-eabi/lib/libc.a(lib_a-lseekr.o):
  in function `_lseek_r':

  /hugo/src/newlib-333/newlib/libc/reent/lseekr.c:49: undefined reference to
  `_lseek'

  
  /tmp/installWin64/lib/gcc/arm-none-eabi/10/../../../../arm-none-eabi/bin/ld:
  /tmp/installWin64/lib/gcc/arm-none-eabi/10/../../../../arm-none-eabi/lib/libc.a(lib_a-readr.o):
  in function `_read_r':

  /hugo/src/newlib-333/newlib/libc/reent/readr.c:49: undefined reference to
  `_read'

  collect2: error: ld returned 1 exit status

  gmake[2]: *** [CMakeFiles/boo.dir/build.make:100: boo] Error 1

  gmake[2]: Leaving directory '/tmp/pbuild/CMakeFiles/_CMakeLTOTest-C/bin'

  gmake[1]: *** [CMakeFiles/Makefile2:88: CMakeFiles/boo.dir/all] Error 2

  gmake[1]: Leaving directory '/tmp/pbuild/CMakeFiles/_CMakeLTOTest-C/bin'

  gmake: *** [Makefile:94: all] Error 2

  



-- Configuring done
-- Generating done
-- Build files have been written to: /tmp/pbuild
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information