Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial draft of ninja support #3508

Closed
wants to merge 19 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ jobs:
arch: ${{ matrix.arch }}

- name: Build and Test Botan
run: python3 ./src/scripts/ci_build.py --cc='msvc' --make-tool='jom' --cpu='${{ matrix.arch }}' --test-results-dir=junit_results ${{ matrix.target }}
run: python3 ./src/scripts/ci_build.py --cc='msvc' --make-tool='ninja' --cpu='${{ matrix.arch }}' --test-results-dir=junit_results ${{ matrix.target }}

linux:
name: "Linux"
Expand Down Expand Up @@ -147,7 +147,7 @@ jobs:
- target: sanitizer
compiler: msvc
host_os: windows-2022
make_tool: jom
make_tool: ninja
- target: sanitizer
compiler: clang
host_os: ubuntu-22.04
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
/Makefile
CMakeLists.txt*
build.ninja
.ninja_log
libbotan*.so.*
*.a
*.so
Expand Down
11 changes: 10 additions & 1 deletion configure.py
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,9 @@ def process_command_line(args):
build_group.add_option('--build-targets', default=None, dest="build_targets", action='append',
help="build specific targets and tools (%s)" % ', '.join(ACCEPTABLE_BUILD_TARGETS))

build_group.add_option('--build-tool', default='make',
help="specify the build tool (make, ninja)")

build_group.add_option('--with-pkg-config', action='store_true', default=None,
help=optparse.SUPPRESS_HELP)
build_group.add_option('--without-pkg-config', dest='with_pkg_config', action='store_false',
Expand Down Expand Up @@ -3152,6 +3155,9 @@ def validate_options(options, info_os, info_cc, available_module_policies):
if options.build_fuzzers == 'klee' and options.os != 'llvm':
raise UserError('Building for KLEE requires targeting LLVM')

if options.build_tool not in ['make', 'ninja']:
raise UserError("Unknown --build-tool option (possible values: make, ninja)")

if options.build_static_lib is False and options.build_shared_lib is False:
raise UserError('With both --disable-static-library and --disable-shared-library, nothing to do')

Expand Down Expand Up @@ -3351,7 +3357,10 @@ def link_headers(headers, visibility, directory):
if options.with_compilation_database:
write_template(in_build_dir('compile_commands.json'), in_build_data('compile_commands.json.in'))

write_template(template_vars['makefile_path'], in_build_data('makefile.in'))
if options.build_tool == 'make':
write_template(template_vars['makefile_path'], in_build_data('makefile.in'))
elif options.build_tool == 'ninja':
write_template(template_vars['ninja_build_path'], in_build_data('ninja.in'))

if options.with_doxygen:
for module_name, info in info_modules.items():
Expand Down
15 changes: 10 additions & 5 deletions doc/building.rst
Original file line number Diff line number Diff line change
Expand Up @@ -181,8 +181,8 @@ On macOS

A build on macOS works much like that on any other Unix-like system.

To build a universal binary for macOS, for older macOs releases,
you need to set some additional build flags.
To build a universal binary for macOS, for older macOs releases,
you need to set some additional build flags.
Do this with the `configure.py` flag `--cc-abi-flags`::

--cc-abi-flags="-force_cpusubtype_ALL -mmacosx-version-min=10.4 -arch i386 -arch ppc"
Expand All @@ -209,14 +209,19 @@ shell), and run::
$ nmake check
$ nmake install

Botan supports the nmake replacement `Jom <https://wiki.qt.io/Jom>`_
which enables you to run multiple build jobs in parallel.
randombit marked this conversation as resolved.
Show resolved Hide resolved

For MinGW, use::

$ python3 configure.py --cc=gcc --os=mingw
$ make

Botan supports the `ninja <https://ninja-build.org>`_ build system
which enables you to run multiple build jobs in parallel::

$ python3 configure.py --cc=msvc --os=windows --build-tool=ninja
$ ninja
$ ninja check
$ ninja install

By default the install target will be ``C:\botan``; you can modify
this with the ``--prefix`` option.

Expand Down
192 changes: 192 additions & 0 deletions src/build-data/ninja.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
ninja_required_version = 1.3

CXX = %{cxx}
LINKER = %{linker}
PYTHON_EXE = %{python_exe}

rule compile_lib
command = %{cxx} %{lib_flags} ${BUILD_FLAGS} ${isa_flags} %{include_paths} %{dash_c} $in %{dash_o}$out

