gpt4 book ai didi

build - 在您构建的库上使用 CMake 中的 --whole-archive

转载 作者:行者123 更新时间:2023-12-02 02:52:35 25 4
gpt4 key购买 nike

我有一个 CMake 项目,同时构建一个静态库并将其与其他代码链接到可执行文件中。由于我不会详细说明的原因,我希望使用 --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_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的值透明地遵循您指定的输出目录目标,或者目标的默认输出目录(如果不这样做)。例如。如果the_static_lib是只需在构建目录中输出,然后 -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;
}

foobar/foo.c

#include <foobar.h>
#include <stdio.h>

void foo(void)
{
puts(__func__);
}

foobar/bar.c

#include <foobar.h>
#include <stdio.h>

void bar(void)
{
puts(__func__);
}

inc/foobar.h

#ifndef FOOBAR_H
#define FOOBAR_H

void foo(void);
void bar(void);

#endif

CMakeLists.txt (1)

cmake_minimum_required(VERSION 3.0)
project(app)
include_directories(inc)
add_library(foobar STATIC foobar/foo.c foobar/bar.c)
set_target_properties(foobar
PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
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")

我们想要 ./build/lib/libfoobar.a来自./foobar/foo.c./foobar/bar.c 。我们想要 ./build/bin/app来自./app/main.c ,链接整个文件./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)

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")

分别:

foobar/CMakeLists.txt (1)

add_library(foobar STATIC foo.c bar.c)
set_target_properties(foobar
PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")

并且使用相同的分隔,但默认输出目录,我们将有:

CMakeLists.txt (3)

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")

foobar/CMakeLists.txt (2)

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

关于build - 在您构建的库上使用 CMake 中的 --whole-archive,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43437424/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com