edgedb 是基于python开发的,同时集成了cython 以下为包的setup.py 配置,从里面我们可以看到关于edgedb 的一些依赖
以及构建过程

setup.py 源码

整体配置不算很多,500 多行,主要是cython extension 配置以及pg 构建配置,以及pg extension 配置,其中添加了关于pg 以及
pg 扩展build 的自定义cmdclass

  • 代码
#
# This source file is part of the EdgeDB open source project.
#
# Copyright 2008-present MagicStack Inc. and the EdgeDB authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# import os.path
import pathlib
import platform
import shutil
import subprocess
import textwrap from distutils import extension as distutils_extension
from distutils.command import build as distutils_build
from distutils.command import build_ext as distutils_build_ext import setuptools
from setuptools.command import develop as setuptools_develop RUNTIME_DEPS = [
'asyncpg~=0.18.2',
'click~=6.7',
'httptools>=0.0.13',
'immutables>=0.9',
'parsing~=1.6.1',
'prompt_toolkit>=2.0.0',
'psutil~=5.6.1',
'Pygments~=2.3.0',
'setproctitle~=1.1.10',
'setuptools_scm~=3.2.0',
'uvloop~=0.12.2', 'graphql-core~=2.1.0',
'promise~=2.2.0',
] CYTHON_DEPENDENCY = 'Cython==0.29.6' DOCS_DEPS = [
'Sphinx~=2.0.0',
'lxml~=4.2.5',
'sphinxcontrib-asyncio~=0.2.0',
] BUILD_DEPS = [
CYTHON_DEPENDENCY,
] EXTRA_DEPS = {
'test': [
'flake8~=3.7.5',
'pycodestyle~=2.5.0',
'coverage~=4.5.2',
'requests-xml~=0.2.3',
'lxml',
'requests-xml',
] + DOCS_DEPS, 'docs': DOCS_DEPS,
} EXT_CFLAGS = ['-O2']
EXT_LDFLAGS = [] if platform.uname().system != 'Windows':
EXT_CFLAGS.extend([
'-std=c99', '-fsigned-char', '-Wall', '-Wsign-compare', '-Wconversion'
]) def _compile_parsers(build_lib, inplace=False):
import parsing import edb.edgeql.parser.grammar.single as edgeql_spec
import edb.edgeql.parser.grammar.block as edgeql_spec2
import edb.edgeql.parser.grammar.sdldocument as schema_spec base_path = pathlib.Path(__file__).parent.resolve() for spec in (edgeql_spec, edgeql_spec2, schema_spec):
spec_path = pathlib.Path(spec.__file__).parent
subpath = pathlib.Path(str(spec_path)[len(str(base_path)) + 1:])
pickle_name = spec.__name__.rpartition('.')[2] + '.pickle'
pickle_path = subpath / pickle_name
cache = build_lib / pickle_path
cache.parent.mkdir(parents=True, exist_ok=True)
parsing.Spec(spec, pickleFile=str(cache), verbose=True)
if inplace:
shutil.copy2(cache, base_path / pickle_path) def _compile_build_meta(build_lib, version, pg_config, runstatedir):
import pkg_resources
from edb.server import buildmeta parsed_version = buildmeta.parse_version(
pkg_resources.parse_version(version)) vertuple = list(parsed_version._asdict().values())
vertuple[2] = int(vertuple[2])
vertuple = tuple(vertuple) content = textwrap.dedent('''\
#
# This source file is part of the EdgeDB open source project.
#
# Copyright 2008-present MagicStack Inc. and the EdgeDB authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
#
# THIS FILE HAS BEEN AUTOMATICALLY GENERATED.
# PG_CONFIG_PATH = {pg_config!r}
RUNSTATE_DIR = {runstatedir!r}
VERSION = {version!r}
''').format(version=vertuple, pg_config=pg_config, runstatedir=runstatedir) directory = build_lib / 'edb' / 'server'
if not directory.exists():
directory.mkdir(parents=True) with open(directory / '_buildmeta.py', 'w+t') as f:
f.write(content) def _compile_postgres(build_base, *,
force_build=False, fresh_build=True,
run_configure=True, build_contrib=True): proc = subprocess.run(
['git', 'submodule', 'status', 'postgres'],
stdout=subprocess.PIPE, universal_newlines=True, check=True)
status = proc.stdout
if status[0] == '-':
print(
'postgres submodule not initialized, '
'run `git submodule init; git submodule update`')
exit(1) proc = subprocess.run(
['git', 'submodule', 'status', 'postgres'],
stdout=subprocess.PIPE, universal_newlines=True, check=True)
revision, _, _ = proc.stdout[1:].partition(' ')
source_stamp = proc.stdout[0] + revision postgres_build = (build_base / 'postgres').resolve()
postgres_src = (pathlib.Path(__file__).parent / 'postgres').resolve()
postgres_build_stamp = postgres_build / 'stamp' if postgres_build_stamp.exists():
with open(postgres_build_stamp, 'r') as f:
build_stamp = f.read()
else:
build_stamp = None is_outdated = source_stamp != build_stamp if is_outdated or force_build:
system = platform.system()
if system == 'Darwin':
uuidlib = 'e2fs'
elif system == 'Linux':
uuidlib = 'e2fs'
else:
raise NotImplementedError('unsupported system: {}'.format(system)) if fresh_build and postgres_build.exists():
shutil.rmtree(postgres_build)
build_dir = postgres_build / 'build'
if not build_dir.exists():
build_dir.mkdir(parents=True) if run_configure or fresh_build or is_outdated:
subprocess.run([
str(postgres_src / 'configure'),
'--prefix=' + str(postgres_build / 'install'),
'--with-uuid=' + uuidlib,
], check=True, cwd=str(build_dir)) subprocess.run(
['make', 'MAKELEVEL=0', '-j', str(max(os.cpu_count() - 1, 1))],
cwd=str(build_dir), check=True) if build_contrib or fresh_build or is_outdated:
subprocess.run(
[
'make', '-C', 'contrib', 'MAKELEVEL=0', '-j',
str(max(os.cpu_count() - 1, 1))
],
cwd=str(build_dir), check=True) subprocess.run(
['make', 'MAKELEVEL=0', 'install'],
cwd=str(build_dir), check=True) if build_contrib or fresh_build or is_outdated:
subprocess.run(
['make', '-C', 'contrib', 'MAKELEVEL=0', 'install'],
cwd=str(build_dir), check=True) with open(postgres_build_stamp, 'w') as f:
f.write(source_stamp) def _compile_postgres_extensions(build_base):
postgres_build = (build_base / 'postgres').resolve()
postgres_build_stamp_path = postgres_build / 'stamp' ext_build = (build_base / 'ext').resolve()
ext_build_stamp_path = ext_build / 'stamp' if postgres_build_stamp_path.exists():
with open(postgres_build_stamp_path, 'r') as f:
postgres_build_stamp = f.read()
else:
raise RuntimeError('Postgres is not built, cannot build extensions') if ext_build_stamp_path.exists():
with open(ext_build_stamp_path, 'r') as f:
ext_build_stamp = f.read()
else:
ext_build_stamp = None ext_dir = (pathlib.Path(__file__).parent / 'ext').resolve()
pg_config = (build_base / 'postgres' / 'install' /
'bin' / 'pg_config').resolve() if not ext_dir.exists():
raise RuntimeError('missing Postgres extension directory') ext_make = ['make', '-C', str(ext_dir), 'PG_CONFIG=' + str(pg_config)] if ext_build_stamp != postgres_build_stamp:
print('Extensions build stamp does not match Postgres build stamp. '
'Rebuilding...')
subprocess.run(ext_make + ['clean'], check=True) ext_build.mkdir(parents=True, exist_ok=True) subprocess.run(ext_make, check=True)
subprocess.run(ext_make + ['install'], check=True) ext_build_stamp = postgres_build_stamp with open(ext_build_stamp_path, 'w') as f:
f.write(ext_build_stamp) class build(distutils_build.build): user_options = distutils_build.build.user_options + [
('pg-config=', None, 'path to pg_config to use with this build'),
('runstatedir=', None, 'directory to use for the runtime state'),
] def initialize_options(self):
super().initialize_options()
self.pg_config = None
self.runstatedir = None def finalize_options(self):
super().finalize_options() def run(self, *args, **kwargs):
super().run(*args, **kwargs)
build_lib = pathlib.Path(self.build_lib)
_compile_parsers(build_lib)
if self.pg_config:
_compile_build_meta(
build_lib,
self.distribution.metadata.version,
self.pg_config,
self.runstatedir,
) class develop(setuptools_develop.develop): def run(self, *args, **kwargs):
_compile_parsers(pathlib.Path('build/lib'), inplace=True)
_compile_postgres(pathlib.Path('build').resolve())
_compile_postgres_extensions(pathlib.Path('build').resolve()) scripts = self.distribution.entry_points['console_scripts']
patched_scripts = [s + '_dev' for s in scripts
if not s.startswith('edgedb-server')]
patched_scripts.append('edb = edb.tools.edb:edbcommands')
self.distribution.entry_points['console_scripts'] = patched_scripts super().run(*args, **kwargs) class build_postgres(setuptools.Command): description = "build postgres" user_options = [
('configure', None, 'run ./configure'),
('build-contrib', None, 'build contrib'),
('fresh-build', None, 'rebuild from scratch'),
] def initialize_options(self):
self.configure = False
self.build_contrib = False
self.fresh_build = False def finalize_options(self):
pass def run(self, *args, **kwargs):
_compile_postgres(
pathlib.Path('build').resolve(),
force_build=True,
fresh_build=self.fresh_build,
run_configure=self.configure,
build_contrib=self.build_contrib) _compile_postgres_extensions(
pathlib.Path('build').resolve()) class build_postgres_ext(setuptools.Command): description = "build postgres extensions" user_options = [] def initialize_options(self):
pass def finalize_options(self):
pass def run(self, *args, **kwargs):
_compile_postgres_extensions(
pathlib.Path('build').resolve()) class build_ext(distutils_build_ext.build_ext): user_options = distutils_build_ext.build_ext.user_options + [
('cython-annotate', None,
'Produce a colorized HTML version of the Cython source.'),
('cython-directives=', None,
'Cython compiler directives'),
] def initialize_options(self):
# initialize_options() may be called multiple times on the
# same command object, so make sure not to override previously
# set options.
if getattr(self, '_initialized', False):
return super(build_ext, self).initialize_options() if os.environ.get('EDGEDB_DEBUG'):
self.cython_always = True
self.cython_annotate = True
self.cython_directives = "linetrace=True"
self.define = 'PG_DEBUG,CYTHON_TRACE,CYTHON_TRACE_NOGIL'
self.debug = True
else:
self.cython_always = False
self.cython_annotate = None
self.cython_directives = None
self.debug = False def finalize_options(self):
# finalize_options() may be called multiple times on the
# same command object, so make sure not to override previously
# set options.
if getattr(self, '_initialized', False):
return import pkg_resources # Double check Cython presence in case setup_requires
# didn't go into effect (most likely because someone
# imported Cython before setup_requires injected the
# correct egg into sys.path.
try:
import Cython
except ImportError:
raise RuntimeError(
'please install {} to compile edgedb from source'.format(
CYTHON_DEPENDENCY)) cython_dep = pkg_resources.Requirement.parse(CYTHON_DEPENDENCY)
if Cython.__version__ not in cython_dep:
raise RuntimeError(
'edgedb requires {}, got Cython=={}'.format(
CYTHON_DEPENDENCY, Cython.__version__
)) from Cython.Build import cythonize directives = {
'language_level': '3'
} if self.cython_directives:
for directive in self.cython_directives.split(','):
k, _, v = directive.partition('=')
if v.lower() == 'false':
v = False
if v.lower() == 'true':
v = True directives[k] = v self.distribution.ext_modules[:] = cythonize(
self.distribution.ext_modules,
compiler_directives=directives,
annotate=self.cython_annotate,
include_path=["edb/server/pgproto/"]) super(build_ext, self).finalize_options() setuptools.setup(
setup_requires=RUNTIME_DEPS + BUILD_DEPS,
use_scm_version=True,
name='edgedb-server',
description='EdgeDB Server',
author='MagicStack Inc.',
author_email='hello@magic.io',
packages=['edb'],
include_package_data=True,
cmdclass={
'build': build,
'build_ext': build_ext,
'develop': develop,
'build_postgres': build_postgres,
'build_postgres_ext': build_postgres_ext,
},
entry_points={
'console_scripts': [
'edgedb = edb.cli:cli',
'edgedb-server = edb.server.main:main',
]
},
ext_modules=[
distutils_extension.Extension(
"edb.server.pgproto.pgproto",
["edb/server/pgproto/pgproto.pyx"],
extra_compile_args=EXT_CFLAGS,
extra_link_args=EXT_LDFLAGS), distutils_extension.Extension(
"edb.server.dbview.dbview",
["edb/server/dbview/dbview.pyx"],
extra_compile_args=EXT_CFLAGS,
extra_link_args=EXT_LDFLAGS), distutils_extension.Extension(
"edb.server.mng_port.edgecon",
["edb/server/mng_port/edgecon.pyx"],
extra_compile_args=EXT_CFLAGS,
extra_link_args=EXT_LDFLAGS), distutils_extension.Extension(
"edb.server.cache.stmt_cache",
["edb/server/cache/stmt_cache.pyx"],
extra_compile_args=EXT_CFLAGS,
extra_link_args=EXT_LDFLAGS), distutils_extension.Extension(
"edb.server.pgcon.pgcon",
["edb/server/pgcon/pgcon.pyx"],
extra_compile_args=EXT_CFLAGS,
extra_link_args=EXT_LDFLAGS), distutils_extension.Extension(
"edb.server.http.http",
["edb/server/http/http.pyx"],
extra_compile_args=EXT_CFLAGS,
extra_link_args=EXT_LDFLAGS), distutils_extension.Extension(
"edb.server.http_edgeql_port.protocol",
["edb/server/http_edgeql_port/protocol.pyx"],
extra_compile_args=EXT_CFLAGS,
extra_link_args=EXT_LDFLAGS), distutils_extension.Extension(
"edb.server.http_graphql_port.protocol",
["edb/server/http_graphql_port/protocol.pyx"],
extra_compile_args=EXT_CFLAGS,
extra_link_args=EXT_LDFLAGS),
],
install_requires=RUNTIME_DEPS,
extras_require=EXTRA_DEPS,
test_suite='tests.suite',
)

