OpenSSL link libcrypto.a in a static way

12,721

Solution 1

OpenSSL link lincrypto.a in a static way
...
"-lcrypto" it links the library in a dynamic way (not good for my case)

Use -l:libcrypto.a. It specifies the full name of the library. Below is from the LD(1) man page. See the part about :filename.

-l namespec
--library=namespec

Add the archive or object file specified by namespec to the list of files to link. This option may be used any number of times. If namespec is of the form :filename, ld will search the library path for a file called filename, otherwise it will search the library path for a file called libnamespec.a.

On systems which support shared libraries, ld may also search for files other than libnamespec.a. Specifically, on ELF and SunOS systems, ld will search a directory for a library called libnamespec.so before searching for one called libnamespec.a. (By convention, a .so extension indicates a shared library.) Note that this behavior does not apply to :filename, which always specifies a file called filename.

The linker will search an archive only once, at the location where it is specified on the command line. If the archive defines a symbol which was undefined in some object which appeared before the archive on the command line, the linker will include the appropriate file(s) from the archive. However, an undefined symbol in an object appearing later on the command line will not cause the linker to search the archive again.

See the -( option for a way to force the linker to search archives multiple times.

You may list the same archive multiple times on the command line.

This type of archive searching is standard for Unix linkers. However, if you are using ld on AIX, note that it is different from the behaviour of the AIX linker.


"[absolute path]/libcrypto.a" it returns "libcrypto.a(dso_dlfcn.o): undefined reference to symbol 'dlclose@@GLIBC_2.2.5' //lib/x86_64-linux-gnu/libdl.so.2: error adding symbols: DSO missing from command line"

For this problem, add -ldl after libcrypto and libssl in your link command.


"[absolute path]/libcrypto.a -ldl"libcrypto.a(evp_enc.o): relocation R_X86_64_32 against `.rodata.str1.1' can not be used when making a shared object; recompile with -fPIC

For this problem, see What does .rodata and -fPIC mean when compiling OpenSSL? and Compilation fails with “relocation R_X86_64_32 against `.rodata.str1.8' can not be used when making a shared object”.

The short of it is, you need to configure OpenSSL with the shared option. If you don't want to build the shared libraries, the add -fPIC to CFLAGS. Also see Compilation and Installation on the OpenSSL wiki.

Solution 2

It looks like your libcrypto.a is not compiled as PIC (or at least as PIE), and your toolchain defaults to creating PIE-enabled executables. You probably have to link with a command like this:

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

Some parts of libcrypto depend on libdl and libpthread, so these libraries are required, too, but you must link them dynamically because they are part of glibc.

Share:
12,721
stackpic91
Author by

stackpic91

Updated on June 04, 2022

Comments

  • stackpic91
    stackpic91 almost 2 years

    I have the following makefile and I would add the library "libcrypto.a" in a static way. I need to do this because the target system cannot install the openssl libraries.

        # 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} "[email protected]"
            $(COMPILE.cc) -O2 -Werror -I../linux -I../Common -I../Common/pbkdf2 -std=c++11 -MMD -MP -MF "[email protected]" -o ${OBJECTDIR}/_ext/7daaf93a/DtaCommand.o ../Common/DtaCommand.cpp 
    
    #...... SIMILAR FOR THE OTHER ELEMENTS OF "OBJECTDIR ......"
    

    I tried to add to my "LDLIBSOPTIONS" several things but I don't find the correct way to do this, for example:

    • "-lcrypto" it links the library in a dynamic way (not good for my case)
    • "[absolute path]/libcrypto.a" it returns "libcrypto.a(dso_dlfcn.o): undefined reference to symbol 'dlclose@@GLIBC_2.2.5' //lib/x86_64-linux-gnu/libdl.so.2: error adding symbols: DSO missing from command line".
      • "[absolute path]/libcrypto.a -ldl"libcrypto.a(evp_enc.o): relocation R_X86_64_32 against `.rodata.str1.1' can not be used when making a shared object; recompile with -fPIC

    Any suggestion ?

    • Florian Weimer
      Florian Weimer almost 7 years
      What do you want to produce? A statically-linked executable? Or a dynamically linked executable which links libcrypto.a statically? Or a shared object?
    • stackpic91
      stackpic91 almost 7 years
      I want to procuce a dynamically linked executable which links libcrypto.a statically.
  • stackpic91
    stackpic91 almost 7 years
    I tried : "-fno-pie -no-pie -lcurses -Wl,-Bstatic -lcrypto -Wl,-Bdynamic -ldl -lpthread" but when I run the generated images on the target machine, it says that it cannot find /usr/lib/libncourses /usr/lib/libstdc++
  • Florian Weimer
    Florian Weimer almost 7 years
    Well, it solved your immediate problem. You didn't say what you actually wanted to do. Static linking is not a solution for your problem. You need to replicate the target environment and build against that, and not some other system.