Неопределенные ссылки с оптимизацией времени соединения
Я пытаюсь связать статическую библиотеку с исполняемым файлом, следуя этому примеру, но на MinGW-w64.
Мой файл CMakeLists: (обратите внимание, что это идентично тому, что в этом ответе)
cmake_minimum_required (VERSION 2.6)
project (hellow)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -flto")
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -flto")
SET(CMAKE_AR "gcc-ar")
SET(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> qcs <TARGET> <LINK_FLAGS> <OBJECTS>")
SET(CMAKE_C_ARCHIVE_FINISH true)
add_library(hello STATIC libhello.c)
add_executable(hellow hello.c)
target_link_libraries(hellow hello)
add_dependencies(hellow hello)
Привет:
extern void hello(void);
int main(void) {
hello();
return 0;
}
libhello.c:
#include <stdio.h>
void hello(void) {
puts("Hello");
}
Конфигурация работает как положено:
-- The C compiler identification is GNU 7.1.0
-- The CXX compiler identification is GNU 7.1.0
-- Check for working C compiler: C:/Program Files (x86)/mingw-w64/i686-7.1.0-win32-dwarf-rt_v5-rev2/mingw32/bin/gcc.exe
-- Check for working C compiler: C:/Program Files (x86)/mingw-w64/i686-7.1.0-win32-dwarf-rt_v5-rev2/mingw32/bin/gcc.exe -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: C:/Program Files (x86)/mingw-w64/i686-7.1.0-win32-dwarf-rt_v5-rev2/mingw32/bin/g++.exe
-- Check for working CXX compiler: C:/Program Files (x86)/mingw-w64/i686-7.1.0-win32-dwarf-rt_v5-rev2/mingw32/bin/g++.exe -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: C:/.../project
Однако при компиляции "как есть" генерируется следующая ошибка:
Scanning dependencies of target hello
[ 25%] Building C object CMakeFiles/hello.dir/libhello.c.obj
[ 50%] Linking C static library libhello.a
Error running link command: The system cannot find the file specified
mingw32-make.exe[3]: *** [CMakeFiles\hello.dir\build.make:95: libhello.a] Error 2
mingw32-make.exe[3]: *** Deleting file 'libhello.a'
mingw32-make.exe[2]: *** [CMakeFiles\Makefile2:67: CMakeFiles/hello.dir/all] Error 2
mingw32-make.exe[1]: *** [CMakeFiles\Makefile2:116: CMakeFiles/hellow.dir/rule] Error 2
mingw32-make.exe: *** [Makefile:130: hellow] Error 2
Удаление SET(CMAKE_C_ARCHIVE_FINISH true)
линия в CMakeLists.txt
файл и перекомпиляция результатов в этой "неопределенной ссылке":
[ 25%] Linking C static library libhello.a
[ 50%] Built target hello
Scanning dependencies of target hellow
[ 75%] Building C object CMakeFiles/hellow.dir/hello.c.obj
[100%] Linking C executable hellow.exe
C:\...\Local\Temp\ccPctpZp.ltrans0.ltrans.o: In function `main':
E:/Documents/MONAD/projects/ltotest/hello.c:4: undefined reference to `hello'
collect2.exe: error: ld returned 1 exit status
mingw32-make.exe[3]: *** [CMakeFiles\hellow.dir\build.make:97: hellow.exe] Error 1
mingw32-make.exe[2]: *** [CMakeFiles\Makefile2:104: CMakeFiles/hellow.dir/all] Error 2
mingw32-make.exe[1]: *** [CMakeFiles\Makefile2:116: CMakeFiles/hellow.dir/rule] Error 2
mingw32-make.exe: *** [Makefile:130: hellow] Error 2
Бег nm libhello.a
показывает, что libhello.c
компилируется с LTO:
libhello.c.obj:
00000000 b .bss
00000000 d .data
00000000 r .gnu.lto_.decls.d7da3e90
00000000 r .gnu.lto_.inline.d7da3e90
00000000 r .gnu.lto_.opts
00000000 r .gnu.lto_.refs.d7da3e90
00000000 r .gnu.lto_.symbol_nodes.d7da3e90
00000000 r .gnu.lto_.symtab.d7da3e90
00000000 r .gnu.lto_hello.d7da3e90
00000000 r .rdata$zzz
00000000 t .text
00000001 C ___gnu_lto_slim
00000001 C ___gnu_lto_v1
Похоже, что это проблема только для MinGW, поскольку в ответе, связанном ранее (как мне кажется, код работает нормально), хотя я сам не смог проверить его. Любые идеи о том, что идет не так / как обойти это?
1 ответ
Провел еще несколько исследований и наткнулся на эту страницу, где упоминается, что также необходимо использовать обертку для ranlib
,
Конечно же, меняется CMakeLists.txt
Следующее содержание позволяет успешно построить проект:
cmake_minimum_required (VERSION 2.6)
project (hellow)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -flto")
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -flto")
SET(CMAKE_AR "gcc-ar")
SET(CMAKE_RANLIB "gcc-ranlib")
SET(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> qcs <TARGET> <LINK_FLAGS> <OBJECTS>")
SET(CMAKE_C_ARCHIVE_FINISH "<CMAKE_RANLIB> <TARGET>")
add_library(hello STATIC libhello.c)
add_executable(hellow hello.c)
target_link_libraries(hellow hello)
add_dependencies(hellow hello)
(обратите внимание на новый SET(CMAKE_RANLIB "gcc-ranlib")
линия)
Кроме того, похоже, что SET(CMAKE_C_ARCHIVE_FINISH "<CMAKE_RANLIB> <TARGET>")
строка не обязательна, так как это значение по умолчанию для CMAKE_C_ARCHIVE_FINISH
,