Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting libcrypto ar error while compiling OpenSSL for Mac

Tags:

macos

openssl

I have been able to compile a specific version of OpenSSL for iOS devices, and I am now trying to compile for Mac OSX. However, when I run my bash script (provided below) I am getting the following error:

ar  r ../../libcrypto.a o_names.o obj_dat.o obj_lib.o obj_err.o obj_xref.o
ar: ../../libcrypto.a is a fat file (use libtool(1) or lipo(1) and ar(1) on it)
ar: ../../libcrypto.a: Inappropriate file type or format

When I run lipo -info libcrypto.a I get the following result:

Architectures in the fat file: libcrypto.a are: i386 x86_64 

This does not make any sense, as my bash script is only configuring OpenSSL for i386 (I was looping to do both, but removed x86_64 once I started getting these problems).

I have tried following the answers for similar SO questions here and here. However, those yielded the same results. Additionally, the Mac installation instructions on the OpenSSL Wiki were of no help either.


My scripts:

Build.sh

projectDir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
ARCHS=("i386")
FIPS_VERSION="2.0.12"
OPENSSL_VERSION="1.0.2g"

rm -rf openssl* fips*
if [ -d "out" ]; then
    rm -rf out
fi

mkdir out
source ./Build-FIPS.sh
cd $projectDir
source ./Build-OpenSSL.sh

Build-OpenSSL.sh

set -e

