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