#!/bin/bash

############################################################################
#                                                                          #
#  Copyright (c) 2001, 2026 NoMachine, http://www.nomachine.com/.          #
#                                                                          #
#  Simple configure script used to build as part of the NX system.         #
#                                                                          #
#  Redistribution and use of the present software is allowed according     #
#  to terms specified in the file LICENSE which comes in the source        #
#  distribution.                                                           #
#                                                                          #
#  Check http://www.nomachine.com/licensing.html for other options.        #
#                                                                          #
#  NX and NoMachine are trademarks of NoMachine S.a.r.l.                   #
#                                                                          #
#  All rights reserved.                                                    #
#                                                                          #
############################################################################

set_flags()
{
  CFLAGS="$CFLAGS -Dstatic_assert=_Static_assert"
  CXXFLAGS="$CXXFLAGS -Dstatic_assert=_Static_assert"

  if [ "$TARGET" = "MinGW" ] || [ "$TARGET" = "MinGW64" ];
  then
    if ( i686-pc-mingw32-gcc --version > /dev/null 2> /dev/null );
    then
      flags="--cross-prefix=i686-pc-mingw32- \
             --target-os=mingw32             \
             --arch=x86                      \
             --enable-w32threads             \
             --disable-pthreads"#            \
             #--enable-memalign-hack"
    else
      flags="--target-os=mingw32" #\
             #--enable-memalign-hack
    fi

  elif [ "$TARGET" = "Linux32" ] || [ "$TARGET" = "Linux64" ] || \
       [ "$TARGET" = "Android" ];
  then
    if test "$CROSS";
    then
      case $CROSS in
      aarch64*)
        flags="$flags --arch=arm64"
        flags="$flags --enable-cross-compile --cross-prefix=$CROSS- --target-os=android"
        ;;
      arm*)
        flags="$flags --arch=arm"
        flags="$flags --enable-cross-compile --cross-prefix=$CROSS- --target-os=linux"
        ;;
      mips*)
        flags="$flags --arch=mips"
        flags="$flags --enable-cross-compile --cross-prefix=$CROSS- --target-os=linux"
        ;;
      i686*)

        flags="$flags --enable-cross-compile --cross-prefix=$CROSS- --arch=i686"

        #
        # Note: Compilation error for android-x86
        # https://lists.libav.org/pipermail/libav-devel/2012-April/025960.html
        #

        flags="$flags --extra-cflags=-mincoming-stack-boundary=4"

        if [ "$TARGET" = "Android" ];
        then
          flags="$flags --target-os=android --disable-asm"
        else
          flags="$flags --target-os=linux"
        fi

        ;;
      x86_64*)

        flags="$flags --enable-cross-compile --cross-prefix=$CROSS- --arch=x86_64"

        if [ "$TARGET" = "Android" ];
        then
          flags="$flags --target-os=android"
        else
          flags="$flags --target-os=linux"
        fi

        ;;
      esac

    fi
  elif [ "$TARGET" = "iOS" ];
  then
    flags="--target-os=darwin --arch=armv6 --enable-cross-compile --cross-prefix=$CROSS- --as=$CROSS-gcc --disable-asm"
  elif [ "$TARGET" = "MacOSX" ];
  then
    if [ ! -z "$CROSS" ];
    then
      flags="--target-os=darwin --arch=$ARCHITECTURE --enable-cross-compile --cross-prefix=$CROSS- --as=$CROSS-gcc"
    fi
  fi

  #
  # Temporary workaround to build FFMPEG with YASM
  # in NX-6, due to problems with old NASM.
  #

  if [ "$TARGET" = "Linux32" ] || [ "$TARGET" = "Linux64" ] || \
     [ "$TARGET" = "MacOSX" ];
  then
    flags="$flags --x86asmexe=yasm"
  fi

  flags="$flags                 \
         --disable-all          \
         --disable-alsa         \
         --disable-bzlib        \
         --disable-iconv        \
         --disable-xlib         \
         --disable-zlib         \
         --disable-dxva2        \
         --disable-videotoolbox \
         --disable-v4l2-m2m     \
         --enable-avcodec       \
         --enable-decoder=h264  \
         --enable-pic           \
         --strip=$(dirname $(which ld))/strip  "

         #--enable-decoder=hevc \
}

#
# Include our configure functions.
#

if test -z "$ROOT"; then
  if test -x "../../../Configure"; then
    ROOT="../../.."
  else
    echo -ne "configure: error: can't find the main configure script\n\n"
    exit 1
  fi
fi

. $ROOT/Configure --functs || include_failed

#
# Setup the configuration environment.
#

setup_cross_configure notarget

setup_configure || setup_failed

#
# USE_PREBUILT=yes skips build and uses pre-built binary on Windows.
#

USE_MINGW_PREBUILT=no

#
# Checking if --build argument is present.
#   If not, use prebuilded libraries.
#

NEED_BUILD="no"