rule compile_exe
command = %{cxx} ${BUILD_FLAGS} ${isa_flags} %{include_paths} %{dash_c} $in %{dash_o}$out

ABI_FLAGS = %{cc_sysroot} %{cxx_abi_flags}
LANG_FLAGS = %{cc_lang_flags} %{os_feature_macros}
LANG_EXE_FLAGS = %{cc_lang_binary_linker_flags}
CXXFLAGS = %{cc_compile_flags} -DBOTAN_IS_BEING_BUILT
WARN_FLAGS = %{cc_warning_flags}
BUILD_FLAGS = ${ABI_FLAGS} ${LANG_FLAGS} ${CXXFLAGS} ${WARN_FLAGS}

LIB_FLAGS = %{lib_flags}
LDFLAGS = %{ldflags}

EXE_LINK_CMD = %{exe_link_cmd}

LIB_LINKS_TO = %{external_link_cmd} %{link_to}
BUILD_DIR_LINK_PATH = %{build_dir_link_path}
EXE_LINKS_TO = %{link_to_botan} ${LIB_LINKS_TO} %{extra_libs}


SCRIPTS_DIR = %{scripts_dir}
INSTALLED_LIB_DIR = %{libdir}

# The primary target
build all: phony %{all_targets}
default all

CLI = %{cli_exe}
TEST = %{test_exe}
LIBRARIES = %{library_targets}


# Library targets

%{if build_static_lib}

rule link_static
command = %{ar_command} %{ar_options} %{ar_output_to}$out $in

build %{out_dir}/%{static_lib_name}: link_static %{join lib_objs}

%{endif}
%{if build_shared_lib}

rule link_shared
command = %{lib_link_cmd} ${ABI_FLAGS} ${LDFLAGS} $in ${LIB_LINKS_TO} %{output_to_exe}$out

build %{out_dir}/%{shared_lib_name}: link_shared %{join lib_objs}
%{endif}
%{if symlink_shared_lib}

rule symlink
command = cd %{out_dir} && ln -fs $in $out

build %{out_dir}/%{soname_base}: symlink %{out_dir}/%{shared_lib_name}
build %{out_dir}/%{soname_patch}: symlink %{out_dir}/%{shared_lib_name}

%{endif}

rule link_cli
command = ${EXE_LINK_CMD} ${ABI_FLAGS} $in ${BUILD_DIR_LINK_PATH} ${LANG_EXE_FLAGS} ${LDFLAGS} ${EXE_LINKS_TO} %{output_to_exe}$out

rule link_tests
command = ${EXE_LINK_CMD} ${ABI_FLAGS} $in ${BUILD_DIR_LINK_PATH} ${LANG_EXE_FLAGS} ${LDFLAGS} %{test_exe_extra_ldflags} ${EXE_LINKS_TO} %{output_to_exe}$out


# Executable targets

build %{cli_exe}: link_cli %{join cli_objs} | %{library_targets}

build %{test_exe}: link_tests %{join test_objs} | %{library_targets}

%{if build_fuzzers}

build fuzzers: phony %{fuzzer_bin}

rule fuzzer_corpus
command = git clone --depth=1 https://github.com/randombit/crypto-corpus.git fuzzer_corpus

build fuzzer_corpus: fuzzer_corpus

rule fuzzer_corpus_zip
command = %{base_dir}/src/scripts/create_corpus_zip.py fuzzer_corpus %{fuzzobj_dir}

build fuzzer_corpus_zip: fuzzer_corpus_zip | fuzzer_corpus

rule link_fuzzer
command = ${EXE_LINK_CMD} ${ABI_FLAGS} $in ${BUILD_DIR_LINK_PATH} ${LANG_EXE_FLAGS} ${LDFLAGS} ${EXE_LINKS_TO} %{fuzzer_lib} %{output_to_exe}$out

%{endif}

%{if build_examples}

build examples: link_cli %{example_bin} | %{library_targets}

%{endif}


%{if build_bogo_shim}

build bogo_shim: link_cli botan_bogo_shim | %{library_targets}

# BoGo shim
build %{out_dir}/botan_bogo_shim: compile_exe %{bogo_shim_src}

%{endif}

# Misc targets

rule build_docs
command = "${PYTHON_EXE}" "${SCRIPTS_DIR}/build_docs.py" --build-dir="%{build_dir}"

build %{doc_stamp_file}: build_docs

rule clean
command = "${PYTHON_EXE}" "${SCRIPTS_DIR}/cleanup.py" --build-dir="%{build_dir}"

