Linux – OpenSSL link libcrypto.a in a static way

g++libcryptolinuxmakefileopenssl

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} "$@.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 ......"

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 ?

Best Answer

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.