代码说明

核心代码还是setuptools.setup 中的内容,一种包含了依赖包以及扩展的配置

  • 依赖

    依赖包含了运行时依赖以及构建依赖

运行时依赖,主要是一些核心库,包括了pg 连接库 http 操作的,graphql 依赖库,cli解析的
RUNTIME_DEPS = [
'asyncpg~=0.18.2',
'click~=6.7',
'httptools>=0.0.13',
'immutables>=0.9',
'parsing~=1.6.1',
'prompt_toolkit>=2.0.0',
'psutil~=5.6.1',
'Pygments~=2.3.0',
'setproctitle~=1.1.10',
'setuptools_scm~=3.2.0',
'uvloop~=0.12.2',
'graphql-core~=2.1.0',
'promise~=2.2.0',
]
CYTHON_DEPENDENCY = 'Cython==0.29.6'
BUILD_DEPS = [
CYTHON_DEPENDENCY,
]
  • 包名称

    edgedb 基本上所有python相关的代码都在edb 中

    packages=['edb'],
  • 自定义cmdclass 以及entry_points

    详细的下边细说

# 添加了关于(pg 以及edgedb)构建,(cython,pg)扩展构建
cmdclass={
'build': build,
'build_ext': build_ext,
'develop': develop,
'build_postgres': build_postgres,
'build_postgres_ext': build_postgres_ext,
},
entry_points={
'console_scripts': [
'edgedb = edb.cli:cli',
'edgedb-server = edb.server.main:main',
]
}
  • 依赖的cython extension 配置

    主要是cython 配置,暴露的包名以及cython 路径,以及编译选项

