building Xcode project with AppleScript
building Xcode project with AppleScript
- Subject: building Xcode project with AppleScript
- From: Dmitry Markman <email@hidden>
- Date: Fri, 22 Feb 2008 18:52:07 -0800
Hi
I finally was able to build our Xcode project practically from scratch.
I'd like to share with other developers with my finding
1. Prerequisites
suppose we want to build Xcode project that build bsd libraries
Project has few targets. Every target build one dynamic library
all build settings for the project and targets will be stored in the xcconfig files
xcconfig files are just plain vanilla text files and build settings are stored there
as simple property, for example PRIVATE_HEADERS_FOLDER_PATH = /usr/local/include
so we can generate those files pretty easily.
unfortunately it's not possible to tell application Xcode to create empty project,
we'll have to create completely empty project and save it as TemplateProject.xcodeproj
So before we begin we have to have
completely empty Xcode project (say TemplateProject.xcodeproj)
project.xcconfig file that contains common settings for all targets
for every target we need xcconfig file as well (say target1.xcconfig)
every target xcconfig file will include project.xcconfig file:
example of the content of the target1.xcconfig file
#include "project.xcconfig"
PRODUCT_NAME = my_bsd_dynamic_library
HEADER_SEARCH_PATHS = $(HEADER_SEARCH_PATHS) $(SANDBOX)/include $(SANDBOX)/messages
GCC_PREPROCESSOR_DEFINITIONS = $(GCC_PREPROCESSOR_DEFINITIONS) SL_SERVICES_INTERNAL
2. Preparation
suppose we have our sources in the $(SANDBOX)/src folder
we'll put our project into that folder
$(SANDBOX)/src folder contains TemplateProject.xcodeproj and project.xcconfig
sources related to target are placed into the $(SANDBOX)/src/target directory
folder $(SANDBOX)/src/target contains target.xcconfig file
________________________
set sandbox to "....." -- POSIX style
set project_name to "...." -- POSIX style could be derived from sandbox
set my_posix_project_path to "...." -- constracted from sandbox and project_name
set my_project_path to POSIX file my_posix_project_path -- use that outside of the tell application "Finder"
set base_config_file_name to "project.xcconfig"
....
tell application "Xcode"
quit
end tell
delay 1
-- removing old project and duplicating template project
tell application "Finder"
set template_project to file template_project_path
set my_project_base_item to folder my_project_base
try
delete file my_project_path
empty trash
end try
set new_project to duplicate template_project with replace
set name of new_project to my_project_name
set new_project to file my_project_path
end tell
________________________
so now we have empty project with name project_name
________________________
tell application "Xcode"
open new_project
set my_project to project of active project document
-- Create groups configs and Sources --
tell root group of my_project
set config_group to make new group with properties {name:"configs"}
set proj_source_group to make new group with properties {name:"Sources"}
end tell
-- now we have 2 groups inside of our project
-- Sources where we'll put all our sources
-- configs where we'll put configuration files
________________________
Rule: we're creating group inside of an another group in the following way
tell <parent_group>
set my_new_group to make new group with properties {......} -- see Xcode dictionary for possible properties
end tell
________________________
-- now we want to add project.xcconfig file into the project
tell config_group
set proj_conf_file_ref to make new file reference with properties {name:base_config_file_name, file encoding:macos roman, path type:absolute, path:config_file_posix_path} -- you can use your own setting here
end tell
________________________
Rule: we're adding file into the group in the following way
tell <parent_group>
set my_new_file to make new file reference with properties {...} -- see Xcode dictionary for possible properties
end tell
warning: we can not set file kind, because it is r/o property. Xcode will decide it by itself
on slow network it could be a problem, because when we'll want to assign xcconfig file to the target, Xcode won't do that, because it didn't set
file's kind to the text.xcconfig just yet
________________________
tell my_project
set configuration settings file of every build configuration to proj_conf_file_ref -- you can assign different config file to different configs
delete every build setting of every build configuration -- so we'll have only properties from xcconfig file
set value of build setting "SANDBOX" of every build configuration to sandbox -- we will use it later
end tell
________________________
Rule: we assigning value of build setting simple in the following way
tell my_project
set value of build setting "......" of <some build configuration> to "....."
end tell
________________________
-- now we're ready to add the targets
set targets_name to {"target1", "target2"}
repeat with target_name in targets_name
set config_file_name to target_name & ".xcconfig"
set conf_posix_path to my_posix_project_base & target_name & "/" & config_file_name
tell config_group
set conf_file_ref to make new file reference with properties {name:config_file_name, file encoding:macos roman, path type:absolute, path:conf_posix_path}
end tell
tell my_project
set bsd_target to target template "BSD/Dynamic Library" -- !!!!!!!!!!!!!!!!!!!!!
set my_new_target to make new target with data bsd_target with properties {name:target_name}
end tell
tell my_new_target
set configuration settings file of every build configuration to conf_file_ref
delete every build setting of every build configuration -- see comments above for project config files
end tell
my GenerateTarget(my_project, source_group, target_name)
end repeat
my CreateExecutable(....)
save
quit
end tell
________________________
Rule: we're creating new target, using project's template targets:
tell my_project
set bsd_target to target template "BSD/Dynamic Library" -- ! see Xcode dictionary for all target templates
set my_new_target to make new target with data bsd_target with properties {name:target_name}
-- important we're using command "make with data", --see standard suite's make command
end tell
________________________
GenerateTarget is subroutine that will populate our target
on GenerateTarget(my_project, src_group, module)
tell application "Xcode"
tell src_group
set src_module_group to make new group with properties {name:module, path:module, path type:group relative}
end tell
set src_path to full path of src_group
tell my_project
set module_target to target module
end tell
set module_file_list to my GenerateModuleFileList(src_path, module) -- here you supply list of the files you want to add
-- in my case module_file_list is list of lists
-- every item of module_file_list is list, where first item is directory name
repeat with dir_file_list in module_file_list
set dir_name to item 1 of dir_file_list
set file_list to rest of dir_file_list
tell matlab_src_module_group
set dir_group to make new group with properties {name:dir_name, path type:group relative, path:dir_name}
end tell
repeat with file_name in file_list
tell dir_group
set new_file to make new file reference with properties {name:file_name, file encoding:macos roman, path type:group relative, path:file_name}
add new_file to (get compile sources phase of module_target) ----- adding file into the target
end tell
end repeat
end repeat
end tell
end GenerateTarget
________________________
Rule: we're adding file into the target in the following way
add new_file to (get compile sources phase of module_target)
where new_file is file reference from Xcode Reference Suite
________________________
we add executable with CreateExecutable subroutine
on CreateExecutable (my_project, sandbox_var)
tell application "Xcode"
set exec_name to "my_exec"
tell my_project
set exec to make new executable with properties {name:exec_name, path:.......}
set active executable to exec
end tell
set dylib_path to ......
tell exec
-- we're setting launch arguments:
make new launch argument with properties {active:true, name:......}
...............
-- we're setting environment variables:
make new environment variable with properties {active:true, name:".....", value:"....."}
-- we're creating additional source directory for the debugger:
make new source directory with properties {path:......}
end tell
end tell
end CreateExecutable
that's about it
any comments and suggestions will be greatly appreciated
thanks
P.S. there is a bug in the Xcode (about 2 years old, that prevents add target dependency into an another target .radar: 4358111)
also, there is no way to add additional compiler flags for specific file radar: 5758855
Dmitry Markman
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Xcode-users mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden