Skip to content

Instantly share code, notes, and snippets.

@lolgear
Last active May 3, 2016 17:00
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lolgear/5750010 to your computer and use it in GitHub Desktop.
Save lolgear/5750010 to your computer and use it in GitHub Desktop.
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