Build 在您构建的库上使用--CMake中的整个存档
我有一个CMake项目,同时构建一个静态库,并将其与其他代码链接到一个可执行文件中。出于我不想讨论的原因,我希望此链接使用Build 在您构建的库上使用--CMake中的整个存档,build,cmake,ld,build-dependencies,Build,Cmake,Ld,Build Dependencies,我有一个CMake项目,同时构建一个静态库,并将其与其他代码链接到一个可执行文件中。出于我不想讨论的原因,我希望此链接使用--whole archive链接器标志进行 现在,这个标志很棘手,因为你不能只在任何地方添加它-你必须切换它,然后列出你想应用它的库,然后取消它 我在某个地方读到(我想不出URL),如果您有一个预先存在的库,您可以通过执行以下操作有效地添加此链接器标志: # Just an example, find_library calls should really be isola
--whole archive
链接器标志进行
现在,这个标志很棘手,因为你不能只在任何地方添加它-你必须切换它,然后列出你想应用它的库,然后取消它
我在某个地方读到(我想不出URL),如果您有一个预先存在的库,您可以通过执行以下操作有效地添加此链接器标志:
# Just an example, find_library calls should really be isolated to separate find modules
find_library(FOO_LIBRARY foo)
set(FOO_LIBRARY "-Wl,--whole-archive ${FOO_LIBRARY} -Wl,--no-whole-archive")
add_executable(hello main.c)
target_link_libraries(hello ${FOO_LIBRARY})
那很好。但是,如果您正在构建的是一个静态库,而您没有预先存在的变量(即,您有add\u library()
CMake命令的对象),该怎么办?是否必须手动指示其路径而不是${FOO_LIBRARY}?或者,您是否可以使用其他技巧来获取CMake在命令行上为其设置的路径
此外,如果我使用某种类似
${FOO_LIBRARY}
-的字符串而不是静态库目标标识符,我相信CMake可能会丢失依赖项,即它可能不会与修改后的库重新链接(甚至不会构建它)因为target_link_libraries命令将看到一个奇怪的字符串,而不是另一个目标的标识符。这可以通过以下方法完成:
add_dependencies(the_exe the_static_lib)
set_target_properties(the_exe LINK_FLAGS
"-L/path/to/the_static_lib -Wl,--whole-archive,-lthe_static_lib,--no-whole-archive")
-L/path/to/The_static_lib
的值透明地遵循您指定的输出目录
要设置的目标,如果不设置,则为目标的默认输出目录。例如,如果静态库
为
只需在build目录中输出,-L/path/to/the_static_lib
将是-L.
这里是一个项目,以合理的一般方式说明,我们
具有结构化的源和头子目录以及不同的常规
输出目录,bin
,lib
$ ls -R
.:
app build CMakeLists.txt foobar inc
./app:
main.c
./build:
./foobar:
bar.c foo.c
./inc:
foobar.h
使用文件:
app/main.c
#include <foobar.h>
int main(void)
{
foo();
bar();
return 0;
}
#include <foobar.h>
#include <stdio.h>
void foo(void)
{
puts(__func__);
}
#include <foobar.h>
#include <stdio.h>
void bar(void)
{
puts(__func__);
}
CMakeLists.txt(1)
我们想从/foobar/foo.c
和/foobar/bar.c
制作/build/lib/libfoobar.a
。
我们想从/app/main.c
创建/build/bin/app
,链接整个归档文件/build/lib/libfoobar.a
生成、构建和运行:
$ cd build; cmake ..; make; ./bin/app
-- The C compiler identification is GNU 8.2.0
-- The CXX compiler identification is GNU 8.2.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/develop/so/cmake_prob/build
Scanning dependencies of target foobar
[ 20%] Building C object CMakeFiles/foobar.dir/foobar/foo.c.o
[ 40%] Building C object CMakeFiles/foobar.dir/foobar/bar.c.o
[ 60%] Linking C static library lib/libfoobar.a
[ 60%] Built target foobar
Scanning dependencies of target app
[ 80%] Building C object CMakeFiles/app.dir/app/main.c.o
[100%] Linking C executable bin/app
[100%] Built target app
foo
bar
类似地,如果我们没有使用CMakeLists.txt
,而是:
CMakeLists.txt(2)
另外:
foobar/CMakeLists.txt(1)
使用相同的分隔,但默认的输出目录,我们有:
CMakeLists.txt(3)
foobar/CMakeLists.txt(2)
那会是这样的:
$ cd build; cmake ..; make; ./app
-- The C compiler identification is GNU 8.2.0
-- The CXX compiler identification is GNU 8.2.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/develop/so/cmake_prob/build
Scanning dependencies of target foobar
[ 20%] Building C object foobar/CMakeFiles/foobar.dir/foo.c.o
[ 40%] Building C object foobar/CMakeFiles/foobar.dir/bar.c.o
[ 60%] Linking C static library libfoobar.a
[ 60%] Built target foobar
Scanning dependencies of target app
[ 80%] Building C object CMakeFiles/app.dir/app/main.c.o
[100%] Linking C executable app
[100%] Built target app
foo
bar
这有点骇人,但是,好吧,它似乎是有效的。这不是100%有效的
add\u dependencies(app foobar)
说,在foobar
之后构建app
。但不是:如果foobar
需要重建,app
也需要重建!看见最好还添加target\u link\u库(app foobar)
,即使此链接没有任何内容或仅包含部分内容。
$ cd build; cmake ..; make; ./bin/app
-- The C compiler identification is GNU 8.2.0
-- The CXX compiler identification is GNU 8.2.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/develop/so/cmake_prob/build
Scanning dependencies of target foobar
[ 20%] Building C object CMakeFiles/foobar.dir/foobar/foo.c.o
[ 40%] Building C object CMakeFiles/foobar.dir/foobar/bar.c.o
[ 60%] Linking C static library lib/libfoobar.a
[ 60%] Built target foobar
Scanning dependencies of target app
[ 80%] Building C object CMakeFiles/app.dir/app/main.c.o
[100%] Linking C executable bin/app
[100%] Built target app
foo
bar
cmake_minimum_required(VERSION 3.0)
project(app)
include_directories(inc)
add_subdirectory(foobar)
add_executable(app app/main.c)
add_dependencies(app foobar)
set_target_properties(app PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
LINK_FLAGS "-Llib -Wl,--whole-archive,-lfoobar,--no-whole-archive")
add_library(foobar STATIC foo.c bar.c)
set_target_properties(foobar
PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
cmake_minimum_required(VERSION 3.0)
project(app)
include_directories(inc)
add_subdirectory(foobar)
add_executable(app app/main.c)
add_dependencies(app foobar)
set_target_properties(app PROPERTIES
LINK_FLAGS "-Lfoobar -Wl,--whole-archive,-lfoobar,--no-whole-archive")
add_library(foobar STATIC foo.c bar.c)
$ cd build; cmake ..; make; ./app
-- The C compiler identification is GNU 8.2.0
-- The CXX compiler identification is GNU 8.2.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/develop/so/cmake_prob/build
Scanning dependencies of target foobar
[ 20%] Building C object foobar/CMakeFiles/foobar.dir/foo.c.o
[ 40%] Building C object foobar/CMakeFiles/foobar.dir/bar.c.o
[ 60%] Linking C static library libfoobar.a
[ 60%] Built target foobar
Scanning dependencies of target app
[ 80%] Building C object CMakeFiles/app.dir/app/main.c.o
[100%] Linking C executable app
[100%] Built target app
foo
bar