Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
15_prepare_thirdParty.sh 6.68 KiB
#!/bin/bash

################################################################################
# Copyright (c) 2021 ITK Engineering GmbH
#               2022-2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License 2.0 which is available at
# http://www.eclipse.org/legal/epl-2.0.
#
# SPDX-License-Identifier: EPL-2.0
################################################################################

################################################################################
# This script prepares the thirdParty dependencies
################################################################################

MYDIR="$(dirname "$(readlink -f $0)")"
cd "$MYDIR/../../.."

REPO_ROOT="$PWD"
file="$REPO_ROOT/utils/ci/conan/conanfile.txt" # Accessing the path of conanfile.txt

# requires by OSI conan build
if [[ -z "$WORKSPACE" ]]; then
  export WORKSPACE="$REPO_ROOT/.."
fi

# Set python command depending on OS
if [[ "${OSTYPE}" = "msys" ]]; then
  PYTHON_COMMAND="${PYTHON_WINDOWS_EXE}"
  export CONAN_CMAKE_GENERATOR="MSYS Makefiles"

else
  PYTHON_COMMAND=python3
fi

# Function to extract the option for the given package as mentioned in conanfile.txt
ExtractOptionsAndQueries() {

  for option in "${listOfOptions[@]}"; do
    # Check if the option belongs to the concerned package
    if [[ $option == ${packageName}* ]]; then
        # Append "-o " before the matched variable
        packageOptions+="-o ${option} "
        packageQueries+="$(echo "$option" | grep -oP "${packageName}.*" | cut -d':' -f2-) AND "
    fi
  done

  # Remove the trailing " AND "
  packageQueries="${packageQueries% AND }"
}

# Function to build package other than protobuf with the given options in conanfile.txt
BuildPackage() {

  "$PYTHON_COMMAND" -m conans.conan create "$REPO_ROOT"/utils/ci/conan/recipe/"$packageName"/all "${each_requirement}" --build=missing $packageOptions
  status=$?
  if [[ "$status" -gt 0 ]]; then
    echo "Error: Failed to create the $each_requirement $packageOptions"
    conan remove --force "$each_requirement"
    exit 1
  fi
}

# Function to parse the conanfile.txt and list out requirements and options
ListOutRequirementsAndOptions() {
    local file="$1"
    local start_pattern="$2"
    local end_pattern="$3"
    local -n section_array="$4"
    local in_section=false

    while IFS= read -r line; do
      if [[ $line != '' ]]; then
        if [[ $line =~ $start_pattern ]]; then
            in_section=true
        elif [[ $line =~ $end_pattern ]]; then
            in_section=false
        fi

        if $in_section; then
            section_array+=("$line")
        fi
      fi
    done < "$file"
    section_array=("${section_array[@]:1}")
}

# List out requirements
listOfRequirements=()
ListOutRequirementsAndOptions "$file" "\[requires\]" "^\[" listOfRequirements

# List out options
listOfOptions=()
ListOutRequirementsAndOptions "$file" "\[options\]" "^\[" listOfOptions

# Detect system settings and create a conan profile
"$PYTHON_COMMAND" -m conans.conan profile new default --detect --force
"$PYTHON_COMMAND" -m conans.conan profile update settings.compiler.libcxx=libstdc++11 default
if [[ "${OSTYPE}" = "msys" ]]; then
  "$PYTHON_COMMAND" -m conans.conan profile update settings.os.subsystem=msys2 default
fi

echo "hotfix: forcing rebuild openscenario_api/v1.3.1@openpass/testing"
conan remove --force openscenario_api/v1.3.1@openpass/testing

echo "list of available packages"
conan search

# Note: If there is a change in recipe of the existing package and would want to
# reinstall the existing package. Then execute conan remove <package> command
# before executing the below "for" loop

# Iterate over the list of requirements
for each_requirement in "${listOfRequirements[@]}"; do

  # Name of the package
  packageName="${each_requirement%%/*}"
  # options command to create the package with the particular option as mentioned in conanfile.txt
  packageOptions=""
  # queries command to check the package with the particular option as mentioned in conanfile.txt is available in local or not
  packageQueries=""

  # If the requirement is protobuf, qt or boost, then we follow the different method, 
  # as we are using conancenter to install and need both shared and static binaries
  if [[ "$packageName" == "protobuf" ]]; then
    continue
  fi

  if [[ "$packageName" == "boost" ]]; then
    continue
  fi

  if [[ "$packageName" == "qt" ]]; then
    continue
  fi

  if [[ "$packageName" == "zlib" ]]; then
    continue
  fi

  if [[ "$packageName" == "minizip" ]]; then
    continue
  fi

  if [[ "$packageName" == "gtest" ]]; then
    continue
  fi


  # Extract options and queries for each package
  ExtractOptionsAndQueries

  # Check if the package is already available in the local
  # conan search results failure if the package is not at all available
  # and just informs that a particular package with the given option is not available, if the same package with another option is available.
  # Therefore, it is important to parse the output and check if the package is available or not
  searchResult=$(conan search -q "$packageQueries" $each_requirement 2>&1)

  # If requirement with the given option is already available, then just install them into deps folder.
  if ! echo "$searchResult" | grep -q -e "no packages for reference" -e "ERROR:"; then
    echo "Package $each_requirement $packageOptions is already available."
  # If requirement with the given option is not available, then create and install them into deps folder.
  else
    echo "Package $each_requirement $packageOptions is not available. Building..."
    BuildPackage
  fi

done

# Command to install all the packages into the required folder. 
# --build=missing argument is necessary as at this point protobuf is checked and if not available it builds from conancenter
"$PYTHON_COMMAND" -m conans.conan  install $file --build=missing --install-folder="$REPO_ROOT/../deps" || exit 1

mv $REPO_ROOT/../deps/protobuf $REPO_ROOT/../deps/protobuf-shared   # rename the deployed protobuf folder as protobuf-shared (to distinguish between protobuf static and shared)

"$PYTHON_COMMAND" -m conans.conan  install protobuf/3.20.0@ --build=missing --install-folder="$REPO_ROOT/../deps" -g deploy -o protobuf:shared=False
status=$?
if [[ "$status" -gt 0 ]]; then
  echo "Error: Failed to install and deploy the protobuf static"
  exit 1
fi

# Apply protobuf patch on port_def.inc and port_undef.inc files
# to avoid GetMessage name conflict on msys
if [[ "${OSTYPE}" = "msys" ]]; then
  cd $REPO_ROOT/../deps/protobuf
  patch -p0 < ../../repo/utils/ci/scripts/patches/protobuf.patch
  cd $REPO_ROOT/../deps/protobuf-shared
  patch -p0 < ../../repo/utils/ci/scripts/patches/protobuf.patch
fi