Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
this is very helpful script, which can helps me and you to build Xcode libraries into frameworks ;) (NB: It will need some fixes about framework Resources)
#----- Common functions -----#
sub say {
for (@_){print; print "\n";}
}
sub qxx{
my $what = shift;
say qq(I will do $what);
my $str = qx($what);
if ($?){
die "I fall down on < $what >\n! because of < $? >";
}
return $str;
}
sub chmp{
for $what(@_){
my $what = shift;
$what =~ s/\s+&//;
$what =~ s/^\s+//;
$what;
}
return @_;
}
my @necessarySettingsFiedls = qw(CONFIGURATION_BUILD_DIR
DERIVED_FILES_DIR
DERIVED_FILE_DIR
DERIVED_SOURCES_DIR
EXECUTABLE_NAME
EXECUTABLE_PATH
FRAMEWORK_SEARCH_PATHS
FULL_PRODUCT_NAME
HEADER_SEARCH_PATHS
PRODUCT_NAME
PROJECT_DERIVED_FILE_DIR
PROJECT_DIR
PROJECT_FILE_PATH
PROJECT_NAME
PUBLIC_HEADERS_FOLDER_PATH
TARGET_BUILD_DIR
TARGET_NAME
SDK_NAME
);
#----- script for building frameworks -----#
use Cwd;
use File::Spec;
use File::Basename;
use Data::Dumper;
#use List::MoreUtils;
# This script will have several parts : #
# getting info, setting building phases and etc. #
# every part will have number and name #
# ----------------------------------------#
# ---- Part One: Getting Project's Info - #
# move upward
chdir('..');
# take info of project
my $projname = (grep {/.+[.]xcodeproj/}qx(ls))[0];
chomp $projname;
say "this is $projname";
#say qx(xcodebuild\ -project\ $projname\ -showBuildSettings);
print '\n 1\n' if (' CONFIGURATION_BUILD_DIR ' ~~ @necessarySettingsFiedls);
my %HASH_OF_SETTINGS =
map{@{$_}}
grep{$_->[0]~~@necessarySettingsFiedls}
map{m/\s*(\w+)\s*[=]\s*(.+)\s*/ and $_=[$1,$2]}
split /\n/, qxx qq(xcodebuild -project $projname -showBuildSettings);
$HASH_OF_SETTINGS{BUILD_LOCAL_DIRECTORY} = File::Spec->catfile($HASH_OF_SETTINGS{PROJECT_DIR}, 'build');
$HASH_OF_SETTINGS{BUILD_LOCAL_FRAMEWORK_DIRECTORY} = File::Spec->catfile($HASH_OF_SETTINGS{BUILD_LOCAL_DIRECTORY},$HASH_OF_SETTINGS{PROJECT_NAME}.'.framework');
# say Dumper (\%HASH_OF_SETTINGS);
# ---- Part Two: Compiling Project ------- #
# Now I can compile project. #
# I will set some helpers variables #
# for futher usage. You know, it will be #
# useful enough ;) #
# ---------------------------------------- #
# Remember: my friend is %HASH_OF_SETTINGS
sub xcode_build_framework{
my ($target_name, $sdk_name, $config_name) = @_;
my $execute_str = qq(xcodebuild -target $target_name
-sdk $sdk_name
-configuration $config_name
clean build 1>/dev/null);
$execute_str =~ s/\n//g;
$execute_str =~ s/\s+/ /g;
say qxx $execute_str;
}
#build for all platforms and all sdks
xcode_build_framework $HASH_OF_SETTINGS{TARGET_NAME}, "iphoneos", "Debug";
xcode_build_framework $HASH_OF_SETTINGS{TARGET_NAME}, "iphonesimulator", "Debug";
xcode_build_framework $HASH_OF_SETTINGS{TARGET_NAME}, "iphoneos", "Release";
xcode_build_framework $HASH_OF_SETTINGS{TARGET_NAME}, "iphonesimulator", "Release";
# ---- Part Three: Make Universal --------- #
# At this part I will create universal app #
# for framework. and after that I will move #
# all of that to these directories #
# ----------------------------------------- #
# Remember: my friend is %HASH_OF_SETTINGS
sub lipo_universal_lib{
my ($path_to_build,$project_name,$config_name,$target_name) = @_;
my $first = File::Spec->catfile($path_to_build,"$config_name-iphoneos",$target_name);
my $second = File::Spec->catfile($path_to_build,"$config_name-iphonesimulator",$target_name);
my $target = File::Spec->catfile($path_to_build,"$config_name-universal");
mkdir $target unless -e $target;
$target = File::Spec->catfile($target,$project_name);
my $execute_str = qq(lipo -create $first $second
-output $target);
$execute_str =~ s/\n//g;
$execute_str =~ s/\s+/ /g;
say $execute_str;
say qxx $execute_str;
}
lipo_universal_lib $HASH_OF_SETTINGS{BUILD_LOCAL_DIRECTORY},$HASH_OF_SETTINGS{PROJECT_NAME},"Debug",$HASH_OF_SETTINGS{EXECUTABLE_NAME};
lipo_universal_lib $HASH_OF_SETTINGS{BUILD_LOCAL_DIRECTORY},$HASH_OF_SETTINGS{PROJECT_NAME},"Release",$HASH_OF_SETTINGS{EXECUTABLE_NAME};
# --- Part Four: Make Directories ---------- #
# At this part I will create directories for #
# framework and add symlinks. also copy some #
# shit in it. #
# ------------------------------------------ #
my %FRAMEWORK_OPTIONS = (
FRAMEWORK_VERSION=>'A',
FRAMEWORK_CURRENT_VERSION=>1,
FRAMEWORK_COMPATIBILITY_VERSION=>1
);
sub cleanDirectory{
my $directory = shift;
if (-d $directory) {
say "I will delete directory $directory";
say qx(rm -rf $directory);
}
}
sub createCanonicalFrameworkDirectory{
$,="___";
say "my parameters: @_ \n";
my ($build_path,$project_name,$version)=@_;
my $framework_dir = $build_path;
#my $framework_dir = File::Spec->catfile($build_path,qq'$project_name.framework');
say "Create directories in $framework_dir";
qx(mkdir -p $framework_dir);
mkdir File::Spec->catfile($framework_dir,'Versions');
mkdir File::Spec->catfile($framework_dir,'Versions',$version);
mkdir File::Spec->catfile($framework_dir,'Versions',$version,'Headers');
mkdir File::Spec->catfile($framework_dir,'Versions',$version,'Resources');
#create symlinks
say "Create symlinks";
qx(ln -s $version $framework_dir/Versions/Current);
qx(ln -s Versions/Current/Headers $framework_dir/Headers);
qx(ln -s Versions/Current/Resources $framework_dir/Resources);
qx(ln -s Versions/Current/$project_name $framework_dir/$project_name);
}
cleanDirectory $HASH_OF_SETTINGS{BUILD_LOCAL_FRAMEWORK_DIRECTORY};
createCanonicalFrameworkDirectory($HASH_OF_SETTINGS{BUILD_LOCAL_FRAMEWORK_DIRECTORY},$HASH_OF_SETTINGS{PROJECT_NAME},$FRAMEWORK_OPTIONS{FRAMEWORK_VERSION});
# --- Part Five: Copy Files to framework --- #
# Now I need to copy files from builded #
# before library to new framework folder #
# ------------------------------------------ #
sub copyFilesToFrameworkDirectory{
my ($path_to_build, $sdk_name, $config_name, $project_name, $framework_directory) = @_;
#copy headers
my ($from,$to);
$from = File::Spec->catfile ($path_to_build,$config_name.'-'.$sdk_name,'include',$project_name,"*.h");
$to = File::Spec->catfile ($framework_directory,'Versions','A','Headers');
my $execute_str = qq(cp $from $to);
say qxx $execute_str;
#copy resources #TODO: add search *.bundle and other stuff in PROJECT_DIR
# $from = File::Spec->catfile ($path_to_build,$config_name.'-'.$sdk_name,'include',$project_name)."*.h";
# $to = File::Spec->catfile ($framework_directory,'Versions','A','Headers');
# my $execute_str = qq(cp $from $to);
# say qxx $execute_str;
#copy binary
$from = File::Spec->catfile ($path_to_build,$config_name.'-universal','*');
$to = File::Spec->catfile ($framework_directory,'Versions','A');
$execute_str = qq(cp $from $to);
say qxx $execute_str;
}
copyFilesToFrameworkDirectory($HASH_OF_SETTINGS{BUILD_LOCAL_DIRECTORY},"iphoneos","Release", $HASH_OF_SETTINGS{PROJECT_NAME},$HASH_OF_SETTINGS{BUILD_LOCAL_FRAMEWORK_DIRECTORY});
# --- Part Six: Copy Files to framework ---- #
# Now I need to copy files from builded #
# before library to new framework folder #
# ------------------------------------------ #
say "AND....";
say "WELL DONE! I BUILD $HASH_OF_SETTINGS{PROJECT_NAME} framework IN DIRECTORY $HASH_OF_SETTINGS{BUILD_LOCAL_FRAMEWORK_DIRECTORY}";
__DATA__
=head1 DESCRIPTION
for usage that script, put it in xcode project directory:
# for example, it can be placed in ~>/scripts
# where '~>' is your xcode project directory
=cut
__END__
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment