【问题标题】:OpenSSL link libcrypto.a in a static wayOpenSSL 以静态方式链接 libcrypto.a
【发布时间】:2018-01-01 14:34:32
【问题描述】:

我有以下生成文件,我将以静态方式添加库“libcrypto.a”。我需要这样做,因为目标系统无法安装 openssl 库。

    # Environment
    MKDIR=mkdir
    CP=cp
    GREP=grep
    NM=x86_64-linux-nm
    CCADMIN=CCadmin
    RANLIB=x86_64-linux-ranlib
    CC=x86_64-linux-gnu-gcc
    CCC=x86_64-linux-gnu-g++
    CXX=x86_64-linux-gnu-g++
    FC=x86_64-linux-gfortran
    AS=x86_64-linux-as

    # Macros
    CND_PLATFORM=GNU-Linux
    CND_DLIB_EXT=so
    CND_CONF=Release_x86_64
    CND_DISTDIR=dist
    CND_BUILDDIR=build

    # Include project Makefile
    include Makefile

    # Object Directory
    OBJECTDIR=${CND_BUILDDIR}/${CND_CONF}/${CND_PLATFORM}

    # Object Files
    OBJECTFILES= \
        ${OBJECTDIR}/_ext/7daaf93a/DtaCommand.o \
        ${OBJECTDIR}/_ext/7daaf93a/DtaDev.o \
        ${OBJECTDIR}/_ext/7daaf93a/DtaDevGeneric.o \
        ${OBJECTDIR}/_ext/7daaf93a/DtaDevOpal.o \
        ${OBJECTDIR}/_ext/7daaf93a/DtaDevOpal1.o \
        ${OBJECTDIR}/_ext/7daaf93a/DtaDevOpal2.o \
        ${OBJECTDIR}/_ext/7daaf93a/DtaHashPwd.o \
        ${OBJECTDIR}/_ext/7daaf93a/DtaHexDump.o \
        ${OBJECTDIR}/_ext/7daaf93a/DtaResponse.o \
        ${OBJECTDIR}/_ext/7daaf93a/DtaSession.o \
        ${OBJECTDIR}/_ext/b7b9df0c/blockwise.o \
        ${OBJECTDIR}/_ext/b7b9df0c/chash.o \
        ${OBJECTDIR}/_ext/b7b9df0c/hmac.o \
        ${OBJECTDIR}/_ext/b7b9df0c/pbkdf2.o \
        ${OBJECTDIR}/_ext/b7b9df0c/sha1.o \
        ${OBJECTDIR}/_ext/822bcbe5/DtaDevLinuxNvme.o \
        ${OBJECTDIR}/_ext/822bcbe5/DtaDevLinuxSata.o \
        ${OBJECTDIR}/_ext/822bcbe5/DtaDevOS.o \
        ${OBJECTDIR}/GetPassPhrase.o \
        ${OBJECTDIR}/LinuxPBA.o \
        ${OBJECTDIR}/UnlockSEDs.o


    # C Compiler Flags
    CFLAGS=-m64

    # CC Compiler Flags
    CCFLAGS=-m64
    CXXFLAGS=-m64

    # Link Libraries and Options
    LDLIBSOPTIONS=-lcurses -ltinfo

    # Build Targets
    .build-conf: ${BUILD_SUBPROJECTS}
        "${MAKE}"  -f nbproject/Makefile-${CND_CONF}.mk ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/linuxpba

    ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/linuxpba: ${OBJECTFILES}
        ${MKDIR} -p ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}
        ${LINK.cc} -o ${CND_DISTDIR}/${CND_CONF}/${CND_PLATFORM}/linuxpba ${OBJECTFILES} ${LDLIBSOPTIONS} -s

    ${OBJECTDIR}/_ext/7daaf93a/DtaCommand.o: ../Common/DtaCommand.cpp 
        ${MKDIR} -p ${OBJECTDIR}/_ext/7daaf93a
        ${RM} "$@.d"
        $(COMPILE.cc) -O2 -Werror -I../linux -I../Common -I../Common/pbkdf2 -std=c++11 -MMD -MP -MF "$@.d" -o ${OBJECTDIR}/_ext/7daaf93a/DtaCommand.o ../Common/DtaCommand.cpp 

#...... SIMILAR FOR THE OTHER ELEMENTS OF "OBJECTDIR ......"

