如何使用 g++ 链接到 lib 并同时创建共享 .so 文件或 CMake

发布于 2025-01-16 07:41:13 字数 2885 浏览 2 评论 0原文

文件夹/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 来链接 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 命令问题。 你能帮我解决这个问题吗?

File structure under folder /home/cyan/proj

fst
 | -- include
 |     |-- fstlib
 |            |-- fst_row_reader.h
 |            |-- fst
 |                 |-- interface
 |                         |-- fststore.h
 |
 | -- lib
       |-- libfst.so

test.cc

CMakeLists.txt

fst folder is a library I added and used in 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);
    }
}

*Note: In my actual test.cc I used some functions in fst library. Here is just a sample for simplicity.

Problem

Previously, I can simply use g++ test.cc -fPIC -shared -o test.so to get the .so file. However, since I included the fst lib, I got the following error:

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.

My attempt:

$ 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.

I also tried CMakeLists.txt to link the fst library as well as create a .so file under the path /home/cyan/proj/build/lib. But I am very new to CMake. Here is my attempt:

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)

But I can't find any files under the /home/cyan/proj/build/lib. I guess this is my CMake command issue.
Could you please help me with this problem?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

水溶 2025-01-23 07:41:13

使用位于文件系统上的库的最方便的方法是将信息与导入的库目标关联起来,这样您就可以使用 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)

这样信息就很容易重用并列出放在一个地方,而不是将其分散到链接目标的不同目标属性中。

更高级一点,但更好的是编写 fst-config.cmakefst-config-version.cmake 文件并将它们放在“安装目录”中该库允许您使用 find_package(fst) 执行创建导入库的逻辑,这使得该库可以轻松地在多个 cmake 项目中重用,但这超出了本答案的范围。
find_package 文档提供了有关以下内容的更多信息:如何做到这一点。


顺便说一句:请注意使用 CMAKE_CURRENT_SOURCE_DIR 而不是 CMAKE_SOURCE_DIR。如果您在包含变量引用的 CMakeLists.txt 文件的目录内指定绝对路径,因为 CMAKE_SOURCE_DIR 指的是顶级源目录,如果您使用 add_subdirectory 包含 CMakeLists.txt

The most convenient way of using a library located on the file system imho associating the info with a imported library target which allows you to just link it using 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)

this way the info is easy to reuse and it listed in a single place instead of spreading it into different target properties of the linking target.

A bit more advanced, but even better would be to write fst-config.cmake and fst-config-version.cmake files and putting them in the "installation directory" of the library which would allow you to use find_package(fst) to execute the logic creating the imported library which makes the library simple to reuse across multiple cmake projects, but this is beyond the scope of this answer.
The find_package documentation provides more info about how to do this.


Btw: Note the use of CMAKE_CURRENT_SOURCE_DIR instead of CMAKE_SOURCE_DIR. If you're specifying absolute paths inside the directory containing the CMakeLists.txt file containing the variable reference, since CMAKE_SOURCE_DIR refers to the toplevel source dir which may be different, if you're including the CMakeLists.txt using add_subdirectory.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文