function main() {
    verifyopenssl
    for ((i=0; i < ${#ARCHS[@]}; i++))
    do
        makeopenssl "${ARCHS[i]}"
    done
}

function verifyopenssl() {
    gpg --verify $projectDir/../Source/openssl-$OPENSSL_VERSION.tar.gz.asc
    tar -zxf $projectDir/../Source/openssl-$OPENSSL_VERSION.tar.gz
    cd openssl-$OPENSSL_VERSION
}

function makeopenssl() {
    BUILD_ARCH=$1
    SDK_NAME="macosx"
    GCC=$(xcrun -sdk ${SDK_NAME} -find gcc)
    SDK_PATH=$(xcrun -sdk ${SDK_NAME} --show-sdk-path)
    MACHINE="darwin-i386-cc"
#   BSD_ARCH="BSD-generic32"

    CONFIG_ARGS="$MACHINE \
        $BSD_ARCH \
        --openssldir=$projectDir/out/openssl_${BUILD_ARCH} \
        fips \
        --with-fipsdir=${projectDir}/out/fips_${BUILD_ARCH} \
        no-idea \
        no-cast \
        no-seed \
        no-md2 \
        no-sha0 \
        no-whirlpool \
        -DL_ENDIAN"

    export CC="${GCC} -arch ${BUILD_ARCH}"
    export CFLAGS="-isysroot ${SDK_PATH} -I ${projectDir}/out/fips_${BUILD_ARCH}/include"
    export LDFLAGS="-arch $BUILD_ARCH"
    ./Configure ${CONFIG_ARGS}

    make depend
    make
    # make install
    # make clean && make dclean
}

main $@
like image 899
AeroBuffalo Avatar asked May 06 '16 02:05

AeroBuffalo


2 Answers

Following @jww's answer, I found that changing the following line (around line 69) in the main Makefile (the one in the root folder) solved the ar linking problem that @jww mentioned:

AR= ar $(ARFLAGS) r to AR= libtool -o

Making this change did get me further along in the process. However, I began having other problems. Further "research" led me to the OpenSSL FAQ page which had a question talking about OpenSSL failing to build on Mac. It pointed me to the PROBLEMS file in the root directory of the OpenSSL source code. That file said that there is a MAC ld problem:

This is really a misfeature in ld, which seems to look for .dylib libraries along the whole library path before it bothers looking for .a libraries. This means that -L switches won't matter unless OpenSSL is built with shared library support.

The workaround may be to change the following lines in apps/Makefile and test/Makefile:

LIBCRYPTO=-L.. -lcrypto
LIBSSL=-L.. -lssl

to:

LIBCRYPTO=../libcrypto.a
LIBSSL=../libssl.a

With this information, I created a patch file for the root Makefile and the Makefile in the apps folder. I also found that I had to comment out the instructions in the main Makefile and the apps/Makefile to build the openssl binary / executable. This should only be necessary if you want to run make install.

The patch files exists at the same level as the Build.sh script. And after fiddling around with my Build-OpenSSL.sh script I was finally able to get it to build for both i386 and x86_64.

For future reference, I am including the complete contents of the two patch files, and the original two script files below.


Build.sh

#!/bin/bash
#

projectDir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

ARCHS=("i386" "x86_64")
FIPS_VERSION="2.0.12"
OPENSSL_VERSION="1.0.2g"

rm -rf openssl*
if [ -d "out" ]; then
    rm -rf out
fi

mkdir out
source ./Build-FIPS.sh
source ./Build-OpenSSL.sh

Build-OpenSSL.sh

#!/bin/bash
#

set -e

function main() {
    verifyopenssl
    for ((i=0; i < ${#ARCHS[@]}; i++))
    do
        makeopenssl "${ARCHS[i]}"
    done
}

function verifyopenssl() {
    gpg --verify $projectDir/../Source/openssl-$OPENSSL_VERSION.tar.gz.asc
    tar -zxf $projectDir/../Source/openssl-$OPENSSL_VERSION.tar.gz
    cd openssl-$OPENSSL_VERSION
}

function makeopenssl() {
    BUILD_ARCH=$1
    SDK_NAME="macosx"
    GCC=$(xcrun -sdk ${SDK_NAME} -find gcc)
    SDK_PATH=$(xcrun -sdk ${SDK_NAME} --show-sdk-path)
    if [[ $BUILD_ARCH = "i386" ]]; then
        MACHINE="darwin-i386-cc"
        NISTP=""
    elif [[ $BUILD_ARCH = "x86_64" ]]; then
        MACHINE="darwin64-x86_64-cc"
        NISTP="enable-ec_nistp_64_gcc_128"
    else
        exit
    fi

    CONFIG_ARGS="$MACHINE \
        $NISTP \
        --openssldir=$projectDir/out/openssl_${BUILD_ARCH} \
        fips \
        --with-fipsdir=${projectDir}/out/fips_${BUILD_ARCH} \
        no-idea \
        no-cast \
        no-seed \
        no-md2 \
        no-sha0 \
        no-whirlpool \
        -DL_ENDIAN"

    ./Configure ${CONFIG_ARGS}

    patch Makefile < ../MainMake.patch
    patch apps/Makefile < ../AppMake.patch
    make depend
    make build_libcrypto build_libssl
    make install_sw
    make clean && make dclean
    patch -R Makefile < ../MainMake.patch
    patch -R apps/Makefile < ../AppMake.patch
}

main $@

AppMake.patch

--- apps/Makefile   2016-03-01 06:36:53.000000000 -0700
+++ ../Makefile 2016-05-06 13:00:16.000000000 -0600
@@ -26,8 +26,8 @@

 DLIBCRYPTO=../libcrypto.a
 DLIBSSL=../libssl.a
-LIBCRYPTO=-L.. -lcrypto
-LIBSSL=-L.. -lssl
+LIBCRYPTO=../libcrypto.a
+LIBSSL=../libssl.a

 PROGRAM= openssl

@@ -101,24 +101,24 @@
    $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO

 install:
-   @[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
-   @set -e; for i in $(EXE); \
-   do  \
-   (echo installing $$i; \
-    cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i.new; \
-    chmod 755 $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i.new; \
-    mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i.new $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i ); \
-    done;
-   @set -e; for i in $(SCRIPTS); \
-   do  \
-   (echo installing $$i; \
-    cp $$i $(INSTALL_PREFIX)$(OPENSSLDIR)/misc/$$i.new; \
-    chmod 755 $(INSTALL_PREFIX)$(OPENSSLDIR)/misc/$$i.new; \
-    mv -f $(INSTALL_PREFIX)$(OPENSSLDIR)/misc/$$i.new $(INSTALL_PREFIX)$(OPENSSLDIR)/misc/$$i ); \
-    done
-   @cp openssl.cnf $(INSTALL_PREFIX)$(OPENSSLDIR)/openssl.cnf.new; \
-   chmod 644 $(INSTALL_PREFIX)$(OPENSSLDIR)/openssl.cnf.new; \
-   mv -f  $(INSTALL_PREFIX)$(OPENSSLDIR)/openssl.cnf.new $(INSTALL_PREFIX)$(OPENSSLDIR)/openssl.cnf
+   # @[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
+   # @set -e; for i in $(EXE); \
+   # do  \
+   # (echo installing $$i; \
+   #  cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i.new; \
+   #  chmod 755 $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i.new; \
+   #  mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i.new $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i ); \
+   #  done;
+   # @set -e; for i in $(SCRIPTS); \
+   # do  \
+   # (echo installing $$i; \
+   #  cp $$i $(INSTALL_PREFIX)$(OPENSSLDIR)/misc/$$i.new; \
+   #  chmod 755 $(INSTALL_PREFIX)$(OPENSSLDIR)/misc/$$i.new; \
+   #  mv -f $(INSTALL_PREFIX)$(OPENSSLDIR)/misc/$$i.new $(INSTALL_PREFIX)$(OPENSSLDIR)/misc/$$i ); \
+   #  done
+   # @cp openssl.cnf $(INSTALL_PREFIX)$(OPENSSLDIR)/openssl.cnf.new; \
+   # chmod 644 $(INSTALL_PREFIX)$(OPENSSLDIR)/openssl.cnf.new; \
+   # mv -f  $(INSTALL_PREFIX)$(OPENSSLDIR)/openssl.cnf.new $(INSTALL_PREFIX)$(OPENSSLDIR)/openssl.cnf

 tags:
    ctags $(SRC)

MainMake.patch

--- Makefile    2016-05-06 13:06:11.000000000 -0600
+++ ../Makefile 2016-05-06 13:06:44.000000000 -0600
@@ -602,8 +602,8 @@
    chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig/libcrypto.pc
    cp libssl.pc $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig
    chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig/libssl.pc
-   cp openssl.pc $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig
-   chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig/openssl.pc
+   # cp openssl.pc $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig
+   # chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig/openssl.pc

 install_html_docs:
    here="`pwd`"; \
like image 89
AeroBuffalo Avatar answered Sep 25 '22 05:09

AeroBuffalo


ar  r ../../libcrypto.a o_names.o obj_dat.o obj_lib.o obj_err.o obj_xref.o
ar: ../../libcrypto.a is a fat file (use libtool(1) or lipo(1) and ar(1) on it)
ar: ../../libcrypto.a: Inappropriate file type or format

ar, libtool and -arch is the reason the answer says "... supplying -arch x86_64 -arch i386 will result in a build failure because of the way OpenSSL's build system forms commands" at Build Multiarch OpenSSL on OS X.

You need to use Apple's libtool, and stop using ar. Apple's libtool knows about architectures, ar does not.

Another small wrinkle is the makefile does something like this, if I recall correctly. It makes it difficult to simply use Apple's libtool, and stop using ar:

$(AR) $(ARFLAGS) $@ ...

In many makefiles you can simply make AR="libtool -o", but this case is different because the command comes out libtool -o r libcrypto.a or similar. I also seem to recall something like make AR="libtool" ARFLAGS="r -o $@" does not work well either.

I used to patch the makefile after config to do it.

like image 28
jww Avatar answered Sep 26 '22 05:09

jww