我尝试在“LDLIBSOPTIONS”中添加几项内容,但找不到正确的方法,例如:

  • -lcrypto”它以动态方式链接库(对我的情况不利)
  • "[absolute path]/libcrypto.a" 它返回 "libcrypto.a(dso_dlfcn.o): undefined reference to symbol 'dlclose@@GLIBC_2.2.5' //lib/x86_64-linux-gnu/libdl.so.2:添加符号时出错:命令行中缺少 DSO”。
    • "[absolute path]/libcrypto.a -ldl"libcrypto.a(evp_enc.o): relocation R_X86_64_32 against `.rodata.str1.1' 不能在进行共享时使用目的;用 -fPIC 重新编译

有什么建议吗?

【问题讨论】:

  • 你想生产什么?静态链接的可执行文件?还是静态链接 libcrypto.a 的动态链接可执行文件?还是共享对象?
  • 我想生成一个动态链接的可执行文件,它静态链接 libcrypto.a。

标签: linux makefile openssl g++ libcrypto


【解决方案1】:

OpenSSL 以静态方式链接 lincrypto.a
...
“-lcrypto”它以动态方式链接库(不适合我的情况)

使用-l:libcrypto.a。它指定库的全名。以下来自LD(1) man page。见:filename部分。

-l namespec
--library=namespec

将 namespec 指定的档案或目标文件添加到列表中 要链接的文件。此选项可以使用任意次数。如果 namespec 的格式为 :filename,ld 将在库路径中搜索 一个名为 filename 的文件,否则它将在库路径中搜索 一个名为 libnamespec.a 的文件。

在支持共享库的系统上,ld 也可以搜索 libnamespec.a 以外的文件。具体来说,在 ELF 和 SunOS 上 系统,ld 将在目录中搜索名为的库 libnamespec.so 在搜索一个名为 libnamespec.a 之前。 (经过 约定,.so 扩展名表示共享库。)请注意 此行为不适用于 :filename,它总是指定一个 名为文件名的文件。

链接器只会在存档位置搜索一次 在命令行中指定。如果档案定义了一个符号 在存档之前出现的某些对象中未定义 在命令行上,链接器将包含适当的文件 从档案中。但是,对象中出现未定义的符号 稍后在命令行上不会导致链接器搜索 再次存档。

请参阅-( 选项以了解强制链接器搜索档案的方法 多次。

您可以在命令行上多次列出同一个存档。

这种类型的存档搜索是 Unix 链接器的标准。然而, 如果您在 AIX 上使用 ld,请注意它与 AIX 链接器的行为。


"[absolute path]/libcrypto.a" 它返回 "libcrypto.a(dso_dlfcn.o): undefined reference to symbol 'dlclose@@GLIBC_2.2.5' //lib/x86_64-linux-gnu/libdl.so .2:添加符号时出错:命令行中缺少 DSO"

对于这个问题,在你的链接命令中添加-ldl after libcryptolibssl


"[absolute path]/libcrypto.a -ldl"libcrypto.a(evp_enc.o): relocation R_X86_64_32 against `.rodata.str1.1' 制作共享对象时不能使用;用 -fPIC 重新编译

有关此问题,请参阅What does .rodata and -fPIC mean when compiling OpenSSL?Compilation fails with “relocation R_X86_64_32 against `.rodata.str1.8' can not be used when making a shared object”

简而言之,您需要使用 shared 选项配置 OpenSSL。如果您不想构建共享库,请将-fPIC 添加到CFLAGS。另请参阅 OpenSSL wiki 上的 Compilation and Installation

【讨论】:

    【解决方案2】:

    看起来您的libcrypto.a 未编译为 PIC(或至少未编译为 PIE),并且您的工具链默认创建启用 PIE 的可执行文件。您可能必须使用这样的命令链接:

    gcc -fno-pie -no-pie … -Wl,-Bstatic -lcrypto -Wl,-Bdynamic -ldl -lpthread
    

    libcrypto 的某些部分依赖于 libdl 和 libpthread,因此这些库也是必需的,但您必须动态链接它们,因为它们是 glibc 的一部分。

    【讨论】:

    • 我试过:“-fno-pie -no-pie -lcurses -Wl,-Bstatic -lcrypto -Wl,-Bdynamic -ldl -lpthread”但是当我在目标机器上运行生成的图像时,它说它找不到 /usr/lib/libncourses /usr/lib/libstdc++
    • 嗯,它解决了你眼前的问题。你没有说你真正想做什么。静态链接不是解决您的问题的方法。您需要复制目标环境并针对它进行构建,而不是其他系统。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多