ext_modules=[
distutils_extension.Extension(
"edb.server.pgproto.pgproto",
["edb/server/pgproto/pgproto.pyx"],
extra_compile_args=EXT_CFLAGS,
extra_link_args=EXT_LDFLAGS), distutils_extension.Extension(
"edb.server.dbview.dbview",
["edb/server/dbview/dbview.pyx"],
extra_compile_args=EXT_CFLAGS,
extra_link_args=EXT_LDFLAGS), distutils_extension.Extension(
"edb.server.mng_port.edgecon",
["edb/server/mng_port/edgecon.pyx"],
extra_compile_args=EXT_CFLAGS,
extra_link_args=EXT_LDFLAGS), distutils_extension.Extension(
"edb.server.cache.stmt_cache",
["edb/server/cache/stmt_cache.pyx"],
extra_compile_args=EXT_CFLAGS,
extra_link_args=EXT_LDFLAGS), distutils_extension.Extension(
"edb.server.pgcon.pgcon",
["edb/server/pgcon/pgcon.pyx"],
extra_compile_args=EXT_CFLAGS,
extra_link_args=EXT_LDFLAGS), distutils_extension.Extension(
"edb.server.http.http",
["edb/server/http/http.pyx"],
extra_compile_args=EXT_CFLAGS,
extra_link_args=EXT_LDFLAGS), distutils_extension.Extension(
"edb.server.http_edgeql_port.protocol",
["edb/server/http_edgeql_port/protocol.pyx"],
extra_compile_args=EXT_CFLAGS,
extra_link_args=EXT_LDFLAGS), distutils_extension.Extension(
"edb.server.http_graphql_port.protocol",
["edb/server/http_graphql_port/protocol.pyx"],
extra_compile_args=EXT_CFLAGS,
extra_link_args=EXT_LDFLAGS),
],
install_requires=RUNTIME_DEPS,
extras_require=EXTRA_DEPS,

