は、問題を再現MCVE CMakeのプロジェクトです:
$ ls -R hellow
hellow:
CMakeLists.txt hello.c libhello.c
$ cat hellow/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_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)
$ cat hellow/hello.c
extern void hello(void);
int main(void)
{
hello();
return 0;
}
$ cat hellow/libhello.c
#include <stdio.h>
void hello(void)
{
puts("Hello");
}
設定が良いです:
$ mkdir build_hellow
$ cd build_hellow/
$ cmake ../hellow
-- The C compiler identification is GNU 5.4.0
-- The CXX compiler identification is GNU 5.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- 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: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- 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: /home/imk/dev/so/build_hellow
ビルドは問題ごとに失敗します。
$ make
Scanning dependencies of target hello
[ 25%] Building C object CMakeFiles/hello.dir/libhello.c.o
[ 50%] Linking C static library libhello.a
/usr/bin/ar: CMakeFiles/hello.dir/libhello.c.o: plugin needed to handle lto object
/usr/bin/ranlib: libhello.c.o: plugin needed to handle lto object
[ 50%] Built target hello
Scanning dependencies of target hellow
[ 75%] Building C object CMakeFiles/hellow.dir/hello.c.o
[100%] Linking C executable hellow
/tmp/ccV0lG36.ltrans0.ltrans.o: In function `main':
<artificial>:(.text+0x5): undefined reference to `hello'
collect2: error: ld returned 1 exit status
CMakeFiles/hellow.dir/build.make:95: recipe for target 'hellow' failed
make[2]: *** [hellow] Error 1
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/hellow.dir/all' failed
make[1]: *** [CMakeFiles/hellow.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2
以上があります一つの解決策。 1つは、上記のCMakeLists.txt
の3つのコメント行 をコメント解除することです。次に、
$ cmake ../hellow/
-- The C compiler identification is GNU 5.4.0
-- The CXX compiler identification is GNU 5.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- 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: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- 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: /home/imk/dev/so/build_hellow
$ make
Scanning dependencies of target hello
[ 25%] Building C object CMakeFiles/hello.dir/libhello.c.o
[ 50%] Linking C static library libhello.a
[ 50%] Built target hello
Scanning dependencies of target hellow
[ 75%] Building C object CMakeFiles/hellow.dir/hello.c.o
[100%] Linking C executable hellow
[100%] Built target hellow
$ ./hellow
Hello
この修正プログラムでは、次の事実を利用します。
は、ビルド破り問題:
/usr/bin/ar: CMakeFiles/hello.dir/libhello.c.o: plugin needed to handle lto object
...
/usr/bin/ranlib: libhello.c.o: plugin needed to handle lto object
オプションar
とranlib
を与えることによって解決することができます。しかし
--plugin=$(gcc --print-file-name=liblto_plugin.so)
は、GNU ranlib
は単にar -s
の同義語であり、gcc-ar
は ですそのプラグインを提供するar
のラッパー。C静的ライブラリの
cmakeののビルドテンプレートは次のとおりです。
CMAKE_C_ARCHIVE_CREATE (= <CMAKE_AR> qc <TARGET> <LINK_FLAGS> <OBJECTS>)
CMAKE_C_ARCHIVE_FINISH (= <CMAKE_RANLIB> <TARGET>)
GNU ar
のために相当する:これらの設定を持つので
CMAKE_C_ARCHIVE_CREATE (= <CMAKE_AR> qcs <TARGET> <LINK_FLAGS> <OBJECTS>)
CMAKE_C_ARCHIVE_FINISH (= true) # Or any other no-op command
プラス:
SET(CMAKE_AR "gcc-ar")
たち'元気。 C++プロジェクトで
は、当然のことながら、CMAKE_CXX_ARCHIVE_CREATE
とCMAKE_CXX_ARCHIVE_FINISH
を設定しますCMakeCache.txt' 'やCMakeののGUI(経由' CMAKE_AR'キャッシュされた変数に 'GCC-ar'で' ar'を交換しようとしました高度なオプションの下で)? GCCのための 'INTERPROCEDURAL_OPTIMIZATION'は動作しませんCMakeのGitLabページの[公開の問題](https://gitlab.kitware.com/cmake/cmake/issues/15939)です。 – Florian
@Florian:私は試したところで、 'CMAKE_AR'を設定しても問題は解決しません。あなたはまた 'CMAKE_CXX_ARCHIVE_CREATE'と' CMAKE_CXX_ARCHIVE_FINISH'(cf. @Mike Kinghanの答え) – CpCd0y