Это можно сделать с помощью:
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
С файлами:
приложение/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
person
Mike Kinghan
schedule
02.03.2019