if ( [ $# -eq 1 ] && [ "$1" = "--build" ])                     || \
    [ "$TARGET" = "FreeBSD32" ] || [ "$TARGET" = "FreeBSD64" ] || \
    [ "$TARGET" = "Solaris"   ]
then
  NEED_BUILD="yes"
fi

#
# Check if the target is based on autoconf.
#

if test "$TARGET" = "Linux32"   || test "$TARGET" = "Linux64"   || \
   test "$TARGET" = "Cygwin"    || test "$TARGET" = "MinGW"     || \
   test "$TARGET" = "MacOSX"    || test "$TARGET" = "Solaris"   || \
   test "$TARGET" = "Android"   || test "$TARGET" = "iOS"       || \
   test "$TARGET" = "FreeBSD32" || test "$TARGET" = "FreeBSD64" || \
   test "$TARGET" = "MinGW64"; then

  if test "$NEED_BUILD" = "yes"; then

    #
    # Generate a new configure script.
    #

    echo -ne "configure: generating the original configure script... "

    cp -p configure.in reconfig.status

    echo -ne "reconfig.status\n"

    #
    # Run the script with our parameters.
    #

    echo -ne "configure: running the original configure script... "

    echo -ne "reconfig.status\n"

    LDFLAGS="-L$ROOT/Build/lib $LDFLAGS"
    export LDFLAGS

    cp -p Makefile.in Makefile

    if test "$TARGET" = "MinGW" || test "$TARGET" = "MinGW64"; then

      if test "x$USE_MINGW_PREBUILT" = xyes ; then

        empty_makefile $ROOT

        replace_targets Makefile

        flush_targets Makefile

        touch config.status

        echo "configure: Using pre-built binary."

        exit 0

      fi

      rm -rf tmp
      mkdir tmp

      TMPDIR="tmp"
      export TMPDIR

      if ( i686-pc-mingw32-gcc --version > /dev/null 2> /dev/null ) ; then

        echo "configure: Cross compiler detected."

        CFLAGS="-I$ROOT/Build/include -fPIC"
        export CFLAGS
        CXXFLAGS=""
        export CXXFLAGS
        CPPFLAGS=""
        export CPPFLAGS

      else
        echo "configure: No cross compiler detected."
      fi

    elif test "$TARGET" = "Solaris"; then

      if test -f /usr/xpg4/bin/grep; then

        #
        # Our binary path must be prefixed to
        # other paths because the usage of our
        # sed version is fundamental to correc-
        # tly create the Makefile.
        #

        PATH="$BUILD/bin:/usr/xpg4/bin:$PATH"

        export PATH

      fi
    fi

    cat ./FFCleanupList >> Makefile

    set_flags

    run_configure $flags || run_failed

    #
    # Now post-process the generated makefile.
    #

    replace_targets Makefile

    objects="ffmpeg.o cmdutils.o"
    archives="libavcodec/libavcodec.a libavutil/libavutil.a"
    libraries="-logg -lvorbis -lvorbisenc -lm -lz"

    if test "$TARGET" = "Linux32" || test "$TARGET" = "Linux64"; then

      if test `gcc -dumpversion | cut -d '.' -f 1` -ge 3; then

        libraries="$libraries -pthread"

      else

        libraries="$libraries -lpthread"

      fi

    elif test "$TARGET" = "MacOSX" || test "$TARGET" = "iOS"; then

      libraries="$libraries -lpthread"

    elif test "$TARGET" = "Solaris"; then

      libraries="$libraries -lpthread -lsocket -lrt -lnsl"

    fi

    lib_version=`ffbuild/version.sh`

    if test "$TARGET" = "MinGW" || test "$TARGET" = "MinGW64"; then

      add_library Makefile "avcodec" "libavcodec" "$lib_version" "0" "-lavutil -lm -lws2_32 -lz -lbcrypt"

    elif test "$TARGET" = "MacOSX" || test "$TARGET" = "iOS" ; then

      if test "$(get_xcode_version major)" -lt 5; then

        NOALL_LOAD="-noall_load"

      fi

      add_library Makefile "avcodec" "libavcodec" "$lib_version" "0" "$NOALL_LOAD libavutil/libavutil.a -lm -pthread -lz"

    elif test "$TARGET" = "Android"; then

      add_library_android Makefile "avcodec" "libavcodec" "$lib_version" "0" "-Wl\,-Bsymbolic -lavutil -lm -pthread -lz"

      add_dependency Makefile install "$ROOT/Build/lib/libav.so"

    elif test "$TARGET" = "Solaris"; then

      add_library Makefile "avcodec" "libavcodec" "$lib_version" "0" "-Wl\,-Bsymbolic -lavutil -lm -lpthread -lz"

    else

      add_library Makefile "avcodec" "libavcodec" "$lib_version" "0" "-Wl\,-Bsymbolic -lavutil -lm -pthread -lz"
      replace_string Makefile "libavcodec.so" "libav.so"

    fi

    add_dependency Makefile install "message"

    add_command Makefile distclean "rm -rf \$(FF_CLEANUP)"

    flush_targets Makefile

    #
    # Create final library libav.* merged from avcodec and avutil.
    #

    if test "$TARGET" = "MinGW" || test "$TARGET" = "MinGW64"; then

      replace_string Makefile "libavcodec.dll" "libav.dll"
      replace_string Makefile "libavcodec.def" "libav.def"

    elif test "$TARGET" = "MacOSX" || test "$TARGET" = "iOS" ; then

      #
      # Fix 'duplicate symbol' error when linking.
      #

      replace_string Makefile "-all_load" "-force_load"

      replace_string Makefile "libavcodec.dylib" "libav.dylib"

    elif test "$TARGET" = "Android"; then

      replace_string Makefile "libavcodec.so" "libav.so"

    elif test "$TARGET" = "Solaris"; then

      replace_string Makefile "libavcodec.so" "libav.so"

    else

      replace_string Makefile "libavcodec.so" "libav.so"

    fi

    replace_string Makefile "^clean: "              "clean:: "
    replace_string Makefile "^distclean: "          "distclean:: "
    replace_string Makefile "additional-clean:"     "additional-clean::"
    replace_string Makefile "additional-distclean:" "additional-distclean::"

    touch config.status

  else

    if [ "$TARGET" = "Linux32" ] || [ "$TARGET" = "Linux64" ] || \
       [ "$TARGET" = "MacOSX"  ] || [ "$TARGET" = "MinGW"   ] || \
       [ "$TARGET" = "Cygwin"  ] || [ "$TARGET" = "MinGW64" ] || \
       [ "$TARGET" = "Android" ] || [ "$TARGET" = "iOS"     ]
    then

      #
      # Using prebuilded library
      #

      create_makefile || makefile_failed

      replace_targets Makefile

      #
      # Setting missing flags.
      #

      set_flags

      #
      # Copy only header files.
      #  

      cat ./libavcodec/Headers >> Makefile

      cat ./libavutil/Headers >> Makefile

      cat ./FFCleanupList >> Makefile

      build_dir=$(cd ../../../Build/ && pwd)
      prefix_flag="--prefix=$build_dir"

      touch ./USE_PREBUILT

      source ./configure.in $prefix_flag $flags --disable-x86asm;

      add_command Makefile install "rm -rf $ROOT/Build/lib/libav.*"

      #
      # Check if it is Linux ARM environment and choose proper prebuilt library.
      #

      if [ "$TARGET" = "Linux32" ] && [ "$ARCHITECTURE" = "armv6lhf" ]
      then
        add_command Makefile install "cp ./prebuilt/${TARGET}/armv6/libav.* $ROOT/Build/lib/"

      elif [ "$TARGET" = "Linux32" ] && [ "$ARCHITECTURE" = "armv7lhf" ]
      then
        add_command Makefile install "cp ./prebuilt/${TARGET}/armv7/libav.* $ROOT/Build/lib/"

      elif [ "$TARGET" = "Linux64" ] && [ "$ARCHITECTURE" = "arm64" ]
      then
        add_command Makefile install "cp ./prebuilt/${TARGET}/arm64/libav.* $ROOT/Build/lib/"

      elif [ "$TARGET" = "Android" ]
      then
        ARCHDIR=$(echo $ARCHITECTURE | tr '[:upper:]' '[:lower:]')

        add_command Makefile install "cp ./prebuilt/${TARGET}/$ARCHDIR/libav.* $ROOT/Build/lib/"

      elif [ "$TARGET" = "iOS" ] && [ "$ARCHITECTURE" = "arm64" ]
      then
          add_command Makefile install "cp ./prebuilt/${TARGET}/libav* $ROOT/Build/lib/"

      else
        add_command Makefile install "cp ./prebuilt/${TARGET}/libav.* $ROOT/Build/lib/"
      fi

      add_command Makefile install "rm -rf $ROOT/Build/include/libavcodec/ $ROOT/Build/include/libavutil/"
    
      add_command Makefile install "mkdir $ROOT/Build/include/libavcodec"

      add_command Makefile install "mkdir $ROOT/Build/include/libavutil"

      add_command Makefile install "cd ./libavcodec && cp -p \$(HEADERS_CODEC) $ROOT/Build/include/libavcodec/"

      add_command Makefile install "cd ./libavutil && cp -p \$(HEADERS_UTIL) $ROOT/Build/include/libavutil/"

      add_command Makefile install "cd ./libavutil && cp -p \$(BUILT_HEADERS) $ROOT/Build/include/libavutil/"

      add_command Makefile distclean "rm -rf \$(FF_CLEANUP)"

      flush_targets Makefile

      echo "configure: Using pre-built library."

      made ./config.status
    fi
  fi

else

  echo -ne "configure: error: don't know what to do for target $TARGET\n\n"

  exit 1

fi