cmdclass 说明

cmdclass 是edgedb 包的核心部分,包含了cython 构建以及pg 源码构建pg extension 扩展构建

  • build_ext 说明

    主要是cython 相关的配置

class build_ext(distutils_build_ext.build_ext):

    user_options = distutils_build_ext.build_ext.user_options + [
('cython-annotate', None,
'Produce a colorized HTML version of the Cython source.'),
('cython-directives=', None,
'Cython compiler directives'),
] def initialize_options(self):
# initialize_options() may be called multiple times on the
# same command object, so make sure not to override previously
# set options.
if getattr(self, '_initialized', False):
return super(build_ext, self).initialize_options() if os.environ.get('EDGEDB_DEBUG'):
self.cython_always = True
self.cython_annotate = True
self.cython_directives = "linetrace=True"
self.define = 'PG_DEBUG,CYTHON_TRACE,CYTHON_TRACE_NOGIL'
self.debug = True
else:
self.cython_always = False
self.cython_annotate = None
self.cython_directives = None
self.debug = False def finalize_options(self):
# finalize_options() may be called multiple times on the
# same command object, so make sure not to override previously
# set options.
if getattr(self, '_initialized', False):
return import pkg_resources # Double check Cython presence in case setup_requires
# didn't go into effect (most likely because someone
# imported Cython before setup_requires injected the
# correct egg into sys.path.
try:
import Cython
except ImportError:
raise RuntimeError(
'please install {} to compile edgedb from source'.format(
CYTHON_DEPENDENCY)) cython_dep = pkg_resources.Requirement.parse(CYTHON_DEPENDENCY)
if Cython.__version__ not in cython_dep:
raise RuntimeError(
'edgedb requires {}, got Cython=={}'.format(
CYTHON_DEPENDENCY, Cython.__version__
)) from Cython.Build import cythonize directives = {
'language_level': '3'
} if self.cython_directives:
for directive in self.cython_directives.split(','):
k, _, v = directive.partition('=')
if v.lower() == 'false':
v = False
if v.lower() == 'true':
v = True directives[k] = v self.distribution.ext_modules[:] = cythonize(
self.distribution.ext_modules,
compiler_directives=directives,
annotate=self.cython_annotate,
include_path=["edb/server/pgproto/"]) super(build_ext, self).finalize_options()
  • build_postgres pg 构建配置

    pg 是edgedb 的核心,build_postgres 提供了pg 源码编译的处理

