3 # Copyright (C) 2004-2020 ZNC, see the NOTICE file for details.
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
9 # http://www.apache.org/licenses/LICENSE-2.0
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
18 # http://stackoverflow.com/questions/18993438/shebang-env-preferred-python-version
19 # http://stackoverflow.com/questions/12070516/conditional-shebang-line-for-different-versions-of-python
21 which python3
>/dev
/null
2>&1 && exec python3
"$0" "$@"
22 which python
>/dev
/null
2>&1 && exec python
"$0" "$@"
23 which python2
>/dev
/null
2>&1 && exec python2
"$0" "$@"
24 echo "Error: znc-buildmod requires python"
25 exec echo "Either install python, or use cmake directly"
28 from __future__ import print_function
38 if sys.version_info
< (3, 0):
39 class TemporaryDirectory
(object
):
41 self.name
= tempfile.mkdtemp
()
43 def __exit__
(self
, *a
, **k
):
44 shutil.rmtree
(self.name
)
45 tempfile.TemporaryDirectory
= TemporaryDirectory
47 parser
= argparse.ArgumentParser
(
48 description
='Build external ZNC modules and place the results to '
49 'current directory. Several modules can be built at once.',
50 epilog
='Adjustable environment variables: CXXFLAGS, LDFLAGS, LIBS')
51 parser.add_argument
('-v', '--verbose', action
='count', default
=0,
52 help='use -vvv for more verbosity')
53 parser.add_argument
('files', nargs
='+', metavar
='file.cpp',
54 help="path to the module's source file")
55 args
= parser.parse_args
()
57 with tempfile.TemporaryDirectory
() as cmdir
:
58 with open
(os.path.
join(cmdir
, 'CMakeLists.txt'), 'w') as cm
:
59 print
('cmake_minimum_required(VERSION 3.1)', file=cm
)
60 print
('project(ExternalModules LANGUAGES CXX)', file=cm
)
61 print
('find_package(ZNC @ZNC_VERSION_MAJOR@.@ZNC_VERSION_MINOR@ HINTS '
62 '@CMAKE_INSTALL_FULL_DATADIR@/znc REQUIRED)', file=cm
)
64 print
('set(CMAKE_VERBOSE_MAKEFILE true)', file=cm
)
66 for mod_cpp
in args.files
:
67 mod
, _
= os.path.splitext
(os.path.
basename(mod_cpp
))
69 print
('add_library(module_{} MODULE {})'.format
(
70 mod
, os.path.abspath
(mod_cpp
)), file=cm
)
71 print
('znc_setup_module(TARGET module_{} NAME {})'.format
(mod
, mod
),
73 print
('target_link_libraries(module_{} PRIVATE {})'.format
(
74 mod
, os.environ.get
('LIBS', '')), file=cm
)
77 with open
(os.path.
join(cmdir
, 'CMakeLists.txt')) as cm
:
80 with tempfile.TemporaryDirectory
() as build
:
81 command = ['cmake', cmdir
]
83 cmd.append
('--debug-output')
88 subprocess.check_call
(command, cwd
=build
)
89 subprocess.check_call
(['cmake', '--build', '.'], cwd
=build
)
91 for so
in glob.iglob
(os.path.
join(build
, '*.so')):
93 os.remove
(os.path.
basename(so
))
96 shutil.copy
(so
, os.getcwd
())