我正在为项目编写构建系统,我不确定可执行文件,静态库和共享库之间的链接.
对我来说有三个肯定:
关于第三次肯定,我仍然怀疑......
你能告诉我这件事吗?
如果下面的代码是线程安全的,有人可以向我澄清一下吗?
int get_time(uint64_t *time)
{
struct timespec spec;
if (!time)
return -EFAULT;
if (clock_gettime(CLOCK_REALTIME, &spec) == -1)
return -errno;
*time = //convert timespec into nanoseconds
return SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)
这是一个可以由多个线程调用的库中的API.规范是一个局部变量,所以它不应该是一个问题.正确?我的疑问是关于clock_getime(POSIX.1-2001)和time参数的赋值.我想介绍一个互斥锁,但我不确定它是否是严格要求的.
使用Normal指针,它很简单:
int* p = new int;
int* x = new int;
p=x;
Run Code Online (Sandbox Code Playgroud)
但是有了共享,有:swap,reset等等
std::shared_ptr<int> x = NULL;
std::shared_ptr<int> y = NULL;
Run Code Online (Sandbox Code Playgroud)
我知道重置用于"新"
x.reset(new int(5));
Run Code Online (Sandbox Code Playgroud)
如果我希望x和y都指向这个新的整数5,我是否使用reset或swap或=?我真的很困惑.
y = x;
y.swap(x);
y.reset(x);
Run Code Online (Sandbox Code Playgroud)
有人可以解释一下吗?
谢谢.
根据我的理解,内联函数可以在头文件和源文件中(使用inline关键字),默认情况下,头文件中定义的memeber函数可以由编译器内联.
我的问题是以下源文件add.h
#ifndef ADD_H
#define ADD_H
class Add {
public:
int add(int a, int b);
};
#endif /* ADD_H */
Run Code Online (Sandbox Code Playgroud)
add.cpp
#include <iostream>
#include "add.h"
inline int Add::add(int a, int b) {
std::cout << "FUNC: " << __func__ << std::endl;
return a + b;
}
Run Code Online (Sandbox Code Playgroud)
main.cpp中
#include "add.h"
int main() {
Add a;
a.add(6,7);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如果我编译add.cpp和main.cpp
g++ -c add.cpp
g++ -c main.cpp
g++ main.o add.o
Run Code Online (Sandbox Code Playgroud)
它抱怨
main.o: In function `main':
main.cpp:(.text+0x1a): undefined reference to `Add::add(int, int)'
collect2: error: …Run Code Online (Sandbox Code Playgroud) c++ optimization inline shared-libraries compiler-optimization
比方说,你编译C ++共享库libBeta.so,这使得利用预现有的C ++共享库libAlpha1.so,libAlpha2.so,libAlpha3.so,等。如果我接着写它使用C ++应用程序libBeta.so直接(并因此间接使用其它库),我要我的应用程序链接到libBeta.so只,还是应该将我的应用程序链接到所有库?
我的直觉告诉我,我应该只链接到libBeta.so,因为链接到所有库似乎libBeta.so已经是多余的,就像已经链接到其他库一样。但是,undefined reference to错误证明了我的直觉是错误的。
有人可以解释一下为什么我的直觉在某些情况下可能是错误的吗?
ps:
编辑
事实证明,我用于编译的工具在编译可执行文件和编译共享库时具有不同的行为。编译共享库时,省略了与子库的链接:(
我尝试创建共享库并main.c使用此库编译我
我关注这个网站:http://www.yolinux.com/TUTORIALS/LibraryArchives-StaticAndDynamic.html
我给出这些命令:
gcc -fPIC -c *.c
gcc -shared -Wl,-rpath,/opt/lib -Wl,-soname,libctest.so.1 -o libctest.so.1.0 *.o
sudo mv libctest.so.1.0 /opt/lib
sudo ln -sf /opt/lib/libctest.so.1.0 /opt/lib/libctest.so
sudo ln -sf /opt/lib/libctest.so.1.0 /opt/lib/libctest.so.1
gcc -Wall -L/opt/lib main.c -lctest -o prog
Run Code Online (Sandbox Code Playgroud)
命令没有错误.当我执行二进制文件时,./prog它给出了./prog: error while loading shared libraries: libctest.so.1: cannot open shared object file: No such file or directory
但是libctest.so.1在/opt/lib
lrwxrwxrwx 1 root root 24 Aug 18 17:06 libctest.so -> /opt/lib/libctest.so.1.0
lrwxrwxrwx 1 root root 24 …Run Code Online (Sandbox Code Playgroud) 当我在阅读http://eli.thegreenplace.net/2011/11/03/position-independent-code-pic-in-shared-libraries/#id1时, 问题来了:
在进程的虚拟地址空间中加载后,PIC共享库如何知道如何引用外部变量?
这是有问题的共享库的代码:
#include <stdio.h>
extern long var;
void
shara_func(void)
{
printf("%ld\n", var);
}
Run Code Online (Sandbox Code Playgroud)
生成对象代码,然后生成共享对象(库):
gcc -fPIC -c lib1.c # produce PIC lib1.o
gcc -fPIC -shared lib1.o -o liblib1.so # produce PIC shared library
Run Code Online (Sandbox Code Playgroud)
shara_func在共享库中反汇编:
objdump -d liblib1.so
...
00000000000006d0 <shara_func>:
6d0: 55 push %rbp
6d1: 48 89 e5 mov %rsp,%rbp
6d4: 48 8b 05 fd 08 20 00 mov 0x2008fd(%rip),%rax # 200fd8 <_DYNAMIC+0x1c8>
6db: 48 8b 00 mov (%rax),%rax
6de: 48 89 c6 mov %rax,%rsi
6e1: …Run Code Online (Sandbox Code Playgroud) linux shared-libraries relocation extern position-independent-code
我正在将我的应用程序从VS2015移植到VS2017,并尝试找出正确的迁移路径.我还将我的Web服务移动到.NET Core,以利用部署到Linux或Windows服务器.我看到我可以选择在.NET Standard或.NET Core中创建基本库..NET Core库是否有任何优势,或者我应该在.NET Standard中默认创建基本库?
我正在设计可以在我的其他C ++项目中链接的库的集合。为了使该集合易于使用,我希望能够链接到各个库,或者链接到包含所有其他库的一个主库。如何在CMakeLists.txt文件中指定?
例如:
add_library(library1 SHARED
file1.cpp
file2.cpp
)
add_library(library2 SHARED
file3.cpp
file4.cpp
)
# Define a master library that contains both of the others
add_library(master_library SHARED
library1
library2
)
Run Code Online (Sandbox Code Playgroud)
是否有使用CMake获得此功能的正确方法?
这个问题不是重复的:CMake:是否可以仅从静态库而不从源构建可执行文件?
这仅与共享库有关,与静态库或可执行文件无关。
我正在尝试以一步一步的方式构建以下示例代码:
#include <stdio.h>
int main(void) {
puts("hello, world");
}
Run Code Online (Sandbox Code Playgroud)
这是我的Makefile:
CC=clang
CFLAGS=-g
LD=ld
LDFLAGS=-macosx_version_min 10.12
LDLIBS=-L/usr/lib/system/
a.out: main.o
$(LD) $(LDFLAGS) $< $(LOADLIBES) $(LDLIBS)
main.o: main.c
$(CC) $(CFLAGS) $(CPPFLAGS) -c $<
Run Code Online (Sandbox Code Playgroud)
它没有创建问题main.o,但在链接阶段引发错误:
$? make
ld -macosx_version_min 10.12 main.o -L/usr/lib/system/
Undefined symbols for architecture x86_64:
"_puts", referenced from:
_main in main.o
ld: symbol(s) not found for inferred architecture x86_64
make: *** [a.out] Error 1
Run Code Online (Sandbox Code Playgroud)
好像ld找不到C标准库.我究竟做错了什么?
供您参考,这是输出clang main.c -v,它正确连接:
$? clang main.c -v …Run Code Online (Sandbox Code Playgroud) shared-libraries ×10
c++ ×5
c ×4
linux ×2
.net-core ×1
cmake ×1
compilation ×1
extern ×1
g++ ×1
inline ×1
linker ×1
macos ×1
makefile ×1
optimization ×1
pointers ×1
posix ×1
relocation ×1
shared-ptr ×1