class build_postgres(setuptools.Command):

    description = "build postgres"

    user_options = [
('configure', None, 'run ./configure'),
('build-contrib', None, 'build contrib'),
('fresh-build', None, 'rebuild from scratch'),
] def initialize_options(self):
self.configure = False
self.build_contrib = False
self.fresh_build = False def finalize_options(self):
pass def run(self, *args, **kwargs):
_compile_postgres(
pathlib.Path('build').resolve(),
force_build=True,
fresh_build=self.fresh_build,
run_configure=self.configure,
build_contrib=self.build_contrib) _compile_postgres_extensions(
pathlib.Path('build').resolve())
  • build_postgres_ext 提供pg 扩展的构建处理

    目前主要的扩展是提供一些工具类的封装扩展名称为 edbsys,代码在ext 中

class build_postgres_ext(setuptools.Command):
description = "build postgres extensions"
user_options = []
def initialize_options(self):
pass
def finalize_options(self):
pass
def run(self, *args, **kwargs):
_compile_postgres_extensions(
pathlib.Path('build').resolve())
  • build 配置

    主要提供了pg_config 的配置,指定后边pg 以及pg 扩展构建的环境

class build(distutils_build.build):

    user_options = distutils_build.build.user_options + [
('pg-config=', None, 'path to pg_config to use with this build'),
('runstatedir=', None, 'directory to use for the runtime state'),
] def initialize_options(self):
super().initialize_options()
self.pg_config = None
self.runstatedir = None def finalize_options(self):
super().finalize_options() def run(self, *args, **kwargs):
super().run(*args, **kwargs)
build_lib = pathlib.Path(self.build_lib)
_compile_parsers(build_lib)
if self.pg_config:
_compile_build_meta(
build_lib,
self.distribution.metadata.version,
self.pg_config,
self.runstatedir,
)

