C++ 为什么';以下重复符号的gcc报告错误?
我正在Ubuntu Linux上工作,以构建Android和Linux二进制文件。我有一个由两个共享库链接的静态库,静态库中有一个全局对象 据我所知,全局对象将同时存在于C++ 为什么';以下重复符号的gcc报告错误?,c++,linux,gcc,compiler-construction,linker,C++,Linux,Gcc,Compiler Construction,Linker,我正在Ubuntu Linux上工作,以构建Android和Linux二进制文件。我有一个由两个共享库链接的静态库,静态库中有一个全局对象 据我所知,全局对象将同时存在于*。因此,并将导致问题,因为每个共享库中的函数符号访问不同的全局变量 (在构建两个共享库时,我在命令行中引用了静态库。我一直在使用-Wl,--whole archive和-Wl,-z,defs开关。因此共享库包含静态库的符号。) 因此,问题是: 在链接可执行文件时,为什么GCC/LD不报告这种情况下的重复符号错误 这是否意味着我
*。因此
,并将导致问题,因为每个共享库中的函数符号访问不同的全局变量
(在构建两个共享库时,我在命令行中引用了静态库。我一直在使用-Wl,--whole archive
和-Wl,-z,defs
开关。因此共享库包含静态库的符号。)
因此,问题是:
abc_123()
,以及调用同一函数的其他函数,以及使用这些函数的测试程序
lib1.h
lib2.h
lib1a.c
在Linux上构建和运行
这是来自Ubuntu14.04LTSVM(托管在MacOSX10.9.3上),编译器是GCC4.8.2
$ make -B SOEXT=so UFLAGS=-fPIC
gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -Werror -fPIC -c test1.c
gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -Werror -fPIC -c lib1a.c
gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -Werror -fPIC -c lib1b.c
gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -Werror -fPIC -c lib2a.c
gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -Werror -fPIC -c lib2b.c
gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -Werror -fPIC -shared -o library2.so lib2a.o lib2b.o
gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -Werror -fPIC -shared -o library1.so lib1a.o lib1b.o -L. -lrary2
gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -Werror -fPIC -o test1 test1.o -L. -lrary1 -lrary2
$ LD_LIBRARY_PATH=$PWD:$LD_LIBRARY_PATH ./test1
Cross-library linking and calling
Main calling abc_123(29)
Library 1:lib1a.c:15:abc_123() - 29
Note this extra message
Main calling def_345(45)
Library 1:lib1b.c:17-->>def_345() - 45
Library 2:lib2b.c:15-->>ghi_678() - 55
Library 1:lib1a.c:15:abc_123() - 550
Note this extra message
Library 2:lib2b.c:17<<--ghi_678() - 55
Library 1:lib1b.c:19<<--def_345() - 45
Main calling ghi_678(57)
Library 2:lib2b.c:15-->>ghi_678() - 57
Library 1:lib1a.c:15:abc_123() - 570
Note this extra message
Library 2:lib2b.c:17<<--ghi_678() - 57
Demonstration over
$
请注意,ghi_678()
中的代码从library2.so
调用abc_123()
,而不是在Linux上从library1.so
调用的版本
您可以玩反向链接顺序,然后看看会发生什么
道德的
不要在多个共享库中构建包含相同功能的软件;如果在平台之间进行移植,您会感到困惑。共享库行为依赖于平台的经验证据
下面是一些普通代码,演示了两个共享库,它们都定义了符号(函数)abc_123()
,以及调用同一函数的其他函数,以及使用这些函数的测试程序
lib1.h
lib2.h
lib1a.c
在Linux上构建和运行
这是来自Ubuntu14.04LTSVM(托管在MacOSX10.9.3上),编译器是GCC4.8.2
$ make -B SOEXT=so UFLAGS=-fPIC
gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -Werror -fPIC -c test1.c
gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -Werror -fPIC -c lib1a.c
gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -Werror -fPIC -c lib1b.c
gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -Werror -fPIC -c lib2a.c
gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -Werror -fPIC -c lib2b.c
gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -Werror -fPIC -shared -o library2.so lib2a.o lib2b.o
gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -Werror -fPIC -shared -o library1.so lib1a.o lib1b.o -L. -lrary2
gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -Werror -fPIC -o test1 test1.o -L. -lrary1 -lrary2
$ LD_LIBRARY_PATH=$PWD:$LD_LIBRARY_PATH ./test1
Cross-library linking and calling
Main calling abc_123(29)
Library 1:lib1a.c:15:abc_123() - 29
Note this extra message
Main calling def_345(45)
Library 1:lib1b.c:17-->>def_345() - 45
Library 2:lib2b.c:15-->>ghi_678() - 55
Library 1:lib1a.c:15:abc_123() - 550
Note this extra message
Library 2:lib2b.c:17<<--ghi_678() - 55
Library 1:lib1b.c:19<<--def_345() - 45
Main calling ghi_678(57)
Library 2:lib2b.c:15-->>ghi_678() - 57
Library 1:lib1a.c:15:abc_123() - 570
Note this extra message
Library 2:lib2b.c:17<<--ghi_678() - 57
Demonstration over
$
请注意,ghi_678()
中的代码从library2.so
调用abc_123()
,而不是在Linux上从library1.so
调用的版本
您可以玩反向链接顺序,然后看看会发生什么
道德的
不要构建软件
#include <stdio.h>
#include "lib1.h"
void abc_123(int i)
{
printf("Library 1:%s:%d:%s() - %d\n", __FILE__, __LINE__, __func__, i);
printf("Note this extra message\n");
}
#include <stdio.h>
#include "lib1.h"
#include "lib2.h"
void def_345(int i)
{
printf("Library 1:%s:%d-->>%s() - %d\n", __FILE__, __LINE__, __func__, i);
ghi_678(i+10);
printf("Library 1:%s:%d<<--%s() - %d\n", __FILE__, __LINE__, __func__, i);
}
#include <stdio.h>
#include "lib2.h"
void abc_123(int i)
{
printf("Library 2:%s:%d:%s() - %d\n", __FILE__, __LINE__, __func__, i);
printf("This is a completely different message\n");
}
#include <stdio.h>
#include "lib2.h"
void ghi_678(int i)
{
printf("Library 2:%s:%d-->>%s() - %d\n", __FILE__, __LINE__, __func__, i);
abc_123(i * 10);
printf("Library 2:%s:%d<<--%s() - %d\n", __FILE__, __LINE__, __func__, i);
}
#include <stdio.h>
#include "lib1.h"
#include "lib2.h"
int main(void)
{
printf("Cross-library linking and calling\n");
printf("Main calling abc_123(29)\n");
abc_123(29);
printf("Main calling def_345(45)\n");
def_345(45);
printf("Main calling ghi_678(57)\n");
ghi_678(57);
printf("Demonstration over\n");
return 0;
}
CC = gcc #/usr/bin/gcc
WFLAG1 = -Wall
WFLAG2 = -Wextra
WFLAG3 = -Wmissing-prototypes
WFLAG4 = -Wstrict-prototypes
WFLAG5 = -Wold-style-definition
WFLAG6 = -Werror
WFLAGS = ${WFLAG1} ${WFLAG2} ${WFLAG3} ${WFLAG4} ${WFLAG5} ${WFLAG6}
SFLAGS = -std=c11
GFLAGS = -g
OFLAGS = -O3
UFLAGS = # Set on command line
IFLAG1 = # -I${HOME}/inc
IFLAGS = # ${IFLAG1}
SOEXT = dylib
LDFLAG1 = -L.
LDLIB1 = -lrary1
LDLIB2 = -lrary2
LDFLAGS = ${LDFLAG1}
LDLIBS = ${LDLIB1} ${LDLIB2}
CFLAGS = ${OFLAGS} ${GFLAGS} ${IFLAGS} ${SFLAGS} ${WFLAGS} ${UFLAGS}
LNKSHLIB = -shared
LIBRARY1 = library1.${SOEXT}
LIBRARY2 = library2.${SOEXT}
LIB1.o = lib1a.o lib1b.o
LIB2.o = lib2a.o lib2b.o
TEST1.o = test1.o
PROGRAM = test1
all: ${PROGRAM}
${PROGRAM}: ${TEST1.o} ${LIBRARY1} ${LIBRARY2}
${CC} ${CFLAGS} -o $@ ${TEST1.o} ${LDFLAGS} ${LDLIBS}
${LIBRARY1}: ${LIB1.o} ${LIBRARY2}
${CC} ${CFLAGS} ${LNKSHLIB} -o $@ ${LIB1.o} ${LDFLAGS} ${LDLIB2}
${LIBRARY2}: ${LIB2.o}
${CC} ${CFLAGS} ${LNKSHLIB} -o $@ ${LIB2.o}
$ make -B SOEXT=so UFLAGS=-fPIC
gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -Werror -fPIC -c test1.c
gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -Werror -fPIC -c lib1a.c
gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -Werror -fPIC -c lib1b.c
gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -Werror -fPIC -c lib2a.c
gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -Werror -fPIC -c lib2b.c
gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -Werror -fPIC -shared -o library2.so lib2a.o lib2b.o
gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -Werror -fPIC -shared -o library1.so lib1a.o lib1b.o -L. -lrary2
gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -Werror -fPIC -o test1 test1.o -L. -lrary1 -lrary2
$ LD_LIBRARY_PATH=$PWD:$LD_LIBRARY_PATH ./test1
Cross-library linking and calling
Main calling abc_123(29)
Library 1:lib1a.c:15:abc_123() - 29
Note this extra message
Main calling def_345(45)
Library 1:lib1b.c:17-->>def_345() - 45
Library 2:lib2b.c:15-->>ghi_678() - 55
Library 1:lib1a.c:15:abc_123() - 550
Note this extra message
Library 2:lib2b.c:17<<--ghi_678() - 55
Library 1:lib1b.c:19<<--def_345() - 45
Main calling ghi_678(57)
Library 2:lib2b.c:15-->>ghi_678() - 57
Library 1:lib1a.c:15:abc_123() - 570
Note this extra message
Library 2:lib2b.c:17<<--ghi_678() - 57
Demonstration over
$
$ make -B
gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -Werror -c -o test1.o test1.c
gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -Werror -c -o lib1a.o lib1a.c
gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -Werror -c -o lib1b.o lib1b.c
gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -Werror -c -o lib2a.o lib2a.c
gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -Werror -c -o lib2b.o lib2b.c
gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -Werror -shared -o library2.dylib lib2a.o lib2b.o
gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -Werror -shared -o library1.dylib lib1a.o lib1b.o -L. -lrary2
gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -Werror -o test1 test1.o -L. -lrary1 -lrary2
$ ./test1
Cross-library linking and calling
Main calling abc_123(29)
Library 1:lib1a.c:15:abc_123() - 29
Note this extra message
Main calling def_345(45)
Library 1:lib1b.c:17-->>def_345() - 45
Library 2:lib2b.c:15-->>ghi_678() - 55
Library 2:lib2a.c:16:abc_123() - 550
This is a completely different message
Library 2:lib2b.c:17<<--ghi_678() - 55
Library 1:lib1b.c:19<<--def_345() - 45
Main calling ghi_678(57)
Library 2:lib2b.c:15-->>ghi_678() - 57
Library 2:lib2a.c:16:abc_123() - 570
This is a completely different message
Library 2:lib2b.c:17<<--ghi_678() - 57
Demonstration over
$