如何使用 g++ 或 CMake link 到一个 lib 并同时创建一个共享的 .so 文件
how to link to a lib and create a shared .so file at the same time using g++ or CMake
文件夹/home/cyan/proj
下的文件结构
fst
| -- include
| |-- fstlib
| |-- fst_row_reader.h
| |-- fst
| |-- interface
| |-- fststore.h
|
| -- lib
|-- libfst.so
test.cc
CMakeLists.txt
fst
文件夹是我在test.cc
.
中添加和使用的库
test.cc
#include <iostream>
#include <fstlib/fst_row_reader.h>
class Add{
public:
double add2num(int a, double b){
return a + b;
}
};
extern "C"
{
Add* test_new(){
return new Add;
}
int my_func(Add* t, int a, double b){
return t->add2num(a, b);
}
}
*注意:在我实际的test.cc
中,我使用了fst
库中的一些函数。为了简单起见,这里只是一个示例。
问题
以前,我可以简单地使用 g++ test.cc -fPIC -shared -o test.so
来获取 .so
文件。但是,由于我包含了 fst
库,所以出现以下错误:
In file included from /home/cyan/proj/fst/include/fstlib/fst_row_reader.h:7:0,
from read_fst.cc:1:
/home/cyan/proj/fst/include/fstlib/fst_reader.h:6:10: fatal error: fstlib/fst/interface/fststore.h: No such file or directory
#include <fstlib/fst/interface/fststore.h>
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
我的尝试:
$ g++ -L/home/cyan/proj/fst/lib -l:libfst.so
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status
---------------------------------------------------------
$ g++ read_fst.cc -L /home/cyan/proj/fst/lib/libfst.so -fPIC -shared -o test.so
In file included from /home/cyan/proj/fst/include/fstlib/fst_row_reader.h:7:0,
from read_fst.cc:1:
/home/cyan/proj/fst/include/fstlib/fst_reader.h:6:10: fatal error: fstlib/fst/interface/fststore.h: No such file or directory
#include <fstlib/fst/interface/fststore.h>
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
我还尝试 CMakeLists.txt
到 link fst
库以及在路径 /home/cyan/proj/build/lib
下创建一个 .so
文件。但我对 CMake 很陌生。这是我的尝试:
cmake_minimum_required(VERSION 3.0.0)
project(MY_PROJ VERSION 0.1.0)
set(mylibSRCS test.cc)
message(STATUS "Build test.so")
include_directories(${CMAKE_SOURCE_DIR}/fst/include)
link_directories(${CMAKE_SOURCE_DIR}/fst/lib)
add_library(MY_PROJ SHARED ${mylibSRCS})
set_target_properties(MY_PROJ PROPERTIES
LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
target_link_libraries(MY_PROJ ${CMAKE_SOURCE_DIR}/fst/lib/libfst.so) # link to my fst lib
target_link_libraries(MY_PROJ)
但是我在/home/cyan/proj/build/lib
下找不到任何文件。我想这是我的 CMake 命令问题。
你能帮我解决这个问题吗?
最方便的使用位于文件系统上的库的方法恕我直言,将信息与导入的库目标相关联,这样您就可以 link 使用 target_link_libraries
:
add_library(fst SHARED IMPORTED)
target_include_directories(fst INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/fst/include)
set_target_properties(fst PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/fst/lib/libfst.so)
...
target_link_libraries(MY_PROJ PRIVATE fst)
这样信息就很容易重用,而且它列在一个地方而不是分散到 linking 目标的不同目标属性中。
更高级一点,但更好的方法是编写 fst-config.cmake
和 fst-config-version.cmake
文件并将它们放在库的“安装目录”中,这样您就可以使用 find_package(fst)
执行创建导入库的逻辑,这使得库可以简单地跨多个 cmake 项目重用,但这超出了本答案的范围。
find_package
documentation 提供了有关如何执行此操作的更多信息。
顺便说一句:注意使用 CMAKE_CURRENT_SOURCE_DIR
而不是 CMAKE_SOURCE_DIR
。如果您在包含包含变量引用的 CMakeLists.txt
文件的目录中指定绝对路径,因为 CMAKE_SOURCE_DIR
指的是可能不同的顶层源目录,如果您包含 CMakeLists.txt
使用 add_subdirectory
.
文件夹/home/cyan/proj
fst
| -- include
| |-- fstlib
| |-- fst_row_reader.h
| |-- fst
| |-- interface
| |-- fststore.h
|
| -- lib
|-- libfst.so
test.cc
CMakeLists.txt
fst
文件夹是我在test.cc
.
test.cc
#include <iostream>
#include <fstlib/fst_row_reader.h>
class Add{
public:
double add2num(int a, double b){
return a + b;
}
};
extern "C"
{
Add* test_new(){
return new Add;
}
int my_func(Add* t, int a, double b){
return t->add2num(a, b);
}
}
*注意:在我实际的test.cc
中,我使用了fst
库中的一些函数。为了简单起见,这里只是一个示例。
问题
以前,我可以简单地使用 g++ test.cc -fPIC -shared -o test.so
来获取 .so
文件。但是,由于我包含了 fst
库,所以出现以下错误:
In file included from /home/cyan/proj/fst/include/fstlib/fst_row_reader.h:7:0,
from read_fst.cc:1:
/home/cyan/proj/fst/include/fstlib/fst_reader.h:6:10: fatal error: fstlib/fst/interface/fststore.h: No such file or directory
#include <fstlib/fst/interface/fststore.h>
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
我的尝试:
$ g++ -L/home/cyan/proj/fst/lib -l:libfst.so
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status
---------------------------------------------------------
$ g++ read_fst.cc -L /home/cyan/proj/fst/lib/libfst.so -fPIC -shared -o test.so
In file included from /home/cyan/proj/fst/include/fstlib/fst_row_reader.h:7:0,
from read_fst.cc:1:
/home/cyan/proj/fst/include/fstlib/fst_reader.h:6:10: fatal error: fstlib/fst/interface/fststore.h: No such file or directory
#include <fstlib/fst/interface/fststore.h>
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
我还尝试 CMakeLists.txt
到 link fst
库以及在路径 /home/cyan/proj/build/lib
下创建一个 .so
文件。但我对 CMake 很陌生。这是我的尝试:
cmake_minimum_required(VERSION 3.0.0)
project(MY_PROJ VERSION 0.1.0)
set(mylibSRCS test.cc)
message(STATUS "Build test.so")
include_directories(${CMAKE_SOURCE_DIR}/fst/include)
link_directories(${CMAKE_SOURCE_DIR}/fst/lib)
add_library(MY_PROJ SHARED ${mylibSRCS})
set_target_properties(MY_PROJ PROPERTIES
LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
target_link_libraries(MY_PROJ ${CMAKE_SOURCE_DIR}/fst/lib/libfst.so) # link to my fst lib
target_link_libraries(MY_PROJ)
但是我在/home/cyan/proj/build/lib
下找不到任何文件。我想这是我的 CMake 命令问题。
你能帮我解决这个问题吗?
最方便的使用位于文件系统上的库的方法恕我直言,将信息与导入的库目标相关联,这样您就可以 link 使用 target_link_libraries
:
add_library(fst SHARED IMPORTED)
target_include_directories(fst INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/fst/include)
set_target_properties(fst PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/fst/lib/libfst.so)
...
target_link_libraries(MY_PROJ PRIVATE fst)
这样信息就很容易重用,而且它列在一个地方而不是分散到 linking 目标的不同目标属性中。
更高级一点,但更好的方法是编写 fst-config.cmake
和 fst-config-version.cmake
文件并将它们放在库的“安装目录”中,这样您就可以使用 find_package(fst)
执行创建导入库的逻辑,这使得库可以简单地跨多个 cmake 项目重用,但这超出了本答案的范围。
find_package
documentation 提供了有关如何执行此操作的更多信息。
顺便说一句:注意使用 CMAKE_CURRENT_SOURCE_DIR
而不是 CMAKE_SOURCE_DIR
。如果您在包含包含变量引用的 CMakeLists.txt
文件的目录中指定绝对路径,因为 CMAKE_SOURCE_DIR
指的是可能不同的顶层源目录,如果您包含 CMakeLists.txt
使用 add_subdirectory
.