说明

以上只是一个简单的分析,这个文件主要是为了进行edgedb 打包构建处理的,里面也使用了关于cython 的技术
还是值得学习的

参考资料

https://github.com/edgedb/edgedb
https://medium.com/@shamir.stav_83310/making-your-c-library-callable-from-python-by-wrapping-it-with-cython-b09db35012a3
https://github.com/stavshamir/cython-c-wrapper/
https://cython.readthedocs.io/en/latest/src/tutorial/external.html
https://cython.readthedocs.io/en/latest/src/tutorial/clibraries.html
http://pages.cs.wisc.edu/~yezheng/post/cython/
https://github.com/rongfengliang/cython-c-pip-demo/tree/local_source

 
 
 
 

edgedb 内部pg 数据存储的探索 (三) 源码包setup.py 文件的更多相关文章

  1. edgedb 内部pg 数据存储的探索 (四) 源码编译

      edgedb 基于python开发,同时源码重包含了好多子项目,以下进行简单的源码编译 clone 代码 需要递归处理,加上recursive,比较慢稍等 git clone --recursiv ...

  2. edgedb 内部pg 数据存储的探索 (一)基本环境搭建

    edgedb 是基于pg 上的对象关系数据库,已经写过使用docker 运行的demo,为了探索内部的原理,做了一下尝试,开启pg 访问 后边会进一步的学习 环境准备 为了测试,使用yum 安装 安装 ...

  3. edgedb 内部pg 数据存储的探索 (二) 创建数据库命令说明

    前面已经创建好了一个简单可以访问pg 的edgedb 环境,现在测试几个数据库操作命令在pg 的存储 创建数据库 连接环境 注意账户是按照上次创建的环境配置 edgedb -u edgedb 创建数据 ...

  4. edgedb 内部pg 数据存储的探索 (五) 运行进程列表信息

    做为一个简单的记录,方便后期分析学习 当前包含了一个timescale 的extension 可以不用关注 信息 ps -ef |grep edgedb edgedb 10559 24858 0 4月 ...

  5. 65、Spark Streaming:数据接收原理剖析与源码分析

    一.数据接收原理 二.源码分析 入口包org.apache.spark.streaming.receiver下ReceiverSupervisorImpl类的onStart()方法 ### overr ...

  6. java io系列15之 DataOutputStream(数据输出流)的认知、源码和示例

    本章介绍DataOutputStream.我们先对DataOutputStream有个大致认识,然后再深入学习它的源码,最后通过示例加深对它的了解. 转载请注明出处:http://www.cnblog ...

  7. Linux学习(二十)软件安装与卸载(三)源码包安装

    一.概述 源码包安装的优点在于它自由程度比较高,可以指定目录与组件.再有,你要是能改源码也可以. 二.安装方法 步骤 1.从官网或者信任站点下载源码包 [root@localhost ~]# wget ...

  8. 利用PHPExcel 实现excel数据的导入导出(源码实现)

    利用PHPExcel 实现excel数据的导入导出(源码实现) 在开发过程中,经常会遇到导入导出的需求,利用phpexcel类实现起来也是比较容易的,下面,我们一步一步实现 提前将phpexcel类下 ...

  9. android 数据存储<一>----android短信发送器之文件的读写(手机+SD卡)

    本文实践知识点有有三: 1.布局文件,android布局有相对布局.线性布局,绝对布局.表格布局.标签布局等,各个布局能够嵌套的. 本文的布局文件就是线性布局的嵌套 <LinearLayout ...

