diff --git a/SConstruct b/SConstruct index 09c939af3..cf6a18c08 100644 --- a/SConstruct +++ b/SConstruct @@ -8,8 +8,10 @@ Currently, the aim is to provide a way to compile or copy the implementation fil To run the compilation for all implementations in one language, e.g. C, run the command `scons build/c`, and the resulting executables will be available in the `build/c` directory, each in their respective algorithm directory, containing the executable.""" from pathlib import Path +from collections import namedtuple import os + rust_cargo_builder = Builder(action=['cargo build --bins --manifest-path $MANIFEST', Move('$TARGET$PROGSUFFIX', '$SOURCE_DIR/target/debug/main$PROGSUFFIX')]) @@ -23,6 +25,8 @@ env = Environment(ENV=os.environ, 'Go': go_builder}, tools=['gcc', 'gnulink', 'g++', 'gas', 'gfortran']) +Export('env') + env['CFLAGS'] = '-Wall -Wextra -Werror' env['CXXFLAGS'] = '-std=c++17' env['ASFLAGS'] = '--64' @@ -30,7 +34,7 @@ env['ASFLAGS'] = '--64' # Add other languages here when you want to add language targets # Put 'name_of_language_directory' : 'file_extension' languages = { - 'c': 'c', + 'c': 'c', 'cpp': 'cpp', 'asm-x64': 's', 'rust': 'rs', @@ -38,33 +42,45 @@ languages = { 'fortran': 'f90', } +# Do not add new Builders here, add them to the BUILDERS argument in the call to Environment above env.C = env.Program env.CPlusPlus = env.Program env.X64 = env.Program env.Fortran = env.Program -Export('env') +for language in languages: + Alias(language, f'#/build/{language}') sconscripts = [] files_to_compile = {language: [] for language in languages} -for chapter_dir in Path.cwd().joinpath('contents').iterdir(): - if (code_dir := (chapter_dir / 'code')).exists(): - for path in code_dir.iterdir(): - if path.stem in languages: - # Check for overriding sconscript - if (sconscript_path := path / 'SConscript').exists(): - sconscripts.append(sconscript_path) - SConscript(sconscript_path, exports='env') +FileInformation = namedtuple('FileInformation', ['path', 'chapter', 'language']) + + +contents_path = Path.cwd().joinpath('contents') +for chapter_dir in contents_path.iterdir(): + for code_dir in chapter_dir.glob('**/code'): + # For nested chapters e.g. contents/convolutions/1d/ + extended_chapter_path = code_dir.relative_to(contents_path).parent + + for language_dir in code_dir.iterdir(): + if (language := language_dir.stem) in languages: + new_files = [FileInformation(path=file_path, + chapter=extended_chapter_path, + language=language) + for file_path in language_dir.glob(f'**/*.{languages[language]}') + ] + # Check for overriding SConscript + if (sconscript_path := language_dir / 'SConscript').exists(): + SConscript(sconscript_path, exports={'files_to_compile': new_files}) else: - files_to_compile[path.stem].extend(path.glob(f'*.{languages[path.stem]}')) + files_to_compile[language].extend(new_files) -sconscript_dir_path = Path('sconscripts') +sconscript_dir_path = Path.cwd().joinpath('sconscripts') for language, files in files_to_compile.items(): if files: if (sconscript_path := sconscript_dir_path / f"{language}_SConscript").exists(): - SConscript(sconscript_path, exports = {'files_to_compile': files, - 'language': language}) + SConscript(sconscript_path, exports = {'files_to_compile': files}) else: print(f'{language} file found at {files[0]}, but no sconscript file is present ') diff --git a/contents/approximate_counting/code/c/SConscript b/contents/approximate_counting/code/c/SConscript index 34a951e7f..984e0eb11 100644 --- a/contents/approximate_counting/code/c/SConscript +++ b/contents/approximate_counting/code/c/SConscript @@ -1,6 +1,6 @@ -Import('*') -from pathlib import Path +Import('files_to_compile env') -dirname = Path.cwd().parents[1].stem - -env.C(f'#/build/c/{dirname}', Glob('*.c'), LIBS='m') +for file_info in files_to_compile: + build_target = f'#/build/{file_info.language}/{file_info.chapter}/{file_info.path.stem}' + build_result = env.C(build_target, str(file_info.path), LIBS='m') + env.Alias(str(file_info.chapter), build_result) diff --git a/contents/cooley_tukey/code/asm-x64/SConscript b/contents/cooley_tukey/code/asm-x64/SConscript index 05360fe6c..2a10fbc14 100644 --- a/contents/cooley_tukey/code/asm-x64/SConscript +++ b/contents/cooley_tukey/code/asm-x64/SConscript @@ -1,6 +1,6 @@ -Import('*') -from pathlib import Path +Import('files_to_compile env') -dirname = Path.cwd().parents[1].stem - -env.X64(f'#/build/asm-x64/{dirname}', Glob('*.s'), LIBS=['m'], LINKFLAGS='-no-pie') +for file_info in files_to_compile: + build_target = f'#/build/{file_info.language}/{file_info.chapter}/{file_info.path.stem}' + build_result = env.X64(build_target, str(file_info.path), LIBS='m', LINKFLAGS='-no-pie') + env.Alias(str(file_info.chapter), build_result) \ No newline at end of file diff --git a/contents/cooley_tukey/code/c/SConscript b/contents/cooley_tukey/code/c/SConscript index 2cd13de37..bb40f4a85 100644 --- a/contents/cooley_tukey/code/c/SConscript +++ b/contents/cooley_tukey/code/c/SConscript @@ -1,6 +1,6 @@ -Import('*') -from pathlib import Path +Import('files_to_compile env') -dirname = Path.cwd().parents[1].stem - -env.C(f'#/build/c/{dirname}', Glob('*.c'), LIBS=['m', 'fftw3']) +for file_info in files_to_compile: + build_target = f'#/build/{file_info.language}/{file_info.chapter}/{file_info.path.stem}' + build_result = env.C(build_target, str(file_info.path), LIBS=['m', 'fftw3']) + env.Alias(str(file_info.chapter), build_result) \ No newline at end of file diff --git a/contents/euclidean_algorithm/code/fortran/SConscript b/contents/euclidean_algorithm/code/fortran/SConscript deleted file mode 100644 index 8146feee9..000000000 --- a/contents/euclidean_algorithm/code/fortran/SConscript +++ /dev/null @@ -1,6 +0,0 @@ -Import('*') -from pathlib import Path - -dirname = Path.cwd().parents[1].stem - -env.Fortran(f'#/build/fortran/{dirname}', 'euclidean.f90') diff --git a/contents/forward_euler_method/code/asm-x64/SConscript b/contents/forward_euler_method/code/asm-x64/SConscript index 9322fd10c..2a10fbc14 100644 --- a/contents/forward_euler_method/code/asm-x64/SConscript +++ b/contents/forward_euler_method/code/asm-x64/SConscript @@ -1,6 +1,6 @@ -Import('*') -from pathlib import Path +Import('files_to_compile env') -dirname = Path.cwd().parents[1].stem - -env.X64(f'#/build/asm-x64/{dirname}', Glob('*.s'), LIBS='m', LINKFLAGS='-no-pie') +for file_info in files_to_compile: + build_target = f'#/build/{file_info.language}/{file_info.chapter}/{file_info.path.stem}' + build_result = env.X64(build_target, str(file_info.path), LIBS='m', LINKFLAGS='-no-pie') + env.Alias(str(file_info.chapter), build_result) \ No newline at end of file diff --git a/contents/forward_euler_method/code/c/SConscript b/contents/forward_euler_method/code/c/SConscript index 34a951e7f..b81220a0e 100644 --- a/contents/forward_euler_method/code/c/SConscript +++ b/contents/forward_euler_method/code/c/SConscript @@ -1,6 +1,6 @@ -Import('*') -from pathlib import Path +Import('files_to_compile env') -dirname = Path.cwd().parents[1].stem - -env.C(f'#/build/c/{dirname}', Glob('*.c'), LIBS='m') +for file_info in files_to_compile: + build_target = f'#/build/{file_info.language}/{file_info.chapter}/{file_info.path.stem}' + build_result = env.C(build_target, str(file_info.path), LIBS='m') + env.Alias(str(file_info.chapter), build_result) \ No newline at end of file diff --git a/contents/graham_scan/code/c/SConscript b/contents/graham_scan/code/c/SConscript index 34a951e7f..c404efbd8 100644 --- a/contents/graham_scan/code/c/SConscript +++ b/contents/graham_scan/code/c/SConscript @@ -1,6 +1,6 @@ -Import('*') -from pathlib import Path +Import('files_to_compile env') -dirname = Path.cwd().parents[1].stem - -env.C(f'#/build/c/{dirname}', Glob('*.c'), LIBS='m') +for file_info in files_to_compile: + build_target = f'#/build/{file_info.language}/{file_info.chapter}/{file_info.path.stem}' + build_result = env.C(build_target, str(file_info.path), LIBS='m') + env.Alias(str(file_info.chapter), build_result) diff --git a/contents/split-operator_method/code/c/SConscript b/contents/split-operator_method/code/c/SConscript index 2cd13de37..bb40f4a85 100644 --- a/contents/split-operator_method/code/c/SConscript +++ b/contents/split-operator_method/code/c/SConscript @@ -1,6 +1,6 @@ -Import('*') -from pathlib import Path +Import('files_to_compile env') -dirname = Path.cwd().parents[1].stem - -env.C(f'#/build/c/{dirname}', Glob('*.c'), LIBS=['m', 'fftw3']) +for file_info in files_to_compile: + build_target = f'#/build/{file_info.language}/{file_info.chapter}/{file_info.path.stem}' + build_result = env.C(build_target, str(file_info.path), LIBS=['m', 'fftw3']) + env.Alias(str(file_info.chapter), build_result) \ No newline at end of file diff --git a/contents/split-operator_method/code/cpp/SConscript b/contents/split-operator_method/code/cpp/SConscript index a25ed8c91..f9ec1b545 100644 --- a/contents/split-operator_method/code/cpp/SConscript +++ b/contents/split-operator_method/code/cpp/SConscript @@ -1,6 +1,6 @@ -Import('*') -from pathlib import Path +Import('files_to_compile env') -dirname = Path.cwd().parents[1].stem - -env.CPlusPlus(f'#/build/cpp/{dirname}', Glob('*.cpp'), LIBS=['m', 'fftw3']) +for file_info in files_to_compile: + build_target = f'#/build/{file_info.language}/{file_info.chapter}/{file_info.path.stem}' + build_result = env.CPlusPlus(build_target, str(file_info.path), LIBS=['m', 'fftw3']) + env.Alias(str(file_info.chapter), build_result) diff --git a/sconscripts/asm-x64_SConscript b/sconscripts/asm-x64_SConscript index caabf226f..ba90ee330 100644 --- a/sconscripts/asm-x64_SConscript +++ b/sconscripts/asm-x64_SConscript @@ -1,6 +1,6 @@ -Import('files_to_compile language env') -from pathlib import Path +Import('files_to_compile env') -for file in files_to_compile: - chapter_name = file.parent.parent.parent.stem - env.X64(f'#/build/{language}/{chapter_name}', str(file), LINKFLAGS='-no-pie') +for file_info in files_to_compile: + build_target = f'#/build/{file_info.language}/{file_info.chapter}/{file_info.path.stem}' + build_result = env.X64(build_target, str(file_info.path), LINKFLAGS='-no-pie') + env.Alias(str(file_info.chapter), build_result) \ No newline at end of file diff --git a/sconscripts/c_SConscript b/sconscripts/c_SConscript index a0cbffd95..ebc6aeead 100644 --- a/sconscripts/c_SConscript +++ b/sconscripts/c_SConscript @@ -1,6 +1,6 @@ Import('files_to_compile env') -from pathlib import Path -for file in files_to_compile: - chapter_name = file.parent.parent.parent.stem - env.C(f'#/build/c/{chapter_name}', str(file)) +for file_info in files_to_compile: + build_target = f'#/build/{file_info.language}/{file_info.chapter}/{file_info.path.stem}' + build_result = env.C(build_target, str(file_info.path)) + env.Alias(str(file_info.chapter), build_result) \ No newline at end of file diff --git a/sconscripts/cpp_SConscript b/sconscripts/cpp_SConscript index a30e08652..f1ae9f974 100644 --- a/sconscripts/cpp_SConscript +++ b/sconscripts/cpp_SConscript @@ -1,6 +1,6 @@ Import('files_to_compile env') -from pathlib import Path -for file in files_to_compile: - chapter_name = file.parent.parent.parent.stem - env.CPlusPlus(f'#/build/cpp/{chapter_name}', str(file)) +for file_info in files_to_compile: + build_target = f'#/build/{file_info.language}/{file_info.chapter}/{file_info.path.stem}' + build_result = env.CPlusPlus(build_target, str(file_info.path)) + env.Alias(str(file_info.chapter), build_result) diff --git a/sconscripts/fortran_SConscript b/sconscripts/fortran_SConscript index df3e7fc27..ab85e9f06 100644 --- a/sconscripts/fortran_SConscript +++ b/sconscripts/fortran_SConscript @@ -1,6 +1,6 @@ Import('files_to_compile env') -from pathlib import Path -for file in files_to_compile: - chapter_name = file.parent.parent.parent.stem - env.Fortran(f'#/build/fortran/{chapter_name}', str(file)) +for file_info in files_to_compile: + build_target = f'#/build/{file_info.language}/{file_info.chapter}/{file_info.path.stem}' + build_result = env.Fortran(build_target, str(file_info.path)) + env.Alias(str(file_info.chapter), build_result) \ No newline at end of file diff --git a/sconscripts/go_SConscript b/sconscripts/go_SConscript index 795be1d53..d521574a9 100644 --- a/sconscripts/go_SConscript +++ b/sconscripts/go_SConscript @@ -1,6 +1,6 @@ Import('files_to_compile env') -from pathlib import Path -for file in files_to_compile: - chapter_name = file.parent.parent.parent.stem - env.Go(f'#/build/go/{chapter_name}', str(file)) +for file_info in files_to_compile: + build_target = f'#/build/{file_info.language}/{file_info.chapter}/{file_info.path.stem}' + build_result = env.Go(build_target, str(file_info.path)) + env.Alias(str(file_info.chapter), build_result) diff --git a/sconscripts/rust_SConscript b/sconscripts/rust_SConscript index b9cf669c7..d93b9d680 100644 --- a/sconscripts/rust_SConscript +++ b/sconscripts/rust_SConscript @@ -1,14 +1,15 @@ Import('files_to_compile env') -from pathlib import Path -for file in files_to_compile: - chapter_name = file.parent.parent.parent.stem - if (file.parent / 'Cargo.toml').exists(): - env.cargo(target=f'#/build/rust/{chapter_name}', - source=str(file), - MANIFEST=str(file.parent / 'Cargo.toml'), - SOURCE_DIR=str(file.parent)) - env.Clean('rust', str(file.parent / 'target')) +for file_info in files_to_compile: + build_target = f'#/build/{file_info.language}/{file_info.chapter}/{file_info.path.stem}' + if (file_info.path.parent / 'Cargo.toml').exists(): + build_result = env.cargo(target=build_target, + source=str(file_info.path), + MANIFEST=str(file_info.path.parent / 'Cargo.toml'), + SOURCE_DIR=str(file_info.path.parent)) + env.Clean('rust', str(file_info.path.parent / 'target')) else: - env.rustc(f'#/build/rust/{chapter_name}', str(file)) - env.Clean('rust', f'#/build/rust/{chapter_name}.pdb') + build_result = env.rustc(build_target, str(file_info.path)) + env.Clean('rust', f'{build_target}.pdb') + + env.Alias(str(file_info.chapter), build_result) \ No newline at end of file