gpt4 book ai didi

C++使用源码、静态存档等动态库创建动态库

转载 作者:行者123 更新时间:2023-12-01 14:25:10 25 4
gpt4 key购买 nike

在我的用例中,我有 YAML-CPP , SQLite3 ,以及我想要全部合并到同一个动态库“libdata.so”中的“data.cpp”文件。 diagram of expected behavior

我首先编译了yaml-cpp(作为存档):

mkdir -p "build"
cd "build"
cmake ..
make -j5

获取“libyaml-cpp.a”。

然后我编译sqlite3:

gcc -c -o libsqlite3.a sqlite3.c -lpthread -ldl

获取'libsqlite3.a'。我知道这是一个基于 C 的文件,它与 C++ 之间存在差异,但我读到它在这里应该不会有太大差异。我也知道我正在使用用于动态加载的 -lpthread -ldl,但我不确定如何绕过它。

我的问题是:我能否使用 YAMP-CPP 和 SQLite3 编译我的“data.cpp”文件,使它们都存在于同一个“libdata.so”输出文件中(链接器将在其中当“data.cpp”调用时使用“libdata.so”中包含的 YAML-CPP 和 SQLite3 函数)?

我试过:

g++ -c -fPIC -o libdata.so \
-Wl,--whole-archive libsqlite3.a \
-Wl,--whole-archive libyaml-cpp.a \
-ldl -lpthread \
data.cpp

(为了片段的缘故,所有文件都位于同一目录中)

更新
我将 botje 的建议添加到该行中,这在一定程度上有所帮助。经过更多的研究,我发现了一些更进一步的作品:

gcc -DSQLITE_OMIT_LOAD_EXTENSION -c -fPIC -lpthread -o libsqlite3.a sqlite3.c

mkdir -p "build"
cd "build"
env CFLAGS='-fPIC' CXXFLAGS='-fPIC' cmake ..
make -j$(CORES)
cd ..
cp "build/libyaml-cpp.a" ./

g++ -shared -fPIC -o libdata.so \
-L./ \
-Wl,-Bdynamic data.cpp \
-Wl,-Bstatic -lsqlite3 -lyaml-cpp \
-Wl,-Bdynamic -lpthread

g++ -L./ -ldata -o tester tester.cpp

库现在可以编译,但是,当我尝试使用“tester.cpp”链接它时,出现错误:

/usr/bin/ld: libdata.so: undefined reference to YAML::detail...

我猜这可能是一个标志排序问题,但我不确定它应该是什么顺序。在 data.cpp 参数之前放置 SQLite3 和 YAML-CPP 的标志无法编译共享库。

最佳答案

经过更多研究,这是对我有用的方法(特别冗长):

# Compile SQLite3:
# - Disable the plugin loader (removes the libdl dependency)
# - Compile only (-c)
# - Use Position Independent Code (-fPIC)
# - Add the PThread library
# - After compilation, archive object (for completeness)
gcc -DSQLITE_OMIT_LOAD_EXTENSION -c -fPIC -pthread -o sqlite3.o sqlite3.c


# Compile YAML-CPP
# - Create (and enter) a build directory
# - Run CMAKE with -fPIC enabled
# - Run MAKE
# - Exit and copy archive from build directory
mkdir -p "build"
cd "build"
env CFLAGS='-fPIC' CXXFLAGS='-fPIC' cmake ..
make -j$(CORES)
cd ..
cp build/libyaml-cpp.a libyaml-cpp.a


# Compile Shared Library
# - Ensure shared (-shared) (also prevents looking for a 'main')
# - Use Position Independent Code (-fPIC)
# - Use current directory for locating libraries
# - Set target CPP file
# - STATICALLY link from SQLite3 and YAML-CPP archives
# - DYNAMICALLY link from PThread library (used by SQLite3 for thread-safe access)
g++ -shared -fPIC -o libdata.so data.cpp \
-L./ \
-Wl,-Bstatic -l:sqlite3.o -lyaml-cpp \
-Wl,-Bdynamic -pthread


# Compile Test Program
# - Specify current directory for includes and libraries
# - Link dynamically to 'libdata.so'
g++ -I./ -L./ -ldata -o tester tester.cpp

我遇到的最后一个问题是缺少 YAML-CPP 的包含目录。

一些信用笔记:

  • @Botje:指出我在共享库的编译中需要-shared 而不是-c。 (libdata.so)
  • @Maxim Egorushkin:用于链接到 very useful document关于这件事。

还有一件事需要注意,当在 C++ 程序中链接 C 库时,您可能需要使用“extern "C"”(如链接页面中所述)。这在使用 SQLite3 库时尤为重要。

关于C++使用源码、静态存档等动态库创建动态库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62523542/

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