随机推荐

  1. JAVAEE 第八周

    equals():反映的是对象或变量具体的值,即两个对象里面包含的值--可能是对象的引用,也可能是值类型的值. hashCode():计算出对象实例的哈希码,并返回哈希码,又称为散列函数.根类Obje ...

  2. vivado2015.4保存ila波形数据

    reference: https://www.cnblogs.com/pejoicen/p/d8b3c4f3aa29b8de7963893d4b99d361.html Vivado2015.4下,il ...

  3. 2017-10-22模拟赛T2 或(or.*)

    题面 [题目描述]你需要构造一个长度为 n 的数列 X,当中的数字范围从 0 到 2^30-1.除此之外你需要满足 m 个条件,第 i 个条件为 X[li]|X[li+1]|……|X[ri]=pi.| ...

  4. Ionic2 渐变隐藏导航栏|标题栏

    废话少说 直接上代码.... //导入需要用到的命名空间 ViewChild,Content import { Component, ViewChild } from '@angular/core'; ...

  5. 精进之路之CAS

    CAS (Compare And Swap) 即比较交换, 是一种实现并发算法时常用到的技术,Java并发包中的很多类都使用了CAS技术,本文将深入的介绍CAS的原理. 其算法核心思想如下 执行函数: ...

  6. java中字符串“不可变性”的破坏,使用反射破坏final属性。以及涉及到字符串常量池的问题。

    大家都清楚java中String类是不可变的,它的定义中包含final关键字.一旦被创建,值就不能被改变(引用是可以改变的). 但这种“不可变性”不是完全可靠的,可以通过反射机制破坏.参考一下代码: ...

  7. 微信浏览器软键盘弹出与页面resize的问题

    使用微信打开网页,弹出软键盘时遇到的兼容问题 过去开发中遇到过很多这种情况,页面底部需要固定定位一个按钮,广告栏或者菜单栏,页面中有表单项需要填写,在打开手机虚拟键盘的时候,底部固定定位的元素会处在软 ...

  8. 清华机试中手机键盘问题求解 java 和 c

    题目描述:按照手机键盘输入字母的方式,计算所花费的时间 如:a,b,c都在“1”键上,输入a只需要按一次,输入c需要连续按三次.如果连续两个字符不在同一个按键上,则可直接按,如:ad需要按两下,kz需 ...

  9. Flyweight 享元(结构型)

    一:描述:(该模式实际应用较少) Flyweight 享元模式是对大量细粒度的元素进行共享和重用.减少对象的创建减轻内存: 注和单例模式不同的是:享元模式的各个对象佣有各自的行为并可实例化,单例模式的 ...

  10. read读文件

    FILE *fp=fopen("F:\\QQBrowser_Setup_DNF.exe", "rb"); fseek(fp, , SEEK_END); long ...