Skip to content

Commit

Permalink
Add option to generate CMakeLists.txt (#143)
Browse files Browse the repository at this point in the history
  • Loading branch information
technothecow authored Jun 23, 2024
1 parent 6825bae commit 4ee9a69
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 10 deletions.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ pip3 install .
- `global-opt-out` - отказаться от отправки статистики для глобального рейтинга
- `save-html-statements`, `save-md-statements` (по умолчанию оба значения `true`) - выбор формата сохранения условий при синхронизации
- `save-attachments` (по умолчанию `true`) - сохранять приложенные к условиям файлы
- `generate-cmakelists` (по умолчанию `false`) - генерировать CMakeLists.txt

Имена переменных окружения, если они используются, должны быть в upper-case. Например, для переопределения опции `save-html-statements` используется переменная окружения `SAVE_HTML_STATEMENTS`

Expand Down Expand Up @@ -233,3 +234,12 @@ export KKS_CUSTOM_URL=https://caos-alt.somedomain.ru
kks sync --code=all
# ...
```

## Генерация CMakeLists.txt

Для генерации `CMakeLists.txt` необходимо добавить флаг `cmakelists = true` в раздел `[Options]` файла конфигурации `~/.kks/config.ini`:

```ini
[Options]
generate-cmakelists = true
```
2 changes: 1 addition & 1 deletion kks/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '1.16.30'
__version__ = '1.16.31'
43 changes: 43 additions & 0 deletions kks/cmd/init.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from kks.util.click import OptFlagCommand, FlagOption, OptFlagOption, Choice2
from kks.util.common import find_workspace, get_hidden_dir, format_file
from kks.util.config import target_file, global_comment
from kks.util.storage import Config


@click.command(cls=OptFlagCommand)
Expand Down Expand Up @@ -79,6 +80,8 @@ def init(force, config, config_opt):
else:
hidden.mkdir()

write_cmakelists(path)

action = 'Updated' if old_workspace else 'Initialized'
click.secho(f'{action} workspace in directory {path.absolute()}', fg='green', bold=True)

Expand Down Expand Up @@ -120,3 +123,43 @@ def create_config(directory, is_global, update, force):
click.secho('Default targets are written to ', fg='green', nl=False)
click.secho(format_file(file))
click.secho('The config file is not updated automatically.', bold=True)


def write_cmakelists(directory):
config = Config()
if not config.options.generate_cmakelists:
return

click.secho('Writing CMakeLists.txt...', fg='green')

path = directory / 'CMakeLists.txt'

if path.exists():
return

path.write_text('''cmake_minimum_required(VERSION 3.10)
project(caos C ASM)
# Function to recursively add subdirectories
function(add_subdirectories_recursively dir)
if(IS_DIRECTORY ${dir})
file(GLOB sub_dirs RELATIVE ${dir} ${dir}/*)
foreach(sub_dir ${sub_dirs})
if(IS_DIRECTORY ${dir}/${sub_dir})
if(EXISTS ${dir}/${sub_dir}/CMakeLists.txt)
# Prepend the relative path from the source directory to the current directory
get_filename_component(full_dir "${dir}/${sub_dir}" REALPATH BASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
file(RELATIVE_PATH rel_dir "${CMAKE_CURRENT_SOURCE_DIR}" "${full_dir}")
add_subdirectory(${rel_dir})
endif()
add_subdirectories_recursively(${dir}/${sub_dir})
endif()
endforeach()
endif()
endfunction()
# Call the function on the current source directory
add_subdirectories_recursively(${CMAKE_CURRENT_SOURCE_DIR})
''')
64 changes: 55 additions & 9 deletions kks/cmd/sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,57 @@ def sync_attachments(problem, dest_dir, session):
f.write(page.content)


def write_genpy(task_dir):
gen = task_dir / 'gen.py'

if gen.exists():
return

with gen.open('w') as file:
file.write('import sys\n'
'import random\n'
'\n'
't = int(sys.argv[1])\n'
'random.seed(t)\n')


def write_cmakelists(task_dir, suffix, name):
if suffix not in ('.c', '.S'):
click.secho(f'Unsupported solution language with suffix {suffix}, skipping CMakeLists.txt generation',
fg='yellow', err=True)
return

cmakelists_path = task_dir / 'CMakeLists.txt'

if cmakelists_path.exists():
return

language = 'ASM' if suffix == '.S' else 'C'

from kks.util.config import find_target
from kks.binary import ASAN_ARGS
target = find_target('default')

compiler_flags_list = target.flags
link_flags_list = [f'-l{lib}' for lib in target.libs]

if not target.asm64bit:
compiler_flags_list.append('-m32')
link_flags_list.append('-m32')

if target.default_asan:
compiler_flags_list += ASAN_ARGS
link_flags_list += ASAN_ARGS

compile_flags = " ".join(compiler_flags_list)
link_flags = " ".join(link_flags_list)

with cmakelists_path.open('w') as f:
f.write(f'add_executable({name} {name}{suffix})\n'
f'set_target_properties({name} PROPERTIES COMPILE_FLAGS "{compile_flags}" LINK_FLAGS "{link_flags}")\n'
f'set_source_files_properties({name}{suffix} PROPERTIES LANGUAGE {language})\n')


@click.command(short_help='Parse problems from ejudge', cls=OptFlagCommand)
@click.option('--code', cls=FlagOption, is_flag=True,
help='Download latest submitted solutions')
Expand Down Expand Up @@ -226,15 +277,10 @@ def sync(code, code_opt, force, filters):
main = (task_dir / problem.short_name).with_suffix(problem.suffix())
main.touch()

gen = task_dir / 'gen.py'
if config.options.generate_cmakelists:
write_cmakelists(task_dir, problem.suffix(), problem.short_name)

if not gen.exists():
with gen.open('w') as file:
file.write('import sys\n'
'import random\n'
'\n'
't = int(sys.argv[1])\n'
'random.seed(t)\n')
write_genpy(task_dir)

solve = task_dir / 'solve.py'
solve.touch()
Expand Down Expand Up @@ -284,6 +330,6 @@ def sync(code, code_opt, force, filters):
color = 'green' if old_problems + new_problems == total_problems else 'red'
click.secho('Sync done!', fg='green')
click.secho(
f'Synced tasks: {old_problems+new_problems}/{total_problems} ({old_problems} unchanged)',
f'Synced tasks: {old_problems + new_problems}/{total_problems} ({old_problems} unchanged)',
fg=color
)
1 change: 1 addition & 0 deletions kks/util/storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ class OptionsSection(EnvSection):
max_kr: bool = False
deadline_warning_days: int = 1
sort_todo_by_deadline: bool = True
generate_cmakelists: bool = False
global_opt_out: bool
keep_bad_credentials: bool

Expand Down

0 comments on commit 4ee9a69

Please sign in to comment.