初始化
63
cocos2d-x/tools/cocos2d-console/.gitignore
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
*.py[cod]
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Packages
|
||||
*.egg
|
||||
*.egg-info
|
||||
dist
|
||||
build
|
||||
eggs
|
||||
parts
|
||||
var
|
||||
sdist
|
||||
develop-eggs
|
||||
.installed.cfg
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
.coverage
|
||||
.tox
|
||||
nosetests.xml
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
|
||||
# Mr Developer
|
||||
.mr.developer.cfg
|
||||
.project
|
||||
.pydevproject
|
||||
|
||||
# Ignore files build by xcode
|
||||
*.mode*v*
|
||||
*.pbxuser
|
||||
*.xcbkptlist
|
||||
*.xcscheme
|
||||
*.xcworkspacedata
|
||||
*.xcuserstate
|
||||
xcschememanagement.plist
|
||||
build/
|
||||
.DS_Store
|
||||
._.*
|
||||
xcuserdata/
|
||||
DerivedData/
|
||||
.idea/*
|
||||
|
||||
# Ignore the files from download
|
||||
bin/sdkbox*
|
||||
plugins/plugin_compile/build_web/bin
|
||||
plugins/plugin_jscompile/
|
||||
plugins/plugin_luacompile/bin/msvcr110.dll
|
||||
plugins/plugin_generate/proj_modifier/plutil-win32/
|
||||
version.json
|
||||
v*-console-*.zip
|
||||
|
||||
# vim
|
||||
*~
|
||||
|
||||
# Ignore the files generated by toexec/build-console
|
||||
toexec/output/
|
||||
toexec/build/
|
||||
142
cocos2d-x/tools/cocos2d-console/README.md
Normal file
@@ -0,0 +1,142 @@
|
||||
# cocos2d-console
|
||||
|
||||
|
||||
|
||||
## Download
|
||||
|
||||
```sh
|
||||
$ NOT DONE YET
|
||||
```
|
||||
|
||||
## Install
|
||||
|
||||
```sh
|
||||
$ NOT DONE YET
|
||||
```
|
||||
|
||||
## Vision of cocos2d-console
|
||||
|
||||
|
||||
A command line tool that lets you create, run, publish, debug, etc… your game. It is the swiss-army knife for cocos2d.
|
||||
|
||||
This command line tool is in its early stages.
|
||||
|
||||
Examples:
|
||||
|
||||
```
|
||||
# starts a new project called "My Game" for multi-platform
|
||||
|
||||
$ cocos new MyGame -l cpp -p org.cocos2d.mygame
|
||||
|
||||
$ cd MyGame
|
||||
|
||||
# Will deploy the project to device and run it
|
||||
$ cocos run -p android
|
||||
|
||||
|
||||
```
|
||||
|
||||
# Devel Info
|
||||
|
||||
## Internals
|
||||
|
||||
`cocos.py` is an script whose only responsability is to call its plugins.
|
||||
`cocos.bat` will invoke `cocos.py` on windows
|
||||
`cocos` will invoke `cocos.py` on Mac OS X and linux
|
||||
|
||||
To get a list of all the registered plugins:
|
||||
|
||||
```
|
||||
$ cocos
|
||||
```
|
||||
|
||||
To run the "new" plugin:
|
||||
|
||||
```
|
||||
$ cocos new
|
||||
```
|
||||
|
||||
## Adding a new plugin to the console
|
||||
|
||||
You have to edit `bin/cocos2d.ini`, and add the class name of your new plugin there. Let's say that you want to add a plugin that deploys the project:
|
||||
|
||||
|
||||
```
|
||||
# should be a subclass of CCPlugin
|
||||
project_deploy.CCPluginDeploy
|
||||
```
|
||||
|
||||
And now you have to create a file called `project_deploy.py` in the `plugins` folder.
|
||||
A new, empty plugin, would look like the code shown below:
|
||||
|
||||
```
|
||||
import cocos
|
||||
|
||||
# Plugins should be a sublass of CCPlugin
|
||||
class CCPluginDeploy(cocos.CCPlugin):
|
||||
|
||||
# in default category
|
||||
@staticmethod
|
||||
def plugin_category():
|
||||
return ""
|
||||
|
||||
@staticmethod
|
||||
def plugin_name():
|
||||
return "deploy"
|
||||
|
||||
@staticmethod
|
||||
def brief_description():
|
||||
return "Deploy the project to target."
|
||||
|
||||
def run(self, argv, dependencies):
|
||||
print "plugin called!"
|
||||
print argv
|
||||
|
||||
```
|
||||
|
||||
Plugins are divided by category, depending on it's function: project, engine, ...
|
||||
|
||||
The plugins of `project` is in default category, it's an empty stirng `""`.
|
||||
|
||||
# Generate Executable
|
||||
|
||||
Now you can use the `toexec/build_console.py` for generating a executable file of `cocos` command.
|
||||
|
||||
## Environment Requirement
|
||||
|
||||
* [Python 2.7](https://www.python.org) (2.7.5 is well tested)
|
||||
* [PyInstaller](https://pypi.python.org/pypi/PyInstaller) (PyInstaller 2.1 is well tested)
|
||||
* Necessary PATH environment for python & pyinstaller.
|
||||
|
||||
__Attention:To keep compatible with both Windows-32bit & Windows-64bit, please install 32bit python on Windows.__
|
||||
|
||||
## Steps
|
||||
|
||||
Run `python build_console.py` in command line. Then the executable file & necessary files will be generated in `toexec/output/PLATFORM`.
|
||||
|
||||
The usage of `build_console.py`:
|
||||
|
||||
```
|
||||
usage: build_console.py [-h] [-s SRC_PATH] [-d DST_PATH]
|
||||
|
||||
Generate executable file for cocos2d-console by PyInstaller.
|
||||
|
||||
optional arguments:
|
||||
-h, --help show this help message and exit
|
||||
-s SRC_PATH, --src-path SRC_PATH
|
||||
Specify the path of cocos2d-console.
|
||||
-d DST_PATH, --dst-path DST_PATH
|
||||
Specify the path of output.
|
||||
```
|
||||
|
||||
## Using the Executable
|
||||
|
||||
The generated executable files can replace the source code of cocos2d-console.
|
||||
|
||||
To fit the limitation of the cocos2d-console implementation. The generated executable files should located at `ENGINE_PATH/tools/cocos2d-console/bin`.
|
||||
|
||||
Then you can use the executable file as same as the source code.
|
||||
|
||||
# Commands Required
|
||||
|
||||
Please see this [issue](https://github.com/cocos2d/cocos2d-console/issues/27)
|
||||
6
cocos2d-x/tools/cocos2d-console/config.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"version":"creator-console-2",
|
||||
"zip_file_size":"45045282",
|
||||
"repo_name":"console-binary",
|
||||
"repo_parent":"https://github.com/cocos2d/"
|
||||
}
|
||||
307
cocos2d-x/tools/cocos2d-console/download-bin.py
Executable file
@@ -0,0 +1,307 @@
|
||||
#!/usr/bin/env python
|
||||
#coding=utf-8
|
||||
#
|
||||
# ./download-bin.py
|
||||
#
|
||||
# Download cocos2d-console resources from github (https://github.com/natural-law/console-binary) and extract from ZIP
|
||||
#
|
||||
# Helps prevent repo bloat due to large binary files since they can
|
||||
# be hosted separately.
|
||||
#
|
||||
|
||||
"""****************************************************************************
|
||||
Copyright (c) 2014 cocos2d-x.org
|
||||
Copyright (c) 2014 Chukong Technologies Inc.
|
||||
|
||||
http://www.cocos2d-x.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
****************************************************************************"""
|
||||
|
||||
import os.path,zipfile
|
||||
import shutil
|
||||
import sys
|
||||
import traceback
|
||||
import distutils
|
||||
import fileinput
|
||||
import json
|
||||
|
||||
from optparse import OptionParser
|
||||
from time import time
|
||||
from sys import stdout
|
||||
from distutils.errors import DistutilsError
|
||||
from distutils.dir_util import copy_tree, remove_tree
|
||||
|
||||
class UnrecognizedFormat:
|
||||
def __init__(self, prompt):
|
||||
self._prompt = prompt
|
||||
def __str__(self):
|
||||
return self._prompt
|
||||
|
||||
class CocosZipInstaller(object):
|
||||
def __init__(self, workpath, config_path, version_path, remote_version_key = None):
|
||||
self._workpath = workpath
|
||||
self._config_path = config_path
|
||||
self._version_path = version_path
|
||||
|
||||
data = self.load_json_file(config_path)
|
||||
|
||||
self._current_version = data["version"]
|
||||
self._repo_name = data["repo_name"]
|
||||
self._filename = self._current_version + '.zip'
|
||||
self._url = data["repo_parent"] + self._repo_name + '/archive/' + self._filename
|
||||
self._zip_file_size = int(data["zip_file_size"])
|
||||
current_version = self._current_version
|
||||
# 'v' letter was swallowed by github, so we need to substring it from the 2nd letter
|
||||
if current_version[0] == 'v':
|
||||
current_version = current_version[1:]
|
||||
self._extracted_folder_name = self._repo_name + '-' + current_version
|
||||
|
||||
try:
|
||||
data = self.load_json_file(version_path)
|
||||
if remote_version_key == None:
|
||||
self._remote_version = data["version"]
|
||||
else:
|
||||
self._remote_version = data[remote_version_key]
|
||||
except:
|
||||
print("==> version file doesn't exist")
|
||||
|
||||
def get_input_value(self, prompt):
|
||||
ret = raw_input(prompt)
|
||||
ret.rstrip(" \t")
|
||||
return ret
|
||||
|
||||
def download_file(self):
|
||||
print("==> Ready to download '%s' from '%s'" % (self._filename, self._url))
|
||||
import urllib2
|
||||
try:
|
||||
u = urllib2.urlopen(self._url)
|
||||
except urllib2.HTTPError as e:
|
||||
if e.code == 404:
|
||||
print("==> Error: Could not find the file from url: '%s'" % (self._url))
|
||||
print("==> Http request failed, error code: " + str(e.code) + ", reason: " + e.read())
|
||||
sys.exit(1)
|
||||
|
||||
f = open(self._filename, 'wb')
|
||||
meta = u.info()
|
||||
content_len = meta.getheaders("Content-Length")
|
||||
file_size = 0
|
||||
if content_len and len(content_len) > 0:
|
||||
file_size = int(content_len[0])
|
||||
else:
|
||||
# github server may not reponse a header information which contains `Content-Length`,
|
||||
# therefore, the size needs to be written hardcode here. While server doesn't return
|
||||
# `Content-Length`, use it instead
|
||||
print("==> WARNING: Couldn't grab the file size from remote, use 'zip_file_size' section in '%s'" % self._config_path)
|
||||
file_size = self._zip_file_size
|
||||
|
||||
print("==> Start to download, please wait ...")
|
||||
|
||||
file_size_dl = 0
|
||||
block_sz = 8192
|
||||
block_size_per_second = 0
|
||||
old_time=time()
|
||||
|
||||
while True:
|
||||
buffer = u.read(block_sz)
|
||||
if not buffer:
|
||||
break
|
||||
|
||||
file_size_dl += len(buffer)
|
||||
block_size_per_second += len(buffer)
|
||||
f.write(buffer)
|
||||
new_time = time()
|
||||
if (new_time - old_time) > 1:
|
||||
speed = block_size_per_second / (new_time - old_time) / 1000.0
|
||||
status = ""
|
||||
if file_size != 0:
|
||||
percent = file_size_dl * 100. / file_size
|
||||
status = r"Downloaded: %6dK / Total: %dK, Percent: %3.2f%%, Speed: %6.2f KB/S " % (file_size_dl / 1000, file_size / 1000, percent, speed)
|
||||
else:
|
||||
status = r"Downloaded: %6dK, Speed: %6.2f KB/S " % (file_size_dl / 1000, speed)
|
||||
|
||||
status = status + chr(8)*(len(status)+1)
|
||||
print(status),
|
||||
sys.stdout.flush()
|
||||
block_size_per_second = 0
|
||||
old_time = new_time
|
||||
|
||||
print("==> Downloading finished!")
|
||||
f.close()
|
||||
|
||||
def ensure_directory(self, target):
|
||||
if not os.path.exists(target):
|
||||
os.mkdir(target)
|
||||
|
||||
def unpack_zipfile(self, extract_dir):
|
||||
"""Unpack zip `filename` to `extract_dir`
|
||||
|
||||
Raises ``UnrecognizedFormat`` if `filename` is not a zipfile (as determined
|
||||
by ``zipfile.is_zipfile()``).
|
||||
"""
|
||||
|
||||
if not zipfile.is_zipfile(self._filename):
|
||||
raise UnrecognizedFormat("%s is not a zip file" % (self._filename))
|
||||
|
||||
print("==> Extracting files, please wait ...")
|
||||
z = zipfile.ZipFile(self._filename)
|
||||
try:
|
||||
for info in z.infolist():
|
||||
name = info.filename
|
||||
|
||||
# don't extract absolute paths or ones with .. in them
|
||||
if name.startswith('/') or '..' in name:
|
||||
continue
|
||||
|
||||
target = os.path.join(extract_dir, *name.split('/'))
|
||||
if not target:
|
||||
continue
|
||||
if name.endswith('/'):
|
||||
# directory
|
||||
self.ensure_directory(target)
|
||||
else:
|
||||
# file
|
||||
data = z.read(info.filename)
|
||||
f = open(target,'wb')
|
||||
try:
|
||||
f.write(data)
|
||||
finally:
|
||||
f.close()
|
||||
del data
|
||||
unix_attributes = info.external_attr >> 16
|
||||
if unix_attributes:
|
||||
os.chmod(target, unix_attributes)
|
||||
finally:
|
||||
z.close()
|
||||
print("==> Extraction done!")
|
||||
|
||||
|
||||
def ask_to_delete_downloaded_zip_file(self):
|
||||
ret = self.get_input_value("==> Whether to delete '%s' file? It may be reused when you execute this script next time! (yes/no): " % self._filename)
|
||||
ret = ret.strip()
|
||||
if ret != 'yes' and ret != 'no':
|
||||
print("==> Invalid answer, please answer 'yes' or 'no'!")
|
||||
return self.ask_to_delete_downloaded_zip_file()
|
||||
else:
|
||||
return True if ret == 'yes' else False
|
||||
|
||||
def download_zip_file(self):
|
||||
if not os.path.isfile(self._filename):
|
||||
self.download_file()
|
||||
try:
|
||||
if not zipfile.is_zipfile(self._filename):
|
||||
raise UnrecognizedFormat("%s is not a zip file" % (self._filename))
|
||||
except UnrecognizedFormat as e:
|
||||
print("==> Unrecognized zip format from your local '%s' file!" % (self._filename))
|
||||
if os.path.isfile(self._filename):
|
||||
os.remove(self._filename)
|
||||
print("==> Download it from internet again, please wait...")
|
||||
self.download_zip_file()
|
||||
|
||||
def need_to_update(self):
|
||||
if not os.path.isfile(self._version_path):
|
||||
return True
|
||||
|
||||
with open(self._version_path) as data_file:
|
||||
data = json.load(data_file)
|
||||
|
||||
if self._remote_version == self._current_version:
|
||||
return False
|
||||
return True
|
||||
|
||||
def load_json_file(self, file_path):
|
||||
if not os.path.isfile(file_path):
|
||||
raise Exception("Could not find (%s)" % (file_path))
|
||||
|
||||
with open(file_path) as data_file:
|
||||
data = json.load(data_file)
|
||||
return data
|
||||
|
||||
def run(self, folder_for_extracting, remove_downloaded, force_update, download_only):
|
||||
if not force_update and not self.need_to_update():
|
||||
print("==> Not need to update!")
|
||||
return
|
||||
|
||||
if os.path.exists(self._extracted_folder_name):
|
||||
shutil.rmtree(self._extracted_folder_name)
|
||||
|
||||
self.download_zip_file()
|
||||
|
||||
if not download_only:
|
||||
self.unpack_zipfile(self._workpath)
|
||||
print("==> Copying files...")
|
||||
dst_folder_path = os.path.join(self._workpath, folder_for_extracting)
|
||||
if not os.path.exists(dst_folder_path):
|
||||
os.makedirs(dst_folder_path)
|
||||
distutils.dir_util.copy_tree(self._extracted_folder_name, dst_folder_path)
|
||||
print("==> Cleaning...")
|
||||
if os.path.exists(self._extracted_folder_name):
|
||||
shutil.rmtree(self._extracted_folder_name)
|
||||
if os.path.isfile(self._filename):
|
||||
if remove_downloaded != None:
|
||||
if remove_downloaded == 'yes':
|
||||
os.remove(self._filename)
|
||||
elif self.ask_to_delete_downloaded_zip_file():
|
||||
os.remove(self._filename)
|
||||
else:
|
||||
print("==> Download (%s) finish!" % self._filename)
|
||||
|
||||
|
||||
def _check_python_version():
|
||||
major_ver = sys.version_info[0]
|
||||
if major_ver > 2:
|
||||
print ("The python version is %d.%d. But python 2.x is required. (Version 2.7 is well tested)\n"
|
||||
"Download it here: https://www.python.org/" % (major_ver, sys.version_info[1]))
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def main():
|
||||
workpath = os.path.dirname(os.path.realpath(__file__))
|
||||
|
||||
if not _check_python_version():
|
||||
sys.exit(1)
|
||||
|
||||
parser = OptionParser()
|
||||
parser.add_option('-r', '--remove-download',
|
||||
action="store", type="string", dest='remove_downloaded', default=None,
|
||||
help="Whether to remove downloaded zip file, 'yes' or 'no'")
|
||||
|
||||
parser.add_option("-f", "--force-update",
|
||||
action="store_true", dest="force_update", default=False,
|
||||
help="Whether to force update the third party libraries")
|
||||
|
||||
parser.add_option("-d", "--download-only",
|
||||
action="store_true", dest="download_only", default=False,
|
||||
help="Only download zip file of the third party libraries, will not extract it")
|
||||
|
||||
(opts, args) = parser.parse_args()
|
||||
|
||||
print("=======================================================")
|
||||
print("==> Prepare to download console binaries!")
|
||||
installer = CocosZipInstaller(workpath, os.path.join(workpath, 'config.json'), os.path.join(workpath, 'version.json'), "version")
|
||||
installer.run("", opts.remove_downloaded, opts.force_update, opts.download_only)
|
||||
|
||||
# -------------- main --------------
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
main()
|
||||
except Exception as e:
|
||||
traceback.print_exc()
|
||||
sys.exit(1)
|
||||
65
cocos2d-x/tools/cocos2d-console/plugins/plugin_clean.py
Normal file
@@ -0,0 +1,65 @@
|
||||
#!/usr/bin/python
|
||||
# ----------------------------------------------------------------------------
|
||||
# cocos2d "clean" plugin
|
||||
#
|
||||
# Author: Luis Parravicini
|
||||
#
|
||||
# License: MIT
|
||||
# ----------------------------------------------------------------------------
|
||||
'''
|
||||
"clean" plugin for cocos2d command line tool
|
||||
'''
|
||||
|
||||
__docformat__ = 'restructuredtext'
|
||||
|
||||
import os
|
||||
import shutil
|
||||
|
||||
import cocos2d
|
||||
from plugin_dist import CCPluginDist
|
||||
|
||||
class CCPluginClean(cocos2d.CCPlugin):
|
||||
"""
|
||||
cleans a project
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
def plugin_name():
|
||||
return "clean"
|
||||
|
||||
@staticmethod
|
||||
def brief_description():
|
||||
return "removes files produced by compilation"
|
||||
|
||||
def clean_android(self):
|
||||
if not self._platforms.is_android_active():
|
||||
return
|
||||
project_dir = self._platforms.project_path()
|
||||
|
||||
cocos2d.Logging.info("cleaning native")
|
||||
obj_path = os.path.join(project_dir, 'obj')
|
||||
self._rmdir(obj_path)
|
||||
cocos2d.Logging.info("cleaning java")
|
||||
self._run_cmd("cd \"%s\" && ant clean" % project_dir)
|
||||
|
||||
def clean_ios(self):
|
||||
if not self._platforms.is_ios_active():
|
||||
return
|
||||
project_dir = self._platforms.project_path()
|
||||
|
||||
cocos2d.Logging.info("removing intermediate files")
|
||||
self._run_cmd("cd \"%s\" && xcodebuild clean" % project_dir)
|
||||
self._rmdir(CCPluginDist.target_path(project_dir))
|
||||
|
||||
def _rmdir(self, path):
|
||||
if os.path.exists(path):
|
||||
try:
|
||||
shutil.rmtree(path)
|
||||
except OSError as e:
|
||||
raise cocos2d.CCPluginError("Error removing directory: " + str(e.args))
|
||||
|
||||
|
||||
def run(self, argv, dependencies):
|
||||
self.parse_args(argv)
|
||||
self.clean_android()
|
||||
self.clean_ios()
|
||||
@@ -0,0 +1 @@
|
||||
from project_compile import CCPluginCompile
|
||||
539
cocos2d-x/tools/cocos2d-console/plugins/plugin_compile/build_android.py
Executable file
@@ -0,0 +1,539 @@
|
||||
#!/usr/bin/python
|
||||
# build_native.py
|
||||
# Build native codes
|
||||
|
||||
|
||||
import sys
|
||||
import os, os.path
|
||||
import shutil
|
||||
from optparse import OptionParser
|
||||
import cocos
|
||||
from MultiLanguage import MultiLanguage
|
||||
import cocos_project
|
||||
import json
|
||||
import re
|
||||
from xml.dom import minidom
|
||||
|
||||
import utils
|
||||
|
||||
import project_compile
|
||||
|
||||
BUILD_CFIG_FILE="build-cfg.json"
|
||||
|
||||
class AndroidBuilder(object):
|
||||
|
||||
CFG_KEY_COPY_TO_ASSETS = "copy_to_assets"
|
||||
CFG_KEY_MUST_COPY_TO_ASSERTS = "must_copy_to_assets"
|
||||
CFG_KEY_STORE = "key_store"
|
||||
CFG_KEY_STORE_PASS = "key_store_pass"
|
||||
CFG_KEY_ALIAS = "alias"
|
||||
CFG_KEY_ALIAS_PASS = "alias_pass"
|
||||
|
||||
GRADLE_KEY_STORE = "RELEASE_STORE_FILE"
|
||||
GRADLE_KEY_ALIAS = "RELEASE_KEY_ALIAS"
|
||||
GRADLE_KEY_STORE_PASS = "RELEASE_STORE_PASSWORD"
|
||||
GRADLE_KEY_ALIAS_PASS = "RELEASE_KEY_PASSWORD"
|
||||
|
||||
def __init__(self, verbose, app_android_root, no_res, proj_obj):
|
||||
self._verbose = verbose
|
||||
|
||||
self.app_android_root = app_android_root
|
||||
self._no_res = no_res
|
||||
self._project = proj_obj
|
||||
|
||||
# check environment variable
|
||||
self.sdk_root = cocos.check_environment_variable('ANDROID_SDK_ROOT')
|
||||
self.sign_prop_file = os.path.join(self.app_android_root, "gradle.properties")
|
||||
|
||||
self._parse_cfg()
|
||||
|
||||
def _run_cmd(self, command, cwd=None):
|
||||
cocos.CMDRunner.run_cmd(command, self._verbose, cwd=cwd)
|
||||
|
||||
def _parse_cfg(self):
|
||||
self.cfg_path = os.path.join(self.app_android_root, BUILD_CFIG_FILE)
|
||||
try:
|
||||
f = open(self.cfg_path)
|
||||
cfg = json.load(f, encoding='utf8')
|
||||
f.close()
|
||||
except Exception:
|
||||
raise cocos.CCPluginError(MultiLanguage.get_string('COMPILE_ERROR_PARSE_CFG_FAILED_FMT', self.cfg_path),
|
||||
cocos.CCPluginError.ERROR_PARSE_FILE)
|
||||
|
||||
if cfg.has_key(project_compile.CCPluginCompile.CFG_KEY_MUST_COPY_RESOURCES):
|
||||
if self._no_res:
|
||||
self.res_files = cfg[project_compile.CCPluginCompile.CFG_KEY_MUST_COPY_RESOURCES]
|
||||
else:
|
||||
self.res_files = cfg[project_compile.CCPluginCompile.CFG_KEY_MUST_COPY_RESOURCES] + cfg[project_compile.CCPluginCompile.CFG_KEY_COPY_RESOURCES]
|
||||
else:
|
||||
self.res_files = cfg[project_compile.CCPluginCompile.CFG_KEY_COPY_RESOURCES]
|
||||
|
||||
self.ndk_module_paths = cfg['ndk_module_path']
|
||||
|
||||
# get the properties for sign release apk
|
||||
self.key_store_str = AndroidBuilder.GRADLE_KEY_STORE
|
||||
self.key_alias_str = AndroidBuilder.GRADLE_KEY_ALIAS
|
||||
self.key_store_pass_str = AndroidBuilder.GRADLE_KEY_STORE_PASS
|
||||
self.key_alias_pass_str = AndroidBuilder.GRADLE_KEY_ALIAS_PASS
|
||||
|
||||
move_cfg = {}
|
||||
self.key_store = None
|
||||
if cfg.has_key(AndroidBuilder.CFG_KEY_STORE):
|
||||
self.key_store = cfg[AndroidBuilder.CFG_KEY_STORE]
|
||||
move_cfg[self.key_store_str] = self.key_store
|
||||
del cfg[AndroidBuilder.CFG_KEY_STORE]
|
||||
|
||||
self.key_store_pass = None
|
||||
if cfg.has_key(AndroidBuilder.CFG_KEY_STORE_PASS):
|
||||
self.key_store_pass = cfg[AndroidBuilder.CFG_KEY_STORE_PASS]
|
||||
move_cfg[self.key_store_pass_str] = self.key_store_pass
|
||||
del cfg[AndroidBuilder.CFG_KEY_STORE_PASS]
|
||||
|
||||
self.alias = None
|
||||
if cfg.has_key(AndroidBuilder.CFG_KEY_ALIAS):
|
||||
self.alias = cfg[AndroidBuilder.CFG_KEY_ALIAS]
|
||||
move_cfg[self.key_alias_str] = self.alias
|
||||
del cfg[AndroidBuilder.CFG_KEY_ALIAS]
|
||||
|
||||
self.alias_pass = None
|
||||
if cfg.has_key(AndroidBuilder.CFG_KEY_ALIAS_PASS):
|
||||
self.alias_pass = cfg[AndroidBuilder.CFG_KEY_ALIAS_PASS]
|
||||
move_cfg[self.key_alias_pass_str] = self.alias_pass
|
||||
del cfg[AndroidBuilder.CFG_KEY_ALIAS_PASS]
|
||||
|
||||
if len(move_cfg) > 0:
|
||||
# move the config into ant.properties
|
||||
self._move_cfg(move_cfg)
|
||||
with open(self.cfg_path, 'w') as outfile:
|
||||
json.dump(cfg, outfile, sort_keys = True, indent = 4)
|
||||
outfile.close()
|
||||
|
||||
def has_keystore_in_signprops(self):
|
||||
keystore = None
|
||||
pattern = re.compile(r"^RELEASE_STORE_FILE=(.+)")
|
||||
|
||||
try:
|
||||
file_obj = open(self.sign_prop_file)
|
||||
for line in file_obj:
|
||||
str1 = line.replace(' ', '')
|
||||
str2 = str1.replace('\t', '')
|
||||
match = pattern.match(str2)
|
||||
if match is not None:
|
||||
keystore = match.group(1)
|
||||
break
|
||||
file_obj.close()
|
||||
except:
|
||||
pass
|
||||
|
||||
if keystore is None:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
def _write_sign_properties(self, cfg):
|
||||
file_obj = open(self.sign_prop_file, "a+")
|
||||
for key in cfg.keys():
|
||||
str_cfg = "%s=%s\n" % (key, cfg[key])
|
||||
file_obj.write(str_cfg)
|
||||
|
||||
file_obj.close()
|
||||
|
||||
def _move_cfg(self, cfg):
|
||||
if not self.has_keystore_in_signprops():
|
||||
self._write_sign_properties(cfg)
|
||||
|
||||
def remove_c_libs(self, libs_dir):
|
||||
for file_name in os.listdir(libs_dir):
|
||||
lib_file = os.path.join(libs_dir, file_name)
|
||||
if os.path.isfile(lib_file):
|
||||
ext = os.path.splitext(lib_file)[1]
|
||||
if ext == ".a" or ext == ".so":
|
||||
os.remove(lib_file)
|
||||
|
||||
def _get_android_sdk_tools_ver(self, sdk_tools_path):
|
||||
cfg_file = os.path.join(sdk_tools_path, 'source.properties')
|
||||
|
||||
if os.path.isfile(cfg_file):
|
||||
f = open(cfg_file)
|
||||
lines = f.readlines()
|
||||
pattern = r'^Pkg\.Revision=(\d+)\.(\d+)'
|
||||
for l in lines:
|
||||
match = re.match(pattern, l.strip())
|
||||
if match:
|
||||
return ((int)(match.group(1)), (int)(match.group(2)))
|
||||
|
||||
raise cocos.CCPluginError(MultiLanguage.get_string('COMPILE_ERROR_UNKNOWN_ANDROID_SDK_TOOLS_VERSION'),
|
||||
cocos.CCPluginError.ERROR_PATH_NOT_FOUND)
|
||||
|
||||
def _update_project_properties(self, folder_path, target_str):
|
||||
props_path = os.path.join(folder_path, 'project.properties')
|
||||
f = open(props_path)
|
||||
lines = f.readlines()
|
||||
f.close()
|
||||
|
||||
pattern = r'^target=(.*)$'
|
||||
matched = False
|
||||
new_line = 'target=%s\n' % target_str
|
||||
for i in range(0, len(lines)):
|
||||
l = lines[i]
|
||||
match = re.match(pattern, l.strip())
|
||||
if match:
|
||||
lines[i] = new_line
|
||||
matched = True
|
||||
|
||||
if not matched:
|
||||
lines.append('\n')
|
||||
lines.append(new_line)
|
||||
|
||||
f = open(props_path, 'w')
|
||||
f.writelines(lines)
|
||||
f.close()
|
||||
|
||||
def _write_local_properties(self, folder_path):
|
||||
local_porps_path = os.path.join(folder_path, 'local.properties')
|
||||
sdk_dir = self.sdk_root
|
||||
ndk_dir = cocos.check_environment_variable('NDK_ROOT')
|
||||
if cocos.os_is_win32():
|
||||
# On Windows, the path should be like:
|
||||
# sdk.dir = C:\\path\\android-sdk
|
||||
sdk_dir = sdk_dir.replace('\\', '\\\\')
|
||||
ndk_dir = ndk_dir.replace('\\', '\\\\')
|
||||
lines = [
|
||||
'sdk.dir=%s\n' % sdk_dir,
|
||||
'ndk.dir=%s\n' % ndk_dir
|
||||
]
|
||||
f = open(local_porps_path, 'w')
|
||||
f.writelines(lines)
|
||||
f.close()
|
||||
|
||||
def update_project(self, android_platform):
|
||||
manifest_path = os.path.join(self.app_android_root, 'app')
|
||||
|
||||
# check the android platform
|
||||
target_str = self.check_android_platform(self.sdk_root, android_platform, manifest_path)
|
||||
|
||||
# should manually update the project
|
||||
self._write_local_properties(manifest_path)
|
||||
self._update_project_properties(manifest_path, target_str)
|
||||
|
||||
# copy the local.properties to the app_android_root
|
||||
file_name = 'local.properties'
|
||||
src_path = os.path.normpath(os.path.join(manifest_path, file_name))
|
||||
dst_path = os.path.normpath(os.path.join(self.app_android_root, file_name))
|
||||
if src_path != dst_path:
|
||||
if os.path.isfile(dst_path):
|
||||
os.remove(dst_path)
|
||||
shutil.copy(src_path, dst_path)
|
||||
|
||||
def get_toolchain_version(self, ndk_root, compile_obj):
|
||||
return "4.9"
|
||||
|
||||
def do_ndk_build(self, ndk_build_param, build_mode, compile_obj):
|
||||
cocos.Logging.info(MultiLanguage.get_string('COMPILE_INFO_NDK_MODE', build_mode))
|
||||
ndk_root = cocos.check_environment_variable('NDK_ROOT')
|
||||
|
||||
toolchain_version = self.get_toolchain_version(ndk_root, compile_obj)
|
||||
|
||||
ndk_work_dir = os.path.join(self.app_android_root, 'app')
|
||||
|
||||
reload(sys)
|
||||
sys.setdefaultencoding('utf8')
|
||||
ndk_path = cocos.CMDRunner.convert_path_to_cmd(os.path.join(ndk_root, "ndk-build"))
|
||||
|
||||
module_paths = []
|
||||
for cfg_path in self.ndk_module_paths:
|
||||
the_path = cocos.replace_env_variable(cfg_path)
|
||||
if not os.path.isabs(the_path):
|
||||
the_path = os.path.normpath(os.path.join(self.app_android_root, the_path))
|
||||
|
||||
module_paths.append(the_path)
|
||||
|
||||
# delete template static and dynamic files
|
||||
obj_local_dir = os.path.join(ndk_work_dir, "obj", "local")
|
||||
if os.path.isdir(obj_local_dir):
|
||||
for abi_dir in os.listdir(obj_local_dir):
|
||||
static_file_path = os.path.join(ndk_work_dir, "obj", "local", abi_dir)
|
||||
if os.path.isdir(static_file_path):
|
||||
self.remove_c_libs(static_file_path)
|
||||
|
||||
# windows should use ";" to seperate module paths
|
||||
if cocos.os_is_win32():
|
||||
ndk_module_path = ';'.join(module_paths)
|
||||
else:
|
||||
ndk_module_path = ':'.join(module_paths)
|
||||
|
||||
ndk_module_path= 'NDK_MODULE_PATH=' + ndk_module_path
|
||||
|
||||
if ndk_build_param is None:
|
||||
ndk_build_cmd = '%s -C %s %s' % (ndk_path, ndk_work_dir, ndk_module_path)
|
||||
else:
|
||||
ndk_build_cmd = '%s -C %s %s %s' % (ndk_path, ndk_work_dir, ' '.join(ndk_build_param), ndk_module_path)
|
||||
|
||||
ndk_build_cmd = '%s NDK_TOOLCHAIN_VERSION=%s' % (ndk_build_cmd, toolchain_version)
|
||||
|
||||
if build_mode == 'debug':
|
||||
ndk_build_cmd = '%s NDK_DEBUG=1' % ndk_build_cmd
|
||||
|
||||
self._run_cmd(ndk_build_cmd)
|
||||
|
||||
|
||||
def _xml_attr(self, dir, file_name, node_name, attr):
|
||||
doc = minidom.parse(os.path.join(dir, file_name))
|
||||
return doc.getElementsByTagName(node_name)[0].getAttribute(attr)
|
||||
|
||||
def update_lib_projects(self, sdk_root, sdk_tool_path, android_platform, property_path):
|
||||
property_file = os.path.join(property_path, "project.properties")
|
||||
if not os.path.isfile(property_file):
|
||||
return
|
||||
|
||||
patten = re.compile(r'^android\.library\.reference\.[\d]+=(.+)')
|
||||
for line in open(property_file):
|
||||
str1 = line.replace(' ', '')
|
||||
str2 = str1.replace('\t', '')
|
||||
match = patten.match(str2)
|
||||
if match is not None:
|
||||
# a lib project is found
|
||||
lib_path = match.group(1)
|
||||
abs_lib_path = os.path.join(property_path, lib_path)
|
||||
abs_lib_path = os.path.normpath(abs_lib_path)
|
||||
if os.path.isdir(abs_lib_path):
|
||||
target_str = self.check_android_platform(sdk_root, android_platform, abs_lib_path)
|
||||
command = "%s update lib-project -p %s -t %s" % (cocos.CMDRunner.convert_path_to_cmd(sdk_tool_path), abs_lib_path, target_str)
|
||||
self._run_cmd(command)
|
||||
|
||||
self.update_lib_projects(sdk_root, sdk_tool_path, android_platform, abs_lib_path)
|
||||
|
||||
def get_api_level(self, target_str, raise_error=True):
|
||||
match = re.match(r'android-(\d+)', target_str)
|
||||
if match is not None:
|
||||
ret = int(match.group(1))
|
||||
else:
|
||||
if raise_error:
|
||||
raise cocos.CCPluginError(MultiLanguage.get_string('COMPILE_ERROR_NOT_VALID_AP_FMT', target_str),
|
||||
cocos.CCPluginError.ERROR_PARSE_FILE)
|
||||
else:
|
||||
ret = -1
|
||||
|
||||
return ret
|
||||
|
||||
def get_target_config(self, proj_path):
|
||||
property_file = os.path.join(proj_path, "project.properties")
|
||||
if not os.path.isfile(property_file):
|
||||
raise cocos.CCPluginError(MultiLanguage.get_string('COMPILE_ERROR_FILE_NOT_FOUND_FMT', property_file),
|
||||
cocos.CCPluginError.ERROR_PATH_NOT_FOUND)
|
||||
|
||||
patten = re.compile(r'^target=(.+)')
|
||||
for line in open(property_file):
|
||||
str1 = line.replace(' ', '')
|
||||
str2 = str1.replace('\t', '')
|
||||
match = patten.match(str2)
|
||||
if match is not None:
|
||||
target = match.group(1)
|
||||
target_num = self.get_api_level(target)
|
||||
if target_num > 0:
|
||||
return target_num
|
||||
|
||||
raise cocos.CCPluginError(MultiLanguage.get_string('COMPILE_ERROR_TARGET_NOT_FOUND_FMT', property_file),
|
||||
cocos.CCPluginError.ERROR_PARSE_FILE)
|
||||
|
||||
# check the selected android platform
|
||||
def check_android_platform(self, sdk_root, android_platform, proj_path):
|
||||
ret = android_platform
|
||||
if android_platform is None:
|
||||
min_platform = self.get_target_config(proj_path)
|
||||
# not specified platform, use the one in project.properties
|
||||
ret = 'android-%d' % min_platform
|
||||
|
||||
ret_path = os.path.join(cocos.CMDRunner.convert_path_to_python(sdk_root), "platforms", ret)
|
||||
if not os.path.isdir(ret_path):
|
||||
raise cocos.CCPluginError(MultiLanguage.get_string('COMPILE_ERROR_NO_AP_IN_SDK_FMT', ret),
|
||||
cocos.CCPluginError.ERROR_PATH_NOT_FOUND)
|
||||
|
||||
return ret
|
||||
|
||||
def gradle_build_apk(self, build_mode, instant_game):
|
||||
# check the compileSdkVersion & buildToolsVersion
|
||||
check_file = os.path.join(self.app_android_root, 'app', 'build.gradle')
|
||||
f = open(check_file)
|
||||
lines = f.readlines()
|
||||
f.close()
|
||||
|
||||
compile_sdk_ver = None
|
||||
build_tools_ver = None
|
||||
compile_sdk_pattern = r'compileSdkVersion[ \t]+([\d]+)'
|
||||
build_tools_pattern = r'buildToolsVersion[ \t]+"(.+)"'
|
||||
for line in lines:
|
||||
line_str = line.strip()
|
||||
match1 = re.match(compile_sdk_pattern, line_str)
|
||||
if match1:
|
||||
compile_sdk_ver = match1.group(1)
|
||||
|
||||
match2 = re.match(build_tools_pattern, line_str)
|
||||
if match2:
|
||||
build_tools_ver = match2.group(1)
|
||||
|
||||
if compile_sdk_ver is not None:
|
||||
# check the compileSdkVersion
|
||||
check_folder_name = 'android-%s' % compile_sdk_ver
|
||||
check_path = os.path.join(self.sdk_root, 'platforms', check_folder_name)
|
||||
if not os.path.isdir(check_path):
|
||||
cocos.Logging.warning(MultiLanguage.get_string('COMPILE_WARNING_COMPILE_SDK_FMT',
|
||||
(compile_sdk_ver, check_path)))
|
||||
|
||||
if build_tools_ver is not None:
|
||||
# check the buildToolsVersion
|
||||
check_path = os.path.join(self.sdk_root, 'build-tools', build_tools_ver)
|
||||
if not os.path.isdir(check_path):
|
||||
cocos.Logging.warning(MultiLanguage.get_string('COMPILE_WARNING_BUILD_TOOLS_FMT',
|
||||
(build_tools_ver, check_path)))
|
||||
|
||||
# invoke gradlew for gradle building
|
||||
if cocos.os_is_win32():
|
||||
gradle_path = os.path.join(self.app_android_root, 'gradlew.bat')
|
||||
else:
|
||||
gradle_path = os.path.join(self.app_android_root, 'gradlew')
|
||||
|
||||
if not os.path.isfile(gradle_path):
|
||||
raise cocos.CCPluginError(MultiLanguage.get_string('COMPILE_ERROR_GRALEW_NOT_EXIST_FMT', gradle_path),
|
||||
cocos.CCPluginError.ERROR_PATH_NOT_FOUND)
|
||||
|
||||
mode_str = 'Debug' if build_mode == 'debug' else 'Release'
|
||||
cmd = '"%s" --parallel --info ' % (gradle_path)
|
||||
if instant_game:
|
||||
cmd += ':instantapp:'
|
||||
cmd += 'assemble%s' % (mode_str)
|
||||
self._run_cmd(cmd, cwd=self.app_android_root)
|
||||
|
||||
def do_build_apk(self, build_mode, no_apk, instant_game, output_dir, custom_step_args, compile_obj):
|
||||
project_name = None
|
||||
setting_file = os.path.join(self.app_android_root, 'settings.gradle')
|
||||
if os.path.isfile(setting_file):
|
||||
# get project name from settings.gradle
|
||||
f = open(setting_file)
|
||||
lines = f.readlines()
|
||||
f.close()
|
||||
pattern = r"project\(':(.*)'\)\.projectDir[ \t]*=[ \t]*new[ \t]*File\(settingsDir, 'app'\)"
|
||||
for line in lines:
|
||||
line_str = line.strip()
|
||||
match = re.match(pattern, line_str)
|
||||
if match:
|
||||
project_name = match.group(1)
|
||||
break
|
||||
if instant_game:
|
||||
project_name = 'instantapp'
|
||||
if project_name is None:
|
||||
# use default project name
|
||||
project_name = 'app'
|
||||
if instant_game:
|
||||
relative_path = '%s/build/outputs/apk' % (project_name)
|
||||
gen_apk_folder = os.path.join(self.app_android_root, relative_path)
|
||||
else:
|
||||
gen_apk_folder = os.path.join(self.app_android_root, 'app/build/outputs/apk')
|
||||
|
||||
if not no_apk:
|
||||
# remove old apk file
|
||||
if os.path.isdir(gen_apk_folder):
|
||||
shutil.rmtree(gen_apk_folder)
|
||||
|
||||
# gather the sign info if necessary
|
||||
if build_mode == "release" and not self.has_keystore_in_signprops():
|
||||
self._gather_sign_info()
|
||||
|
||||
# build apk
|
||||
self.gradle_build_apk(build_mode, instant_game)
|
||||
|
||||
# copy the apk to output dir
|
||||
if output_dir:
|
||||
apk_name = '%s-%s' % (project_name, build_mode)
|
||||
apk_name += '.apk'
|
||||
gen_apk_path = os.path.join(gen_apk_folder, apk_name)
|
||||
|
||||
# Android Studio 2.x.x uses 'app/build/outputs/apk' as output directory,
|
||||
# but Android Studio 3.x.x appends 'debug' or 'release' directory after 'app/build/outputs/apk'.
|
||||
if not os.path.exists(gen_apk_path):
|
||||
gen_apk_path = os.path.join(gen_apk_folder, build_mode, apk_name)
|
||||
|
||||
if not os.path.exists(output_dir):
|
||||
os.makedirs(output_dir)
|
||||
shutil.copy(gen_apk_path, output_dir)
|
||||
cocos.Logging.info(MultiLanguage.get_string('COMPILE_INFO_MOVE_APK_FMT', output_dir))
|
||||
|
||||
if build_mode == "release":
|
||||
signed_name = "%s-%s-signed" % (project_name, build_mode)
|
||||
signed_name += '.apk'
|
||||
apk_path = os.path.join(output_dir, signed_name)
|
||||
if os.path.exists(apk_path):
|
||||
os.remove(apk_path)
|
||||
os.rename(os.path.join(output_dir, apk_name), apk_path)
|
||||
else:
|
||||
apk_path = os.path.join(output_dir, apk_name)
|
||||
return apk_path
|
||||
else:
|
||||
raise cocos.CCPluginError(MultiLanguage.get_string('COMPILE_ERROR_NOT_SPECIFY_OUTPUT'),
|
||||
cocos.CCPluginError.ERROR_WRONG_ARGS)
|
||||
|
||||
def _gather_sign_info(self):
|
||||
user_cfg = {}
|
||||
# get the path of keystore file
|
||||
while True:
|
||||
inputed = self._get_user_input(MultiLanguage.get_string('COMPILE_TIP_INPUT_KEYSTORE'))
|
||||
inputed = inputed.strip()
|
||||
if not os.path.isabs(inputed):
|
||||
start_path = os.path.join(self.app_android_root, 'app')
|
||||
abs_path = os.path.join(start_path, inputed)
|
||||
else:
|
||||
abs_path = inputed
|
||||
|
||||
if os.path.isfile(abs_path):
|
||||
user_cfg[self.key_store_str] = inputed.replace('\\', '/')
|
||||
break
|
||||
else:
|
||||
cocos.Logging.warning(MultiLanguage.get_string('COMPILE_INFO_NOT_A_FILE'))
|
||||
|
||||
# get the alias of keystore file
|
||||
user_cfg[self.key_alias_str] = self._get_user_input(MultiLanguage.get_string('COMPILE_TIP_INPUT_ALIAS'))
|
||||
|
||||
# get the keystore password
|
||||
user_cfg[self.key_store_pass_str] = self._get_user_input(MultiLanguage.get_string('COMPILE_TIP_INPUT_KEY_PASS'))
|
||||
|
||||
# get the alias password
|
||||
user_cfg[self.key_alias_pass_str] = self._get_user_input(MultiLanguage.get_string('COMPILE_TIP_INPUT_ALIAS_PASS'))
|
||||
|
||||
# write the config into ant.properties
|
||||
self._write_sign_properties(user_cfg)
|
||||
|
||||
def _get_user_input(self, tip_msg):
|
||||
cocos.Logging.warning(tip_msg)
|
||||
ret = None
|
||||
while True:
|
||||
ret = raw_input()
|
||||
break
|
||||
|
||||
return ret
|
||||
|
||||
def get_apk_info(self):
|
||||
manifest_path = os.path.join(self.app_android_root, 'app')
|
||||
gradle_cfg_path = os.path.join(manifest_path, 'build.gradle')
|
||||
package = None
|
||||
if os.path.isfile(gradle_cfg_path):
|
||||
# get package name from build.gradle
|
||||
f = open(gradle_cfg_path)
|
||||
for line in f.readlines():
|
||||
line_str = line.strip()
|
||||
pattern = r'applicationId[ \t]+"(.*)"'
|
||||
match = re.match(pattern, line_str)
|
||||
if match:
|
||||
package = match.group(1)
|
||||
break
|
||||
if package is None:
|
||||
# get package name from AndroidManifest.xml
|
||||
package = self._xml_attr(manifest_path, 'AndroidManifest.xml', 'manifest', 'package')
|
||||
|
||||
activity_name = self._xml_attr(manifest_path, 'AndroidManifest.xml', 'activity', 'android:name')
|
||||
if activity_name.startswith('.'):
|
||||
activity = package + activity_name
|
||||
else:
|
||||
activity = activity_name
|
||||
ret = (package, activity)
|
||||
|
||||
return ret
|
||||
@@ -0,0 +1,145 @@
|
||||
#!/usr/bin/python
|
||||
import os
|
||||
import json
|
||||
import cocos
|
||||
from MultiLanguage import MultiLanguage
|
||||
import sys
|
||||
import subprocess
|
||||
|
||||
|
||||
JDK_1_7 = "1.7"
|
||||
JDK_1_6 = "1.6"
|
||||
|
||||
def check_jdk_version():
|
||||
commands = [
|
||||
"java",
|
||||
"-version"
|
||||
]
|
||||
child = subprocess.Popen(commands, stderr=subprocess.PIPE)
|
||||
|
||||
jdk_version = None
|
||||
for line in child.stderr:
|
||||
if 'java version' in line:
|
||||
if '1.6' in line:
|
||||
jdk_version = JDK_1_6
|
||||
else:
|
||||
jdk_version = JDK_1_7
|
||||
|
||||
child.wait()
|
||||
|
||||
if jdk_version is None:
|
||||
raise cocos.CCPluginError(MultiLanguage.get_string('COMPILE_ERROR_NO_VALID_JDK'),
|
||||
cocos.CCPluginError.ERROR_TOOLS_NOT_FOUND)
|
||||
|
||||
return jdk_version
|
||||
|
||||
def gen_buildxml(project_dir, project_json, output_dir, build_opts):
|
||||
# get engine dir (not real)
|
||||
engineDir = project_json["engineDir"]
|
||||
# get real engine dir
|
||||
engine_dir = os.path.normpath(os.path.join(project_dir, engineDir))
|
||||
# get real publish dir
|
||||
publish_dir = output_dir
|
||||
# get tools dir
|
||||
if getattr(sys, 'frozen', None):
|
||||
tools_dir = os.path.realpath(os.path.dirname(sys.executable))
|
||||
else:
|
||||
tools_dir = os.path.realpath(os.path.dirname(__file__))
|
||||
|
||||
# download the binary files
|
||||
compiler_1_6 = os.path.join(tools_dir, "bin", "compiler-1.6.jar")
|
||||
compiler_1_7 = os.path.join(tools_dir, "bin", "compiler-1.7.jar")
|
||||
if not os.path.exists(compiler_1_6) or not os.path.exists(compiler_1_7):
|
||||
download_cmd_path = os.path.join(tools_dir, os.pardir, os.pardir, os.pardir)
|
||||
subprocess.call("python %s -f" % (os.path.join(download_cmd_path, "download-bin.py")), shell=True, cwd=download_cmd_path)
|
||||
|
||||
try:
|
||||
f = open(os.path.join(engine_dir, "moduleConfig.json"))
|
||||
module_cfg = json.load(f)
|
||||
finally:
|
||||
f.close()
|
||||
|
||||
ccModuleMap = module_cfg["module"]
|
||||
modules = project_json.get("modules", ["core"])
|
||||
renderMode = project_json.get("renderMode", 0)
|
||||
mainJs = project_json.get("main", "main.js")
|
||||
ccJsList = [module_cfg["bootFile"]]
|
||||
userJsList = project_json.get("jsList", [])
|
||||
|
||||
if renderMode != 1 and "base4webgl" not in modules:
|
||||
modules[0:0] = ["base4webgl"]
|
||||
|
||||
for item in modules:
|
||||
arr = _getJsListOfModule(ccModuleMap, item)
|
||||
if arr != None:
|
||||
ccJsList += arr
|
||||
|
||||
userJsList.append(mainJs)
|
||||
|
||||
buildXmlTempFile = open(os.path.join(tools_dir, "template", "build.xml"))
|
||||
|
||||
try:
|
||||
buildContent = buildXmlTempFile.read()
|
||||
finally:
|
||||
buildXmlTempFile.close()
|
||||
|
||||
jdk_version = check_jdk_version()
|
||||
sourceMapOpened = build_opts.get("sourceMapOpened")
|
||||
if jdk_version == JDK_1_6:
|
||||
sourceMapOpened = False
|
||||
sourceMapContent = 'sourceMapOutputFile="' + os.path.join(publish_dir, "sourcemap") + '" sourceMapFormat="V3"' if sourceMapOpened else ""
|
||||
|
||||
|
||||
|
||||
buildContent = buildContent.replace("%projectDir%", project_dir)
|
||||
buildContent = buildContent.replace("%engineDir%", engine_dir)
|
||||
buildContent = buildContent.replace("%publishDir%", publish_dir)
|
||||
buildContent = buildContent.replace("%outputFileName%", build_opts["outputFileName"])
|
||||
buildContent = buildContent.replace("%toolsDir%", tools_dir)
|
||||
buildContent = buildContent.replace("%compiler%", "compiler-%s.jar" % jdk_version)
|
||||
buildContent = buildContent.replace("%compilationLevel%", build_opts["compilationLevel"])
|
||||
buildContent = buildContent.replace("%sourceMapCfg%", sourceMapContent)
|
||||
buildContent = buildContent.replace("%ccJsList%", _getFileArrStr(ccJsList))
|
||||
buildContent = buildContent.replace("%userJsList%", _getFileArrStr(userJsList))
|
||||
buildContent = buildContent.replace("%debug%", build_opts["debug"])
|
||||
|
||||
buildXmlOutputFile = open(os.path.join(publish_dir, "build.xml"), "w")
|
||||
buildXmlOutputFile.write(buildContent)
|
||||
buildXmlOutputFile.close()
|
||||
|
||||
|
||||
_jsAddedCache = {}
|
||||
|
||||
def _getJsListOfModule(moduleMap, moduleName):
|
||||
if _jsAddedCache.get(moduleName) != None:
|
||||
return None
|
||||
_jsAddedCache[moduleName] = True
|
||||
jsList = []
|
||||
tempList = moduleMap[moduleName]
|
||||
|
||||
for item in tempList:
|
||||
if _jsAddedCache.get(item):
|
||||
continue
|
||||
extname = os.path.splitext(item)[1]
|
||||
|
||||
if extname == None or extname == "":
|
||||
arr = _getJsListOfModule(moduleMap, item)
|
||||
if arr != None:
|
||||
jsList += arr
|
||||
elif extname == ".js":
|
||||
jsList.append(item)
|
||||
|
||||
_jsAddedCache[item] = True
|
||||
|
||||
return jsList
|
||||
|
||||
|
||||
def _getFileArrStr(jsList):
|
||||
str = ""
|
||||
|
||||
index = 0
|
||||
for item in jsList:
|
||||
str += ' <file name="' + item + '"/>\r\n'
|
||||
|
||||
return str
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0"?>
|
||||
<project name="Javascript compress project" basedir="%projectDir%" default="compile">
|
||||
|
||||
<taskdef name="jscomp" classname="com.google.javascript.jscomp.ant.CompileTask"
|
||||
classpath="%toolsDir%/bin/%compiler%"/>
|
||||
|
||||
<target name="compile">
|
||||
<jscomp compilationLevel="%compilationLevel%"
|
||||
warning="quiet"
|
||||
debug="%debug%"
|
||||
output="%publishDir%/%outputFileName%"
|
||||
languagein="ECMASCRIPT5"
|
||||
%sourceMapCfg%
|
||||
>
|
||||
<sources dir="%engineDir%">
|
||||
%ccJsList%
|
||||
</sources>
|
||||
<sources dir="${basedir}">
|
||||
%userJsList%
|
||||
</sources>
|
||||
</jscomp>
|
||||
</target>
|
||||
</project>
|
||||
231
cocos2d-x/tools/cocos2d-console/plugins/plugin_deploy.py
Normal file
@@ -0,0 +1,231 @@
|
||||
#!/usr/bin/python
|
||||
# ----------------------------------------------------------------------------
|
||||
# cocos "install" plugin
|
||||
#
|
||||
# Copyright 2013 (C) Luis Parravicini
|
||||
#
|
||||
# License: MIT
|
||||
# ----------------------------------------------------------------------------
|
||||
'''
|
||||
"install" plugin for cocos command line tool
|
||||
'''
|
||||
|
||||
__docformat__ = 'restructuredtext'
|
||||
|
||||
import os
|
||||
import cocos
|
||||
from MultiLanguage import MultiLanguage
|
||||
|
||||
|
||||
class CCPluginDeploy(cocos.CCPlugin):
|
||||
"""
|
||||
Install a project
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
def depends_on():
|
||||
return ('compile',)
|
||||
|
||||
@staticmethod
|
||||
def plugin_name():
|
||||
return "deploy"
|
||||
|
||||
@staticmethod
|
||||
def brief_description():
|
||||
return MultiLanguage.get_string('DEPLOY_BRIEF')
|
||||
|
||||
def _add_custom_options(self, parser):
|
||||
parser.add_argument("-m", "--mode", dest="mode", default='debug',
|
||||
help=MultiLanguage.get_string('DEPLOY_ARG_MODE'))
|
||||
parser.add_argument("--instant-game", dest="instant_game", action="store_true",
|
||||
help=MultiLanguage.get_string('DEPLOY_ARG_INSTANT_GAME'))
|
||||
parser.add_argument("--launch-url", dest="launch_url", default='',
|
||||
help=MultiLanguage.get_string('RUN_ARG_LAUNCH_URL'))
|
||||
|
||||
def _check_custom_options(self, args):
|
||||
|
||||
if args.mode != 'release':
|
||||
args.mode = 'debug'
|
||||
|
||||
self._mode = 'debug'
|
||||
self._instant_game = args.instant_game
|
||||
self._launch_url = args.launch_url
|
||||
if 'release' == args.mode:
|
||||
self._mode = args.mode
|
||||
|
||||
def _is_debug_mode(self):
|
||||
return self._mode == 'debug'
|
||||
|
||||
def _get_install_target_sdk_version(self, adb_path):
|
||||
import subprocess
|
||||
cmds = [adb_path, 'shell', 'getprop', 'ro.build.version.sdk']
|
||||
|
||||
child = subprocess.Popen(cmds, stdout=subprocess.PIPE)
|
||||
out = child.stdout.read()
|
||||
child.wait()
|
||||
errCode = child.returncode
|
||||
|
||||
return (errCode, out)
|
||||
|
||||
def deploy_ios(self, dependencies):
|
||||
if not self._platforms.is_ios_active():
|
||||
return
|
||||
|
||||
compile_dep = dependencies['compile']
|
||||
self._iosapp_path = compile_dep._iosapp_path
|
||||
self._use_sdk = compile_dep.use_sdk
|
||||
|
||||
def deploy_mac(self, dependencies):
|
||||
if not self._platforms.is_mac_active():
|
||||
return
|
||||
|
||||
compile_dep = dependencies['compile']
|
||||
self._macapp_path = compile_dep._macapp_path
|
||||
self.target_name = compile_dep.target_name
|
||||
|
||||
def deploy_web(self, dependencies):
|
||||
if not self._platforms.is_web_active():
|
||||
return
|
||||
|
||||
compile_dep = dependencies['compile']
|
||||
self.sub_url = compile_dep.sub_url
|
||||
self.run_root = compile_dep.run_root
|
||||
|
||||
def deploy_win32(self, dependencies):
|
||||
if not self._platforms.is_win32_active():
|
||||
return
|
||||
|
||||
compile_dep = dependencies['compile']
|
||||
self.run_root = compile_dep.run_root
|
||||
self.project_name = compile_dep.project_name
|
||||
|
||||
def find_xap_deploy_tool(self):
|
||||
import _winreg
|
||||
import re
|
||||
if cocos.os_is_32bit_windows():
|
||||
reg_flag_list = [ _winreg.KEY_WOW64_32KEY ]
|
||||
else:
|
||||
reg_flag_list = [ _winreg.KEY_WOW64_64KEY, _winreg.KEY_WOW64_32KEY ]
|
||||
|
||||
pattern = re.compile(r"v(\d+).(\d+)")
|
||||
find_ret = None
|
||||
find_major = -1
|
||||
find_minor = -1
|
||||
for reg_flag in reg_flag_list:
|
||||
cocos.Logging.info(MultiLanguage.get_string('DEPLOY_INFO_FIND_XAP_FMT',
|
||||
("32bit" if reg_flag == _winreg.KEY_WOW64_32KEY else "64bit")))
|
||||
try:
|
||||
wp = _winreg.OpenKey(
|
||||
_winreg.HKEY_LOCAL_MACHINE,
|
||||
r"SOFTWARE\Microsoft\Microsoft SDKs\WindowsPhone",
|
||||
0,
|
||||
_winreg.KEY_READ | reg_flag
|
||||
)
|
||||
except:
|
||||
# windows phone not found, continue
|
||||
continue
|
||||
|
||||
i = 0
|
||||
while True:
|
||||
try:
|
||||
version = _winreg.EnumKey(wp, i)
|
||||
except:
|
||||
break
|
||||
|
||||
i += 1
|
||||
match = re.match(pattern, version)
|
||||
if match:
|
||||
major = int(match.group(1))
|
||||
minor = int(match.group(2))
|
||||
if major > 7:
|
||||
try:
|
||||
key = _winreg.OpenKey(wp, "%s\Install Path" % version)
|
||||
value, type = _winreg.QueryValueEx(key, "Install Path")
|
||||
tool_path = os.path.join(value, "Tools", "XAP Deployment", "XapDeployCmd.exe")
|
||||
if os.path.isfile(tool_path):
|
||||
if (find_ret is None) or (major > find_major) or (major == find_major and minor > find_minor):
|
||||
find_ret = tool_path
|
||||
find_major = major
|
||||
find_minor = minor
|
||||
except:
|
||||
pass
|
||||
|
||||
return find_ret
|
||||
|
||||
def deploy_wp8(self, dependencies):
|
||||
if not self._platforms.is_wp8_active():
|
||||
return
|
||||
|
||||
compile_dep = dependencies['compile']
|
||||
run_root = compile_dep.run_root
|
||||
product_id = compile_dep.product_id
|
||||
xap_file_name = compile_dep.xap_file_name
|
||||
self.xap_path = os.path.join(run_root, xap_file_name)
|
||||
|
||||
# find the XapDeployCmd.exe
|
||||
self.deploy_tool = self.find_xap_deploy_tool()
|
||||
if self.deploy_tool is None:
|
||||
raise cocos.CCPluginError(MultiLanguage.get_string('DEPLOY_ERROR_XAPCMD_NOT_FOUND'),
|
||||
cocos.CCPluginError.ERROR_TOOLS_NOT_FOUND)
|
||||
|
||||
# uninstall the app on wp8 by product ID
|
||||
try:
|
||||
uninstall_cmd = '"%s" /uninstall %s /targetdevice:xd' % (self.deploy_tool, product_id)
|
||||
self._run_cmd(uninstall_cmd)
|
||||
except:
|
||||
pass
|
||||
|
||||
def deploy_linux(self, dependencies):
|
||||
if not self._platforms.is_linux_active():
|
||||
return
|
||||
|
||||
compile_dep = dependencies['compile']
|
||||
self.run_root = compile_dep.run_root
|
||||
self.project_name = compile_dep.project_name
|
||||
|
||||
def deploy_android(self, dependencies):
|
||||
if not self._platforms.is_android_active():
|
||||
return
|
||||
|
||||
cocos.Logging.info(MultiLanguage.get_string('DEPLOY_INFO_INSTALLING_APK'))
|
||||
|
||||
compile_dep = dependencies['compile']
|
||||
self.package = compile_dep.android_package
|
||||
self.activity = compile_dep.android_activity
|
||||
apk_path = compile_dep.apk_path
|
||||
sdk_root = cocos.check_environment_variable('ANDROID_SDK_ROOT')
|
||||
|
||||
if self._instant_game:
|
||||
ia_path = cocos.CMDRunner.convert_path_to_cmd(os.path.join(sdk_root, 'extras', 'google', 'instantapps', 'tools', 'ia.jar'))
|
||||
if self._launch_url:
|
||||
adb_install = "java -jar %s run -u %s %s" % (ia_path, self._launch_url, apk_path)
|
||||
else:
|
||||
adb_install = "java -jar %s run %s" % (ia_path, apk_path)
|
||||
else:
|
||||
adb_path = cocos.CMDRunner.convert_path_to_cmd(os.path.join(sdk_root, 'platform-tools', 'adb'))
|
||||
# do uninstall only when that app is installed
|
||||
if cocos.app_is_installed(adb_path, self.package):
|
||||
adb_uninstall= "%s uninstall %s" % (adb_path, self.package)
|
||||
self._run_cmd(adb_uninstall)
|
||||
adb_install = "%s install -r \"%s\"" % (adb_path, apk_path)
|
||||
self._run_cmd(adb_install)
|
||||
|
||||
def get_filename_by_extention(self, ext, path):
|
||||
filelist = os.listdir(path)
|
||||
|
||||
for fname in filelist:
|
||||
name, extention = os.path.splitext(fname)
|
||||
if extention == ext:
|
||||
return fname
|
||||
return None
|
||||
|
||||
def run(self, argv, dependencies):
|
||||
self.parse_args(argv)
|
||||
cocos.Logging.info(MultiLanguage.get_string('DEPLOY_INFO_MODE_FMT', self._mode))
|
||||
self.deploy_ios(dependencies)
|
||||
self.deploy_mac(dependencies)
|
||||
self.deploy_android(dependencies)
|
||||
self.deploy_web(dependencies)
|
||||
self.deploy_win32(dependencies)
|
||||
self.deploy_linux(dependencies)
|
||||
self.deploy_wp8(dependencies)
|
||||
94
cocos2d-x/tools/cocos2d-console/plugins/plugin_dist.py
Normal file
@@ -0,0 +1,94 @@
|
||||
#!/usr/bin/python
|
||||
# ----------------------------------------------------------------------------
|
||||
# cocos2d "dist" plugin
|
||||
#
|
||||
# Copyright 2014 (C) Luis Parravicini
|
||||
#
|
||||
# License: MIT
|
||||
# ----------------------------------------------------------------------------
|
||||
'''
|
||||
"dist" plugin for cocos2d command line tool
|
||||
'''
|
||||
|
||||
__docformat__ = 'restructuredtext'
|
||||
|
||||
import re
|
||||
import os
|
||||
import cocos2d
|
||||
|
||||
class CCPluginDist(cocos2d.CCPlugin):
|
||||
"""
|
||||
builds a project for distribution
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
def plugin_name():
|
||||
return "dist"
|
||||
|
||||
@staticmethod
|
||||
def brief_description():
|
||||
return "builds a project for distribution"
|
||||
|
||||
def init(self, options, working_dir):
|
||||
super(CCPluginDist, self).init(options, working_dir)
|
||||
|
||||
if self._platforms.is_ios_active():
|
||||
if not options.provisioning:
|
||||
raise cocos2d.CCPluginError("Provisioning profile is needed")
|
||||
else:
|
||||
self._provisioning = options.provisioning
|
||||
|
||||
def _add_custom_options(self, parser):
|
||||
parser.add_option("-f", "--provisioning",
|
||||
dest="provisioning",
|
||||
help="provisioning profile to use (needed for iOS distribution)")
|
||||
|
||||
def dist_android(self):
|
||||
if not self._platforms.is_android_active():
|
||||
return
|
||||
project_dir = self._platforms.project_path()
|
||||
|
||||
raise cocos2d.CCPluginError("unimplemented")
|
||||
|
||||
def _find_ios_scheme(self, project_dir):
|
||||
out = self._output_for("cd \"%s\" && xcodebuild -list" % project_dir)
|
||||
|
||||
match = re.search('Schemes:(.*)', out, re.DOTALL)
|
||||
if match is None:
|
||||
raise cocos2d.CCPluginError("Couldn't find the schemes list")
|
||||
|
||||
schemes = match.group(1).split()
|
||||
if len(schemes) == 0:
|
||||
raise cocos2d.CCPluginError("Couldn't find a scheme")
|
||||
|
||||
return schemes[0]
|
||||
|
||||
|
||||
@staticmethod
|
||||
def target_path(project_dir):
|
||||
return os.path.join(project_dir, '..', 'target')
|
||||
|
||||
def dist_ios(self):
|
||||
if not self._platforms.is_ios_active():
|
||||
return
|
||||
project_dir = self._platforms.project_path()
|
||||
|
||||
scheme = self._find_ios_scheme(project_dir)
|
||||
cocos2d.Logging.info("using scheme %s" % scheme)
|
||||
|
||||
archive_path = os.path.join(CCPluginDist.target_path(project_dir), scheme + '.xcarchive')
|
||||
cocos2d.Logging.info("archiving")
|
||||
self._run_cmd("cd '%s' && xcodebuild -scheme '%s' -archivePath '%s' archive" % (project_dir, scheme, archive_path))
|
||||
|
||||
cocos2d.Logging.info("exporting archive")
|
||||
ipa_path = os.path.join(os.path.dirname(archive_path), scheme + '.ipa')
|
||||
if os.path.exists(ipa_path):
|
||||
os.remove(ipa_path)
|
||||
self._run_cmd("cd '%s' && xcodebuild -exportArchive -exportFormat IPA -archivePath '%s' -exportPath '%s' -exportProvisioningProfile '%s'" % (project_dir, archive_path, ipa_path, self._provisioning))
|
||||
cocos2d.Logging.info("\nThe ipa was created at:\n%s" % os.path.abspath(ipa_path))
|
||||
cocos2d.Logging.info("\nNow you can use 'Application Loader' to submit the .ipa\n")
|
||||
|
||||
def run(self, argv, dependencies):
|
||||
self.parse_args(argv)
|
||||
self.dist_android()
|
||||
self.dist_ios()
|
||||
@@ -0,0 +1,2 @@
|
||||
|
||||
from plugin_framework import CCPluginFramework
|
||||
@@ -0,0 +1,31 @@
|
||||
|
||||
import cocos
|
||||
from MultiLanguage import MultiLanguage
|
||||
|
||||
from package.helper import ProjectHelper
|
||||
|
||||
|
||||
class FrameworkAdd(cocos.CCPlugin):
|
||||
@staticmethod
|
||||
def plugin_name():
|
||||
return "add-framework"
|
||||
|
||||
@staticmethod
|
||||
def brief_description():
|
||||
return MultiLanguage.get_string('FRAMEWORK_ADD_BRIEF')
|
||||
|
||||
# parse arguments
|
||||
def parse_args(self, argv):
|
||||
from argparse import ArgumentParser
|
||||
|
||||
parser = ArgumentParser(prog="cocos %s" % self.__class__.plugin_name(),
|
||||
description=self.__class__.brief_description())
|
||||
parser.add_argument("name", metavar="NAME", help=MultiLanguage.get_string('FRAMEWORK_ADD_ARG_NAME'))
|
||||
return parser.parse_args(argv)
|
||||
|
||||
def run(self, argv):
|
||||
args = self.parse_args(argv)
|
||||
name = args.name
|
||||
|
||||
project = ProjectHelper.get_current_project()
|
||||
ProjectHelper.add_framework(project, name)
|
||||
@@ -0,0 +1,31 @@
|
||||
|
||||
import cocos
|
||||
from MultiLanguage import MultiLanguage
|
||||
|
||||
from package.helper import ProjectHelper
|
||||
|
||||
|
||||
class FrameworkCreate(cocos.CCPlugin):
|
||||
@staticmethod
|
||||
def plugin_name():
|
||||
return "create-framework"
|
||||
|
||||
@staticmethod
|
||||
def brief_description():
|
||||
return MultiLanguage.get_string('FRAMEWORK_CREATE_BRIEF')
|
||||
|
||||
# parse arguments
|
||||
def parse_args(self, argv):
|
||||
from argparse import ArgumentParser
|
||||
|
||||
parser = ArgumentParser(prog="cocos %s" % self.__class__.plugin_name(),
|
||||
description=self.__class__.brief_description())
|
||||
parser.add_argument("name", metavar="NAME", help=MultiLanguage.get_string('FRAMEWORK_CREATE_ARG_NAME'))
|
||||
return parser.parse_args(argv)
|
||||
|
||||
def run(self, argv):
|
||||
args = self.parse_args(argv)
|
||||
name = args.name
|
||||
|
||||
project = ProjectHelper.get_current_project()
|
||||
ProjectHelper.create_framework(project, name)
|
||||
@@ -0,0 +1,31 @@
|
||||
|
||||
import cocos
|
||||
from MultiLanguage import MultiLanguage
|
||||
|
||||
from package.helper import ProjectHelper
|
||||
|
||||
|
||||
class FrameworkRemove(cocos.CCPlugin):
|
||||
@staticmethod
|
||||
def plugin_name():
|
||||
return "remove-framework"
|
||||
|
||||
@staticmethod
|
||||
def brief_description():
|
||||
return MultiLanguage.get_string('FRAMEWORK_REMOVE_BRIEF')
|
||||
|
||||
# parse arguments
|
||||
def parse_args(self, argv):
|
||||
from argparse import ArgumentParser
|
||||
|
||||
parser = ArgumentParser(prog="cocos %s" % self.__class__.plugin_name(),
|
||||
description=self.__class__.brief_description())
|
||||
parser.add_argument("name", metavar="NAME", help=MultiLanguage.get_string('FRAMEWORK_REMOVE_ARG_NAME'))
|
||||
return parser.parse_args(argv)
|
||||
|
||||
def run(self, argv):
|
||||
args = self.parse_args(argv)
|
||||
name = args.name
|
||||
|
||||
project = ProjectHelper.get_current_project()
|
||||
ProjectHelper.remove_framework(project, name)
|
||||
@@ -0,0 +1,31 @@
|
||||
|
||||
import cocos
|
||||
from MultiLanguage import MultiLanguage
|
||||
|
||||
from package.helper import ProjectHelper
|
||||
|
||||
|
||||
class FrameworkSet(cocos.CCPlugin):
|
||||
@staticmethod
|
||||
def plugin_name():
|
||||
return "set-framework"
|
||||
|
||||
@staticmethod
|
||||
def brief_description():
|
||||
return MultiLanguage.get_string('FRAMEWORK_SET_BRIEF')
|
||||
|
||||
# parse arguments
|
||||
def parse_args(self, argv):
|
||||
from argparse import ArgumentParser
|
||||
|
||||
parser = ArgumentParser(prog="cocos %s" % self.__class__.plugin_name(),
|
||||
description=self.__class__.brief_description())
|
||||
parser.add_argument("name", metavar="NAME", help=MultiLanguage.get_string('FRAMEWORK_SET_ARG_NAME'))
|
||||
return parser.parse_args(argv)
|
||||
|
||||
def run(self, argv):
|
||||
args = self.parse_args(argv)
|
||||
name = args.name
|
||||
|
||||
project = ProjectHelper.get_current_project()
|
||||
ProjectHelper.set_framework(project, name, "1.0")
|
||||
@@ -0,0 +1,31 @@
|
||||
|
||||
import cocos
|
||||
from MultiLanguage import MultiLanguage
|
||||
|
||||
from package.helper import ProjectHelper
|
||||
|
||||
|
||||
class FrameworkUpdate(cocos.CCPlugin):
|
||||
@staticmethod
|
||||
def plugin_name():
|
||||
return "update-framework"
|
||||
|
||||
@staticmethod
|
||||
def brief_description():
|
||||
return MultiLanguage.get_string('FRAMEWORK_UPDATE_BRIEF')
|
||||
|
||||
# parse arguments
|
||||
def parse_args(self, argv):
|
||||
from argparse import ArgumentParser
|
||||
|
||||
parser = ArgumentParser(prog="cocos %s" % self.__class__.plugin_name(),
|
||||
description=self.__class__.brief_description())
|
||||
parser.add_argument("name", metavar="NAME", help=MultiLanguage.get_string('FRAMEWORK_UPDATE_ARG_NAME'))
|
||||
return parser.parse_args(argv)
|
||||
|
||||
def run(self, argv):
|
||||
args = self.parse_args(argv)
|
||||
name = args.name
|
||||
|
||||
project = ProjectHelper.get_current_project()
|
||||
ProjectHelper.update_framework(project, name)
|
||||
@@ -0,0 +1,62 @@
|
||||
# ----------------------------------------------------------------------------
|
||||
# cocos "package" plugin
|
||||
#
|
||||
# Copyright 2014 (C) cocos2d-x.org
|
||||
#
|
||||
# License: MIT
|
||||
# ----------------------------------------------------------------------------
|
||||
'''
|
||||
"framework" plugins
|
||||
'''
|
||||
|
||||
__docformat__ = 'restructuredtext'
|
||||
|
||||
import cocos
|
||||
from MultiLanguage import MultiLanguage
|
||||
|
||||
|
||||
class CCPluginFramework(cocos.CCPlugin):
|
||||
@staticmethod
|
||||
def plugin_name():
|
||||
return "framework"
|
||||
|
||||
@staticmethod
|
||||
def brief_description():
|
||||
return MultiLanguage.get_string('FRAMEWORK_BRIEF')
|
||||
|
||||
def parse_args(self, argv):
|
||||
if len(argv) < 1:
|
||||
print "usage: cocos framework [-h] COMMAND arg [arg ...]"
|
||||
print MultiLanguage.get_string('FRAMEWORK_ERROR_TOO_FEW_ARGS')
|
||||
return None
|
||||
|
||||
return {"command": argv[0]}
|
||||
|
||||
def run(self, argv, dependencies):
|
||||
args = self.parse_args(argv)
|
||||
if args is None:
|
||||
return
|
||||
|
||||
command = args["command"]
|
||||
|
||||
if command == "add":
|
||||
from framework_add import FrameworkAdd
|
||||
CommandClass = FrameworkAdd
|
||||
elif command == "remove":
|
||||
from framework_remove import FrameworkRemove
|
||||
CommandClass = FrameworkRemove
|
||||
elif command == "update":
|
||||
from framework_update import FrameworkUpdate
|
||||
CommandClass = FrameworkUpdate
|
||||
elif command == "create":
|
||||
from framework_create import FrameworkCreate
|
||||
CommandClass = FrameworkCreate
|
||||
elif command == "set":
|
||||
from framework_set import FrameworkSet
|
||||
CommandClass = FrameworkSet
|
||||
else:
|
||||
message = MultiLanguage.get_string('FRAMEWORK_ERROR_INVALID_CMD_FMT', command)
|
||||
raise cocos.CCPluginError(message, cocos.CCPluginError.ERROR_CMD_NOT_FOUND)
|
||||
|
||||
commandObject = CommandClass()
|
||||
commandObject.run(argv[1:])
|
||||
@@ -0,0 +1,3 @@
|
||||
from gen_libs import LibsCompiler
|
||||
from gen_simulator import SimulatorCompiler
|
||||
from gen_templates import TemplateGenerator
|
||||
@@ -0,0 +1,67 @@
|
||||
#include "AppDelegate.h"
|
||||
#include "HelloWorldScene.h"
|
||||
|
||||
USING_NS_CC;
|
||||
|
||||
AppDelegate::AppDelegate() {
|
||||
|
||||
}
|
||||
|
||||
AppDelegate::~AppDelegate()
|
||||
{
|
||||
}
|
||||
|
||||
//if you want a different context,just modify the value of glContextAttrs
|
||||
//it will takes effect on all platforms
|
||||
void AppDelegate::initGLContextAttrs()
|
||||
{
|
||||
//set OpenGL context attributions,now can only set six attributions:
|
||||
//red,green,blue,alpha,depth,stencil
|
||||
GLContextAttrs glContextAttrs = {8, 8, 8, 8, 24, 8};
|
||||
|
||||
GLView::setGLContextAttrs(glContextAttrs);
|
||||
}
|
||||
|
||||
bool AppDelegate::applicationDidFinishLaunching() {
|
||||
// initialize director
|
||||
auto director = Director::getInstance();
|
||||
auto glview = director->getOpenGLView();
|
||||
if(!glview) {
|
||||
glview = GLViewImpl::createWithRect("HelloCpp", Rect(0, 0, 960, 640));
|
||||
director->setOpenGLView(glview);
|
||||
}
|
||||
|
||||
director->getOpenGLView()->setDesignResolutionSize(960, 640, ResolutionPolicy::SHOW_ALL);
|
||||
|
||||
// turn on display FPS
|
||||
director->setDisplayStats(true);
|
||||
|
||||
// set FPS. the default value is 1.0/60 if you don't call this
|
||||
director->setAnimationInterval(1.0 / 60);
|
||||
|
||||
FileUtils::getInstance()->addSearchPath("res");
|
||||
|
||||
// create a scene. it's an autorelease object
|
||||
auto scene = HelloWorld::createScene();
|
||||
|
||||
// run
|
||||
director->runWithScene(scene);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// This function will be called when the app is inactive. When comes a phone call,it's be invoked too
|
||||
void AppDelegate::applicationDidEnterBackground() {
|
||||
Director::getInstance()->stopAnimation();
|
||||
|
||||
// if you use SimpleAudioEngine, it must be pause
|
||||
// SimpleAudioEngine::getInstance()->pauseBackgroundMusic();
|
||||
}
|
||||
|
||||
// this function will be called when the app is active again
|
||||
void AppDelegate::applicationWillEnterForeground() {
|
||||
Director::getInstance()->startAnimation();
|
||||
|
||||
// if you use SimpleAudioEngine, it must resume here
|
||||
// SimpleAudioEngine::getInstance()->resumeBackgroundMusic();
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
#include "HelloWorldScene.h"
|
||||
#include "cocostudio/CocoStudio.h"
|
||||
#include "ui/CocosGUI.h"
|
||||
|
||||
USING_NS_CC;
|
||||
|
||||
using namespace cocostudio::timeline;
|
||||
|
||||
Scene* HelloWorld::createScene()
|
||||
{
|
||||
// 'scene' is an autorelease object
|
||||
auto scene = Scene::create();
|
||||
|
||||
// 'layer' is an autorelease object
|
||||
auto layer = HelloWorld::create();
|
||||
|
||||
// add layer as a child to scene
|
||||
scene->addChild(layer);
|
||||
|
||||
// return the scene
|
||||
return scene;
|
||||
}
|
||||
|
||||
// on "init" you need to initialize your instance
|
||||
bool HelloWorld::init()
|
||||
{
|
||||
/** you can create scene with following comment code instead of using csb file.
|
||||
// 1. super init first
|
||||
if ( !Layer::init() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Size visibleSize = Director::getInstance()->getVisibleSize();
|
||||
Vec2 origin = Director::getInstance()->getVisibleOrigin();
|
||||
|
||||
/////////////////////////////
|
||||
// 2. add a menu item with "X" image, which is clicked to quit the program
|
||||
// you may modify it.
|
||||
|
||||
// add a "close" icon to exit the progress. it's an autorelease object
|
||||
auto closeItem = MenuItemImage::create(
|
||||
"CloseNormal.png",
|
||||
"CloseSelected.png",
|
||||
CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));
|
||||
|
||||
closeItem->setPosition(Vec2(origin.x + visibleSize.width - closeItem->getContentSize().width/2 ,
|
||||
origin.y + closeItem->getContentSize().height/2));
|
||||
|
||||
// create menu, it's an autorelease object
|
||||
auto menu = Menu::create(closeItem, NULL);
|
||||
menu->setPosition(Vec2::ZERO);
|
||||
this->addChild(menu, 1);
|
||||
|
||||
/////////////////////////////
|
||||
// 3. add your codes below...
|
||||
|
||||
// add a label shows "Hello World"
|
||||
// create and initialize a label
|
||||
|
||||
auto label = Label::createWithTTF("Hello World", "fonts/Marker Felt.ttf", 24);
|
||||
|
||||
// position the label on the center of the screen
|
||||
label->setPosition(Vec2(origin.x + visibleSize.width/2,
|
||||
origin.y + visibleSize.height - label->getContentSize().height));
|
||||
|
||||
// add the label as a child to this layer
|
||||
this->addChild(label, 1);
|
||||
|
||||
// add "HelloWorld" splash screen"
|
||||
auto sprite = Sprite::create("HelloWorld.png");
|
||||
|
||||
// position the sprite on the center of the screen
|
||||
sprite->setPosition(Vec2(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y));
|
||||
|
||||
// add the sprite as a child to this layer
|
||||
this->addChild(sprite, 0);
|
||||
**/
|
||||
|
||||
//////////////////////////////
|
||||
// 1. super init first
|
||||
if ( !Layer::init() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
auto rootNode = CSLoader::createNode("MainScene.csb");
|
||||
|
||||
addChild(rootNode);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#ifndef __HELLOWORLD_SCENE_H__
|
||||
#define __HELLOWORLD_SCENE_H__
|
||||
|
||||
#include "cocos2d.h"
|
||||
|
||||
class HelloWorld : public cocos2d::Layer
|
||||
{
|
||||
public:
|
||||
// there's no 'id' in cpp, so we recommend returning the class instance pointer
|
||||
static cocos2d::Scene* createScene();
|
||||
|
||||
// Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone
|
||||
virtual bool init();
|
||||
|
||||
// implement the "static create()" method manually
|
||||
CREATE_FUNC(HelloWorld);
|
||||
};
|
||||
|
||||
#endif // __HELLOWORLD_SCENE_H__
|
||||
@@ -0,0 +1,110 @@
|
||||
{
|
||||
"do_default":{
|
||||
"exclude_from_template": [
|
||||
"res-landscape",
|
||||
"res-portrait"
|
||||
],
|
||||
"append_from_template": {
|
||||
"from": "res-landscape",
|
||||
"to": ""
|
||||
},
|
||||
"project_rename":{
|
||||
"src_project_name":"HelloCpp",
|
||||
"files":[
|
||||
"proj.win32/PROJECT_NAME.vcxproj",
|
||||
"proj.win32/PROJECT_NAME.vcxproj.filters",
|
||||
"proj.win32/PROJECT_NAME.vcxproj.user",
|
||||
"proj.win32/PROJECT_NAME.sln",
|
||||
"proj.ios_mac/PROJECT_NAME.xcodeproj",
|
||||
"PROJECT_NAME.ccs",
|
||||
"PROJECT_NAME.cfg",
|
||||
"PROJECT_NAME.udf"
|
||||
]
|
||||
},
|
||||
"project_replace_project_name":{
|
||||
"src_project_name":"HelloCpp",
|
||||
"files":[
|
||||
"Classes/AppDelegate.cpp",
|
||||
"proj.win32/PROJECT_NAME.vcxproj",
|
||||
"proj.win32/PROJECT_NAME.vcxproj.filters",
|
||||
"proj.win32/PROJECT_NAME.vcxproj.user",
|
||||
"proj.win32/PROJECT_NAME.sln",
|
||||
"PROJECT_NAME.ccs",
|
||||
"proj.win32/main.cpp",
|
||||
"proj.android/.project",
|
||||
"proj.android/.cproject",
|
||||
"proj.android/AndroidManifest.xml",
|
||||
"proj.android/build.xml",
|
||||
"proj.android/res/values/strings.xml",
|
||||
"proj.ios_mac/ios/main.m",
|
||||
"proj.ios_mac/ios/Prefix.pch",
|
||||
"proj.ios_mac/PROJECT_NAME.xcodeproj/project.pbxproj"
|
||||
]
|
||||
},
|
||||
"project_replace_package_name":{
|
||||
"src_package_name":"org.cocos2dx.hellocpp",
|
||||
"files":[
|
||||
"proj.android/AndroidManifest.xml"
|
||||
]
|
||||
},
|
||||
"project_replace_mac_bundleid": {
|
||||
"src_bundle_id": "org.cocos2dx.hellocpp",
|
||||
"files": [
|
||||
"proj.ios_mac/mac/Info.plist"
|
||||
]
|
||||
},
|
||||
"project_replace_ios_bundleid": {
|
||||
"src_bundle_id": "org.cocos2dx.hellocpp",
|
||||
"files": [
|
||||
"proj.ios_mac/ios/Info.plist"
|
||||
]
|
||||
}
|
||||
},
|
||||
"change_orientation": {
|
||||
"append_from_template": {
|
||||
"from": "res-portrait",
|
||||
"to": ""
|
||||
},
|
||||
"modify_files": [
|
||||
{
|
||||
"file_path": "Classes/AppDelegate.cpp",
|
||||
"pattern": "GLViewImpl::createWithRect\\((.*),\\s*Rect\\(\\s*(\\d+),\\s*(\\d+),\\s*(\\d+),\\s*(\\d+)\\)\\)",
|
||||
"replace_string": "GLViewImpl::createWithRect(\\1, Rect(\\2, \\3, \\5, \\4))"
|
||||
},
|
||||
{
|
||||
"file_path": "Classes/AppDelegate.cpp",
|
||||
"pattern": "setDesignResolutionSize\\(\\s*(\\d+),\\s*(\\d+),(.*)\\)",
|
||||
"replace_string": "setDesignResolutionSize(\\2, \\1,\\3)"
|
||||
},
|
||||
{
|
||||
"file_path": "proj.ios_mac/ios/Info.plist",
|
||||
"pattern": "UIInterfaceOrientationLandscapeRight",
|
||||
"replace_string": "UIInterfaceOrientationPortrait"
|
||||
},
|
||||
{
|
||||
"file_path": "proj.ios_mac/ios/Info.plist",
|
||||
"pattern": "UIInterfaceOrientationLandscapeLeft",
|
||||
"replace_string": "UIInterfaceOrientationPortraitUpsideDown"
|
||||
},
|
||||
{
|
||||
"file_path": "proj.android/AndroidManifest.xml",
|
||||
"pattern": "android:screenOrientation=\\\".*\\\"",
|
||||
"replace_string": "android:screenOrientation=\"portrait\""
|
||||
}
|
||||
],
|
||||
"project_rename":{
|
||||
"src_project_name":"HelloCpp",
|
||||
"files":[
|
||||
"PROJECT_NAME.ccs",
|
||||
"PROJECT_NAME.cfg",
|
||||
"PROJECT_NAME.udf"
|
||||
]
|
||||
},
|
||||
"project_replace_project_name":{
|
||||
"src_project_name":"HelloCpp",
|
||||
"files":[
|
||||
"PROJECT_NAME.ccs"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 2013
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HelloCpp", "HelloCpp.vcxproj", "{76A39BB2-9B84-4C65-98A5-654D86B86F2A}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{76A39BB2-9B84-4C65-98A5-654D86B86F2A}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{76A39BB2-9B84-4C65-98A5-654D86B86F2A}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{76A39BB2-9B84-4C65-98A5-654D86B86F2A}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{76A39BB2-9B84-4C65-98A5-654D86B86F2A}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,11 @@
|
||||
<Solution>
|
||||
<PropertyGroup Name="HelloCpp" Version="2.1.0.0" Type="CocosStudio" />
|
||||
<SolutionFolder>
|
||||
<Group ctype="ResourceGroup">
|
||||
<RootFolder Name=".">
|
||||
<Project Name="MainScene.csd" />
|
||||
<Image Name="HelloWorld.png" />
|
||||
</RootFolder>
|
||||
</Group>
|
||||
</SolutionFolder>
|
||||
</Solution>
|
||||
@@ -0,0 +1 @@
|
||||
<Properties PublishDirectory="Resources/res" SolutionSize="960 * 640" DefaultSerializer="Serializer_FlatBuffers" CustomSerializer="Serializer_FlatBuffers" />
|
||||
@@ -0,0 +1,6 @@
|
||||
<UserData>
|
||||
<OpenedDocuments>
|
||||
<FilePathData Path="MainScene.csd" />
|
||||
</OpenedDocuments>
|
||||
<ActiveDocument Path="MainScene.csd" />
|
||||
</UserData>
|
||||
|
After Width: | Height: | Size: 208 KiB |
|
After Width: | Height: | Size: 208 KiB |
@@ -0,0 +1,29 @@
|
||||
<GameProjectFile>
|
||||
<PropertyGroup Type="Scene" Name="MainScene" ID="a2ee0952-26b5-49ae-8bf9-4f1d6279b798" Version="2.1.0.0" />
|
||||
<Content ctype="GameProjectContent">
|
||||
<Content>
|
||||
<Animation Duration="0" Speed="1.0000" />
|
||||
<ObjectData Name="Scene" FrameEvent="" RightMargin="-960.0000" TopMargin="-640.0000" ctype="SingleNodeObjectData">
|
||||
<Position X="0.0000" Y="0.0000" />
|
||||
<Scale ScaleX="1.0000" ScaleY="1.0000" />
|
||||
<AnchorPoint />
|
||||
<CColor A="255" R="255" G="255" B="255" />
|
||||
<Size X="960.0000" Y="640.0000" />
|
||||
<PrePosition X="0.0000" Y="0.0000" />
|
||||
<PreSize X="0.0000" Y="0.0000" />
|
||||
<Children>
|
||||
<NodeObjectData Name="Default" ActionTag="953446860" FrameEvent="" Tag="5" ObjectIndex="2" ctype="SpriteObjectData">
|
||||
<Position X="480.0000" Y="320.0000" />
|
||||
<Scale ScaleX="1.0000" ScaleY="1.0000" />
|
||||
<AnchorPoint ScaleX="0.5000" ScaleY="0.5000" />
|
||||
<CColor A="255" R="255" G="255" B="255" />
|
||||
<Size X="960.0000" Y="640.0000" />
|
||||
<PrePosition X="0.5000" Y="0.5000" />
|
||||
<PreSize X="0.0000" Y="0.0000" />
|
||||
<FileData Type="Normal" Path="HelloWorld.png" />
|
||||
</NodeObjectData>
|
||||
</Children>
|
||||
</ObjectData>
|
||||
</Content>
|
||||
</Content>
|
||||
</GameProjectFile>
|
||||
@@ -0,0 +1,11 @@
|
||||
<Solution>
|
||||
<PropertyGroup Name="HelloCpp" Version="2.1.0.0" Type="CocosStudio" />
|
||||
<SolutionFolder>
|
||||
<Group ctype="ResourceGroup">
|
||||
<RootFolder Name=".">
|
||||
<Project Name="MainScene.csd" />
|
||||
<Image Name="HelloWorld.png" />
|
||||
</RootFolder>
|
||||
</Group>
|
||||
</SolutionFolder>
|
||||
</Solution>
|
||||
@@ -0,0 +1 @@
|
||||
<Properties publishHasCocos2dxCode="False" PublishDirectory="Resources/res" SolutionSize="640 * 960" DefaultSerializer="Serializer_FlatBuffers" CustomSerializer="Serializer_FlatBuffers" />
|
||||
@@ -0,0 +1,6 @@
|
||||
<UserData>
|
||||
<OpenedDocuments>
|
||||
<FilePathData Path="MainScene.csd" />
|
||||
</OpenedDocuments>
|
||||
<ActiveDocument Path="MainScene.csd" />
|
||||
</UserData>
|
||||
|
After Width: | Height: | Size: 80 KiB |
|
After Width: | Height: | Size: 80 KiB |
@@ -0,0 +1,29 @@
|
||||
<GameProjectFile>
|
||||
<PropertyGroup Type="Scene" Name="MainScene" ID="a2ee0952-26b5-49ae-8bf9-4f1d6279b798" Version="2.1.0.0" />
|
||||
<Content ctype="GameProjectContent">
|
||||
<Content>
|
||||
<Animation Duration="0" Speed="1.0000" />
|
||||
<ObjectData Name="Scene" FrameEvent="" ctype="SingleNodeObjectData">
|
||||
<Position X="0.0000" Y="0.0000" />
|
||||
<Scale ScaleX="1.0000" ScaleY="1.0000" />
|
||||
<AnchorPoint />
|
||||
<CColor A="255" R="255" G="255" B="255" />
|
||||
<Size X="640.0000" Y="960.0000" />
|
||||
<PrePosition X="0.0000" Y="0.0000" />
|
||||
<PreSize X="0.0000" Y="0.0000" />
|
||||
<Children>
|
||||
<NodeObjectData Name="Default" ActionTag="-620272433" FrameEvent="" Tag="5" ObjectIndex="3" ctype="SpriteObjectData">
|
||||
<Position X="320.0000" Y="480.0000" />
|
||||
<Scale ScaleX="1.0000" ScaleY="1.0000" />
|
||||
<AnchorPoint ScaleX="0.5000" ScaleY="0.5000" />
|
||||
<CColor A="255" R="255" G="255" B="255" />
|
||||
<Size X="640.0000" Y="960.0000" />
|
||||
<PrePosition X="0.5000" Y="0.5000" />
|
||||
<PreSize X="0.0000" Y="0.0000" />
|
||||
<FileData Type="Normal" Path="HelloWorld.png" />
|
||||
</NodeObjectData>
|
||||
</Children>
|
||||
</ObjectData>
|
||||
</Content>
|
||||
</Content>
|
||||
</GameProjectFile>
|
||||
|
After Width: | Height: | Size: 75 KiB |
|
After Width: | Height: | Size: 190 KiB |
|
After Width: | Height: | Size: 369 KiB |
|
After Width: | Height: | Size: 45 KiB |
|
After Width: | Height: | Size: 80 KiB |
@@ -0,0 +1,170 @@
|
||||
{
|
||||
"do_default":{
|
||||
"exclude_from_template":[
|
||||
"frameworks/runtime-src",
|
||||
"res-landscape",
|
||||
"res-portrait"
|
||||
],
|
||||
"append_from_template": {
|
||||
"from": "res-landscape",
|
||||
"to": ""
|
||||
},
|
||||
"project_rename": {
|
||||
"src_project_name": "HelloJavascript",
|
||||
"files": [
|
||||
"PROJECT_NAME.ccs",
|
||||
"PROJECT_NAME.cfg",
|
||||
"PROJECT_NAME.udf"
|
||||
]
|
||||
},
|
||||
"project_replace_project_name":{
|
||||
"src_project_name":"HelloJavascript",
|
||||
"files":[
|
||||
"config.json",
|
||||
".project",
|
||||
"PROJECT_NAME.ccs"
|
||||
]
|
||||
},
|
||||
"append_dir":[
|
||||
{
|
||||
"from": "cocos/scripting/js-bindings/script",
|
||||
"to": "script",
|
||||
"include": [
|
||||
"*.js"
|
||||
]
|
||||
},
|
||||
{
|
||||
"from": "web",
|
||||
"to": "frameworks/cocos2d-html5"
|
||||
}
|
||||
]
|
||||
},
|
||||
"do_add_native_support":{
|
||||
"append_from_template":{
|
||||
"from":"frameworks/runtime-src",
|
||||
"to":"frameworks/runtime-src",
|
||||
"exclude":[
|
||||
"proj.android/bin",
|
||||
"proj.android/assets",
|
||||
"proj.ios_mac/HelloJavascript.xcodeproj/project.xcworkspace",
|
||||
"proj.ios_mac/HelloJavascript.xcodeproj/xcuserdata",
|
||||
"proj.win32/Debug.win32",
|
||||
"proj.win32/Release.win32",
|
||||
"proj.win32/HelloJavascript.sdf"
|
||||
]
|
||||
},
|
||||
"append_dir":[
|
||||
{
|
||||
"from":"tools/bindings-generator",
|
||||
"to":"tools/bindings-generator",
|
||||
"exclude":[
|
||||
".git"
|
||||
]
|
||||
},
|
||||
{
|
||||
"from":"tools",
|
||||
"to":"tools",
|
||||
"include":[
|
||||
"tojs"
|
||||
]
|
||||
}
|
||||
],
|
||||
"project_rename":{
|
||||
"src_project_name":"HelloJavascript",
|
||||
"files":[
|
||||
"frameworks/runtime-src/proj.win32/PROJECT_NAME.vcxproj",
|
||||
"frameworks/runtime-src/proj.win32/PROJECT_NAME.vcxproj.filters",
|
||||
"frameworks/runtime-src/proj.win32/PROJECT_NAME.vcxproj.user",
|
||||
"frameworks/runtime-src/proj.win32/PROJECT_NAME.sln",
|
||||
"frameworks/runtime-src/proj.ios_mac/PROJECT_NAME.xcodeproj"
|
||||
]
|
||||
},
|
||||
"project_replace_project_name":{
|
||||
"src_project_name":"HelloJavascript",
|
||||
"files":[
|
||||
"config.json",
|
||||
".project",
|
||||
"frameworks/runtime-src/proj.win32/PROJECT_NAME.vcxproj",
|
||||
"frameworks/runtime-src/proj.win32/PROJECT_NAME.vcxproj.filters",
|
||||
"frameworks/runtime-src/proj.win32/PROJECT_NAME.vcxproj.user",
|
||||
"frameworks/runtime-src/proj.win32/PROJECT_NAME.sln",
|
||||
"frameworks/runtime-src/proj.win32/main.cpp",
|
||||
"frameworks/runtime-src/proj.android/.project",
|
||||
"frameworks/runtime-src/proj.android/AndroidManifest.xml",
|
||||
"frameworks/runtime-src/proj.android/build.xml",
|
||||
"frameworks/runtime-src/proj.android/res/values/strings.xml",
|
||||
"frameworks/runtime-src/proj.ios_mac/ios/main.m",
|
||||
"frameworks/runtime-src/proj.ios_mac/ios/Prefix.pch",
|
||||
"frameworks/runtime-src/proj.ios_mac/mac/SimulatorApp.mm",
|
||||
"frameworks/runtime-src/proj.ios_mac/PROJECT_NAME.xcodeproj/project.pbxproj",
|
||||
"frameworks/runtime-src/Classes/AppDelegate.cpp"
|
||||
]
|
||||
},
|
||||
"project_replace_package_name":{
|
||||
"src_package_name":"org.cocos2dx.hellojavascript",
|
||||
"files":[
|
||||
"frameworks/runtime-src/proj.android/AndroidManifest.xml"
|
||||
]
|
||||
},
|
||||
"project_replace_mac_bundleid":{
|
||||
"src_bundle_id":"org.cocos2dx.hellojavascript",
|
||||
"files":[
|
||||
"frameworks/runtime-src/proj.ios_mac/mac/Info.plist"
|
||||
]
|
||||
},
|
||||
"project_replace_ios_bundleid":{
|
||||
"src_bundle_id":"org.cocos2dx.hellojavascript",
|
||||
"files":[
|
||||
"frameworks/runtime-src/proj.ios_mac/ios/Info.plist"
|
||||
]
|
||||
}
|
||||
},
|
||||
"change_orientation": {
|
||||
"append_from_template": {
|
||||
"from": "res-portrait",
|
||||
"to": ""
|
||||
},
|
||||
"modify_files": [
|
||||
{
|
||||
"file_path": "config.json",
|
||||
"pattern": "\\\"isLandscape\\\"\\s*:.*,",
|
||||
"replace_string": "\"isLandscape\": false,"
|
||||
},
|
||||
{
|
||||
"file_path": "main.js",
|
||||
"pattern": "setDesignResolutionSize\\(\\s*(\\d+),\\s*(\\d+),(.*)\\)",
|
||||
"replace_string": "setDesignResolutionSize(\\2, \\1,\\3)"
|
||||
},
|
||||
{
|
||||
"file_path": "frameworks/runtime-src/proj.ios_mac/ios/Info.plist",
|
||||
"pattern": "UIInterfaceOrientationLandscapeRight",
|
||||
"replace_string": "UIInterfaceOrientationPortrait"
|
||||
},
|
||||
{
|
||||
"file_path": "frameworks/runtime-src/proj.ios_mac/ios/Info.plist",
|
||||
"pattern": "UIInterfaceOrientationLandscapeLeft",
|
||||
"replace_string": "UIInterfaceOrientationPortraitUpsideDown"
|
||||
},
|
||||
{
|
||||
"file_path": "frameworks/runtime-src/proj.android/AndroidManifest.xml",
|
||||
"pattern": "android:screenOrientation=\\\".*\\\"",
|
||||
"replace_string": "android:screenOrientation=\"portrait\""
|
||||
}
|
||||
],
|
||||
"project_rename":{
|
||||
"src_project_name":"HelloJavascript",
|
||||
"files":[
|
||||
"PROJECT_NAME.ccs",
|
||||
"PROJECT_NAME.cfg",
|
||||
"PROJECT_NAME.udf"
|
||||
]
|
||||
},
|
||||
"project_replace_project_name":{
|
||||
"src_project_name":"HelloJavascript",
|
||||
"files":[
|
||||
"PROJECT_NAME.ccs"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 2013
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HelloJavascript", "HelloJavascript.vcxproj", "{3B0B58B1-2734-488E-A542-ECEC11EB2455}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{3B0B58B1-2734-488E-A542-ECEC11EB2455}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{3B0B58B1-2734-488E-A542-ECEC11EB2455}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{3B0B58B1-2734-488E-A542-ECEC11EB2455}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{3B0B58B1-2734-488E-A542-ECEC11EB2455}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,11 @@
|
||||
<Solution>
|
||||
<PropertyGroup Name="HelloJavascript" Version="2.1.0.0" Type="CocosStudio" />
|
||||
<SolutionFolder>
|
||||
<Group ctype="ResourceGroup">
|
||||
<RootFolder Name=".">
|
||||
<Project Name="MainScene.csd" />
|
||||
<Image Name="HelloWorld.png" />
|
||||
</RootFolder>
|
||||
</Group>
|
||||
</SolutionFolder>
|
||||
</Solution>
|
||||
@@ -0,0 +1 @@
|
||||
<Properties PublishDirectory="res" SolutionSize="960 * 640" DefaultSerializer="Serializer_FlatBuffers" CustomSerializer="Serializer_FlatBuffers" />
|
||||
@@ -0,0 +1,6 @@
|
||||
<UserData>
|
||||
<OpenedDocuments>
|
||||
<FilePathData Path="MainScene.csd" />
|
||||
</OpenedDocuments>
|
||||
<ActiveDocument Path="MainScene.csd" />
|
||||
</UserData>
|
||||
|
After Width: | Height: | Size: 208 KiB |
@@ -0,0 +1,29 @@
|
||||
<GameProjectFile>
|
||||
<PropertyGroup Type="Scene" Name="MainScene" ID="a2ee0952-26b5-49ae-8bf9-4f1d6279b798" Version="2.1.0.0" />
|
||||
<Content ctype="GameProjectContent">
|
||||
<Content>
|
||||
<Animation Duration="0" Speed="1.0000" />
|
||||
<ObjectData Name="Scene" FrameEvent="" RightMargin="-960.0000" TopMargin="-640.0000" ctype="SingleNodeObjectData">
|
||||
<Position X="0.0000" Y="0.0000" />
|
||||
<Scale ScaleX="1.0000" ScaleY="1.0000" />
|
||||
<AnchorPoint />
|
||||
<CColor A="255" R="255" G="255" B="255" />
|
||||
<Size X="960.0000" Y="640.0000" />
|
||||
<PrePosition X="0.0000" Y="0.0000" />
|
||||
<PreSize X="0.0000" Y="0.0000" />
|
||||
<Children>
|
||||
<NodeObjectData Name="Default" ActionTag="953446860" FrameEvent="" Tag="5" ObjectIndex="2" ctype="SpriteObjectData">
|
||||
<Position X="480.0000" Y="320.0000" />
|
||||
<Scale ScaleX="1.0000" ScaleY="1.0000" />
|
||||
<AnchorPoint ScaleX="0.5000" ScaleY="0.5000" />
|
||||
<CColor A="255" R="255" G="255" B="255" />
|
||||
<Size X="960.0000" Y="640.0000" />
|
||||
<PrePosition X="0.5000" Y="0.5000" />
|
||||
<PreSize X="0.0000" Y="0.0000" />
|
||||
<FileData Type="Normal" Path="HelloWorld.png" />
|
||||
</NodeObjectData>
|
||||
</Children>
|
||||
</ObjectData>
|
||||
</Content>
|
||||
</Content>
|
||||
</GameProjectFile>
|
||||
|
After Width: | Height: | Size: 208 KiB |
@@ -0,0 +1,85 @@
|
||||
{
|
||||
"ID": "a2ee0952-26b5-49ae-8bf9-4f1d6279b798",
|
||||
"Version": "2.1.0.0",
|
||||
"Type": "Scene",
|
||||
"Name": "MainScene",
|
||||
"Content": {
|
||||
"Content": {
|
||||
"Animation": {
|
||||
"Duration": 0,
|
||||
"Speed": 1.0,
|
||||
"Timelines": [],
|
||||
"ctype": "TimelineActionData"
|
||||
},
|
||||
"AnimationList": [],
|
||||
"ObjectData": {
|
||||
"PrePosition": {
|
||||
"X": 0.0,
|
||||
"Y": 0.0
|
||||
},
|
||||
"PreSize": {
|
||||
"X": 0.0,
|
||||
"Y": 0.0
|
||||
},
|
||||
"RightMargin": -960.0,
|
||||
"TopMargin": -640.0,
|
||||
"Children": [
|
||||
{
|
||||
"FileData": {
|
||||
"Type": "Normal",
|
||||
"Path": "HelloWorld.png"
|
||||
},
|
||||
"Tag": 5,
|
||||
"PrePosition": {
|
||||
"X": 0.5,
|
||||
"Y": 0.5
|
||||
},
|
||||
"PreSize": {
|
||||
"X": 0.0,
|
||||
"Y": 0.0
|
||||
},
|
||||
"ActionTag": 953446860,
|
||||
"Position": {
|
||||
"X": 480.0,
|
||||
"Y": 320.0
|
||||
},
|
||||
"Scale": {
|
||||
"ScaleX": 1.0,
|
||||
"ScaleY": 1.0
|
||||
},
|
||||
"AnchorPoint": {
|
||||
"ScaleX": 0.5,
|
||||
"ScaleY": 0.5
|
||||
},
|
||||
"CColor": {},
|
||||
"Size": {
|
||||
"X": 960.0,
|
||||
"Y": 640.0
|
||||
},
|
||||
"FrameEvent": "",
|
||||
"Name": "Default",
|
||||
"ctype": "SpriteObjectData"
|
||||
}
|
||||
],
|
||||
"Position": {
|
||||
"X": 0.0,
|
||||
"Y": 0.0
|
||||
},
|
||||
"Scale": {
|
||||
"ScaleX": 1.0,
|
||||
"ScaleY": 1.0
|
||||
},
|
||||
"AnchorPoint": {},
|
||||
"CColor": {},
|
||||
"Size": {
|
||||
"X": 960.0,
|
||||
"Y": 640.0
|
||||
},
|
||||
"FrameEvent": "",
|
||||
"Name": "Scene",
|
||||
"ctype": "SingleNodeObjectData"
|
||||
},
|
||||
"ctype": "GameProjectData"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<Solution>
|
||||
<PropertyGroup Name="HelloJavascript" Version="2.1.0.0" Type="CocosStudio" />
|
||||
<SolutionFolder>
|
||||
<Group ctype="ResourceGroup">
|
||||
<RootFolder Name=".">
|
||||
<Project Name="MainScene.csd" />
|
||||
<Image Name="HelloWorld.png" />
|
||||
</RootFolder>
|
||||
</Group>
|
||||
</SolutionFolder>
|
||||
</Solution>
|
||||
@@ -0,0 +1 @@
|
||||
<Properties publishHasCocos2dxCode="False" PublishDirectory="res" SolutionSize="640 * 960" DefaultSerializer="Serializer_FlatBuffers" CustomSerializer="Serializer_FlatBuffers" />
|
||||
@@ -0,0 +1,6 @@
|
||||
<UserData>
|
||||
<OpenedDocuments>
|
||||
<FilePathData Path="MainScene.csd" />
|
||||
</OpenedDocuments>
|
||||
<ActiveDocument Path="MainScene.csd" />
|
||||
</UserData>
|
||||
|
After Width: | Height: | Size: 80 KiB |
@@ -0,0 +1,29 @@
|
||||
<GameProjectFile>
|
||||
<PropertyGroup Type="Scene" Name="MainScene" ID="a2ee0952-26b5-49ae-8bf9-4f1d6279b798" Version="2.1.0.0" />
|
||||
<Content ctype="GameProjectContent">
|
||||
<Content>
|
||||
<Animation Duration="0" Speed="1.0000" />
|
||||
<ObjectData Name="Scene" FrameEvent="" ctype="SingleNodeObjectData">
|
||||
<Position X="0.0000" Y="0.0000" />
|
||||
<Scale ScaleX="1.0000" ScaleY="1.0000" />
|
||||
<AnchorPoint />
|
||||
<CColor A="255" R="255" G="255" B="255" />
|
||||
<Size X="640.0000" Y="960.0000" />
|
||||
<PrePosition X="0.0000" Y="0.0000" />
|
||||
<PreSize X="0.0000" Y="0.0000" />
|
||||
<Children>
|
||||
<NodeObjectData Name="Default" ActionTag="-620272433" FrameEvent="" Tag="5" ObjectIndex="3" ctype="SpriteObjectData">
|
||||
<Position X="320.0000" Y="480.0000" />
|
||||
<Scale ScaleX="1.0000" ScaleY="1.0000" />
|
||||
<AnchorPoint ScaleX="0.5000" ScaleY="0.5000" />
|
||||
<CColor A="255" R="255" G="255" B="255" />
|
||||
<Size X="640.0000" Y="960.0000" />
|
||||
<PrePosition X="0.5000" Y="0.5000" />
|
||||
<PreSize X="0.0000" Y="0.0000" />
|
||||
<FileData Type="Normal" Path="HelloWorld.png" />
|
||||
</NodeObjectData>
|
||||
</Children>
|
||||
</ObjectData>
|
||||
</Content>
|
||||
</Content>
|
||||
</GameProjectFile>
|
||||
|
After Width: | Height: | Size: 75 KiB |
|
After Width: | Height: | Size: 190 KiB |
|
After Width: | Height: | Size: 369 KiB |
|
After Width: | Height: | Size: 45 KiB |
|
After Width: | Height: | Size: 80 KiB |
|
After Width: | Height: | Size: 80 KiB |
@@ -0,0 +1,83 @@
|
||||
{
|
||||
"ID": "a2ee0952-26b5-49ae-8bf9-4f1d6279b798",
|
||||
"Version": "2.1.0.0",
|
||||
"Type": "Scene",
|
||||
"Name": "MainScene",
|
||||
"Content": {
|
||||
"Content": {
|
||||
"Animation": {
|
||||
"Duration": 0,
|
||||
"Speed": 1.0,
|
||||
"Timelines": [],
|
||||
"ctype": "TimelineActionData"
|
||||
},
|
||||
"AnimationList": [],
|
||||
"ObjectData": {
|
||||
"PrePosition": {
|
||||
"X": 0.0,
|
||||
"Y": 0.0
|
||||
},
|
||||
"PreSize": {
|
||||
"X": 0.0,
|
||||
"Y": 0.0
|
||||
},
|
||||
"Children": [
|
||||
{
|
||||
"FileData": {
|
||||
"Type": "Normal",
|
||||
"Path": "HelloWorld.png"
|
||||
},
|
||||
"Tag": 5,
|
||||
"PrePosition": {
|
||||
"X": 0.5,
|
||||
"Y": 0.5
|
||||
},
|
||||
"PreSize": {
|
||||
"X": 0.0,
|
||||
"Y": 0.0
|
||||
},
|
||||
"ActionTag": -620272433,
|
||||
"Position": {
|
||||
"X": 320.0,
|
||||
"Y": 480.0
|
||||
},
|
||||
"Scale": {
|
||||
"ScaleX": 1.0,
|
||||
"ScaleY": 1.0
|
||||
},
|
||||
"AnchorPoint": {
|
||||
"ScaleX": 0.5,
|
||||
"ScaleY": 0.5
|
||||
},
|
||||
"CColor": {},
|
||||
"Size": {
|
||||
"X": 640.0,
|
||||
"Y": 960.0
|
||||
},
|
||||
"FrameEvent": "",
|
||||
"Name": "Default",
|
||||
"ctype": "SpriteObjectData"
|
||||
}
|
||||
],
|
||||
"Position": {
|
||||
"X": 0.0,
|
||||
"Y": 0.0
|
||||
},
|
||||
"Scale": {
|
||||
"ScaleX": 1.0,
|
||||
"ScaleY": 1.0
|
||||
},
|
||||
"AnchorPoint": {},
|
||||
"CColor": {},
|
||||
"Size": {
|
||||
"X": 640.0,
|
||||
"Y": 960.0
|
||||
},
|
||||
"FrameEvent": "",
|
||||
"Name": "Scene",
|
||||
"ctype": "SingleNodeObjectData"
|
||||
},
|
||||
"ctype": "GameProjectData"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
|
||||
var HelloWorldLayer = cc.Layer.extend({
|
||||
sprite:null,
|
||||
ctor:function () {
|
||||
//////////////////////////////
|
||||
// 1. super init first
|
||||
this._super();
|
||||
|
||||
/////////////////////////////
|
||||
// 2. add a menu item with "X" image, which is clicked to quit the program
|
||||
// you may modify it.
|
||||
// ask the window size
|
||||
var size = cc.winSize;
|
||||
|
||||
var mainscene = ccs.load(res.MainScene_json);
|
||||
this.addChild(mainscene.node);
|
||||
|
||||
/* you can create scene with following comment code instead of using csb file.
|
||||
/////////////////////////////
|
||||
// 3. add your codes below...
|
||||
// add a label shows "Hello World"
|
||||
// create and initialize a label
|
||||
var helloLabel = new cc.LabelTTF("Hello World", "Arial", 38);
|
||||
// position the label on the center of the screen
|
||||
helloLabel.x = size.width / 2;
|
||||
helloLabel.y = size.height / 2 + 200;
|
||||
// add the label as a child to this layer
|
||||
this.addChild(helloLabel, 5);
|
||||
|
||||
// add "HelloWorld" splash screen"
|
||||
this.sprite = new cc.Sprite(res.HelloWorld_png);
|
||||
this.sprite.attr({
|
||||
x: size.width / 2,
|
||||
y: size.height / 2
|
||||
});
|
||||
this.addChild(this.sprite, 0);
|
||||
*/
|
||||
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
var HelloWorldScene = cc.Scene.extend({
|
||||
onEnter:function () {
|
||||
this._super();
|
||||
var layer = new HelloWorldLayer();
|
||||
this.addChild(layer);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
var res = {
|
||||
HelloWorld_png : "res/HelloWorld.png",
|
||||
MainScene_json : "res/MainScene.json"
|
||||
};
|
||||
|
||||
var g_resources = [];
|
||||
for (var i in res) {
|
||||
g_resources.push(res[i]);
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
{
|
||||
"do_default": {
|
||||
"exclude_from_template": [
|
||||
"frameworks/runtime-src",
|
||||
"res-landscape",
|
||||
"res-portrait"
|
||||
],
|
||||
"append_from_template": {
|
||||
"from": "res-landscape",
|
||||
"to": ""
|
||||
},
|
||||
"project_rename": {
|
||||
"src_project_name": "HelloLua",
|
||||
"files": [
|
||||
"PROJECT_NAME.ccs",
|
||||
"PROJECT_NAME.cfg",
|
||||
"PROJECT_NAME.udf"
|
||||
]
|
||||
},
|
||||
"project_replace_project_name": {
|
||||
"src_project_name": "HelloLua",
|
||||
"files": [
|
||||
"config.json",
|
||||
".project",
|
||||
"PROJECT_NAME.ccs"
|
||||
]
|
||||
},
|
||||
"append_dir": [
|
||||
{
|
||||
"from": "cocos/scripting/lua-bindings/script",
|
||||
"to": "src/cocos",
|
||||
"exclude": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"do_add_native_support": {
|
||||
"append_from_template": {
|
||||
"from": "frameworks/runtime-src",
|
||||
"to": "frameworks/runtime-src",
|
||||
"exclude": [
|
||||
"proj.android/bin",
|
||||
"proj.android/assets",
|
||||
"proj.ios_mac/HelloLua.xcodeproj/project.xcworkspace",
|
||||
"proj.ios_mac/HelloLua.xcodeproj/xcuserdata",
|
||||
"proj.win32/Debug.win32",
|
||||
"proj.win32/Release.win32",
|
||||
"proj.win32/HelloLua.sdf"
|
||||
]
|
||||
},
|
||||
"project_rename": {
|
||||
"src_project_name": "HelloLua",
|
||||
"files": [
|
||||
"frameworks/runtime-src/proj.win32/PROJECT_NAME.vcxproj",
|
||||
"frameworks/runtime-src/proj.win32/PROJECT_NAME.vcxproj.filters",
|
||||
"frameworks/runtime-src/proj.win32/PROJECT_NAME.vcxproj.user",
|
||||
"frameworks/runtime-src/proj.win32/PROJECT_NAME.sln",
|
||||
"frameworks/runtime-src/proj.ios_mac/PROJECT_NAME.xcodeproj"
|
||||
]
|
||||
},
|
||||
"project_replace_project_name": {
|
||||
"src_project_name": "HelloLua",
|
||||
"files": [
|
||||
"config.json",
|
||||
".project",
|
||||
"frameworks/runtime-src/proj.win32/PROJECT_NAME.vcxproj",
|
||||
"frameworks/runtime-src/proj.win32/PROJECT_NAME.vcxproj.filters",
|
||||
"frameworks/runtime-src/proj.win32/PROJECT_NAME.vcxproj.user",
|
||||
"frameworks/runtime-src/proj.win32/PROJECT_NAME.sln",
|
||||
"frameworks/runtime-src/proj.win32/main.cpp",
|
||||
"frameworks/runtime-src/proj.android/.project",
|
||||
"frameworks/runtime-src/proj.android/AndroidManifest.xml",
|
||||
"frameworks/runtime-src/proj.android/build.xml",
|
||||
"frameworks/runtime-src/proj.android/res/values/strings.xml",
|
||||
"frameworks/runtime-src/proj.ios_mac/ios/main.m",
|
||||
"frameworks/runtime-src/proj.ios_mac/ios/Prefix.pch",
|
||||
"frameworks/runtime-src/proj.ios_mac/mac/SimulatorApp.mm",
|
||||
"frameworks/runtime-src/proj.ios_mac/PROJECT_NAME.xcodeproj/project.pbxproj",
|
||||
"frameworks/runtime-src/Classes/AppDelegate.cpp"
|
||||
]
|
||||
},
|
||||
"project_replace_package_name": {
|
||||
"src_package_name": "org.cocos2dx.hellolua",
|
||||
"files": [
|
||||
"frameworks/runtime-src/proj.android/AndroidManifest.xml"
|
||||
]
|
||||
},
|
||||
"project_replace_mac_bundleid": {
|
||||
"src_bundle_id": "org.cocos2dx.hellolua",
|
||||
"files": [
|
||||
"frameworks/runtime-src/proj.ios_mac/mac/Info.plist"
|
||||
]
|
||||
},
|
||||
"project_replace_ios_bundleid": {
|
||||
"src_bundle_id": "org.cocos2dx.hellolua",
|
||||
"files": [
|
||||
"frameworks/runtime-src/proj.ios_mac/ios/Info.plist"
|
||||
]
|
||||
}
|
||||
},
|
||||
"change_orientation": {
|
||||
"append_from_template": {
|
||||
"from": "res-portrait",
|
||||
"to": ""
|
||||
},
|
||||
"modify_files": [
|
||||
{
|
||||
"file_path": "config.json",
|
||||
"pattern": "\\\"isLandscape\\\"\\s*:.*,",
|
||||
"replace_string": "\"isLandscape\": false,"
|
||||
},
|
||||
{
|
||||
"file_path": "src/config.lua",
|
||||
"pattern": "width\\s*=.*,",
|
||||
"replace_string": "width = 640,"
|
||||
},
|
||||
{
|
||||
"file_path": "src/config.lua",
|
||||
"pattern": "height\\s*=.*,",
|
||||
"replace_string": "height = 960,"
|
||||
},
|
||||
{
|
||||
"file_path": "frameworks/runtime-src/proj.ios_mac/ios/Info.plist",
|
||||
"pattern": "UIInterfaceOrientationLandscapeRight",
|
||||
"replace_string": "UIInterfaceOrientationPortrait"
|
||||
},
|
||||
{
|
||||
"file_path": "frameworks/runtime-src/proj.ios_mac/ios/Info.plist",
|
||||
"pattern": "UIInterfaceOrientationLandscapeLeft",
|
||||
"replace_string": "UIInterfaceOrientationPortraitUpsideDown"
|
||||
},
|
||||
{
|
||||
"file_path": "frameworks/runtime-src/proj.android/AndroidManifest.xml",
|
||||
"pattern": "android:screenOrientation=\\\".*\\\"",
|
||||
"replace_string": "android:screenOrientation=\"portrait\""
|
||||
}
|
||||
],
|
||||
"project_rename":{
|
||||
"src_project_name":"HelloLua",
|
||||
"files":[
|
||||
"PROJECT_NAME.ccs",
|
||||
"PROJECT_NAME.cfg",
|
||||
"PROJECT_NAME.udf"
|
||||
]
|
||||
},
|
||||
"project_replace_project_name":{
|
||||
"src_project_name":"HelloLua",
|
||||
"files":[
|
||||
"PROJECT_NAME.ccs"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 2013
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HelloLua", "HelloLua.vcxproj", "{4E6A7A0E-DDD8-4BAA-8B22-C964069364ED}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{4E6A7A0E-DDD8-4BAA-8B22-C964069364ED}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{4E6A7A0E-DDD8-4BAA-8B22-C964069364ED}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{4E6A7A0E-DDD8-4BAA-8B22-C964069364ED}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{4E6A7A0E-DDD8-4BAA-8B22-C964069364ED}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,11 @@
|
||||
<Solution>
|
||||
<PropertyGroup Name="HelloLua" Version="2.1.0.0" Type="CocosStudio" />
|
||||
<SolutionFolder>
|
||||
<Group ctype="ResourceGroup">
|
||||
<RootFolder Name=".">
|
||||
<Project Name="MainScene.csd" />
|
||||
<Image Name="HelloWorld.png" />
|
||||
</RootFolder>
|
||||
</Group>
|
||||
</SolutionFolder>
|
||||
</Solution>
|
||||
@@ -0,0 +1 @@
|
||||
<Properties PublishDirectory="res" SolutionSize="960 * 640" DefaultSerializer="Serializer_FlatBuffers" CustomSerializer="Serializer_FlatBuffers" />
|
||||
@@ -0,0 +1,6 @@
|
||||
<UserData>
|
||||
<OpenedDocuments>
|
||||
<FilePathData Path="MainScene.csd" />
|
||||
</OpenedDocuments>
|
||||
<ActiveDocument Path="MainScene.csd" />
|
||||
</UserData>
|
||||
|
After Width: | Height: | Size: 208 KiB |
@@ -0,0 +1,29 @@
|
||||
<GameProjectFile>
|
||||
<PropertyGroup Type="Scene" Name="MainScene" ID="a2ee0952-26b5-49ae-8bf9-4f1d6279b798" Version="2.1.0.0" />
|
||||
<Content ctype="GameProjectContent">
|
||||
<Content>
|
||||
<Animation Duration="0" Speed="1.0000" />
|
||||
<ObjectData Name="Scene" FrameEvent="" RightMargin="-960.0000" TopMargin="-640.0000" ctype="SingleNodeObjectData">
|
||||
<Position X="0.0000" Y="0.0000" />
|
||||
<Scale ScaleX="1.0000" ScaleY="1.0000" />
|
||||
<AnchorPoint />
|
||||
<CColor A="255" R="255" G="255" B="255" />
|
||||
<Size X="960.0000" Y="640.0000" />
|
||||
<PrePosition X="0.0000" Y="0.0000" />
|
||||
<PreSize X="0.0000" Y="0.0000" />
|
||||
<Children>
|
||||
<NodeObjectData Name="Default" ActionTag="953446860" FrameEvent="" Tag="5" ObjectIndex="2" ctype="SpriteObjectData">
|
||||
<Position X="480.0000" Y="320.0000" />
|
||||
<Scale ScaleX="1.0000" ScaleY="1.0000" />
|
||||
<AnchorPoint ScaleX="0.5000" ScaleY="0.5000" />
|
||||
<CColor A="255" R="255" G="255" B="255" />
|
||||
<Size X="960.0000" Y="640.0000" />
|
||||
<PrePosition X="0.5000" Y="0.5000" />
|
||||
<PreSize X="0.0000" Y="0.0000" />
|
||||
<FileData Type="Normal" Path="HelloWorld.png" />
|
||||
</NodeObjectData>
|
||||
</Children>
|
||||
</ObjectData>
|
||||
</Content>
|
||||
</Content>
|
||||
</GameProjectFile>
|
||||
|
After Width: | Height: | Size: 208 KiB |
@@ -0,0 +1,11 @@
|
||||
<Solution>
|
||||
<PropertyGroup Name="HelloLua" Version="2.1.0.0" Type="CocosStudio" />
|
||||
<SolutionFolder>
|
||||
<Group ctype="ResourceGroup">
|
||||
<RootFolder Name=".">
|
||||
<Project Name="MainScene.csd" />
|
||||
<Image Name="HelloWorld.png" />
|
||||
</RootFolder>
|
||||
</Group>
|
||||
</SolutionFolder>
|
||||
</Solution>
|
||||
@@ -0,0 +1 @@
|
||||
<Properties publishHasCocos2dxCode="False" PublishDirectory="res" SolutionSize="640 * 960" DefaultSerializer="Serializer_FlatBuffers" CustomSerializer="Serializer_FlatBuffers" />
|
||||
@@ -0,0 +1,6 @@
|
||||
<UserData>
|
||||
<OpenedDocuments>
|
||||
<FilePathData Path="MainScene.csd" />
|
||||
</OpenedDocuments>
|
||||
<ActiveDocument Path="MainScene.csd" />
|
||||
</UserData>
|
||||
|
After Width: | Height: | Size: 80 KiB |
@@ -0,0 +1,29 @@
|
||||
<GameProjectFile>
|
||||
<PropertyGroup Type="Scene" Name="MainScene" ID="a2ee0952-26b5-49ae-8bf9-4f1d6279b798" Version="2.1.0.0" />
|
||||
<Content ctype="GameProjectContent">
|
||||
<Content>
|
||||
<Animation Duration="0" Speed="1.0000" />
|
||||
<ObjectData Name="Scene" FrameEvent="" ctype="SingleNodeObjectData">
|
||||
<Position X="0.0000" Y="0.0000" />
|
||||
<Scale ScaleX="1.0000" ScaleY="1.0000" />
|
||||
<AnchorPoint />
|
||||
<CColor A="255" R="255" G="255" B="255" />
|
||||
<Size X="640.0000" Y="960.0000" />
|
||||
<PrePosition X="0.0000" Y="0.0000" />
|
||||
<PreSize X="0.0000" Y="0.0000" />
|
||||
<Children>
|
||||
<NodeObjectData Name="Default" ActionTag="-620272433" FrameEvent="" Tag="5" ObjectIndex="3" ctype="SpriteObjectData">
|
||||
<Position X="320.0000" Y="480.0000" />
|
||||
<Scale ScaleX="1.0000" ScaleY="1.0000" />
|
||||
<AnchorPoint ScaleX="0.5000" ScaleY="0.5000" />
|
||||
<CColor A="255" R="255" G="255" B="255" />
|
||||
<Size X="640.0000" Y="960.0000" />
|
||||
<PrePosition X="0.5000" Y="0.5000" />
|
||||
<PreSize X="0.0000" Y="0.0000" />
|
||||
<FileData Type="Normal" Path="HelloWorld.png" />
|
||||
</NodeObjectData>
|
||||
</Children>
|
||||
</ObjectData>
|
||||
</Content>
|
||||
</Content>
|
||||
</GameProjectFile>
|
||||
|
After Width: | Height: | Size: 75 KiB |
|
After Width: | Height: | Size: 190 KiB |
|
After Width: | Height: | Size: 369 KiB |
|
After Width: | Height: | Size: 45 KiB |
|
After Width: | Height: | Size: 80 KiB |
|
After Width: | Height: | Size: 80 KiB |
@@ -0,0 +1,8 @@
|
||||
|
||||
local MyApp = class("MyApp", cc.load("mvc").AppBase)
|
||||
|
||||
function MyApp:onCreate()
|
||||
math.randomseed(os.time())
|
||||
end
|
||||
|
||||
return MyApp
|
||||
@@ -0,0 +1,22 @@
|
||||
|
||||
local MainScene = class("MainScene", cc.load("mvc").ViewBase)
|
||||
|
||||
MainScene.RESOURCE_FILENAME = "MainScene.csb"
|
||||
|
||||
function MainScene:onCreate()
|
||||
printf("resource node = %s", tostring(self:getResourceNode()))
|
||||
|
||||
--[[ you can create scene with following comment code instead of using csb file.
|
||||
-- add background image
|
||||
display.newSprite("HelloWorld.png")
|
||||
:move(display.center)
|
||||
:addTo(self)
|
||||
|
||||
-- add HelloWorld label
|
||||
cc.Label:createWithSystemFont("Hello World", "Arial", 40)
|
||||
:move(display.cx, display.cy + 200)
|
||||
:addTo(self)
|
||||
]]
|
||||
end
|
||||
|
||||
return MainScene
|
||||
@@ -0,0 +1,26 @@
|
||||
|
||||
-- 0 - disable debug info, 1 - less debug info, 2 - verbose debug info
|
||||
DEBUG = 2
|
||||
|
||||
-- use framework, will disable all deprecated API, false - use legacy API
|
||||
CC_USE_FRAMEWORK = true
|
||||
|
||||
-- show FPS on screen
|
||||
CC_SHOW_FPS = true
|
||||
|
||||
-- disable create unexpected global variable
|
||||
CC_DISABLE_GLOBAL = true
|
||||
|
||||
-- for module display
|
||||
CC_DESIGN_RESOLUTION = {
|
||||
width = 960,
|
||||
height = 640,
|
||||
autoscale = "SHOW_ALL",
|
||||
callback = function(framesize)
|
||||
local ratio = framesize.width / framesize.height
|
||||
if ratio <= 1.34 then
|
||||
-- iPad 768*1024(1536*2048) is 4:3 screen
|
||||
return {autoscale = "SHOW_ALL"}
|
||||
end
|
||||
end
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"libs_output_dir" : "prebuilt",
|
||||
"xcode_projs_info" : {
|
||||
"build/cocos2d_libs.xcodeproj" : {
|
||||
"targets" : "libcocos2d"
|
||||
},
|
||||
"cocos/scripting/js-bindings/proj.ios_mac/cocos2d_js_bindings.xcodeproj" : {
|
||||
"targets" : "libjscocos2d"
|
||||
},
|
||||
"tools/simulator/libsimulator/proj.ios_mac/libsimulator.xcodeproj" : {
|
||||
"targets" : "libsimulator"
|
||||
}
|
||||
},
|
||||
"vs_projs_info" : {
|
||||
"tools/simulator/frameworks/runtime-src/proj.win32/simulator.sln" : {
|
||||
"build_targets" : [
|
||||
"libjscocos2d", "libsimulator"
|
||||
],
|
||||
"rename_targets" : [
|
||||
"libSpine", "libDragonBones",
|
||||
"libcocos2d", "libjscocos2d",
|
||||
"libsimulator", "libBox2D"
|
||||
]
|
||||
}
|
||||
},
|
||||
"android_mks" : [
|
||||
"cocos/Android.mk",
|
||||
"cocos/audio/android/Android.mk",
|
||||
"cocos/scripting/js-bindings/proj.android/Android.mk",
|
||||
"extensions/Android.mk",
|
||||
"cocos/ui/Android.mk",
|
||||
"cocos/network/Android.mk",
|
||||
"cocos/platform/android/Android.mk",
|
||||
"cocos/editor-support/dragonbones/proj.android/Android.mk",
|
||||
"cocos/editor-support/spine/Android.mk",
|
||||
"cocos/editor-support/creator/Android.mk",
|
||||
"tools/simulator/libsimulator/proj.android/Android.mk"
|
||||
],
|
||||
"support_vs_versions" : [ 2017 ]
|
||||
}
|
||||
@@ -0,0 +1,350 @@
|
||||
{
|
||||
"copy_from_engine" : [
|
||||
{
|
||||
"from": "templates/cpp-template-default",
|
||||
"to": "cpp-template-binary",
|
||||
"exclude": [
|
||||
"*android-studio",
|
||||
"*win10",
|
||||
"*wp8",
|
||||
"*win8.1-universal",
|
||||
"*linux",
|
||||
"*CMakeLists.txt",
|
||||
"Resources",
|
||||
"cocos-project-template.json"
|
||||
]
|
||||
},
|
||||
{
|
||||
"from": "templates/lua-template-default",
|
||||
"to": "lua-template-binary",
|
||||
"include" : [
|
||||
"config.json",
|
||||
".settings",
|
||||
".project"
|
||||
]
|
||||
},
|
||||
{
|
||||
"from": "templates/lua-template-default/frameworks",
|
||||
"to": "lua-template-binary/frameworks",
|
||||
"exclude": [
|
||||
"*android-studio",
|
||||
"*win10",
|
||||
"*wp8",
|
||||
"*win8.1-universal",
|
||||
"*linux",
|
||||
"*CMakeLists.txt"
|
||||
]
|
||||
},
|
||||
{
|
||||
"from": "templates/lua-template-default/src",
|
||||
"to": "lua-template-binary/src",
|
||||
"exclude": [
|
||||
"app/*"
|
||||
]
|
||||
},
|
||||
{
|
||||
"from": "templates/js-template-runtime",
|
||||
"to": "js-template-binary",
|
||||
"exclude": [
|
||||
"*android-studio",
|
||||
"*win10",
|
||||
"*wp8",
|
||||
"*win8.1-universal",
|
||||
"*linux",
|
||||
"*CMakeLists.txt",
|
||||
"res/*",
|
||||
"runtime/*"
|
||||
]
|
||||
},
|
||||
{
|
||||
"from": "tools/simulator/frameworks/runtime-src/Classes/ide-support",
|
||||
"to": "lua-template-binary/frameworks/runtime-src/Classes/ide-support/",
|
||||
"exclude": [
|
||||
"RuntimeJsImpl.*"
|
||||
]
|
||||
},
|
||||
{
|
||||
"from": "cocos/scripting/lua-bindings/manual",
|
||||
"to": "lua-template-binary/frameworks/runtime-src/Classes",
|
||||
"include": [
|
||||
"lua_module_register.h"
|
||||
]
|
||||
},
|
||||
{
|
||||
"from": "tools/simulator/frameworks/runtime-src/proj.ios_mac/ios",
|
||||
"to": "lua-template-binary/frameworks/runtime-src/proj.ios_mac/ios",
|
||||
"exclude": [
|
||||
"RootViewController.*",
|
||||
"Info.plist"
|
||||
]
|
||||
},
|
||||
{
|
||||
"from": "tools/simulator/frameworks/runtime-src/proj.ios_mac/mac",
|
||||
"to": "lua-template-binary/frameworks/runtime-src/proj.ios_mac/mac",
|
||||
"exclude": [
|
||||
"Info.plist",
|
||||
"Icon.icns",
|
||||
"build-cfg.json"
|
||||
]
|
||||
},
|
||||
{
|
||||
"from": "tools/simulator/frameworks/runtime-src/proj.win32",
|
||||
"to": "lua-template-binary/frameworks/runtime-src/proj.win32/",
|
||||
"include": [
|
||||
"game.rc",
|
||||
"main.cpp",
|
||||
"main.h",
|
||||
"res",
|
||||
"resource.h",
|
||||
"SimulatorWin.cpp",
|
||||
"SimulatorWin.h"
|
||||
]
|
||||
},
|
||||
{
|
||||
"from": "cocos/scripting/js-bindings/manual",
|
||||
"to": "js-template-binary/frameworks/runtime-src/Classes",
|
||||
"include": [
|
||||
"js_module_register.h"
|
||||
]
|
||||
},
|
||||
{
|
||||
"from": "tools/simulator/frameworks/runtime-src/Classes/ide-support",
|
||||
"to": "js-template-binary/frameworks/runtime-src/Classes/ide-support/",
|
||||
"exclude": [
|
||||
"RuntimeLuaImpl.*",
|
||||
"lua_debugger.*"
|
||||
]
|
||||
},
|
||||
{
|
||||
"from": "tools/simulator/frameworks/runtime-src/proj.ios_mac/ios",
|
||||
"to": "js-template-binary/frameworks/runtime-src/proj.ios_mac/ios",
|
||||
"exclude": [
|
||||
"RootViewController.*",
|
||||
"Info.plist"
|
||||
]
|
||||
},
|
||||
{
|
||||
"from": "tools/simulator/frameworks/runtime-src/proj.ios_mac/mac",
|
||||
"to": "js-template-binary/frameworks/runtime-src/proj.ios_mac/mac",
|
||||
"exclude": [
|
||||
"Info.plist",
|
||||
"Icon.icns",
|
||||
"build-cfg.json"
|
||||
]
|
||||
},
|
||||
{
|
||||
"from": "tools/simulator/frameworks/runtime-src/proj.win32",
|
||||
"to": "js-template-binary/frameworks/runtime-src/proj.win32/",
|
||||
"include": [
|
||||
"game.rc",
|
||||
"main.cpp",
|
||||
"main.h",
|
||||
"res",
|
||||
"resource.h",
|
||||
"SimulatorWin.cpp",
|
||||
"SimulatorWin.h"
|
||||
]
|
||||
},
|
||||
{
|
||||
"from": "cocos/platform/android/java/src",
|
||||
"to": "cpp-template-binary/proj.android/src"
|
||||
},
|
||||
{
|
||||
"from": "cocos/platform/android/java/src",
|
||||
"to": "lua-template-binary/frameworks/runtime-src/proj.android/src"
|
||||
},
|
||||
{
|
||||
"from": "cocos/platform/android/java/src",
|
||||
"to": "js-template-binary/frameworks/runtime-src/proj.android/src"
|
||||
},
|
||||
{
|
||||
"from": "cocos/platform/android/java/libs",
|
||||
"to": "cpp-template-binary/proj.android/libs"
|
||||
},
|
||||
{
|
||||
"from": "cocos/platform/android/java/libs",
|
||||
"to": "lua-template-binary/frameworks/runtime-src/proj.android/libs"
|
||||
},
|
||||
{
|
||||
"from": "cocos/platform/android/java/libs",
|
||||
"to": "js-template-binary/frameworks/runtime-src/proj.android/libs"
|
||||
},
|
||||
{
|
||||
"from": "cocos/2d/",
|
||||
"to": "cpp-template-binary/proj.win32/",
|
||||
"include": [
|
||||
"cocos2dx.props"
|
||||
]
|
||||
},
|
||||
{
|
||||
"from": "cocos/2d/",
|
||||
"to": "lua-template-binary/frameworks/runtime-src/proj.win32/",
|
||||
"include": [
|
||||
"cocos2dx.props"
|
||||
]
|
||||
},
|
||||
{
|
||||
"from": "cocos/2d/",
|
||||
"to": "js-template-binary/frameworks/runtime-src/proj.win32/",
|
||||
"include": [
|
||||
"cocos2dx.props"
|
||||
]
|
||||
}
|
||||
],
|
||||
"copy_from_bin_templates" : [
|
||||
{
|
||||
"from": "cpp-template-default",
|
||||
"to": "cpp-template-binary"
|
||||
},
|
||||
{
|
||||
"from": "lua-template-runtime",
|
||||
"to": "lua-template-binary"
|
||||
},
|
||||
{
|
||||
"from": "js-template-runtime",
|
||||
"to": "js-template-binary"
|
||||
}
|
||||
],
|
||||
"vs_projs" : [
|
||||
"cpp-template-binary/proj.win32/HelloCpp.vcxproj",
|
||||
"lua-template-binary/frameworks/runtime-src/proj.win32/HelloLua.vcxproj",
|
||||
"js-template-binary/frameworks/runtime-src/proj.win32/HelloJavascript.vcxproj"
|
||||
],
|
||||
"win32_cfg" : {
|
||||
"main_cpps" : [
|
||||
"cpp-template-binary/proj.win32/main.cpp",
|
||||
"lua-template-binary/frameworks/runtime-src/proj.win32/main.cpp",
|
||||
"js-template-binary/frameworks/runtime-src/proj.win32/main.cpp"
|
||||
],
|
||||
"link_libs" : {
|
||||
"base" : [
|
||||
"libcocos2d.lib", "libbox2d.lib", "libSpine.lib",
|
||||
"librecast.lib", "libbullet.lib"
|
||||
],
|
||||
"lua" : [
|
||||
"libluacocos2d", "libsimulator"
|
||||
],
|
||||
"js" : [
|
||||
"libjscocos2d", "libsimulator"
|
||||
]
|
||||
}
|
||||
},
|
||||
"xcode_projs" : [
|
||||
"cpp-template-binary/proj.ios_mac/HelloCpp.xcodeproj/project.pbxproj",
|
||||
"lua-template-binary/frameworks/runtime-src/proj.ios_mac/HelloLua.xcodeproj/project.pbxproj",
|
||||
"js-template-binary/frameworks/runtime-src/proj.ios_mac/HelloJavascript.xcodeproj/project.pbxproj"
|
||||
],
|
||||
"modify_files" : [
|
||||
{
|
||||
"file_path": "cpp-template-binary/proj.android/project.properties",
|
||||
"pattern": ".*cocos/platform/android/java\\s$",
|
||||
"replace_string": ""
|
||||
},
|
||||
{
|
||||
"file_path": "lua-template-binary/frameworks/runtime-src/proj.android/project.properties",
|
||||
"pattern": ".*cocos/platform/android/java\\s$",
|
||||
"replace_string": ""
|
||||
},
|
||||
{
|
||||
"file_path": "js-template-binary/frameworks/runtime-src/proj.android/project.properties",
|
||||
"pattern": ".*cocos/platform/android/java\\s$",
|
||||
"replace_string": ""
|
||||
},
|
||||
{
|
||||
"file_path": "cpp-template-binary/proj.android/jni/Android.mk",
|
||||
"pattern": "\\$\\(call[ \\t]+import-module,([^\\)]*)\\)",
|
||||
"replace_string": "$(call import-module,\\1/prebuilt-mk)"
|
||||
},
|
||||
{
|
||||
"file_path": "cpp-template-binary/proj.android/jni/Android.mk",
|
||||
"pattern": "\\$\\(call import-add-path.*",
|
||||
"replace_string": ""
|
||||
},
|
||||
{
|
||||
"file_path": "lua-template-binary/frameworks/runtime-src/proj.android/jni/Android.mk",
|
||||
"pattern": "\\$\\(call[ \\t]+import-module,([^\\)]*)\\)",
|
||||
"replace_string": "$(call import-module,\\1/prebuilt-mk)"
|
||||
},
|
||||
{
|
||||
"file_path": "js-template-binary/frameworks/runtime-src/proj.android/jni/Android.mk",
|
||||
"pattern": "\\$\\(call[ \\t]+import-module,([^\\)]*)\\)",
|
||||
"replace_string": "$(call import-module,\\1/prebuilt-mk)"
|
||||
},
|
||||
{
|
||||
"file_path": "js-template-binary/project.json",
|
||||
"pattern": "\\\"modules\\\"[ \\t]*:[ \\t]*\\[(.*)\\]",
|
||||
"replace_string": "\"modules\" : [\\1, \"cocostudio\"]"
|
||||
},
|
||||
{
|
||||
"file_path": "js-template-binary/frameworks/runtime-src/Classes/ide-support/CodeIDESupport.h",
|
||||
"pattern": "#define CC_CODE_IDE_DEBUG_SUPPORT 1",
|
||||
"replace_string": "#define CC_CODE_IDE_DEBUG_SUPPORT 0"
|
||||
},
|
||||
{
|
||||
"file_path": "lua-template-binary/frameworks/runtime-src/Classes/ide-support/CodeIDESupport.h",
|
||||
"pattern": "#define CC_CODE_IDE_DEBUG_SUPPORT 1",
|
||||
"replace_string": "#define CC_CODE_IDE_DEBUG_SUPPORT 0"
|
||||
},
|
||||
{
|
||||
"file_path": "cpp-template-binary/proj.win32/cocos2dx.props",
|
||||
"pattern": "(libbox2d\\.lib;)|(libSpine\\.lib;)",
|
||||
"replace_string": ""
|
||||
},
|
||||
{
|
||||
"file_path": "lua-template-binary/frameworks/runtime-src/proj.win32/cocos2dx.props",
|
||||
"pattern": "(libbox2d\\.lib;)|(libSpine\\.lib;)",
|
||||
"replace_string": ""
|
||||
},
|
||||
{
|
||||
"file_path": "js-template-binary/frameworks/runtime-src/proj.win32/cocos2dx.props",
|
||||
"pattern": "(libbox2d\\.lib;)|(libSpine\\.lib;)",
|
||||
"replace_string": ""
|
||||
}
|
||||
],
|
||||
"build_cfg_files" : {
|
||||
"cpp-template-binary/proj.android/build-cfg.json" : {
|
||||
"replace_string" : [
|
||||
{
|
||||
"src_str" : "../cocos2d",
|
||||
"dst_str" : "${FW_VERSION_PATH}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"lua-template-binary/frameworks/runtime-src/proj.android/build-cfg.json" : {
|
||||
"replace_string" : [
|
||||
{
|
||||
"src_str" : "../../cocos2d-x",
|
||||
"dst_str" : "${FW_VERSION_PATH}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"js-template-binary/frameworks/runtime-src/proj.android/build-cfg.json" : {
|
||||
"replace_string" : [
|
||||
{
|
||||
"src_str" : "../../cocos2d-x/cocos/scripting/js-bindings/script",
|
||||
"dst_str" : "../../../script"
|
||||
},
|
||||
{
|
||||
"src_str" : "../../cocos2d-x",
|
||||
"dst_str" : "${FW_VERSION_PATH}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"lua-template-binary/frameworks/runtime-src/proj.win32/build-cfg.json" : {
|
||||
"replace_string" : [
|
||||
{
|
||||
"src_str" : "../../cocos2d-x/external/lua/luasocket",
|
||||
"dst_str" : "../../luasocket"
|
||||
}
|
||||
]
|
||||
},
|
||||
"js-template-binary/frameworks/runtime-src/proj.win32/build-cfg.json" : {
|
||||
"replace_string" : [
|
||||
{
|
||||
"src_str" : "../../cocos2d-x/cocos/scripting/js-bindings/script",
|
||||
"dst_str" : "../../../script"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
476
cocos2d-x/tools/cocos2d-console/plugins/plugin_generate/gen_libs.py
Executable file
@@ -0,0 +1,476 @@
|
||||
#!/usr/bin/python
|
||||
#-*- coding: UTF-8 -*-
|
||||
|
||||
import os
|
||||
import sys
|
||||
import shutil
|
||||
import json
|
||||
import utils
|
||||
import gen_prebuilt_mk
|
||||
|
||||
import cocos
|
||||
from MultiLanguage import MultiLanguage
|
||||
|
||||
from cocos import CCPluginError
|
||||
from cocos import Logging
|
||||
from argparse import ArgumentParser
|
||||
from utils import ExtendEnv
|
||||
|
||||
class LibsCompiler(cocos.CCPlugin):
|
||||
CFG_FILE = 'configs/gen_libs_config.json'
|
||||
|
||||
KEY_LIBS_OUTPUT = 'libs_output_dir'
|
||||
KEY_XCODE_PROJS_INFO = 'xcode_projs_info'
|
||||
KEY_VS_PROJS_INFO = 'vs_projs_info'
|
||||
KEY_SUPPORT_VS_VERSIONS = 'support_vs_versions'
|
||||
KEY_ANDROID_MKS = "android_mks"
|
||||
CHECK_KEYS = [
|
||||
KEY_LIBS_OUTPUT,
|
||||
KEY_XCODE_PROJS_INFO,
|
||||
KEY_VS_PROJS_INFO,
|
||||
KEY_SUPPORT_VS_VERSIONS,
|
||||
KEY_ANDROID_MKS
|
||||
]
|
||||
|
||||
KEY_XCODE_TARGETS = 'targets'
|
||||
KEY_VS_BUILD_TARGETS = 'build_targets'
|
||||
KEY_VS_RENAME_TARGETS = 'rename_targets'
|
||||
|
||||
@staticmethod
|
||||
def plugin_name():
|
||||
return "gen-libs"
|
||||
|
||||
@staticmethod
|
||||
def brief_description():
|
||||
return MultiLanguage.get_string('GEN_LIBS_BRIEF')
|
||||
|
||||
def parse_args(self, argv):
|
||||
"""Custom and check param list.
|
||||
"""
|
||||
parser = ArgumentParser(prog="cocos %s" % self.__class__.plugin_name(),
|
||||
description=self.__class__.brief_description())
|
||||
parser.add_argument('-c', dest='clean', action="store_true",
|
||||
help=MultiLanguage.get_string('GEN_LIBS_ARG_CLEAN'))
|
||||
parser.add_argument('-e', dest='engine_path', help=MultiLanguage.get_string('GEN_LIBS_ARG_ENGINE'))
|
||||
parser.add_argument('-p', dest='platform', action="append", choices=['ios', 'mac', 'android', 'win32'],
|
||||
help=MultiLanguage.get_string('GEN_LIBS_ARG_PLATFORM'))
|
||||
parser.add_argument('-m', "--mode", dest='compile_mode', default='release', choices=['debug', 'release'],
|
||||
help=MultiLanguage.get_string('GEN_LIBS_ARG_MODE'))
|
||||
parser.add_argument('--dis-strip', dest='disable_strip', action="store_true",
|
||||
help=MultiLanguage.get_string('GEN_LIBS_ARG_DISABLE_STRIP'))
|
||||
group = parser.add_argument_group(MultiLanguage.get_string('GEN_LIBS_GROUP_WIN'))
|
||||
group.add_argument('--vs', dest='vs_version', type=int, default=None,
|
||||
help=MultiLanguage.get_string('GEN_LIBS_ARG_VS'))
|
||||
group = parser.add_argument_group(MultiLanguage.get_string('GEN_LIBS_GROUP_ANDROID'))
|
||||
group.add_argument("--app-abi", dest="app_abi",
|
||||
help=MultiLanguage.get_string('GEN_LIBS_ARG_ABI'))
|
||||
group.add_argument("--ap", dest="android_platform",
|
||||
help=MultiLanguage.get_string('COMPILE_ARG_AP'))
|
||||
group.add_argument("--android-studio", dest="use_studio", action="store_true",
|
||||
help=MultiLanguage.get_string('COMPILE_ARG_STUDIO'))
|
||||
|
||||
(args, unknown) = parser.parse_known_args(argv)
|
||||
self.init(args)
|
||||
|
||||
return args
|
||||
|
||||
def run(self, argv, dependencies):
|
||||
self.parse_args(argv)
|
||||
self.compile()
|
||||
|
||||
def init(self, args):
|
||||
if getattr(sys, 'frozen', None):
|
||||
self.cur_dir = os.path.realpath(os.path.dirname(sys.executable))
|
||||
self.default_engine_path = os.path.join(self.cur_dir, os.pardir, os.pardir, os.pardir)
|
||||
else:
|
||||
self.cur_dir = os.path.realpath(os.path.dirname(__file__))
|
||||
self.default_engine_path = os.path.join(self.cur_dir, os.pardir, os.pardir, os.pardir, os.pardir)
|
||||
self.default_engine_path = os.path.normpath(self.default_engine_path)
|
||||
|
||||
if args.engine_path is None:
|
||||
self.repo_x = self.default_engine_path
|
||||
else:
|
||||
engine_path = os.path.expanduser(args.engine_path)
|
||||
if os.path.isabs(engine_path):
|
||||
self.repo_x = os.path.normpath(engine_path)
|
||||
else:
|
||||
self.repo_x = os.path.normpath(os.path.abspath(engine_path))
|
||||
|
||||
if not os.path.isdir(self.repo_x):
|
||||
raise CCPluginError(MultiLanguage.get_string('GEN_LIBS_ERROR_WRONG_PATH_FMT', self.repo_x),
|
||||
CCPluginError.ERROR_WRONG_ARGS)
|
||||
|
||||
self.cfg_file_path = os.path.join(self.cur_dir, LibsCompiler.CFG_FILE)
|
||||
self.parse_config()
|
||||
|
||||
# arguments check and set
|
||||
self.clean = args.clean
|
||||
self.mode = args.compile_mode
|
||||
self._verbose = True
|
||||
|
||||
if args.platform is None:
|
||||
self.build_ios = True
|
||||
self.build_mac = True
|
||||
self.build_win = True
|
||||
self.build_android = True
|
||||
else:
|
||||
self.build_ios = False
|
||||
self.build_mac = False
|
||||
self.build_win = False
|
||||
self.build_android = False
|
||||
if 'win32' in args.platform:
|
||||
self.build_win = True
|
||||
if 'ios' in args.platform:
|
||||
self.build_ios = True
|
||||
if 'mac' in args.platform:
|
||||
self.build_mac = True
|
||||
if 'android' in args.platform:
|
||||
self.build_android = True
|
||||
|
||||
self.disable_strip = args.disable_strip
|
||||
self.vs_version = args.vs_version
|
||||
self.use_incredibuild = False
|
||||
if args.app_abi is None:
|
||||
self.app_abi = 'armeabi'
|
||||
else:
|
||||
self.app_abi = args.app_abi
|
||||
self.android_platform = args.android_platform
|
||||
self.use_studio = args.use_studio
|
||||
|
||||
|
||||
self.lib_dir = os.path.normpath(os.path.join(self.repo_x, self.cfg_info[LibsCompiler.KEY_LIBS_OUTPUT]))
|
||||
|
||||
def parse_config(self):
|
||||
if not os.path.isfile(self.cfg_file_path):
|
||||
raise CCPluginError(MultiLanguage.get_string('GEN_LIBS_ERROR_WRONG_FILE_FMT', self.cfg_file_path),
|
||||
CCPluginError.ERROR_PATH_NOT_FOUND)
|
||||
|
||||
try:
|
||||
f = open(self.cfg_file_path)
|
||||
self.cfg_info = json.load(f)
|
||||
f.close()
|
||||
except:
|
||||
raise CCPluginError(MultiLanguage.get_string('GEN_LIBS_ERROR_PARSE_FILE_FMT', self.cfg_file_path),
|
||||
CCPluginError.ERROR_PARSE_FILE)
|
||||
|
||||
for k in LibsCompiler.CHECK_KEYS:
|
||||
if k not in self.cfg_info.keys():
|
||||
raise CCPluginError(MultiLanguage.get_string('GEN_LIBS_ERROR_KEY_NOT_FOUND_FMT', (k, self.cfg_file_path)),
|
||||
CCPluginError.ERROR_WRONG_CONFIG)
|
||||
|
||||
def get_cfg_info(self):
|
||||
return self.cfg_info
|
||||
|
||||
def compile(self):
|
||||
if self.clean:
|
||||
self.clean_libs()
|
||||
|
||||
if cocos.os_is_mac():
|
||||
if self.build_mac or self.build_ios:
|
||||
self.compile_mac_ios()
|
||||
|
||||
if cocos.os_is_win32():
|
||||
if self.build_win:
|
||||
self.compile_win()
|
||||
|
||||
if self.build_android:
|
||||
self.compile_android()
|
||||
# generate prebuilt mk files
|
||||
self.modify_binary_mk()
|
||||
|
||||
def build_win32_proj(self, cmd_path, sln_path, proj_name, mode):
|
||||
build_cmd = " ".join([
|
||||
"\"%s\"" % cmd_path,
|
||||
"\"%s\"" % sln_path,
|
||||
"/t:%s" % proj_name,
|
||||
"/property:Configuration=%s" % mode,
|
||||
"/m"
|
||||
])
|
||||
self._run_cmd(build_cmd)
|
||||
|
||||
def compile_win(self):
|
||||
if self.mode == 'debug':
|
||||
mode_str = 'Debug'
|
||||
else:
|
||||
mode_str = 'Release'
|
||||
|
||||
# get the VS versions will be used for compiling
|
||||
support_vs_versions = self.cfg_info[LibsCompiler.KEY_SUPPORT_VS_VERSIONS]
|
||||
compile_vs_versions = support_vs_versions
|
||||
if self.vs_version is not None:
|
||||
if self.vs_version not in support_vs_versions:
|
||||
raise CCPluginError(MultiLanguage.get_string('GEN_LIBS_ERROR_NOT_SUPPORT_VS_FMT', self.vs_version),
|
||||
CCPluginError.ERROR_WRONG_ARGS)
|
||||
else:
|
||||
compile_vs_versions = [ self.vs_version ]
|
||||
|
||||
vs_cmd_info = {}
|
||||
for vs_version in compile_vs_versions:
|
||||
# get the vs command with specified version
|
||||
vs_command = utils.get_msbuild_path(vs_version)
|
||||
if vs_command is None:
|
||||
Logging.warning(MultiLanguage.get_string('GEN_LIBS_WARNING_VS_NOT_FOUND_FMT', vs_version))
|
||||
else:
|
||||
vs_cmd_info[vs_version] = vs_command
|
||||
|
||||
if len(vs_cmd_info) == 0:
|
||||
raise CCPluginError(MultiLanguage.get_string('GEN_LIBS_ERROR_VS_NOT_FOUND'),
|
||||
CCPluginError.ERROR_TOOLS_NOT_FOUND)
|
||||
|
||||
cocos2d_proj_file = os.path.join(self.repo_x, 'cocos/2d/libcocos2d.vcxproj')
|
||||
|
||||
# get the VS projects info
|
||||
win32_proj_info = self.cfg_info[LibsCompiler.KEY_VS_PROJS_INFO]
|
||||
for vs_version in compile_vs_versions:
|
||||
if not vs_version in vs_cmd_info.keys():
|
||||
continue
|
||||
|
||||
# rename the cocos2d project out dll name
|
||||
f = open(cocos2d_proj_file, 'r')
|
||||
old_file_content = f.read()
|
||||
f.close()
|
||||
|
||||
new_file_content = old_file_content.replace('$(OutDir)$(ProjectName).dll', '$(OutDir)$(ProjectName)_%d.dll' % vs_version)
|
||||
f = open(cocos2d_proj_file, 'w')
|
||||
f.write(new_file_content)
|
||||
f.close()
|
||||
|
||||
try:
|
||||
vs_command = vs_cmd_info[vs_version]
|
||||
for key in win32_proj_info.keys():
|
||||
# clean solutions
|
||||
proj_path = os.path.join(self.repo_x, key)
|
||||
clean_cmd = " ".join([
|
||||
"\"%s\"" % vs_command,
|
||||
"\"%s\"" % proj_path,
|
||||
"/t:Clean /p:Configuration=%s" % mode_str
|
||||
])
|
||||
self._run_cmd(clean_cmd)
|
||||
|
||||
for key in win32_proj_info.keys():
|
||||
output_dir = os.path.join(self.lib_dir, "win32")
|
||||
proj_path = os.path.join(self.repo_x, key)
|
||||
|
||||
# get the build folder & win32 output folder
|
||||
build_folder_path = os.path.join(os.path.dirname(proj_path), "%s.win32" % mode_str)
|
||||
win32_output_dir = os.path.join(self.repo_x, output_dir)
|
||||
if not os.path.exists(win32_output_dir):
|
||||
os.makedirs(win32_output_dir)
|
||||
|
||||
# build project
|
||||
if self.use_incredibuild:
|
||||
# use incredibuild, build whole sln
|
||||
build_cmd = " ".join([
|
||||
"BuildConsole",
|
||||
"%s" % proj_path,
|
||||
"/build",
|
||||
"/cfg=\"%s|Win32\"" % mode_str
|
||||
])
|
||||
self._run_cmd(build_cmd)
|
||||
else:
|
||||
for proj_name in win32_proj_info[key][LibsCompiler.KEY_VS_BUILD_TARGETS]:
|
||||
# build the projects
|
||||
self.build_win32_proj(vs_command, proj_path, proj_name, mode_str)
|
||||
|
||||
# copy the libs into prebuilt dir
|
||||
for file_name in os.listdir(build_folder_path):
|
||||
name, ext = os.path.splitext(file_name)
|
||||
if ext != ".lib" and ext != ".dll":
|
||||
continue
|
||||
|
||||
file_path = os.path.join(build_folder_path, file_name)
|
||||
shutil.copy(file_path, win32_output_dir)
|
||||
|
||||
# rename the specified libs
|
||||
suffix = "_%d" % vs_version
|
||||
for proj_name in win32_proj_info[key][LibsCompiler.KEY_VS_RENAME_TARGETS]:
|
||||
src_name = os.path.join(win32_output_dir, "%s.lib" % proj_name)
|
||||
dst_name = os.path.join(win32_output_dir, "%s%s.lib" % (proj_name, suffix))
|
||||
if not os.path.exists(src_name):
|
||||
raise CCPluginError(MultiLanguage.get_string('GEN_LIBS_ERROR_LIB_NOT_GEN_FMT', src_name),
|
||||
CCPluginError.ERROR_PATH_NOT_FOUND)
|
||||
|
||||
if os.path.exists(dst_name):
|
||||
os.remove(dst_name)
|
||||
os.rename(src_name, dst_name)
|
||||
except Exception as e:
|
||||
raise e
|
||||
finally:
|
||||
f = open(cocos2d_proj_file, 'w')
|
||||
f.write(old_file_content)
|
||||
f.close()
|
||||
|
||||
def compile_mac_ios(self):
|
||||
xcode_proj_info = self.cfg_info[LibsCompiler.KEY_XCODE_PROJS_INFO]
|
||||
if self.mode == 'debug':
|
||||
mode_str = 'Debug'
|
||||
else:
|
||||
mode_str = 'Release'
|
||||
|
||||
XCODE_CMD_FMT = "xcodebuild -project \"%s\" -configuration %s -target \"%s\" %s CONFIGURATION_BUILD_DIR=%s"
|
||||
ios_out_dir = os.path.join(self.lib_dir, "ios")
|
||||
mac_out_dir = os.path.join(self.lib_dir, "mac")
|
||||
ios_sim_libs_dir = os.path.join(ios_out_dir, "simulator")
|
||||
ios_dev_libs_dir = os.path.join(ios_out_dir, "device")
|
||||
for key in xcode_proj_info.keys():
|
||||
proj_path = os.path.join(self.repo_x, key)
|
||||
target = xcode_proj_info[key][LibsCompiler.KEY_XCODE_TARGETS]
|
||||
|
||||
if self.build_mac:
|
||||
# compile mac
|
||||
build_cmd = XCODE_CMD_FMT % (proj_path, mode_str, "%s Mac" % target, "", mac_out_dir)
|
||||
self._run_cmd(build_cmd)
|
||||
|
||||
if self.build_ios:
|
||||
# compile ios simulator
|
||||
build_cmd = XCODE_CMD_FMT % (proj_path, mode_str, "%s iOS" % target, "-sdk iphonesimulator ARCHS=\"i386 x86_64\" VALID_ARCHS=\"i386 x86_64\"", ios_sim_libs_dir)
|
||||
build_cmd += ' ONLY_ACTIVE_ARCH=NO'
|
||||
self._run_cmd(build_cmd)
|
||||
|
||||
# compile ios device
|
||||
build_cmd = XCODE_CMD_FMT % (proj_path, mode_str, "%s iOS" % target, "-sdk iphoneos", ios_dev_libs_dir)
|
||||
self._run_cmd(build_cmd)
|
||||
|
||||
if self.build_ios:
|
||||
# generate fat libs for iOS
|
||||
for lib in os.listdir(ios_sim_libs_dir):
|
||||
sim_lib = os.path.join(ios_sim_libs_dir, lib)
|
||||
dev_lib = os.path.join(ios_dev_libs_dir, lib)
|
||||
output_lib = os.path.join(ios_out_dir, lib)
|
||||
lipo_cmd = "lipo -create -output \"%s\" \"%s\" \"%s\"" % (output_lib, sim_lib, dev_lib)
|
||||
|
||||
self._run_cmd(lipo_cmd)
|
||||
|
||||
# remove the simulator & device libs in iOS
|
||||
utils.rmdir(ios_sim_libs_dir)
|
||||
utils.rmdir(ios_dev_libs_dir)
|
||||
|
||||
if not self.disable_strip:
|
||||
# strip the libs
|
||||
if self.build_ios:
|
||||
ios_strip_cmd = "xcrun -sdk iphoneos strip -S %s/*.a" % ios_out_dir
|
||||
self._run_cmd(ios_strip_cmd)
|
||||
if self.build_mac:
|
||||
mac_strip_cmd = "xcrun strip -S %s/*.a" % mac_out_dir
|
||||
self._run_cmd(mac_strip_cmd)
|
||||
|
||||
def compile_android(self):
|
||||
# build .so for android
|
||||
CONSOLE_PATH = "tools/cocos2d-console/bin"
|
||||
ANDROID_A_PATH = "frameworks/runtime-src/proj.android/obj/local"
|
||||
if self.use_studio is not None:
|
||||
ANDROID_A_PATH = "frameworks/runtime-src/proj.android-studio/app/build/intermediates/ndkBuild/" + self.mode + "/obj/local"
|
||||
|
||||
android_out_dir = os.path.join(self.lib_dir, "android")
|
||||
engine_dir = self.repo_x
|
||||
console_dir = os.path.join(engine_dir, CONSOLE_PATH)
|
||||
cocos_py_path = os.path.join(console_dir, 'cocos.py')
|
||||
|
||||
# build the simulator project
|
||||
proj_path = os.path.join(engine_dir, 'tools/simulator')
|
||||
python_path = cocos.check_environment_variable('COCOS_PYTHON_HOME', raise_error=False)
|
||||
if python_path is None:
|
||||
python_path = 'python'
|
||||
else:
|
||||
python_path = os.path.join(python_path, 'python')
|
||||
build_cmd = "\"%s\" \"%s\" compile -s %s -p android --ndk-mode %s --app-abi %s -m %s" % (python_path, cocos_py_path, proj_path, self.mode, self.app_abi, self.mode)
|
||||
if self.android_platform is not None:
|
||||
build_cmd += ' --ap %s' % self.android_platform
|
||||
if self.use_studio is not None:
|
||||
build_cmd += ' --android-studio'
|
||||
|
||||
env_param = ExtendEnv.get_extend_env_str()
|
||||
if env_param and len(env_param) > 0:
|
||||
build_cmd += (' --env "%s"' % env_param)
|
||||
self._run_cmd(build_cmd)
|
||||
|
||||
# copy .a to prebuilt dir
|
||||
obj_dir = os.path.join(proj_path, ANDROID_A_PATH)
|
||||
copy_cfg = {
|
||||
"from": obj_dir,
|
||||
"to": android_out_dir,
|
||||
"include": [
|
||||
"*.a$"
|
||||
]
|
||||
}
|
||||
cocos.copy_files_with_config(copy_cfg, obj_dir, android_out_dir)
|
||||
|
||||
if not self.disable_strip:
|
||||
# strip the android libs
|
||||
ndk_root = cocos.check_environment_variable("NDK_ROOT")
|
||||
if cocos.os_is_win32():
|
||||
if cocos.os_is_32bit_windows():
|
||||
check_bits = [ "", "-x86_64" ]
|
||||
else:
|
||||
check_bits = [ "-x86_64", "" ]
|
||||
|
||||
sys_folder_name = "windows"
|
||||
for bit_str in check_bits:
|
||||
check_folder_name = "windows%s" % bit_str
|
||||
check_path = os.path.join(ndk_root, "toolchains/arm-linux-androideabi-4.9/prebuilt/%s" % check_folder_name)
|
||||
if os.path.isdir(check_path):
|
||||
sys_folder_name = check_folder_name
|
||||
break
|
||||
elif cocos.os_is_mac():
|
||||
sys_folder_name = "darwin-x86_64"
|
||||
else:
|
||||
sys_folder_name = "linux-x86_64"
|
||||
|
||||
# set strip execute file name
|
||||
if cocos.os_is_win32():
|
||||
strip_execute_name = "strip.exe"
|
||||
else:
|
||||
strip_execute_name = "strip"
|
||||
|
||||
# strip arm libs
|
||||
strip_cmd_path = os.path.join(ndk_root, "toolchains/arm-linux-androideabi-4.9/prebuilt/%s/arm-linux-androideabi/bin/%s"
|
||||
% (sys_folder_name, strip_execute_name))
|
||||
if os.path.exists(strip_cmd_path):
|
||||
armlibs = ["armeabi", "armeabi-v7a"]
|
||||
for fold in armlibs:
|
||||
self.trip_libs(strip_cmd_path, os.path.join(android_out_dir, fold))
|
||||
else:
|
||||
raise Exception("(%s) wasn't found." % strip_cmd_path)
|
||||
|
||||
# strip arm64-v8a libs
|
||||
strip_cmd_path = os.path.join(ndk_root, "toolchains/aarch64-linux-android-4.9/prebuilt/%s/aarch64-linux-android/bin/%s" % (sys_folder_name, strip_execute_name))
|
||||
if os.path.exists(strip_cmd_path):
|
||||
if os.path.exists(os.path.join(android_out_dir, "arm64-v8a")):
|
||||
self.trip_libs(strip_cmd_path, os.path.join(android_out_dir, 'arm64-v8a'))
|
||||
else:
|
||||
raise Exception("(%s) wasn't found." % strip_cmd_path)
|
||||
|
||||
# strip x86 libs
|
||||
strip_cmd_path = os.path.join(ndk_root, "toolchains/x86-4.9/prebuilt/%s/i686-linux-android/bin/%s" % (sys_folder_name, strip_execute_name))
|
||||
if os.path.exists(strip_cmd_path):
|
||||
if os.path.exists(os.path.join(android_out_dir, "x86")):
|
||||
self.trip_libs(strip_cmd_path, os.path.join(android_out_dir, 'x86'))
|
||||
else:
|
||||
raise Exception("(%s) wasn't found." % strip_cmd_path)
|
||||
|
||||
def trip_libs(self, strip_cmd, folder):
|
||||
if not os.path.isdir(folder):
|
||||
return
|
||||
|
||||
if cocos.os_is_win32():
|
||||
for name in os.listdir(folder):
|
||||
basename, ext = os.path.splitext(name)
|
||||
if ext == ".a":
|
||||
full_name = os.path.join(folder, name)
|
||||
command = "%s -S %s" % (strip_cmd, full_name)
|
||||
self._run_cmd(command)
|
||||
else:
|
||||
strip_cmd = "%s -S %s/*.a" % (strip_cmd, folder)
|
||||
self._run_cmd(strip_cmd)
|
||||
|
||||
def modify_binary_mk(self):
|
||||
android_libs = os.path.join(self.lib_dir, "android")
|
||||
android_mks = self.cfg_info[LibsCompiler.KEY_ANDROID_MKS]
|
||||
for mk_file in android_mks:
|
||||
mk_file_path = os.path.join(self.repo_x, mk_file)
|
||||
dst_file_path = os.path.join(os.path.dirname(mk_file_path), "prebuilt-mk", os.path.basename(mk_file_path))
|
||||
tmp_obj = gen_prebuilt_mk.MKGenerator(mk_file_path, android_libs, dst_file_path)
|
||||
tmp_obj.do_generate()
|
||||
|
||||
def clean_libs(self):
|
||||
utils.rmdir(self.lib_dir)
|
||||
363
cocos2d-x/tools/cocos2d-console/plugins/plugin_generate/gen_prebuilt_mk.py
Executable file
@@ -0,0 +1,363 @@
|
||||
#!/usr/bin/python
|
||||
# ----------------------------------------------------------------------------
|
||||
# generate the prebuilt Android.mk from source code Android.mk
|
||||
#
|
||||
# Copyright 2014 (C) zhangbin
|
||||
#
|
||||
# License: MIT
|
||||
# ----------------------------------------------------------------------------
|
||||
'''
|
||||
generate the prebuilt Android.mk from source code Android.mk
|
||||
'''
|
||||
|
||||
import os
|
||||
import shutil
|
||||
import re
|
||||
|
||||
from argparse import ArgumentParser
|
||||
|
||||
class MKGenerator(object):
|
||||
|
||||
SRC_FILE_CFG_PATTERN = r"^LOCAL_SRC_FILES[ \t]+[\:\+]=[ \t]+.+"
|
||||
INCLUDE_CFG_PATTERN = r"^include[ \t]+\$\(BUILD_STATIC_LIBRARY\)"
|
||||
|
||||
LIB_MODULE_PATTERN = r"^LOCAL_MODULE[ \t]+\:=[ \t]+(.+)"
|
||||
LIB_MODULE_FILENAME_PATTERN = r"^LOCAL_MODULE_FILENAME[ \t]+\:=[ \t]+(.+)"
|
||||
|
||||
EXPORT_INCLUDE_PATTERN = r"^LOCAL_EXPORT_C_INCLUDES[ \t]+[\:\+]=[ \t]+(.+)"
|
||||
INCLUDE_MODULE_PATTERN = r"^\$\(call[ \t]*import-module,[ \t]*(.*)\)"
|
||||
|
||||
|
||||
KEY_IS_MODULE = 'is_module'
|
||||
KEY_MODULE_LINES = 'lines'
|
||||
|
||||
def __init__(self, src_mk_path, lib_file_path, dst_mk_path=None):
|
||||
if os.path.isabs(src_mk_path):
|
||||
self.src_mk_path = src_mk_path
|
||||
else:
|
||||
self.src_mk_path = os.path.abspath(src_mk_path)
|
||||
|
||||
if os.path.isabs(lib_file_path):
|
||||
self.lib_file_path = lib_file_path
|
||||
else:
|
||||
self.lib_file_path = os.path.abspath(lib_file_path)
|
||||
|
||||
if dst_mk_path is None:
|
||||
self.dst_mk_path = os.path.join(os.path.dirname(src_mk_path), "Android-prebuilt.mk")
|
||||
else:
|
||||
if os.path.isabs(dst_mk_path):
|
||||
self.dst_mk_path = dst_mk_path
|
||||
else:
|
||||
self.dst_mk_path = os.path.abspath(dst_mk_path)
|
||||
|
||||
dst_mk_dir = os.path.dirname(self.dst_mk_path)
|
||||
if not os.path.exists(dst_mk_dir):
|
||||
os.makedirs(dst_mk_dir)
|
||||
|
||||
def get_lib_file_name(self, lines):
|
||||
module_file_name = None
|
||||
module_name = None
|
||||
for line in lines:
|
||||
trim_line = line.lstrip(" ")
|
||||
trim_line = trim_line.rstrip(" ")
|
||||
match1 = re.match(MKGenerator.LIB_MODULE_FILENAME_PATTERN, trim_line)
|
||||
if match1 is not None:
|
||||
module_file_name = match1.group(1)
|
||||
|
||||
match2 = re.match(MKGenerator.LIB_MODULE_PATTERN, trim_line)
|
||||
if match2 is not None:
|
||||
module_name = match2.group(1)
|
||||
|
||||
ret = None
|
||||
if module_file_name is not None:
|
||||
ret = "%s.a" % module_file_name
|
||||
elif module_name is not None:
|
||||
ret = "lib%s.a" % module_name
|
||||
|
||||
return ret
|
||||
|
||||
def modidy_src_file(self, lines, new_src_file):
|
||||
new_lines = []
|
||||
|
||||
src_file_begin_flag = False
|
||||
added = False
|
||||
found_src_file_cfg = False
|
||||
for line in lines:
|
||||
trim_line = line.lstrip(" ")
|
||||
if re.match(MKGenerator.SRC_FILE_CFG_PATTERN, trim_line):
|
||||
found_src_file_cfg = True
|
||||
if not added:
|
||||
new_lines.append("LOCAL_SRC_FILES := %s\n" % new_src_file)
|
||||
added = True
|
||||
if line.endswith("\\\n"):
|
||||
src_file_begin_flag = True
|
||||
elif src_file_begin_flag:
|
||||
if not line.endswith("\\\n"):
|
||||
src_file_begin_flag = False
|
||||
else:
|
||||
new_lines.append(line)
|
||||
|
||||
if not found_src_file_cfg:
|
||||
ret_lines = []
|
||||
for line in new_lines:
|
||||
ret_lines.append(line)
|
||||
if re.match(MKGenerator.LIB_MODULE_FILENAME_PATTERN, line):
|
||||
ret_lines.append("LOCAL_SRC_FILES := %s\n" % new_src_file)
|
||||
else:
|
||||
ret_lines = new_lines
|
||||
|
||||
return ret_lines
|
||||
|
||||
def remove_config(self, lines, cfg_key):
|
||||
new_lines = []
|
||||
cfg_begin = False
|
||||
line_pattern = r"^%s[ ]+[\+\:]=[ ]+.+" % cfg_key
|
||||
for line in lines:
|
||||
trim_line = line.lstrip(" ")
|
||||
if re.match(line_pattern, trim_line):
|
||||
if line.endswith("\\\n"):
|
||||
cfg_begin = True
|
||||
elif cfg_begin:
|
||||
if not line.endswith("\\\n"):
|
||||
cfg_begin = False
|
||||
else:
|
||||
new_lines.append(line)
|
||||
|
||||
return new_lines
|
||||
|
||||
def modify_export_c_include(self, lines):
|
||||
if self.src_mk_path == self.dst_mk_path:
|
||||
return lines
|
||||
|
||||
new_lines = []
|
||||
insert_idx = -1
|
||||
cur_idx = 0
|
||||
include_paths = []
|
||||
cfg_begin = False
|
||||
for line in lines:
|
||||
trim_line = line.lstrip(" ")
|
||||
match = re.match(MKGenerator.EXPORT_INCLUDE_PATTERN, trim_line)
|
||||
if match is not None:
|
||||
if insert_idx == -1:
|
||||
insert_idx = cur_idx
|
||||
|
||||
path_str = match.group(1)
|
||||
if line.endswith("\\\n"):
|
||||
cfg_begin = True
|
||||
path_str = path_str.replace("\\", "")
|
||||
include_paths += path_str.split()
|
||||
elif cfg_begin:
|
||||
path_str = trim_line
|
||||
if line.endswith("\\\n"):
|
||||
path_str = path_str.replace("\\\n", "")
|
||||
else:
|
||||
cfg_begin = False
|
||||
|
||||
include_paths += path_str.split()
|
||||
else:
|
||||
new_lines.append(line)
|
||||
cur_idx += 1
|
||||
|
||||
src_dir = os.path.dirname(self.src_mk_path)
|
||||
dst_dir = os.path.dirname(self.dst_mk_path)
|
||||
rel_path = os.path.relpath(src_dir, dst_dir)
|
||||
new_include_paths = []
|
||||
for include_path in include_paths:
|
||||
if include_path.startswith("$(LOCAL_PATH)"):
|
||||
new_path = include_path.replace("$(LOCAL_PATH)", "$(LOCAL_PATH)/%s" % rel_path)
|
||||
else:
|
||||
new_path = "$(LOCAL_PATH)/%s/%s" % (rel_path, include_path)
|
||||
new_include_paths.append(new_path)
|
||||
|
||||
if len(new_include_paths) > 0:
|
||||
new_path_str = "LOCAL_EXPORT_C_INCLUDES := "
|
||||
new_path_str += " \\\n".join(new_include_paths)
|
||||
new_path_str += "\n"
|
||||
if insert_idx >= 0:
|
||||
new_lines.insert(insert_idx, new_path_str)
|
||||
else:
|
||||
new_lines.append(new_path_str)
|
||||
|
||||
return new_lines
|
||||
|
||||
def modify_include_cfg(self, lines):
|
||||
new_lines = []
|
||||
|
||||
for line in lines:
|
||||
trim_line = line.lstrip(" ")
|
||||
if re.match(MKGenerator.INCLUDE_CFG_PATTERN, trim_line):
|
||||
new_lines.append("include $(PREBUILT_STATIC_LIBRARY)\n")
|
||||
else:
|
||||
new_lines.append(line)
|
||||
|
||||
return new_lines
|
||||
|
||||
def modify_import_module(self, lines):
|
||||
if self.src_mk_path == self.dst_mk_path:
|
||||
return lines
|
||||
|
||||
new_lines = []
|
||||
|
||||
ignore_strs = [
|
||||
"prebuilt",
|
||||
"sources"
|
||||
]
|
||||
ignore_modules = [
|
||||
"android",
|
||||
"android/cpufeatures"
|
||||
]
|
||||
|
||||
for line in lines:
|
||||
trim_line = line.lstrip(" ")
|
||||
match = re.match(MKGenerator.INCLUDE_MODULE_PATTERN, trim_line)
|
||||
if match is not None:
|
||||
module = match.group(1)
|
||||
need_modify = True
|
||||
for str in ignore_strs:
|
||||
if module.find(str) >= 0:
|
||||
need_modify = False
|
||||
break
|
||||
for im in ignore_modules:
|
||||
if module == im:
|
||||
need_modify = False
|
||||
break
|
||||
|
||||
if need_modify:
|
||||
new_lines.append("$(call import-module, %s/prebuilt-mk)\n" % module)
|
||||
else:
|
||||
new_lines.append(line)
|
||||
else:
|
||||
new_lines.append(line)
|
||||
|
||||
return new_lines
|
||||
|
||||
def use_whole_lib(self, lines):
|
||||
new_lines = []
|
||||
for line in lines:
|
||||
new_line = line.replace("LOCAL_STATIC_LIBRARIES", "LOCAL_WHOLE_STATIC_LIBRARIES")
|
||||
new_lines.append(new_line)
|
||||
|
||||
ret_lines = []
|
||||
is_first_time = True
|
||||
pattern = r'LOCAL_WHOLE_STATIC_LIBRARIES[ \t]*:=.*'
|
||||
for line in new_lines:
|
||||
ret_line = line
|
||||
if re.match(pattern, line):
|
||||
if is_first_time:
|
||||
is_first_time = False
|
||||
else:
|
||||
ret_line = line.replace(":=", "+=")
|
||||
|
||||
ret_lines.append(ret_line)
|
||||
|
||||
return ret_lines
|
||||
|
||||
def split_modules(self, origin_lines):
|
||||
ret = []
|
||||
cur_module = {}
|
||||
cur_module[MKGenerator.KEY_MODULE_LINES] = []
|
||||
cur_module[MKGenerator.KEY_IS_MODULE] = False
|
||||
|
||||
pattern_begin = r'include[ \t]+\$\(CLEAR_VARS\)'
|
||||
pattern_end = r'include[ \t]+\$\(BUILD_STATIC_LIBRARY\)'
|
||||
for line in origin_lines:
|
||||
if re.match(pattern_begin, line):
|
||||
if len(cur_module[MKGenerator.KEY_MODULE_LINES]) > 0:
|
||||
ret.append(cur_module)
|
||||
|
||||
cur_module = {}
|
||||
cur_module[MKGenerator.KEY_MODULE_LINES] = []
|
||||
cur_module[MKGenerator.KEY_IS_MODULE] = True
|
||||
|
||||
cur_module[MKGenerator.KEY_MODULE_LINES].append(line)
|
||||
|
||||
if re.match(pattern_end, line):
|
||||
if len(cur_module[MKGenerator.KEY_MODULE_LINES]) > 0:
|
||||
ret.append(cur_module)
|
||||
cur_module = {}
|
||||
cur_module[MKGenerator.KEY_MODULE_LINES] = []
|
||||
cur_module[MKGenerator.KEY_IS_MODULE] = False
|
||||
|
||||
if len(cur_module[MKGenerator.KEY_MODULE_LINES]) > 0:
|
||||
ret.append(cur_module)
|
||||
|
||||
return ret
|
||||
|
||||
def handle_module(self, module_lines, relative_path):
|
||||
# modify the LOCAL_SRC_FILES
|
||||
lib_file_name = self.get_lib_file_name(module_lines)
|
||||
if lib_file_name is None:
|
||||
raise Exception("The mk file %s not specify module name." % self.src_mk_path)
|
||||
|
||||
# .mk file can not use '\' as the path seperator
|
||||
relative_path = relative_path.replace('\\', '/');
|
||||
relative_path = "%s/$(TARGET_ARCH_ABI)/%s" % (relative_path, lib_file_name)
|
||||
|
||||
dst_lines = self.modidy_src_file(module_lines, relative_path)
|
||||
|
||||
# remove the LOCAL_C_INCLUDES & LOCAL_LDLIBS
|
||||
dst_lines = self.remove_config(dst_lines, "LOCAL_C_INCLUDES")
|
||||
dst_lines = self.remove_config(dst_lines, "LOCAL_LDLIBS")
|
||||
|
||||
# modify the LOCAL_EXPORT_C_INCLUDES
|
||||
dst_lines = self.modify_export_c_include(dst_lines)
|
||||
|
||||
# modify the line $(include BUILD_STATIC_LIBRARY)
|
||||
dst_lines = self.modify_include_cfg(dst_lines)
|
||||
|
||||
# use whole libs
|
||||
dst_lines = self.use_whole_lib(dst_lines)
|
||||
|
||||
return dst_lines
|
||||
|
||||
def do_generate(self):
|
||||
src_mk_obj = open(self.src_mk_path)
|
||||
|
||||
# open the dst file
|
||||
tmp_file = "%s-tmp" % self.src_mk_path
|
||||
use_tmp_file = False
|
||||
if self.dst_mk_path == self.src_mk_path:
|
||||
use_tmp_file = True
|
||||
dst_mk_obj = open(tmp_file, "w")
|
||||
else:
|
||||
dst_mk_obj = open(self.dst_mk_path, "w")
|
||||
|
||||
relative_path = os.path.relpath(self.lib_file_path, os.path.dirname(self.dst_mk_path))
|
||||
|
||||
# read the src file
|
||||
src_lines = src_mk_obj.readlines()
|
||||
|
||||
modules = self.split_modules(src_lines)
|
||||
dst_lines = []
|
||||
for module in modules:
|
||||
if module[MKGenerator.KEY_IS_MODULE]:
|
||||
ret_lines = self.handle_module(module[MKGenerator.KEY_MODULE_LINES], relative_path)
|
||||
else:
|
||||
ret_lines = module[MKGenerator.KEY_MODULE_LINES]
|
||||
|
||||
for l in ret_lines:
|
||||
dst_lines.append(l)
|
||||
|
||||
# modify the import-module
|
||||
dst_lines = self.modify_import_module(dst_lines)
|
||||
|
||||
dst_mk_obj.writelines(dst_lines)
|
||||
|
||||
#close files
|
||||
dst_mk_obj.close()
|
||||
src_mk_obj.close()
|
||||
|
||||
# rename the file if temp file used
|
||||
if use_tmp_file:
|
||||
os.remove(self.src_mk_path)
|
||||
os.rename(tmp_file, self.dst_mk_path)
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = ArgumentParser(description="Generate prebuilt engine for Cocos Engine.")
|
||||
parser.add_argument('-s', '--src-mk', dest='src_mk', help='The source Android.mk path.')
|
||||
parser.add_argument('-d', "--dst-mk", dest='dst_mk', help='The output path of Android.mk. Default is beside the source mk with name \"Android-prebuilt.mk\".')
|
||||
parser.add_argument('-l', "--lib-path", dest='lib_path', help='The lib file path.')
|
||||
(args, unknown) = parser.parse_known_args()
|
||||
|
||||
gen_obj = MKGenerator(args.src_mk, args.lib_path, args.dst_mk)
|
||||
gen_obj.do_generate()
|
||||
454
cocos2d-x/tools/cocos2d-console/plugins/plugin_generate/gen_simulator.py
Executable file
@@ -0,0 +1,454 @@
|
||||
#!/usr/bin/python
|
||||
#-*- coding: UTF-8 -*-
|
||||
# ----------------------------------------------------------------------------
|
||||
# Generate Cocos Simulator
|
||||
#
|
||||
# Copyright 2015 (C) zhangbin
|
||||
#
|
||||
# License: MIT
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import string
|
||||
import sys
|
||||
|
||||
import cocos
|
||||
from MultiLanguage import MultiLanguage
|
||||
import utils
|
||||
|
||||
from datetime import date
|
||||
from cocos import CCPluginError, Logging
|
||||
from argparse import ArgumentParser
|
||||
|
||||
class SimulatorCompiler(cocos.CCPlugin):
|
||||
SIMULATOR_PROJ_PATH = 'tools/simulator'
|
||||
SIMULATOR_SLN_PATH = "frameworks/runtime-src/proj.win32/simulator.sln"
|
||||
SIMULATOR_XCODE_PATH = "frameworks/runtime-src/proj.ios_mac/simulator.xcodeproj"
|
||||
COCOS_PY_PATH = 'tools/cocos2d-console/bin/cocos.py'
|
||||
|
||||
DEFAULT_OUTPUT_FOLDER_NAME = 'simulator'
|
||||
|
||||
@staticmethod
|
||||
def plugin_name():
|
||||
return "gen-simulator"
|
||||
|
||||
@staticmethod
|
||||
def brief_description():
|
||||
return MultiLanguage.get_string('GEN_SIM_BRIEF')
|
||||
|
||||
def parse_args(self, argv):
|
||||
parser = ArgumentParser(prog="cocos %s" % self.__class__.plugin_name(),
|
||||
description=self.__class__.brief_description())
|
||||
parser.add_argument('-c', '--clean', dest='do_clean', action='store_true',
|
||||
help=MultiLanguage.get_string('GEN_SIM_ARG_CLEAN'))
|
||||
parser.add_argument('-e', dest='engine_path', help=MultiLanguage.get_string('GEN_SIM_ARG_ENGINE'))
|
||||
parser.add_argument('-m', "--mode", dest='compile_mode', type=str, choices=['debug', 'release'],
|
||||
help=MultiLanguage.get_string('GEN_SIM_ARG_MODE'))
|
||||
parser.add_argument('-o', '--output', dest='out_dir',
|
||||
help=MultiLanguage.get_string('GEN_SIM_ARG_OUTPUT'))
|
||||
parser.add_argument('-p', dest='platform', action="append", choices=['ios', 'mac', 'android', 'win32'],
|
||||
help=MultiLanguage.get_string('GEN_SIM_ARG_PLATFORM'))
|
||||
parser.add_argument('--vs', dest='vs_version', type=int,
|
||||
help=MultiLanguage.get_string('GEN_SIM_ARG_VS'))
|
||||
|
||||
(args, unknown) = parser.parse_known_args()
|
||||
self.init(args)
|
||||
|
||||
return args
|
||||
|
||||
def init(self, args):
|
||||
if getattr(sys, 'frozen', None):
|
||||
self.cur_dir = os.path.realpath(os.path.dirname(sys.executable))
|
||||
self.default_engine_path = os.path.join(self.cur_dir, os.pardir, os.pardir, os.pardir)
|
||||
else:
|
||||
self.cur_dir = os.path.realpath(os.path.dirname(__file__))
|
||||
self.default_engine_path = os.path.join(self.cur_dir, os.pardir, os.pardir, os.pardir, os.pardir)
|
||||
self.default_engine_path = os.path.normpath(self.default_engine_path)
|
||||
|
||||
if args.engine_path is None:
|
||||
self.engine_root = self.default_engine_path
|
||||
else:
|
||||
engine_path = os.path.expanduser(args.engine_path)
|
||||
if os.path.isabs(engine_path):
|
||||
self.engine_root = os.path.normpath(engine_path)
|
||||
else:
|
||||
self.engine_root = os.path.normpath(os.path.abspath(engine_path))
|
||||
|
||||
if not os.path.isdir(self.engine_root):
|
||||
raise CCPluginError(MultiLanguage.get_string('GEN_SIM_ERROR_WRONG_PATH_FMT', self.engine_root),
|
||||
CCPluginError.ERROR_WRONG_ARGS)
|
||||
|
||||
self.simulator_abs_path = os.path.join(self.engine_root, SimulatorCompiler.SIMULATOR_PROJ_PATH)
|
||||
python_path = cocos.check_environment_variable('COCOS_PYTHON_HOME', raise_error=False)
|
||||
if python_path is None:
|
||||
python_path = 'python'
|
||||
else:
|
||||
python_path = os.path.join(python_path, 'python')
|
||||
cocos_py_path = os.path.join(self.engine_root, SimulatorCompiler.COCOS_PY_PATH)
|
||||
self.cocos_bin = '\"%s\" \"%s\"' % (python_path, cocos_py_path)
|
||||
engine_version = utils.get_engine_version(self.engine_root)
|
||||
# get the short version after "cocos2d-x-"
|
||||
self.engine_version = engine_version[10:]
|
||||
|
||||
# get the full path of output dir.
|
||||
if args.out_dir is None:
|
||||
self.simulator_output_dir = os.path.join(self.engine_root, SimulatorCompiler.DEFAULT_OUTPUT_FOLDER_NAME)
|
||||
else:
|
||||
out_dir = os.path.expanduser(args.out_dir)
|
||||
if os.path.isabs(out_dir):
|
||||
self.simulator_output_dir = os.path.normpath(out_dir)
|
||||
else:
|
||||
self.simulator_output_dir = os.path.normpath(os.path.abspath(out_dir))
|
||||
|
||||
# get arguments
|
||||
self.is_clean_before_build = args.do_clean
|
||||
if args.compile_mode is None:
|
||||
self.mode = 'debug'
|
||||
else:
|
||||
self.mode = args.compile_mode
|
||||
|
||||
if args.platform is None:
|
||||
self.build_ios = True
|
||||
self.build_mac = True
|
||||
self.build_win = True
|
||||
self.build_android = True
|
||||
else:
|
||||
self.build_ios = False
|
||||
self.build_mac = False
|
||||
self.build_win = False
|
||||
self.build_android = False
|
||||
if 'win32' in args.platform:
|
||||
self.build_win = True
|
||||
if 'ios' in args.platform:
|
||||
self.build_ios = True
|
||||
if 'mac' in args.platform:
|
||||
self.build_mac = True
|
||||
if 'android' in args.platform:
|
||||
self.build_android = True
|
||||
|
||||
self.build_log = ""
|
||||
self.vs_version = args.vs_version
|
||||
self._verbose = True
|
||||
|
||||
def replace_keyword_with_content(self,content,old,new):
|
||||
found_string = string.find(content,old) >= 0
|
||||
return found_string, string.replace(content,old,new)
|
||||
|
||||
def get_content_from_file(self,file_path):
|
||||
if not os.path.isfile(file_path):
|
||||
raise CCPluginError(MultiLanguage.get_string('GEN_SIM_ERROR_FILE_NOT_FOUND_FMT', file_path),
|
||||
CCPluginError.ERROR_PATH_NOT_FOUND)
|
||||
|
||||
with open(file_path) as f:
|
||||
return f.read()
|
||||
|
||||
def write_content_to_file(self,content, file_path):
|
||||
if not os.path.isfile(file_path):
|
||||
raise CCPluginError(MultiLanguage.get_string('GEN_SIM_ERROR_FILE_NOT_FOUND_FMT', file_path),
|
||||
CCPluginError.ERROR_PATH_NOT_FOUND)
|
||||
|
||||
with open(file_path, 'w') as f:
|
||||
f.write(content)
|
||||
|
||||
def replace_keyword_with_file(self,file_path,keyword_map):
|
||||
content = self.get_content_from_file(file_path)
|
||||
|
||||
found = False
|
||||
for k in keyword_map:
|
||||
old, new = k, keyword_map[k]
|
||||
has_found, content = self.replace_keyword_with_content(content, old, new)
|
||||
if has_found :
|
||||
found = has_found
|
||||
|
||||
if found == True:
|
||||
self.write_content_to_file(content,file_path)
|
||||
|
||||
def get_keywords(self):
|
||||
osx_keyword = {
|
||||
"CC_TARGET_OS_IPHONE,":"CC_TARGET_OS_IPHONE,\n\"COCOS2D_DEBUG=1\",",
|
||||
"CC_TARGET_OS_MAC,":"CC_TARGET_OS_MAC,\n\"COCOS2D_DEBUG=1\",",
|
||||
"COCOS2D_DEBUG=0":"COCOS2D_DEBUG=1",
|
||||
}
|
||||
|
||||
win_keyword = {
|
||||
"_WINDOWS":"_WINDOWS;COCOS2D_DEBUG=1",
|
||||
}
|
||||
|
||||
if cocos.os_is_mac():
|
||||
return osx_keyword
|
||||
if cocos.os_is_win32():
|
||||
return win_keyword
|
||||
|
||||
return {}
|
||||
|
||||
def convert_path_to_win32(self,path):
|
||||
return path.replace("/","\\")
|
||||
|
||||
def get_depend_project_file_list(self):
|
||||
file_list = []
|
||||
|
||||
if cocos.os_is_mac() and (self.build_mac or self.build_ios):
|
||||
IOS_MAC_PROJECT_SUFFIX = "project.pbxproj"
|
||||
IOS_MAC_PROJECT_REFERENCES_TAG = 'ProjectRef ='
|
||||
IOS_MAC_PROJECT_NAME_RE = r'\w+.xcodeproj'
|
||||
IOS_MAC_PROJECT_PATH_RE = r'name = %s; path = (.)*.xcodeproj'
|
||||
|
||||
project_file_path = os.path.join(self.simulator_abs_path,
|
||||
SimulatorCompiler.SIMULATOR_XCODE_PATH,
|
||||
IOS_MAC_PROJECT_SUFFIX)
|
||||
contents_str = self.get_content_from_file(project_file_path)
|
||||
lines = re.split(r'\n', contents_str)
|
||||
|
||||
simulator_mac_project_path = os.path.dirname(os.path.dirname(project_file_path))
|
||||
project_references = []
|
||||
for l in lines:
|
||||
if IOS_MAC_PROJECT_REFERENCES_TAG in l:
|
||||
ret = re.search(IOS_MAC_PROJECT_NAME_RE, l)
|
||||
if ret: project_references.append(ret.group(0))
|
||||
|
||||
for references in project_references:
|
||||
re_str = IOS_MAC_PROJECT_PATH_RE % references
|
||||
ret = re.search(re_str, contents_str)
|
||||
if ret:
|
||||
match_str = ret.group(0)
|
||||
match_str = match_str.replace("name = %s; path = " % references, "")
|
||||
match_str = match_str.replace('"', "")
|
||||
file_list.append(os.path.join(simulator_mac_project_path, match_str, IOS_MAC_PROJECT_SUFFIX))
|
||||
|
||||
if cocos.os_is_win32() and self.build_android:
|
||||
WIN32_PROJECT_TAG = "Project(\""
|
||||
project_file_path = os.path.join(self.simulator_abs_path, SimulatorCompiler.SIMULATOR_SLN_PATH)
|
||||
simulator_win32_project_path = os.path.dirname(project_file_path)
|
||||
|
||||
content_str = self.get_content_from_file(project_file_path)
|
||||
lines = content_str.split('\n')
|
||||
for l in lines:
|
||||
if l.startswith(WIN32_PROJECT_TAG):
|
||||
ret = re.compile('"(.*?)"').findall(l.split(',')[1])
|
||||
if ret:
|
||||
path = self.convert_path_to_win32(os.path.join(simulator_win32_project_path, ret[0]))
|
||||
file_list.append(path)
|
||||
|
||||
return file_list
|
||||
|
||||
def compile_for_osx(self):
|
||||
if self.is_clean_before_build:
|
||||
project_directory = os.path.join(self.simulator_abs_path, "frameworks/runtime-src/proj.ios_mac/")
|
||||
|
||||
command = "xcodebuild -alltargets -configuration %s clean" % ("Debug" if self.mode == 'debug' else 'Release')
|
||||
self._run_cmd(command, project_directory)
|
||||
|
||||
cocos_cmd = "%s compile -p mac -m %s -o \"%s\" --no-res --compile-script 0" % (self.cocos_bin
|
||||
, "debug" if self.mode == 'debug' else "release"
|
||||
, os.path.join(self.simulator_output_dir,"mac"))
|
||||
env_param = utils.ExtendEnv.get_extend_env_str()
|
||||
if env_param and len(env_param) > 0:
|
||||
cocos_cmd += (' --env "%s"' % env_param)
|
||||
|
||||
command = ' '.join([
|
||||
"mkdir -p %s" % (os.path.join(self.simulator_abs_path, "src")),
|
||||
" && %s" % cocos_cmd,
|
||||
# Don't strip executable file since Safari will not be able to detect JSContext for JSB project.
|
||||
# " && strip %s" % (os.path.join(self.simulator_output_dir,"mac/Simulator.app/Contents/MacOS/Simulator")),
|
||||
])
|
||||
|
||||
self._run_cmd(command, self.simulator_abs_path)
|
||||
self.build_log += MultiLanguage.get_string('GEN_SIM_BUILD_SUCCESS_FMT', ('Mac', self.mode))
|
||||
|
||||
def compile_for_ios(self):
|
||||
if self.is_clean_before_build:
|
||||
project_directory = os.path.join(self.simulator_abs_path, "frameworks/runtime-src/proj.ios_mac/")
|
||||
|
||||
command = "xcodebuild -alltargets -configuration %s clean" % ("Debug" if self.mode =='debug' else 'Release')
|
||||
self._run_cmd(command, project_directory)
|
||||
|
||||
cocos_cmd = " %s compile -p ios -m %s -o \"%s\" --no-res --compile-script 0" % (self.cocos_bin
|
||||
, "debug" if self.mode == 'debug' else "release"
|
||||
, os.path.join(self.simulator_output_dir,"ios"))
|
||||
env_param = utils.ExtendEnv.get_extend_env_str()
|
||||
if env_param and len(env_param) > 0:
|
||||
cocos_cmd += (' --env "%s"' % env_param)
|
||||
|
||||
command = ' '.join([
|
||||
cocos_cmd,
|
||||
" && strip %s" % (os.path.join(self.simulator_output_dir,"ios","Simulator.app/Simulator")),
|
||||
" && rm -fr %s" % (os.path.join(self.simulator_output_dir,"ios","Simulator.app.dSYM")),
|
||||
])
|
||||
|
||||
self._run_cmd(command, self.simulator_abs_path)
|
||||
self.build_log += MultiLanguage.get_string('GEN_SIM_BUILD_SUCCESS_FMT', ('iOS', self.mode))
|
||||
|
||||
def compile_for_win32(self):
|
||||
win32_output_dir = os.path.join(self.simulator_output_dir, "win32")
|
||||
win32_output_dir = self.convert_path_to_win32(win32_output_dir)
|
||||
if not os.path.isdir(win32_output_dir):
|
||||
os.makedirs(win32_output_dir)
|
||||
|
||||
lang_file_path = os.path.join(self.simulator_abs_path, "frameworks/runtime-src/Classes/ide-support/lang")
|
||||
lang_copy_command = "xcopy /Y %s %s" % (self.convert_path_to_win32(lang_file_path), win32_output_dir)
|
||||
|
||||
# get the vs version should be used
|
||||
if self.vs_version is None:
|
||||
ver_param = ''
|
||||
else:
|
||||
ver_param = '--vs %d' % self.vs_version
|
||||
|
||||
env_param = utils.ExtendEnv.get_extend_env_str()
|
||||
if self.mode == 'debug':
|
||||
win32_src_dir = os.path.join(self.simulator_abs_path,"runtime/win32/")
|
||||
win32_src_dir = self.convert_path_to_win32(win32_src_dir)
|
||||
win32_dll_dir = self.convert_path_to_win32(os.path.join(os.path.dirname(self.cur_dir),"dll/"))
|
||||
cocos_cmd = " %s compile -p win32 -m debug --no-res --compile-script 0 %s" % (self.cocos_bin, ver_param)
|
||||
if env_param and len(env_param) > 0:
|
||||
cocos_cmd += (' --env "%s"' % env_param)
|
||||
|
||||
command = ' '.join([
|
||||
cocos_cmd,
|
||||
" && xcopy /Y %s*.dll %s" % (win32_src_dir, win32_output_dir),
|
||||
" && xcopy /Y %s*.exe %s" % (win32_src_dir, win32_output_dir),
|
||||
" && %s" % (lang_copy_command),
|
||||
" && if exist %s*.dll xcopy /Y %s*.dll %s" % (win32_dll_dir,win32_dll_dir,win32_output_dir)
|
||||
])
|
||||
else:
|
||||
cocos_cmd = " %s compile -p win32 -m release --no-res --compile-script 0 -o %s %s" % (self.cocos_bin,win32_output_dir,ver_param)
|
||||
if env_param and len(env_param) > 0:
|
||||
cocos_cmd += (' --env "%s"' % env_param)
|
||||
command = ' '.join([
|
||||
cocos_cmd,
|
||||
" && %s" % (lang_copy_command),
|
||||
])
|
||||
|
||||
self._run_cmd(command, self.simulator_abs_path)
|
||||
self.build_log += MultiLanguage.get_string('GEN_SIM_BUILD_SUCCESS_FMT', ('Win32', self.mode))
|
||||
|
||||
def compile_for_android(self):
|
||||
rename_command = ' '.join([
|
||||
"mv %s %s" % (os.path.join(self.simulator_output_dir,"android","simulator-debug.apk"),
|
||||
os.path.join(self.simulator_output_dir,"android","Simulator.apk"))
|
||||
])
|
||||
|
||||
cocos_cmd = " %s compile -p android --ndk-mode %s -o \"%s\" --no-res --compile-script 0" % (self.cocos_bin
|
||||
, "debug" if self.mode == 'debug' else "release"
|
||||
, os.path.join(self.simulator_output_dir,"android"))
|
||||
env_param = utils.ExtendEnv.get_extend_env_str()
|
||||
if env_param and len(env_param) > 0:
|
||||
cocos_cmd += (' --env "%s"' % env_param)
|
||||
|
||||
command = ' '.join([
|
||||
cocos_cmd,
|
||||
"&& %s" % (rename_command),
|
||||
])
|
||||
|
||||
self._run_cmd(command, self.simulator_abs_path)
|
||||
self.build_log += MultiLanguage.get_string('GEN_SIM_BUILD_SUCCESS_FMT', ('Android', self.mode))
|
||||
|
||||
def do_compile(self):
|
||||
if cocos.os_is_mac():
|
||||
if self.build_mac:
|
||||
self.compile_for_osx()
|
||||
if self.build_ios:
|
||||
self.compile_for_ios()
|
||||
|
||||
if cocos.os_is_win32():
|
||||
if self.build_win:
|
||||
self.compile_for_win32()
|
||||
|
||||
if self.build_android:
|
||||
self.compile_for_android()
|
||||
|
||||
def change_cocos2d_debug_macro_to_1(self, file_list):
|
||||
keyword = self.get_keywords()
|
||||
for file_path in file_list:
|
||||
self.replace_keyword_with_file(file_path, keyword)
|
||||
|
||||
def update_bundle_version(self):
|
||||
build_date = date.today().strftime("%Y%m%d")
|
||||
|
||||
if cocos.os_is_mac() and self.build_mac:
|
||||
# mac
|
||||
info_plist_path = os.path.join(self.simulator_abs_path, "frameworks/runtime-src/proj.ios_mac/mac/Info.plist")
|
||||
info_plist_content = self.get_content_from_file(info_plist_path)
|
||||
|
||||
match = re.compile('<key>CFBundleVersion</key>(\s)*<string>(.*?)</string>').findall(info_plist_content)
|
||||
if len(match):
|
||||
build_date_tag = "<string>%s</string>" % match[0][1]
|
||||
keyword_map = { build_date_tag : "<string>%s</string>" % build_date }
|
||||
self.replace_keyword_with_file(info_plist_path, keyword_map)
|
||||
|
||||
match = re.compile('<key>CFBundleShortVersionString</key>(\s)*<string>(.*?)</string>').findall(info_plist_content)
|
||||
if len(match):
|
||||
build_date_tag = "<string>%s</string>" % match[0][1]
|
||||
keyword_map = { build_date_tag : "<string>%s</string>" % self.engine_version }
|
||||
self.replace_keyword_with_file(info_plist_path, keyword_map)
|
||||
|
||||
if cocos.os_is_win32() and self.build_win:
|
||||
# win32
|
||||
game_rc_path = os.path.join(self.simulator_abs_path,"frameworks/runtime-src/proj.win32/game.rc")
|
||||
game_rc_content = self.get_content_from_file(game_rc_path)
|
||||
match = re.compile('"Version[^\(]*\(.*\)"').findall(game_rc_content)
|
||||
if len(match):
|
||||
build_info_str = match[0]
|
||||
target_str = '"Version %s (%s)"' % (self.engine_version, build_date)
|
||||
keyword_map = { build_info_str : target_str}
|
||||
self.replace_keyword_with_file(game_rc_path,keyword_map)
|
||||
|
||||
def backup_files(self, files):
|
||||
for f in files:
|
||||
full_path = os.path.abspath(f)
|
||||
if not os.path.isfile(full_path):
|
||||
continue
|
||||
|
||||
backup_file_path = '%s.bak' % full_path
|
||||
shutil.copyfile(full_path, backup_file_path)
|
||||
|
||||
def rollback_files(self, files):
|
||||
for f in files:
|
||||
full_path = os.path.abspath(f)
|
||||
backup_file_path = '%s.bak' % full_path
|
||||
if not os.path.isfile(backup_file_path):
|
||||
continue
|
||||
|
||||
try:
|
||||
shutil.copyfile(backup_file_path, full_path)
|
||||
os.remove(backup_file_path)
|
||||
except:
|
||||
Logging.warning(MultiLanguage.get_string('GEN_SIM_ROLL_BACK_FAIL_FMT',
|
||||
(full_path, backup_file_path, full_path)))
|
||||
pass
|
||||
|
||||
def run(self, argv, dependencies):
|
||||
self.parse_args(argv)
|
||||
if self.is_clean_before_build:
|
||||
utils.rmdir(self.simulator_output_dir)
|
||||
|
||||
# backup some files
|
||||
modify_files = self.get_depend_project_file_list()
|
||||
if cocos.os_is_mac() and self.build_mac:
|
||||
modify_files.append(os.path.join(self.simulator_abs_path, 'frameworks/runtime-src/proj.ios_mac/mac/Info.plist'))
|
||||
|
||||
if cocos.os_is_win32() and self.build_win:
|
||||
modify_files.append(os.path.join(self.simulator_abs_path, 'frameworks/runtime-src/proj.win32/game.rc'))
|
||||
|
||||
self.backup_files(modify_files)
|
||||
|
||||
try:
|
||||
# modify bundle version
|
||||
self.update_bundle_version()
|
||||
|
||||
# modify project config files
|
||||
self.change_cocos2d_debug_macro_to_1(modify_files)
|
||||
|
||||
# compile simulator
|
||||
self.do_compile()
|
||||
except Exception as e:
|
||||
raise e
|
||||
finally:
|
||||
# roll back modified files
|
||||
self.rollback_files(modify_files)
|
||||
Logging.info("")
|
||||
Logging.info(self.build_log)
|
||||
Logging.info("")
|
||||
|
||||
return 0
|
||||
320
cocos2d-x/tools/cocos2d-console/plugins/plugin_generate/gen_templates.py
Executable file
@@ -0,0 +1,320 @@
|
||||
#!/usr/bin/python
|
||||
#-*- coding: UTF-8 -*-
|
||||
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
import utils
|
||||
import modify_template
|
||||
import re
|
||||
import cocos
|
||||
|
||||
from MultiLanguage import MultiLanguage
|
||||
from cocos import CCPluginError, Logging
|
||||
|
||||
from argparse import ArgumentParser
|
||||
|
||||
class TemplateGenerator(cocos.CCPlugin):
|
||||
|
||||
CONFIG_FILE = "configs/gen_templates_config.json"
|
||||
|
||||
KEY_COPY_FROM_ENGINE = 'copy_from_engine'
|
||||
KEY_COPY_FROM_BIN_TEMP = 'copy_from_bin_templates'
|
||||
KEY_WIN32_CFG = 'win32_cfg'
|
||||
KEY_XCODE_PROJS = 'xcode_projs'
|
||||
KEY_BUILD_CFG_FILES = 'build_cfg_files'
|
||||
KEY_VS_PROJS = 'vs_projs'
|
||||
|
||||
KEY_RM_COPY_RES = 'rm_copy_res'
|
||||
KEY_REPLACE_STRING = 'replace_string'
|
||||
KEY_MODIFY_CFG = 'modify_files'
|
||||
|
||||
@staticmethod
|
||||
def plugin_name():
|
||||
return "gen-templates"
|
||||
|
||||
@staticmethod
|
||||
def brief_description():
|
||||
return MultiLanguage.get_string('GEN_TEMP_BRIEF')
|
||||
|
||||
def parse_args(self, argv):
|
||||
parser = ArgumentParser(prog="cocos %s" % self.__class__.plugin_name(),
|
||||
description=self.__class__.brief_description())
|
||||
(args, unknown) = parser.parse_known_args()
|
||||
self.init(args)
|
||||
|
||||
return args
|
||||
|
||||
def init(self, args):
|
||||
if getattr(sys, 'frozen', None):
|
||||
self.cur_dir = os.path.realpath(os.path.dirname(sys.executable))
|
||||
self.engine_path = os.path.join(self.cur_dir, os.pardir, os.pardir, os.pardir)
|
||||
else:
|
||||
self.cur_dir = os.path.realpath(os.path.dirname(__file__))
|
||||
self.engine_path = os.path.join(self.cur_dir, os.pardir, os.pardir, os.pardir, os.pardir)
|
||||
self.engine_path = os.path.normpath(self.engine_path)
|
||||
|
||||
# get path variables
|
||||
self.lib_dir = os.path.join(self.engine_path, 'prebuilt')
|
||||
self.engine_template_dir = os.path.join(self.engine_path, "templates")
|
||||
|
||||
# get the template config info
|
||||
self.config_json = self.getConfigJson()
|
||||
|
||||
# get engine version
|
||||
self.version = self.get_version_from_source()
|
||||
self.fw_version = self.version.replace(' ', '-')
|
||||
self._verbose = True
|
||||
|
||||
def generate(self):
|
||||
self.clean_template()
|
||||
self.copy_template()
|
||||
self.gen_templates()
|
||||
|
||||
def clean_template(self):
|
||||
utils.rmdir(os.path.join(self.engine_template_dir, "cpp-template-binary"))
|
||||
utils.rmdir(os.path.join(self.engine_template_dir, "lua-template-binary"))
|
||||
utils.rmdir(os.path.join(self.engine_template_dir, "js-template-binary"))
|
||||
|
||||
def copy_template(self):
|
||||
for item in self.config_json[TemplateGenerator.KEY_COPY_FROM_ENGINE]:
|
||||
cocos.copy_files_with_config(item, self.engine_path, self.engine_template_dir)
|
||||
|
||||
for item in self.config_json[TemplateGenerator.KEY_COPY_FROM_BIN_TEMP]:
|
||||
cocos.copy_files_with_config(item, os.path.join(self.cur_dir, 'bin-templates'), self.engine_template_dir)
|
||||
|
||||
def getConfigJson(self):
|
||||
cfg_json_path = os.path.join(self.cur_dir, TemplateGenerator.CONFIG_FILE)
|
||||
f = open(cfg_json_path)
|
||||
config_json = json.load(f)
|
||||
f.close()
|
||||
|
||||
return config_json
|
||||
|
||||
def gen_templates(self):
|
||||
dst_dir = self.engine_template_dir
|
||||
x_path = self.engine_path
|
||||
lib_dir = self.lib_dir
|
||||
|
||||
version = self.fw_version
|
||||
modifier = modify_template.TemplateModifier(x_path, lib_dir, version)
|
||||
|
||||
# modify the VS project file of templates
|
||||
for proj_file in self.config_json[TemplateGenerator.KEY_VS_PROJS]:
|
||||
proj_file_path = os.path.join(self.engine_template_dir, proj_file)
|
||||
modifier.modify_vs_proj(proj_file_path)
|
||||
|
||||
# modify the main.cpp in proj.win32
|
||||
self.modify_win32_maincpp()
|
||||
|
||||
# modify the xcode project file of templates
|
||||
for proj_file in self.config_json[TemplateGenerator.KEY_XCODE_PROJS]:
|
||||
proj_file_path = os.path.join(self.engine_template_dir, proj_file)
|
||||
modifier.modify_xcode_proj(proj_file_path)
|
||||
|
||||
# modify the build-cfg.json for templates
|
||||
self.modify_build_cfg()
|
||||
|
||||
self.modify_version_json(os.path.join(dst_dir, "lua-template-binary/.settings/version.json"))
|
||||
self.modify_version_json(os.path.join(dst_dir, "js-template-binary/.settings/version.json"))
|
||||
|
||||
self.gen_template_config(dst_dir, self.version)
|
||||
|
||||
# modify files in config file
|
||||
self.modify_files()
|
||||
|
||||
def modify_win32_maincpp(self):
|
||||
win32_cfg = self.config_json[TemplateGenerator.KEY_WIN32_CFG]
|
||||
cpp_files = win32_cfg['main_cpps']
|
||||
link_libs_cfg = win32_cfg['link_libs']
|
||||
|
||||
check_pattern = r'^int[\s]+APIENTRY[\s]+_tWinMain'
|
||||
for main_cpp in cpp_files:
|
||||
cpp_full_path = os.path.join(self.engine_template_dir, main_cpp)
|
||||
|
||||
if main_cpp.find('lua-template') >= 0:
|
||||
link_libs = link_libs_cfg['base'] + link_libs_cfg['lua']
|
||||
elif main_cpp.find('js-template') >= 0:
|
||||
link_libs = link_libs_cfg['base'] + link_libs_cfg['js']
|
||||
else:
|
||||
link_libs = link_libs_cfg['base']
|
||||
|
||||
f = open(cpp_full_path)
|
||||
old_lines = f.readlines()
|
||||
f.close()
|
||||
|
||||
new_lines = []
|
||||
for line in old_lines:
|
||||
strip_line = line.strip()
|
||||
if re.match(check_pattern, strip_line):
|
||||
new_lines.append('#if _MSC_VER > 1800\n')
|
||||
for lib in link_libs:
|
||||
new_lines.append('%s\n' % self.get_lib_str(lib, 2015))
|
||||
new_lines.append('#else\n')
|
||||
for lib in link_libs:
|
||||
new_lines.append('%s\n' % self.get_lib_str(lib, 2013))
|
||||
new_lines.append('#endif\n\n')
|
||||
new_lines.append(line)
|
||||
else:
|
||||
new_lines.append(line)
|
||||
|
||||
f = open(cpp_full_path, 'w')
|
||||
f.writelines(new_lines)
|
||||
f.close()
|
||||
|
||||
def get_lib_str(self, lib_name, ver):
|
||||
base, ext = os.path.splitext(lib_name)
|
||||
ret = '#pragma comment(lib,"%s_%d%s")' % (base, ver, ext)
|
||||
return ret
|
||||
|
||||
def modify_file(self, file_path, pattern, replace_str):
|
||||
f = open(file_path)
|
||||
lines = f.readlines()
|
||||
f.close()
|
||||
|
||||
new_lines = []
|
||||
for line in lines:
|
||||
new_line = re.sub(pattern, replace_str, line)
|
||||
new_lines.append(new_line)
|
||||
|
||||
f = open(file_path, "w")
|
||||
f.writelines(new_lines)
|
||||
f.close()
|
||||
|
||||
def modify_files(self):
|
||||
modify_cfg = self.config_json[TemplateGenerator.KEY_MODIFY_CFG]
|
||||
for cfg in modify_cfg:
|
||||
file_path = cfg["file_path"]
|
||||
if not os.path.isabs(file_path):
|
||||
file_path = os.path.abspath(os.path.join(self.engine_template_dir, file_path))
|
||||
|
||||
if not os.path.isfile(file_path):
|
||||
print("%s is not a file." % file_path)
|
||||
continue
|
||||
|
||||
pattern = cfg["pattern"]
|
||||
replace_str = cfg["replace_string"]
|
||||
self.modify_file(file_path, pattern, replace_str)
|
||||
|
||||
def modify_version_json(self, file_path):
|
||||
f = open(file_path)
|
||||
version_info = json.load(f)
|
||||
f.close()
|
||||
|
||||
version_info["engineVersion"] = self.version
|
||||
|
||||
f = open(file_path, "w")
|
||||
json.dump(version_info, f, sort_keys=True, indent=4)
|
||||
f.close()
|
||||
|
||||
def get_version_from_source(self):
|
||||
src_engine_path = self.engine_path
|
||||
version_file_path = os.path.join(src_engine_path, "cocos/cocos2d.cpp")
|
||||
pattern = r".*return[ \t]+\"(.*)\";"
|
||||
|
||||
# restore the version of engine
|
||||
ver = ""
|
||||
f = open(version_file_path)
|
||||
for line in f.readlines():
|
||||
match = re.match(pattern, line)
|
||||
if match:
|
||||
ver = match.group(1)
|
||||
break
|
||||
f.close()
|
||||
|
||||
if len(ver) <= 0:
|
||||
raise CCPluginError(MultiLanguage.get_string('GEN_TEMP_ERROR_VER_NOT_FOUND_FMT', version_file_path),
|
||||
CCPluginError.ERROR_PARSE_FILE)
|
||||
|
||||
return ver
|
||||
|
||||
def gen_template_config(self, template_path, engine_ver):
|
||||
for name in os.listdir(template_path):
|
||||
fullPath = os.path.join(template_path, name)
|
||||
if not os.path.isdir(fullPath):
|
||||
continue
|
||||
|
||||
if not re.match(".*-template-binary", name):
|
||||
continue
|
||||
|
||||
cfg_path = os.path.join(fullPath, ".cocos-project.json")
|
||||
cfg_info = {}
|
||||
if os.path.exists(cfg_path):
|
||||
f = open(cfg_path)
|
||||
cfg_info = json.load(f)
|
||||
f.close()
|
||||
|
||||
cfg_info["engine_version"] = engine_ver
|
||||
cfg_info["engine_type"] = "prebuilt"
|
||||
|
||||
f = open(cfg_path, "w")
|
||||
json.dump(cfg_info, f, sort_keys=True, indent=4)
|
||||
f.close()
|
||||
|
||||
def rm_copy_res(self, file_path, keyword):
|
||||
f = open(file_path)
|
||||
info = json.load(f)
|
||||
f.close()
|
||||
|
||||
changed = False
|
||||
for cpy_res in info['copy_resources']:
|
||||
if cpy_res['from'].find(keyword) >= 0:
|
||||
info['copy_resources'].remove(cpy_res)
|
||||
changed = True
|
||||
break
|
||||
|
||||
if changed:
|
||||
f = open(file_path, 'w')
|
||||
json.dump(info, f, indent=4)
|
||||
f.close()
|
||||
|
||||
def modify_project_properties(self, cfg_path):
|
||||
f = open(cfg_path)
|
||||
lines = f.readlines()
|
||||
f.close()
|
||||
|
||||
new_lines = []
|
||||
pattern = r'android\.library\.reference.*'
|
||||
for line in lines:
|
||||
temp_str = line.strip()
|
||||
if not re.match(pattern, temp_str):
|
||||
new_lines.append(line)
|
||||
|
||||
f = open(cfg_path, 'w')
|
||||
f.writelines(new_lines)
|
||||
f.close()
|
||||
|
||||
def modify_build_cfg(self):
|
||||
build_cfg_files = self.config_json[TemplateGenerator.KEY_BUILD_CFG_FILES]
|
||||
fw_version_path = "${COCOS_X_ROOT}/%s" % self.fw_version
|
||||
|
||||
for build_cfg_file in build_cfg_files:
|
||||
cfg_full_path = os.path.join(self.engine_template_dir, build_cfg_file)
|
||||
file_cfg_info = build_cfg_files[build_cfg_file]
|
||||
|
||||
if file_cfg_info.has_key(TemplateGenerator.KEY_RM_COPY_RES):
|
||||
rm_copy_cfg = file_cfg_info[TemplateGenerator.KEY_RM_COPY_RES]
|
||||
for keyword in rm_copy_cfg:
|
||||
self.rm_copy_res(cfg_full_path, keyword)
|
||||
|
||||
if file_cfg_info.has_key(TemplateGenerator.KEY_REPLACE_STRING):
|
||||
replace_cfg = file_cfg_info[TemplateGenerator.KEY_REPLACE_STRING]
|
||||
f = open(cfg_full_path)
|
||||
file_content = f.read()
|
||||
f.close()
|
||||
|
||||
for replace_cfg_info in replace_cfg:
|
||||
src_str = replace_cfg_info['src_str']
|
||||
dst_str = replace_cfg_info['dst_str']
|
||||
dst_str = dst_str.replace('${FW_VERSION_PATH}', fw_version_path)
|
||||
file_content = file_content.replace(src_str, dst_str)
|
||||
|
||||
f = open(cfg_full_path, "w")
|
||||
f.write(file_content)
|
||||
f.close()
|
||||
|
||||
def run(self, argv, dependencies):
|
||||
self.parse_args(argv)
|
||||
self.generate()
|
||||
Logging.info('')
|
||||
Logging.info(MultiLanguage.get_string('GEN_TEMP_SUCCESS_FMT', self.engine_template_dir))
|
||||
224
cocos2d-x/tools/cocos2d-console/plugins/plugin_generate/modify_template.py
Executable file
@@ -0,0 +1,224 @@
|
||||
#!/usr/bin/python
|
||||
# ----------------------------------------------------------------------------
|
||||
# modify the runtime template for prebuilt engine
|
||||
#
|
||||
# Copyright 2014 (C) zhangbin
|
||||
#
|
||||
# License: MIT
|
||||
# ----------------------------------------------------------------------------
|
||||
'''
|
||||
modify the runtime template for prebuilt engine
|
||||
'''
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
from MultiLanguage import MultiLanguage
|
||||
from cocos import Logging
|
||||
|
||||
LUA_TEMPLATE_PATH = "templates/lua-template-runtime"
|
||||
|
||||
XCODE_LINK_CPP_LIBS = [
|
||||
"libcocos2d"
|
||||
]
|
||||
|
||||
XCODE_LINK_LUA_LIBS = [ "libluacocos2d", "libsimulator" ]
|
||||
|
||||
XCODE_LINK_JS_LIBS = [ "libjscocos2d", "libsimulator" ]
|
||||
|
||||
class TemplateModifier(object):
|
||||
def __init__(self, engine_path, libs_path, version):
|
||||
if os.path.isabs(engine_path):
|
||||
self.engine_path = engine_path
|
||||
else:
|
||||
self.engine_path = os.path.abspath(engine_path)
|
||||
|
||||
if os.path.isabs(libs_path):
|
||||
self.libs_path = libs_path
|
||||
else:
|
||||
self.libs_path = os.path.abspath(libs_path)
|
||||
|
||||
self.version = version
|
||||
|
||||
if getattr(sys, 'frozen', None):
|
||||
self.cur_dir = os.path.realpath(os.path.dirname(sys.executable))
|
||||
else:
|
||||
self.cur_dir = os.path.realpath(os.path.dirname(__file__))
|
||||
proj_modifier_path = os.path.join(self.cur_dir, 'proj_modifier')
|
||||
sys.path.append(proj_modifier_path)
|
||||
|
||||
def modify_xcode_proj(self, proj_file_path):
|
||||
if proj_file_path.find('cpp-template') >= 0:
|
||||
language = 'cpp'
|
||||
elif proj_file_path.find('lua-template') >= 0:
|
||||
language = 'lua'
|
||||
elif proj_file_path.find('js-template') >= 0:
|
||||
language = 'js'
|
||||
else:
|
||||
Logging.warning(MultiLanguage.get_string('GEN_TEMP_UNKNOWN_LANGUAGE_FMT', proj_file_path))
|
||||
return
|
||||
|
||||
import modify_pbxproj
|
||||
pbx_proj = modify_pbxproj.XcodeProject.Load(proj_file_path)
|
||||
|
||||
replace_engine_strs = []
|
||||
if language == "cpp":
|
||||
targetName = "HelloCpp"
|
||||
link_libs = XCODE_LINK_CPP_LIBS
|
||||
replace_engine_strs.append("$(SRCROOT)/../cocos2d")
|
||||
elif language == "lua":
|
||||
targetName = "HelloLua"
|
||||
link_libs = XCODE_LINK_CPP_LIBS + XCODE_LINK_LUA_LIBS
|
||||
replace_engine_strs.append("$(SRCROOT)/../../cocos2d-x")
|
||||
else:
|
||||
targetName = "HelloJavascript"
|
||||
link_libs = XCODE_LINK_CPP_LIBS + XCODE_LINK_JS_LIBS
|
||||
replace_engine_strs.append("$(SRCROOT)/../../cocos2d-x")
|
||||
replace_engine_strs.append("../../cocos2d-x")
|
||||
ios_target_name = "%s-mobile" % targetName
|
||||
mac_target_name = "%s-desktop" % targetName
|
||||
|
||||
# remove the target dependencies
|
||||
pbx_proj.remove_proj_reference("cocos2d_libs.xcodeproj")
|
||||
if language == "lua":
|
||||
pbx_proj.remove_proj_reference("cocos2d_lua_bindings.xcodeproj")
|
||||
pbx_proj.remove_proj_reference("libsimulator.xcodeproj")
|
||||
|
||||
if language == "js":
|
||||
pbx_proj.remove_proj_reference("cocos2d_js_bindings.xcodeproj")
|
||||
pbx_proj.remove_proj_reference("libsimulator.xcodeproj")
|
||||
pbx_proj.remove_file_by_path("../../cocos2d-x/cocos/scripting/js-bindings/script")
|
||||
|
||||
common_group = pbx_proj.get_or_create_group("JS Common")
|
||||
pbx_proj.add_file_if_doesnt_exist("../../../script", common_group, tree="<group>")
|
||||
# pbx_proj.remove_group_by_name("JS Common")
|
||||
|
||||
# add libraries search path
|
||||
libs_path = "/Applications/Cocos/Cocos2d-x/%s/prebuilt" % self.version
|
||||
ios_template_prebuilt_path = "%s/%s" % (libs_path, "ios")
|
||||
pbx_proj.add_library_search_paths(ios_template_prebuilt_path, target_name=ios_target_name, recursive=False)
|
||||
mac_template_prebuilt_path = "%s/%s" % (libs_path, "mac")
|
||||
pbx_proj.add_library_search_paths(mac_template_prebuilt_path, target_name=mac_target_name, recursive=False)
|
||||
|
||||
# add libraries for targets
|
||||
ios_lib_group = pbx_proj.get_or_create_group("ios-libs")
|
||||
mac_lib_group = pbx_proj.get_or_create_group("mac-libs")
|
||||
for lib in link_libs:
|
||||
ios_lib_name = "%s iOS.a" % lib
|
||||
mac_lib_name = "%s Mac.a" % lib
|
||||
ios_lib_path = "%s/%s" % (ios_template_prebuilt_path, ios_lib_name)
|
||||
pbx_proj.add_file_if_doesnt_exist(ios_lib_path, ios_lib_group, tree="<group>", target=ios_target_name)
|
||||
|
||||
mac_lib_path = "%s/%s" % (mac_template_prebuilt_path, mac_lib_name)
|
||||
pbx_proj.add_file_if_doesnt_exist(mac_lib_path, mac_lib_group, tree="<group>", target=mac_target_name)
|
||||
|
||||
# add studio resources to the xcode project of cpp template
|
||||
if language == "cpp":
|
||||
pbx_proj.remove_file_by_path("CloseNormal.png")
|
||||
pbx_proj.remove_file_by_path("CloseSelected.png")
|
||||
pbx_proj.remove_file_by_path("HelloWorld.png")
|
||||
pbx_proj.remove_file_by_path("Marker Felt.ttf")
|
||||
pbx_proj.remove_file_by_path("fonts")
|
||||
pbx_proj.remove_file_by_path("res")
|
||||
|
||||
res_group = pbx_proj.get_or_create_group("Resources")
|
||||
pbx_proj.add_file_if_doesnt_exist("../Resources/res", res_group, tree="<group>")
|
||||
|
||||
if pbx_proj.modified:
|
||||
Logging.info(MultiLanguage.get_string('GEN_TEMP_SAVE_XCODE_PROJ_FMT', proj_file_path))
|
||||
pbx_proj.save()
|
||||
|
||||
# modify the engine path
|
||||
f = open(proj_file_path)
|
||||
file_content = f.read()
|
||||
f.close()
|
||||
|
||||
install_path = "/Applications/Cocos/Cocos2d-x/%s" % self.version
|
||||
for old_engine_path in replace_engine_strs:
|
||||
file_content = file_content.replace(old_engine_path, install_path)
|
||||
|
||||
f = open(proj_file_path, "w")
|
||||
f.write(file_content)
|
||||
f.close()
|
||||
|
||||
def modify_vs_proj(self, proj_file_path):
|
||||
if proj_file_path.find('cpp-template') >= 0:
|
||||
language = 'cpp'
|
||||
elif proj_file_path.find('lua-template') >= 0:
|
||||
language = 'lua'
|
||||
elif proj_file_path.find('js-template') >= 0:
|
||||
language = 'js'
|
||||
else:
|
||||
Logging.warning(MultiLanguage.get_string('GEN_TEMP_UNKNOWN_LANGUAGE_FMT', proj_file_path))
|
||||
return
|
||||
|
||||
import modify_vcxproj
|
||||
vcx_proj = modify_vcxproj.VCXProject(proj_file_path)
|
||||
|
||||
# remove the project references
|
||||
vcx_proj.remove_proj_reference()
|
||||
|
||||
install_path = "$(COCOS_X_ROOT)\\%s\\" % self.version
|
||||
|
||||
copy_libs_cmd = "if not exist \"$(OutDir)\" mkdir \"$(OutDir)\"\n" \
|
||||
"xcopy /Y /Q \"$(EngineRoot)\\prebuilt\\win32\\*.*\" \"$(OutDir)\"\n"
|
||||
vcx_proj.set_event_command('PreLinkEvent', copy_libs_cmd, 'debug')
|
||||
vcx_proj.set_event_command('PreLinkEvent', copy_libs_cmd, 'release')
|
||||
|
||||
if language == "js":
|
||||
custom_step_event = vcx_proj.get_event_command('CustomBuildStep')
|
||||
custom_step_event.replace("$(ProjectDir)..\\..\\cocos2d-x\\cocos\\scripting\\js-bindings\\script",
|
||||
"$(ProjectDir)..\\..\\..\\script")
|
||||
vcx_proj.set_event_command("CustomBuildStep", custom_step_event, create_new=False)
|
||||
|
||||
vcx_proj.remove_predefine_macro("_DEBUG", 'debug')
|
||||
|
||||
Logging.info(MultiLanguage.get_string('GEN_TEMP_SAVE_VS_PROJ_FMT', proj_file_path))
|
||||
vcx_proj.save()
|
||||
|
||||
replace_strs = []
|
||||
replace_strs.append("$(EngineRoot)")
|
||||
if language == "cpp":
|
||||
# link_libs = WIN32_LINK_CPP_LIBS
|
||||
replace_strs.append("$(ProjectDir)..\\cocos2d")
|
||||
replace_strs.append("..\\cocos2d")
|
||||
elif language == "lua":
|
||||
# link_libs = WIN32_LINK_CPP_LIBS + WIN32_LINK_LUA_LIBS
|
||||
replace_strs.append("$(ProjectDir)..\\..\\cocos2d-x")
|
||||
replace_strs.append("..\\..\\cocos2d-x")
|
||||
else:
|
||||
# link_libs = WIN32_LINK_CPP_LIBS + WIN32_LINK_JS_LIBS
|
||||
replace_strs.append("$(ProjectDir)..\\..\\cocos2d-x")
|
||||
replace_strs.append("..\\..\\cocos2d-x")
|
||||
|
||||
# modify the Runtime.cpp
|
||||
vcx_proj_path = os.path.dirname(proj_file_path)
|
||||
cpp_path = os.path.join(vcx_proj_path, os.path.pardir, "Classes/runtime/Runtime.cpp")
|
||||
if os.path.exists(cpp_path):
|
||||
f = open(cpp_path)
|
||||
file_content = f.read()
|
||||
f.close()
|
||||
|
||||
file_content = file_content.replace("#ifndef _DEBUG", "#ifndef COCOS2D_DEBUG")
|
||||
f = open(cpp_path, "w")
|
||||
f.write(file_content)
|
||||
f.close()
|
||||
|
||||
f = open(proj_file_path)
|
||||
file_content = f.read()
|
||||
f.close()
|
||||
|
||||
if language == "lua":
|
||||
# replace the "lua\lua;" to "lua\luajit;"
|
||||
file_content = file_content.replace("lua\\lua;", "lua\\luajit\\include;")
|
||||
|
||||
file_content = file_content.replace("MultiThreadedDebugDLL", "MultiThreadedDLL")
|
||||
for str in replace_strs:
|
||||
file_content = file_content.replace(str, install_path)
|
||||
file_content = file_content.replace('%s\\' % install_path, install_path)
|
||||
|
||||
file_content = file_content.replace("%scocos\\2d\\cocos2dx.props" % install_path, "cocos2dx.props")
|
||||
|
||||
f = open(proj_file_path, "w")
|
||||
f.write(file_content)
|
||||
f.close()
|
||||
@@ -0,0 +1,248 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
from xml.dom import minidom
|
||||
|
||||
def os_is_win32():
|
||||
return sys.platform == 'win32'
|
||||
|
||||
def os_is_mac():
|
||||
return sys.platform == 'darwin'
|
||||
|
||||
IS_DEBUG = False
|
||||
def output_msg(msg):
|
||||
if IS_DEBUG:
|
||||
print(msg)
|
||||
|
||||
class VCXProject(object):
|
||||
def __init__(self, proj_file_path):
|
||||
self.xmldoc = minidom.parse(proj_file_path)
|
||||
self.root_node = self.xmldoc.documentElement
|
||||
if os.path.isabs(proj_file_path):
|
||||
self.file_path = proj_file_path
|
||||
else:
|
||||
self.file_path = os.path.abspath(proj_file_path)
|
||||
|
||||
def get_or_create_node(self, parent, node_name, create_new=True):
|
||||
children = parent.getElementsByTagName(node_name)
|
||||
if len(children) > 0:
|
||||
return children[0]
|
||||
else:
|
||||
if create_new:
|
||||
child = parent.createElement(node_name)
|
||||
return child
|
||||
else:
|
||||
return None
|
||||
|
||||
def save(self, new_path=None):
|
||||
if new_path is None:
|
||||
savePath = self.file_path
|
||||
else:
|
||||
if os.path.isabs(new_path):
|
||||
savePath = new_path
|
||||
else:
|
||||
savePath = os.path.abspath(new_path)
|
||||
|
||||
output_msg("Saving the vcxproj to %s" % savePath)
|
||||
|
||||
if not os.path.isabs(savePath):
|
||||
savePath = os.path.abspath(savePath)
|
||||
|
||||
file_obj = open(savePath, "w")
|
||||
self.xmldoc.writexml(file_obj, encoding="utf-8")
|
||||
file_obj.close()
|
||||
|
||||
file_obj = open(savePath, "r")
|
||||
file_content = file_obj.read()
|
||||
file_obj.close()
|
||||
|
||||
file_content = file_content.replace(""", "\"")
|
||||
file_content = file_content.replace("/>", " />")
|
||||
|
||||
if os_is_mac():
|
||||
file_content = file_content.replace("\n", "\r\n")
|
||||
|
||||
file_content = file_content.replace("?><", "?>\r\n<")
|
||||
|
||||
file_obj = open(savePath, "w")
|
||||
file_obj.write(file_content)
|
||||
file_obj.close()
|
||||
|
||||
output_msg("Saving Finished")
|
||||
|
||||
def remove_lib(self, lib_name):
|
||||
cfg_nodes = self.root_node.getElementsByTagName("ItemDefinitionGroup")
|
||||
for cfg_node in cfg_nodes:
|
||||
cond_attr = cfg_node.attributes["Condition"].value
|
||||
if cond_attr.lower().find("debug") >= 0:
|
||||
cur_mode = "Debug"
|
||||
else:
|
||||
cur_mode = "Release"
|
||||
|
||||
# remove the linked lib config
|
||||
link_node = self.get_or_create_node(cfg_node, "Link")
|
||||
depends_node = self.get_or_create_node(link_node, "AdditionalDependencies")
|
||||
link_info = depends_node.firstChild.nodeValue
|
||||
cur_libs = link_info.split(";")
|
||||
link_modified = False
|
||||
|
||||
if lib_name in cur_libs:
|
||||
output_msg("Remove linked library %s from \"%s\" configuration" % (lib_name, cur_mode))
|
||||
cur_libs.remove(lib_name)
|
||||
link_modified = True
|
||||
|
||||
if link_modified:
|
||||
link_info = ";".join(cur_libs)
|
||||
depends_node.firstChild.nodeValue = link_info
|
||||
|
||||
def add_lib(self, lib_name):
|
||||
cfg_nodes = self.root_node.getElementsByTagName("ItemDefinitionGroup")
|
||||
for cfg_node in cfg_nodes:
|
||||
cond_attr = cfg_node.attributes["Condition"].value
|
||||
if cond_attr.lower().find("debug") >= 0:
|
||||
cur_mode = "Debug"
|
||||
else:
|
||||
cur_mode = "Release"
|
||||
|
||||
# add the linked lib config
|
||||
link_node = self.get_or_create_node(cfg_node, "Link")
|
||||
depends_node = self.get_or_create_node(link_node, "AdditionalDependencies")
|
||||
link_info = depends_node.firstChild.nodeValue
|
||||
cur_libs = link_info.split(";")
|
||||
link_modified = False
|
||||
if lib_name not in cur_libs:
|
||||
output_msg("Add linked library %s for \"%s\" configuration" % (lib_name, cur_mode))
|
||||
cur_libs.insert(0, lib_name)
|
||||
link_modified = True
|
||||
|
||||
if link_modified:
|
||||
link_info = ";".join(cur_libs)
|
||||
depends_node.firstChild.nodeValue = link_info
|
||||
|
||||
def get_event_command(self, event, config=None):
|
||||
cfg_nodes = self.root_node.getElementsByTagName("ItemDefinitionGroup")
|
||||
ret = ""
|
||||
for cfg_node in cfg_nodes:
|
||||
if config is not None:
|
||||
cond_attr = cfg_node.attributes["Condition"].value
|
||||
if cond_attr.lower().find("debug") >= 0:
|
||||
cur_mode = "Debug"
|
||||
else:
|
||||
cur_mode = "Release"
|
||||
|
||||
if cur_mode.lower() != config.lower():
|
||||
continue
|
||||
|
||||
event_nodes = cfg_node.getElementsByTagName(event)
|
||||
if len(event_nodes) <= 0:
|
||||
continue
|
||||
|
||||
event_node = event_nodes[0]
|
||||
cmd_nodes = event_node.getElementsByTagName("Command")
|
||||
if len(cmd_nodes) <= 0:
|
||||
continue
|
||||
|
||||
cmd_node = cmd_nodes[0]
|
||||
ret = cmd_node.firstChild.nodeValue
|
||||
break
|
||||
|
||||
return ret
|
||||
|
||||
def set_event_command(self, event, command, config=None, create_new=True):
|
||||
cfg_nodes = self.root_node.getElementsByTagName("ItemDefinitionGroup")
|
||||
for cfg_node in cfg_nodes:
|
||||
if config is not None:
|
||||
if 'Condition' not in cfg_node.attributes.keys():
|
||||
continue
|
||||
|
||||
cond_attr = cfg_node.attributes["Condition"].value
|
||||
if cond_attr.lower().find("debug") >= 0:
|
||||
cur_mode = "Debug"
|
||||
else:
|
||||
cur_mode = "Release"
|
||||
|
||||
if cur_mode.lower() != config.lower():
|
||||
continue
|
||||
|
||||
event_node = self.get_or_create_node(cfg_node, event, create_new)
|
||||
if event_node is None:
|
||||
continue
|
||||
|
||||
cmd_node = self.get_or_create_node(event_node, "Command")
|
||||
if cmd_node.firstChild is None:
|
||||
impl = minidom.getDOMImplementation()
|
||||
dom = impl.createDocument(None, 'catalog', None)
|
||||
nodeValue = dom.createTextNode(command)
|
||||
cmd_node.appendChild(nodeValue)
|
||||
else:
|
||||
cmd_node.firstChild.nodeValue = command
|
||||
|
||||
def get_node_if(self, parent, name):
|
||||
children = parent.getElementsByTagName(name)
|
||||
child = None
|
||||
if len(children) > 0:
|
||||
child = children[0]
|
||||
else:
|
||||
child = self.xmldoc.createElement(name)
|
||||
parent.appendChild(child)
|
||||
return child
|
||||
|
||||
def set_item(self, event, eventItem, command):
|
||||
cfg_nodes = self.root_node.getElementsByTagName("ItemDefinitionGroup")
|
||||
for cfg_node in cfg_nodes:
|
||||
cond_attr = cfg_node.attributes["Condition"].value
|
||||
if cond_attr.lower().find("debug") >= 0:
|
||||
cur_mode = "Debug"
|
||||
else:
|
||||
cur_mode = "Release"
|
||||
|
||||
output_msg("event: %s" % event)
|
||||
event_node = self.get_node_if(cfg_node, event)
|
||||
cmd_node = self.get_node_if(event_node, eventItem)
|
||||
text_node = self.xmldoc.createTextNode(command)
|
||||
cmd_node.appendChild(text_node)
|
||||
|
||||
def set_include_dirs(self, paths):
|
||||
if "%(AdditionalIncludeDirectories)" not in paths:
|
||||
paths.append("%(AdditionalIncludeDirectories)")
|
||||
|
||||
include_value = ";".join(paths)
|
||||
include_value = include_value.replace("/", "\\")
|
||||
cfg_nodes = self.root_node.getElementsByTagName("ItemDefinitionGroup")
|
||||
for cfg_node in cfg_nodes:
|
||||
compile_node = self.get_or_create_node(cfg_node, "ClCompile")
|
||||
include_node = self.get_or_create_node(compile_node, "AdditionalIncludeDirectories")
|
||||
include_node.firstChild.nodeValue = include_value
|
||||
|
||||
def remove_proj_reference(self):
|
||||
itemgroups = self.root_node.getElementsByTagName("ItemGroup")
|
||||
for item in itemgroups:
|
||||
proj_refers = item.getElementsByTagName("ProjectReference")
|
||||
if len(proj_refers) > 0:
|
||||
self.root_node.removeChild(item)
|
||||
|
||||
def remove_predefine_macro(self, macro, config=None):
|
||||
cfg_nodes = self.root_node.getElementsByTagName("ItemDefinitionGroup")
|
||||
for cfg_node in cfg_nodes:
|
||||
if config is not None:
|
||||
if 'Condition' not in cfg_node.attributes.keys():
|
||||
continue
|
||||
|
||||
cond_attr = cfg_node.attributes["Condition"].value
|
||||
if cond_attr.lower().find("debug") >= 0:
|
||||
cur_mode = "Debug"
|
||||
else:
|
||||
cur_mode = "Release"
|
||||
|
||||
if (cur_mode.lower() != config.lower()):
|
||||
continue
|
||||
|
||||
compile_node = self.get_or_create_node(cfg_node, "ClCompile")
|
||||
predefine_node = self.get_or_create_node(compile_node, "PreprocessorDefinitions")
|
||||
defined_values = predefine_node.firstChild.nodeValue
|
||||
|
||||
defined_list = defined_values.split(";")
|
||||
if macro in defined_list:
|
||||
defined_list.remove(macro)
|
||||
new_value = ";".join(defined_list)
|
||||
predefine_node.firstChild.nodeValue = new_value
|
||||