rule distclean
command = "${PYTHON_EXE}" "${SCRIPTS_DIR}/cleanup.py" --build-dir="%{build_dir}" --distclean

rule install
command = "${PYTHON_EXE}" "${SCRIPTS_DIR}/install.py" --build-dir="%{build_dir}"

rule check
command = "${PYTHON_EXE}" "${SCRIPTS_DIR}/check.py" --build-dir="%{build_dir}"

rule fmt
command = "${PYTHON_EXE}" "${SCRIPTS_DIR}/dev_tools/run_clang_format.py"

rule tidy
command = "${PYTHON_EXE}" "${SCRIPTS_DIR}/dev_tools/run_clang_tidy.py" --only-changed-files

# Target aliases

build cli: phony %{cli_exe}

build tests: phony %{test_exe}

build libs: phony %{library_targets} $
%{if symlink_shared_lib}
%{out_dir}/%{soname_base} %{out_dir}/%{soname_patch}
%{endif}

build docs: phony %{doc_stamp_file}

build clean: clean

build distclean: distclean

build install: install | %{install_targets}

build check: check | tests

build fmt: fmt

build tidy: tidy


# Build Commands

%{for lib_build_info}
build %{obj}: compile_lib %{src}
%{endfor}

%{for cli_build_info}
build %{obj}: compile_exe %{src}
%{endfor}

%{for test_build_info}
build %{obj}: compile_exe %{src}
%{endfor}

%{for fuzzer_build_info}
build %{obj}: compile_exe %{src}

build %{exe}: link_fuzzer %{obj} | %{library_targets}
%{endfor}

%{for examples_build_info}
build %{obj}: compile_exe %{src}

build %{exe}: link_cli %{obj} | %{library_targets}
%{endfor}
2 changes: 1 addition & 1 deletion src/editors/vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
"problemMatcher": "$gcc"
},
"windows": {
"command": "jom",
"command": "ninja",
"problemMatcher": "$msCompile"
},
"presentation": {
Expand Down
2 changes: 1 addition & 1 deletion src/scripts/ci/setup_gh_actions.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#
# (C) 2022 Jack Lloyd
# (C) 2022 René Meusel, Rohde & Schwarz Cybersecurity
# (C) 2023 René Fischer, Rohde & Schwarz Cybersecurity
#
# Botan is released under the Simplified BSD License (see license.txt)

Expand All @@ -11,7 +12,6 @@ param(
[String]$ARCH
)

choco install -y jom
choco install -y sccache

# find the sccache cache location and store it in the build job's environment
Expand Down
26 changes: 13 additions & 13 deletions src/scripts/ci_build.py
Original file line number Diff line number Diff line change
Expand Up @@ -526,18 +526,14 @@ def validate_make_tool(make_tool, build_jobs):
if make_tool == '':
return validate_make_tool('make', build_jobs)

if make_tool not in ['nmake', 'jom', 'make']:
if make_tool not in ['ninja', 'nmake', 'make']:
raise Exception("Don't know about %s as a make tool" % (make_tool))

# Hack to work around jom occasionally failing to install
# https://github.com/randombit/botan/issues/3629
if make_tool == 'jom' and not have_prog('jom'):
return ['nmake']
if make_tool in ['make']:
return make_tool, ['-j%d' % (build_jobs), '-k']

if make_tool in ['make', 'jom']:
return [make_tool, '-j%d' % (build_jobs)]
else:
return [make_tool]
return make_tool, []

def main(args=None):
"""
Expand Down Expand Up @@ -650,13 +646,17 @@ def main(args=None):
options.pkcs11_lib, options.use_gdb, options.disable_werror,
options.extra_cxxflags, options.disabled_tests)

cmds.append([py_interp, os.path.join(root_dir, 'configure.py')] + config_flags)
make_tool, make_opts = validate_make_tool(options.make_tool, options.build_jobs)

make_cmd = validate_make_tool(options.make_tool, options.build_jobs)
if build_dir != '.':
make_cmd = ['indir:%s' % build_dir] + make_cmd
cmds.append([py_interp,
os.path.join(root_dir, 'configure.py')] +
['--build-tool=' + make_tool] +
config_flags)

make_cmd += ['-k']
make_cmd = [make_tool] + make_opts

if build_dir != '.':
make_cmd = ['indir:%s' % build_dir] + [make_tool] + make_opts

if target == 'docs':
cmds.append(make_cmd + ['docs'])
Expand Down
Loading