How to install Android Studio from cli - android

I am curling the latest Android Studio dmg file, mounting the image and copying the .app directory into the Applications directory. When I attempt to open the directory I receive this warning, and when I query the application state, I also receive the code below. Any idea how I can generically install Android Studio from the cli?
Warning:
"Android Studio" is damaged and can't be opened. You should move it to the Trash. Google Chrome.app downloaded this file on
...
| => spctl -a /Applications/Android\ Studio.app/
/Applications/Android Studio.app/: a sealed resource is missing or invalid
...
| => codesign --display --verbose=4 /Applications/Android\ Studio.app/
Executable=/Applications/Android Studio.app/Contents/MacOS/studio
Identifier=com.google.android.studio
Format=app bundle with Mach-O universal (i386 x86_64)
CodeDirectory v=20200 size=537 flags=0x0(none) hashes=11+3 location=embedded
OSPlatform=36
OSSDKVersion=657664
OSVersionMin=657408
Hash type=sha256 size=32
CandidateCDHash sha1=4456b3e77035b4318af16276667c88f7b7d4f9ac
CandidateCDHash sha256=6d95335c6815111d93abd1e87b9fd4648d991bdd
Hash choices=sha1,sha256
Page size=4096
CDHash=6d95335c6815111d93abd1e87b9fd4648d991bdd
Signature size=8948
Authority=Developer ID Application: Google, Inc. (EQHXZ8M8AV)
Authority=Developer ID Certification Authority
Authority=Apple Root CA
Timestamp=Dec 1, 2016, 4:57:25 PM
Info.plist entries=22
TeamIdentifier=EQHXZ8M8AV
Sealed Resources version=2 rules=12 files=11250
Internal requirements count=1 size=188
Android Install Script
#!/usr/bin/env bash
echo "Installing Android Studio"
ANDROID_STUDIO_DMG=$(curl -0 https://developer.android.com/studio/index.html | grep -o --regexp='https://dl.google.com/dl/android/studio/install/[a-zA-Z0-9./?=_-]*/android-studio-ide-[a-zA-Z0-9./?=_-]*-mac.dmg')
./dmginstall.sh $ANDROID_STUDIO_DMG
DMG Install Script - (Modified:https://gist.github.com/rahulgautam/6695872)
#!/usr/bin/env bash
# Downloads and install a .dmg from a URL
#
# Usage
# $ dmginstall [url]
#
# For example, for installing android-studio-ide
# $ dmginstall https://dl.google.com/dl/android/studio/install/2.2.3.0/android-studio-ide-145.3537739-mac.dmg
#
# TODO
# - currently only handles .dmg with .app folders, not .pkg files
# - handle .zip files as well
if [[ $# -lt 1 ]]; then
echo "Usage: dmginstall [url]"
exit 1
fi
url=$*
# Generate a random file name
tmp_file=/tmp/`openssl rand -base64 10 | tr -dc '[:alnum:]'`.dmg
# Download file
echo "Downloading $url..."
curl -# -L -o $tmp_file $url
echo "Please copy and paste the Volumes directory you would like to use"
echo "-----------------------------------------------------------------"
hdiutil mount $tmp_file
IFS= read -r -p "Enter volume: " volume
echo "$volume"
# Locate .app folder and move to /Applications
app=`find "$volume" -name *.app -maxdepth 1 -type d -print0`
echo "Copying `echo $app | awk -F/ '{print $NF}'` into /Applications..."
cp -rv "$app" '/Applications'
# Unmount volume, delete temporal file
echo "Cleaning up..."
hdiutil unmount "$volume"
rm "$tmp_file"
echo "Done!"

Related

Targeting R+ (version 30 and above) requires the resources.arsc of installed APKs to be stored uncompressed and aligned on a 4-byte boundary

I am trying to update android target API from 29 to 30. I have updated:
compileSdkVersion = 30
targetSdkVersion = 30
buildToolsVersion = "30.0.2"
The app is aligned with zipalign -p -f -v 4 before signing as per the official documentation.
When I try to adb install the .apk however I get:
Failure [-124: Failed parse during installPackageLI: Targeting R+
(version 30 and above) requires the resources.arsc of installed APKs
to be stored uncompressed and aligned on a 4-byte boundary]
Has anyone had any success with that?
I had a similar issue.
Observe the zipalign logs for this -
It should not be compressed. If it is, then that is the issue. Somehow you need to make it not compressed. It should look like
resources.arsc (OK)
Give this a try -
unzip -q -o ur-apk.apk -d ur-unzipped-apk-folder
cd ur-unziped-apk-folder
zip -n "resources.arsc" -qr ../zipped.apk *
Use this zipped.apk for alignment and signing as per the official doc.
Note - Apps that target Android 11 (API level 30) or higher can't be installed if they contain a compressed resources.arsc file or if this file is not aligned on a 4-byte boundary
https://developer.android.com/about/versions/11/behavior-changes-11#app-packaging
https://developer.android.com/studio/build/building-cmdline#sign_cmdline
If you zipalign and then sign with an old version of jarsigner then it will unalign during the signing!
Be sure to use the newer apksigner. On my system it is in ~/Android/Sdk/build-tools/32.0.0/apksigner
Here is my repack-n-sign script. Note that you may need to update your BUILD_TOOLS path and set it to the right location:
#!/bin/sh
BUILD_TOOLS=~/Android/Sdk/build-tools/32.0.0/
if [ -z "$1" ]; then
echo "usage: $0 your-app.apk"
exit 1
fi
DIR=`mktemp -d`
DN=`dirname "$1"`
BN=`basename "$1"`
OUT="$DN/repacked-$BN"
OUT_ALIGNED="$DN/aligned-$BN"
OUT_SIGNED="$DN/signed-$BN"
# Debug mode
set -x
# Repack without the META-INF in case it was already signed
# and flag resources.arsc as no-compress:
unzip -q "$1" -d "$DIR"
pushd .
cd $DIR
rm -rf "$DIR/META-INF"
zip -n "resources.arsc" -r ../repacked.$$.apk *
popd
mv "$DIR/../repacked.$$.apk" "$OUT"
# Align
rm -f "$OUT_ALIGNED"
"$BUILD_TOOLS"/zipalign -p -v 4 "$OUT" "$OUT_ALIGNED"
# Verify
"$BUILD_TOOLS"/zipalign -vc 4 "$OUT_ALIGNED"
# Sign
"$BUILD_TOOLS"/apksigner sign -verbose -ks ~/my-release-key.keystore --out "$OUT_SIGNED" "$OUT_ALIGNED"
# Cleanup
rm -rf "$DIR"
echo == Done: $OUT_ALIGNED

Building Android from command line - Package appears to be corrupted

Android Studio is too slow for my computer so I took it upon myself to learn how to build android apps manually. I finished with this script:
#!/usr/bin/env bash
##################################################################
# PREPARE ENVIRONMENT
##################################################################
path=$(pwd)
rm -rf bin
rm -rf gen
mkdir bin
mkdir gen
##################################################################
# SET VARS
##################################################################
# Set your application name
APP_NAME="mygame"
# Define minimal Android revision
ANDROID_REV="27.0.3"
ANDROID_PLATFORM_REV="android-27"
# Define Java compiler command
JAVAC="${JAVA_BIN}/javac -classpath ${ANDROID_SDK}/platforms/${ANDROID_PLATFORM_REV}/android.jar"
JAVAC_BUILD="${JAVAC} -sourcepath src -sourcepath gen -d bin"
##################################################################
# PROCESS
##################################################################
# Generate R class and pack resources and assets into resources.ap_ file
${ANDROID_SDK}/build-tools/${ANDROID_REV}/aapt package -v -f -I ${ANDROID_SDK}/platforms/${ANDROID_PLATFORM_REV}/android.jar -M AndroidManifest.xml -A "assets" -S "res" -m -J "gen" -F bin/resources.ap_
# Compile sources. All *.class files will be put into the bin folder
${JAVAC_BUILD} src/com/mycompany/mygame/*.java
# Generate dex files with compiled Java classes
${ANDROID_SDK}/build-tools/${ANDROID_REV}/dx --dex --output=${path}/bin/classes.dex ${path}/bin
# Recources file need to be copied. This is needed for signing.
mv "${path}/bin/resources.ap_" "${path}/bin/${APP_NAME}.ap_"
# Add generated classes.dex file into application package
${ANDROID_SDK}/build-tools/${ANDROID_REV}/aapt add ${path}/bin/${APP_NAME}.ap_ ${path}/bin/classes.dex
${ANDROID_SDK}/build-tools/${ANDROID_REV}/zipalign -f -v 4 ${path}/bin/${APP_NAME}.ap_ ${path}/bin/${APP_NAME}_unsigned.ap_
# Create signed Android application from *.ap_ file.
${ANDROID_SDK}/build-tools/${ANDROID_REV}/apksigner sign --ks ${path}/keystore/etamagotchi-release-key.keystore --ks-key-alias "mykeystore-alias" ${path}/bin/${APP_NAME}_unsigned.ap_
#
cp ${path}/bin/${APP_NAME}_unsigned.ap_ ${path}/bin/${APP_NAME}.apk
# Delete temp file
rm bin/*.ap_
rm bin/*.dex
It builds successfully. If I try to run adb install mygame.apk it says:
[INSTALL_FAILED_INVALID_APK: Package couldn't be installed in /data/app/com.mycompany.mygame-1: Package /data/app/com.mycompany.mygame-1/base.apk code is missing]
If I manually try to install it says "The package appears to be corrupted". What's wrong with my build script?
I added -source 1.7 -target 1.7 -bootclasspath "${JAVA_HOME}/jre/lib/rt.jar" to my $JAVAC build rule

Continuous Integration with Jenkins for React Native (iOS + Android) project

It is possible to implement Continuous Integration for a React Native app using Jenkins? I haven't found a guide to do this. If there are also other solution, what is the best one? Also, a Mac OS machine is mandatory for iOS project?
Yes, it is totally possible. You only have to execute all actions from the command line instead of XCode or the IDE of your choice. In the case of iOS, have a look at the react-native bundle command to create the JS bundle and xcodebuild and xcrun for compiling the native code. In Android it is a bit easier, since you have the gradle assembleRelease task. Before that you have to run npm install to get all your dependencies, but that should roughly be it.
As for iOS development, unfortunately there is no way around it, you do need an OS X machine.
The first thing is to get a command line build working for both Android and iOS. You can peak at the Xcode or Android Studio logs and copy some of the commands.
I put a build.sh script in the ios and android folders that I can call from a Jenkins job to build respective targets. You could have a build.sh in your project root that calls both.
Todo: I want to figure out how to run eslint airbnb in a Jenkins job and generate a report?
Here is my iOS build.sh script that works with Xcode 9:
#!/bin/sh
############################################
# File: build.sh
# -----------------------
# Author: edOfTheMountain#acme.com
#
# Command line build:
# 1) clean
# 2) build
# 3) archive
# 4) export IPA
#
# http://shashikantjagtap.net/xcodebuild-deploy-ios-app-command-line/
# https://help.apple.com/itc/apploader/e3#/apdATD1E53-D1E1A1303-D1E53A1126
#
isInPath=$(which xcodebuild)
if [ ! -x "${isInPath}" ] ; then
echo "*** Error xcodebuild not found in path"
exit 1
fi
isInPath=$(which xcrun)
if [ ! -x "${isInPath}" ] ; then
echo "*** Error xcrun not found in path"
exit 1
fi
echo "### Start: Cleaning ###############################################################"
rm -rf build
xcodebuild -project MyApp.xcodeproj -scheme MyApp -destination generic/platform=iOS clean
echo "### Done: Cleaning ###############################################################"
# Analyze
# xcodebuild -project MyApp.xcodeproj -scheme MyApp -sdk iphoneos clean analyze
echo "### Start: Building ###############################################################"
# xcodebuild -project MyApp.xcodeproj -target MyApp -showBuildSettings
# xcodebuild -project MyApp.xcodeproj -scheme MyApp -destination generic/platform=iOS build
# Run pod install once before building workspace
pod install
# Now using a Podfile so have to build workspace not build project
xcodebuild -workspace MyApp.xcworkspace -scheme MyApp -destination generic/platform=iOS build
echo "### Done: Building ###############################################################"
CFBundleShortVersionString=`/usr/libexec/PlistBuddy -c "Print :CFBundleShortVersionString" ./MyApp/Info.plist`
CFBundleVersion=`/usr/libexec/PlistBuddy -c "Print :CFBundleVersion" ./MyApp/Info.plist`
echo "CFBundleShortVersionString: ${CFBundleShortVersionString}"
echo "CFBundleVersion: ${CFBundleVersion}"
ipaFileName=MyApp.ipa
renameIpaFileName="field-scout-${CFBundleShortVersionString}.${CFBundleVersion}.ipa"
echo "### Start: Archiving ###############################################################"
# xcodebuild -project MyApp.xcodeproj -scheme MyApp -sdk iphoneos -configuration AppStoreDistribution archive -archivePath $PWD/build/MyApp.xcarchive
# Now using a Podfile so have to build workspace not build project
xcodebuild -workspace MyApp.xcworkspace -scheme MyApp -sdk iphoneos -configuration AppStoreDistribution archive -archivePath $PWD/build/MyApp.xcarchive
echo "### Done: Archiving ###############################################################"
echo "### Start: Exporting ###############################################################"
xcodebuild -exportArchive -archivePath $PWD/build/MyApp.xcarchive -exportOptionsPlist MyApp/ExportOptions.plist -exportPath $PWD/build
ls -al build
echo "### Done: Exporting ###############################################################"
appArchiveFile=build/${ipaFileName}
if [ ! -f "${appArchiveFile}" ]; then
echo "*** Error file not found: ${appArchiveFile}"
exit 1
fi
# Extract and verify archive contents
echo "### Unzip: ${ipaFileName} ###############################################################"
( cd build; unzip -q ${ipaFileName} )
( cd build/Payload; xcrun codesign -dv MyApp.app/ )
outputFile=build/Payload/MyApp.app
if [ ! -d "${outputFile}" ]; then
echo "*** Error file not found: ${outputFile}"
exit 1
fi
rm -rf ./build/Payload
rm -rf ./build/Symbols
# altool is used to verify iOS IPA files
altool_path=/Applications/Xcode.app/Contents/Applications/Application\ Loader.app/Contents/Frameworks/ITunesSoftwareService.framework/Versions/Current/Support
isInPath=$(which altool)
if [ ! -x "${isInPath}" ] ; then
echo "*** Error altool not found in path"
echo "Expected altool path:\n ${altool_path}"
exit 1
fi
# altool validate will trigger a user dialog first time it is run.
# On a jenkins slave you will need to execute manually in a console once, to allow keychain access.
# $ altool --validate-app -f file -u username [-p password] [--output-format xml]
# $ altool --upload-app -f file -u username [-p password] [--output-format xml]
altool --validate-app -f build/${ipaFileName} -u edOfTheMountain#acme.com -p #keychain:"Application Loader: edOfTheMountain#acme.com"
altool --validate-app -f build/${ipaFileName} -u edOfTheMountain#acme.com -p #keychain:"Application Loader: edOfTheMountain#acme.com" --output-format xml > build/validate.xml
altoolValidate=$?
if [ ${altoolValidate} -ne 0 ]; then
echo "*** Error IPA failed to validate: build/${ipaFileName}"
echo "See: build/validate.xml"
exit 1
fi
echo "Rename build/${ipaFileName} to build/${renameIpaFileName}"
mv ./build/${ipaFileName} ./build/${renameIpaFileName}
echo ##############################
echo Done
echo ##############################
echo Ready to upload archive to iTunes:
echo " ${appArchiveFile}"
echo
uploadExample="$( echo altool --upload-app -f build/${renameIpaFileName} -u edOfTheMountain#acme.com -p #keychain:"Application Loader: edOfTheMountain#acme.com" )"
echo "Upload Example:\n ${uploadExample}"
echo

Android Systemtap can not load module

I am trying to load a simple Systemtap module on my GT-i9300
I get the error
Error inserting module '/sdcard/systemtap/modules/monitor_fopen.ko':
Unknown symbol in module
Steps that I took:
1. Get root on the device
I did this by installing this Rom
2. Build custom kernel
# ====================================================
# Add toolchain
user#ubuntu1210:~/Programs$ git clone https://android.googlesource.com/platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7
user#ubuntu1210:~$ sudo gedit .bashrc
# Toolchain
export PATH=${PATH}:~/Programs/arm-linux-androideabi-4.7/bin
# Reboot ubuntu
# ====================================================
# ====================================================
# Download and extract to ~/android/kernel :
# https://github.com/SlimRoms/kernel_samsung_smdk4412.git
user#ubuntu1210:~$ cd android/kernel/kernel_samsung_smdk4412/
# ====================================================
# ====================================================
# Set configuration for compiling
user#ubuntu1210:~/android/kernel/kernel_samsung_smdk4412$ make clean -j4 ARCH=arm SUBARCH=arm CROSS_COMPILE=arm-linux-androideabi-
user#ubuntu1210:~/android/kernel/kernel_samsung_smdk4412$ make ARCH=arm SUBARCH=arm CROSS_COMPILE=arm-linux-androideabi- slim_i9300_defconfig
user#ubuntu1210:~/android/kernel/kernel_samsung_smdk4412$ gedit .config
# Enable config parameters:
CONFIG_DEBUG_INFO, CONFIG_KPROBES, CONFIG_RELAY, CONFIG_DEBUG_FS, CONFIG_MODULES, CONFIG_MODULE_UNLOAD
# ====================================================
# Build Kernel
user#ubuntu1210:~/android/kernel/kernel_samsung_smdk4412$ make -j4 ARCH=arm SUBARCH=arm CROSS_COMPILE=arm-linux-androideabi-
3. Flash built zImage to device
# Download and extract bootimg_tools.zip from
# http://forum.xda-developers.com/showpost.php?p=44670032&postcount=12
#
# Download correct ROM .zip file and extract boot.img to the same folder as bootimg_tools
user#ubuntu1210:~/bootimg_tools$ perl split_bootimg.pl boot.img
user#ubuntu1210:~/bootimg_tools$ perl unpack_ramdisk boot.img-ramdisk.gz ramdisk
user#ubuntu1210:~/bootimg_tools$ perl repack_ramdisk ramdisk boot.img-ramdisk.cpio.gz
user#ubuntu1210:~/bootimg_tools$ cp /home/user/kernel_samsung_smdk4412/arch/arm/boot/zImage boot.img-kernel
user#ubuntu1210:~/bootimg_tools$ ./mkbootimg --kernel boot.img-kernel --ramdisk boot.img-ramdisk.cpio.gz --cmdline 'console=null androidboot.hardware=qcom user_debug=31 zcache' --base 0x80200000 --pagesize 2048 -o boot.img
# Download and install heimdall
# https://bitbucket.org/benjamin_dobell/heimdall/downloads
user#ubuntu1210:~/bootimg_tools$ adb reboot bootloader
user#ubuntu1210:~/bootimg_tools$ sudo heimdall flash --BOOT boot.img --verbose
4. Install systemtap on PC
user#ubuntu1210:~$ mkdir systemtap
user#ubuntu1210:~$ cd systemtap/
user#ubuntu1210:~/systemtap$ git clone https://github.com/flipreverse/systemtap-android.git
user#ubuntu1210:~/systemtap$ cd systemtap-android/
user#ubuntu1210:~/systemtap/systemtap-android$ git submodule init
user#ubuntu1210:~/systemtap/systemtap-android$ git submodule update
user#ubuntu1210:~/systemtap/systemtap-android$ sh build.sh
5. Create an .stp file
user#ubuntu1210:~$ cd /home/user/systemtap/systemtap-android/scripts/
user#ubuntu1210:~$ vi monitor_fopen.stp
#! /usr/bin/stap
probe begin
{
printf("start monitoring");
}
probe end
{
printf("end monitoring");
}
6. Build .ko file out of .stp file using compiled Kernel
user#ubuntu1210:~$ /home/user/systemtap/systemtap-android/installed/bin/stap
-p 4 -v
-a arm
-B CROSS_COMPILE=/home/user/Programs/arm-linux-androideabi-4.7/bin/arm-linux-androideabi-
-r /home/user/android/kernel/kernel_samsung_smdk4412/
-j /home/user/systemtap/systemtap-android/installed/share/systemtap/tapset/
-R /home/user/systemtap/systemtap-android/installed/share/systemtap/runtime/
-t -g -m monitor_fopen /home/user/systemtap/systemtap-android/scripts/monitor_fopen.stp
7. Install Systemtap Android App on the device that runs the custom Kernel
https://github.com/flipreverse/systemtap-android-app
8. Start the app and give the app root access
Superuser.apk should ask you whether Systemtap can have root access
9. Push the .ko file from step 6 to the sdcard
user#ubuntu1210:~$ adb push monitor_fopen.ko /sdcard/systemtap/modules/monitor_fopen.ko
10. Load the module
user#ubuntu1210:~$ adb shell
shell#android:/ $ su
root#android:/ # cd /data/data/com.systemtap.android
root#android:/data/data/com.systemtap.android # sh start_stap.sh
modulename=monitor_fopen
moduledir=/sdcard/systemtap/modules
outputname=monitor_fopen_2014.mm.dd_sss
outputdir=/sdcard/systemtap/stap_output
logdir=/sdcard/systemtap/stap_log
rundir=/sdcard/systemtap/stap_run
stapdir=/data/data/com.systemtap.android
:q!
11. Read result from loading the module
user#ubuntu1210:~$ adb shell
shell#android:/ $ cd sdcard/systemtap/stap_log/
shell#android:/sdcard/systemtap/stap_log $ cat monitor_fopen_2014.mm.dd_sss.txt
Loaded kernel module: monitor_fopen.ko
Output file: monitor_fopen_2014.mm.dd_sss.*
Error inserting module '/sdcard/systemtap/modules/monitor_fopen.ko': Unknown symbol in module
I have no idea in what step I went wrong. Does anyone have a clue?
thanks to #adelphus, he remembered me to use dmesg and I found the error:
Android: Unknown symbol _GLOBAL_OFFSET_TABLE_
With the help of this site I edited the Makefile of the kernel to
CFLAGS_MODULE = -fno-pic
Redoing all the other steps in my OP then worked.

Linking with versioned shared library in Android NDK

I am trying to load two shared libraries in my Android application through the loadLibrary call:
System.loadLibrary("mywrapper");
System.loadLibrary("crypto");
I keep running catching the `UnsatisfiedLinkError. Here is a more detailed version of the error.
Caused by: java.lang.UnsatisfiedLinkError: Cannot load library: link_image[1969]:
130 could not load needed library 'libcrypto.so.1.0.0' for
'libmywrapper.so' (load_library[1111]: Library 'libcrypto.so.1.0.0' not found)
Any ideas?
After spending some time I found out that Android doesn't support versioned libraries. Has any one faced the same issue?
I had the same problem on building libwebsockets for Android, which needs to link with OpenSSL. I use libssl.so as example. You should do the same for related .so files.
Before:
huiying#huiying-PORTEGE-R835:~$ objdump -p libssl.so | grep so
libssl.so: file format elf32-little
NEEDED libcrypto.so.1.0.0
NEEDED libdl.so
NEEDED libc.so
SONAME libssl.so.1.0.0
After
huiying#huiying-PORTEGE-R835:~$ rpl -R -e .so.1.0.0 "_1_0_0.so" libssl.so
Replacing ".so.1.0.0" with "_1_0_0.so" (case sensitive) (partial words matched)
.
A Total of 2 matches replaced in 1 file searched.
huiying#huiying-PORTEGE-R835:~$ objdump -p libssl.so | grep so
libssl.so: file format elf32-little
NEEDED libcrypto_1_0_0.so
NEEDED libdl.so
NEEDED libc.so
SONAME libssl_1_0_0.so
And don't forget to change file name "libssl.so" to "libssl_1_0_0.so".
The hack works. I have running Android app to prove it. See my rant at http://computervisionandjava.blogspot.com/2015/05/trouble-with-versioned-shared-libraries.html.
It seems android has an issue with loading versioned libraries.The issue at hand was because of library so-name in my case libcrypto.so.1.0.0. Even if you rename the library and try to load it as a prebuilt shared library in an android make file it fails.( It has to be because the library name is somehow embedded in the file. And any library that links with it expects to be linked with a library of with the same name )
I hope there are other ways out there when it comes to handling libraries with version names in android.
For now I am evading the problem all together by using static libraries of openssl and linking them with my own shared library.
Year 2014 and still no support for versioned shared libs. So I made a script to patch SONAME. Just point the script to input dir where all versioned libs placed. Then check output dir "unver".
#!/bin/bash
DIR="$1"
if [ "$DIR" == "" ]; then
echo "Usage: fix-soname.sh <target dir>"
exit
fi
if [ ! -d $DIR ]; then
echo "Not found: $DIR"
exit
fi
OUT="$DIR/unver"
echo "Input=$DIR"
echo "Output=$OUT"
CWD=$(pwd)
cd $DIR
# prep dirs
mkdir -p $OUT
rm -f -R $OUT/*
# rename libs and copy to out dir
find "$DIR" -type f -name '*.so*' | while read FILE; do
NAME=$(basename "$FILE")
SONAME=$NAME
while read SYMLINK; do
X=$(basename "$SYMLINK")
#echo "$X (${#X}) -> $NAME (${#NAME})"
if [ "${#X}" -lt "${#SONAME}" ]; then
SONAME=$X
fi
done<<EOT
`find -L $DIR -samefile $FILE`
EOT
#echo $SONAME
cp -f $SONAME $OUT/
done
# patch libs in out dir
find "$OUT" -type f -name '*.so*' | while read FILE; do
# get file name without path
NAME=$(basename "$FILE")
# extract SONAME from shared lib
SONAME=`readelf -d $FILE | grep '(SONAME)' | grep -P '(?<=\[)(lib.*?)(?=\])' -o`
#echo "$NAME [$SONAME]"
# patch SONAME if required
if [ "$NAME" != "$SONAME" ]; then
L1=${#NAME}
L2=${#SONAME}
LDIFF=$((L2-L1))
#echo "$NAME [$SONAME] ($LDIFF)"
if [ "$LDIFF" -gt "0" ]; then
SONEW=$NAME
for (( c=1; c<=$LDIFF; c++ )); do
SONEW+="\x00"
done
echo "$NAME [$SONAME] -> $SONEW ($LDIFF)"
rpl -R -e "$SONAME" "$SONEW" $OUT
fi
fi
done
cd $CWD

Categories

Resources