From acd5da195764214d30b3f37e66d285614fb5cd31 Mon Sep 17 00:00:00 2001 From: Gabriel Ferreira Date: Wed, 2 Feb 2022 23:37:56 +0000 Subject: [PATCH] build: refresh project on scratch changes --- examples/tutorial/CMakeLists.txt | 9 ++++-- ns3 | 49 +++++++++++++++++++++++++------- scratch/CMakeLists.txt | 16 +++++++++-- 3 files changed, 59 insertions(+), 15 deletions(-) diff --git a/examples/tutorial/CMakeLists.txt b/examples/tutorial/CMakeLists.txt index 4ecca4e18..614aa2423 100644 --- a/examples/tutorial/CMakeLists.txt +++ b/examples/tutorial/CMakeLists.txt @@ -45,7 +45,8 @@ build_example( build_example( NAME fifth - SOURCE_FILES fifth.cc tutorial-app.cc + SOURCE_FILES fifth.cc + tutorial-app.cc LIBRARIES_TO_LINK ${libcore} ${libpoint-to-point} @@ -55,7 +56,8 @@ build_example( build_example( NAME sixth - SOURCE_FILES sixth.cc tutorial-app.cc + SOURCE_FILES sixth.cc + tutorial-app.cc LIBRARIES_TO_LINK ${libcore} ${libpoint-to-point} @@ -65,7 +67,8 @@ build_example( build_example( NAME seventh - SOURCE_FILES seventh.cc tutorial-app.cc + SOURCE_FILES seventh.cc + tutorial-app.cc LIBRARIES_TO_LINK ${libcore} ${libstats} diff --git a/ns3 b/ns3 index f23a6bff6..b65a20fdc 100755 --- a/ns3 +++ b/ns3 @@ -210,7 +210,8 @@ def parse_args(argv): help='Try "./ns3 docs --help" for more documentation options') parser_docs.add_argument('docs', help='Build project documentation', - choices=["manual", "models", "tutorial", "contributing", "sphinx", "doxygen-no-build", "doxygen", "all"], + choices=["manual", "models", "tutorial", "contributing", + "sphinx", "doxygen-no-build", "doxygen", "all"], action="store", type=str, default=None) parser.add_argument('-j', '--jobs', @@ -288,11 +289,11 @@ def check_c4che_data(output_directory): ns3_modules_bindings = [] ns3_modules = None - c4che_info = {"BUILD_PROFILE" : None, - "VERSION" : None, - "ENABLE_EXAMPLES" : False, - "ENABLE_SUDO" : False, - "ENABLE_TESTS" : False, + c4che_info = {"BUILD_PROFILE": None, + "VERSION": None, + "ENABLE_EXAMPLES": False, + "ENABLE_SUDO": False, + "ENABLE_TESTS": False, } if output_directory and os.path.exists(c4che_path): exec(open(c4che_path).read(), globals(), c4che_info) @@ -525,6 +526,22 @@ def configure_cmake(cmake, args, current_cmake_cache_folder, current_cmake_gener if ret.returncode != 0: exit(ret.returncode) + update_scratches_list(current_cmake_cache_folder) + + +def update_scratches_list(current_cmake_cache_folder): + # Store list of scratches to trigger a reconfiguration step if needed + current_scratch_sources = glob.glob(os.path.join(ns3_path, "scratch", "**", "*.cc"), recursive=True) + with open(os.path.join(current_cmake_cache_folder, "ns3scratches"), "w") as f: + f.write("\n".join(current_scratch_sources)) + + +def refresh_cmake(current_cmake_cache_folder, output): + ret = subprocess.run([shutil.which("cmake"), ".."], cwd=current_cmake_cache_folder, stdout=output) + if ret.returncode != 0: + exit(ret.returncode) + update_scratches_list(current_cmake_cache_folder) + def get_program_shortcuts(build_profile, ns3_version): build_status_file = os.sep.join([out_dir, "build-status.py"]) @@ -541,7 +558,7 @@ def get_program_shortcuts(build_profile, ns3_version): if "pch_exec" in program: continue temp_path = program.replace(out_dir, "").split(os.sep) - temp_path.pop(0) # remove first path separator + temp_path.pop(0) # remove first path separator # Remove version prefix and build type suffix from shortcuts (or keep them too?) temp_path[-1] = temp_path[-1].replace("-" + build_profile, "").replace("ns" + ns3_version + "-", "") @@ -702,6 +719,7 @@ def reconfigure_cmake_to_force_refresh(cmake, current_cmake_cache_folder, output raise Exception("Reconfiguring CMake to force refresh failed. " "A backup of the settings was saved in %s" % settings_bak_file) + update_scratches_list(current_cmake_cache_folder) def get_target_to_build(program_path, ns3_version, build_profile): if ".py" in program_path: @@ -1001,7 +1019,7 @@ def main(): args.build = ['uninstall'] # Get build profile and other settings - c4che_info, ns3_modules = check_c4che_data(out_dir) + c4che_info, ns3_modules = check_c4che_data(out_dir) build_profile = c4che_info["BUILD_PROFILE"] enable_sudo = c4che_info["ENABLE_SUDO"] ns3_version = c4che_info["VERSION"] @@ -1064,12 +1082,23 @@ def main(): # We end things earlier if only checking the current project configuration return + # Check for changes in scratch sources and trigger a reconfigure if sources changed + if current_cmake_cache_folder: + current_scratch_sources = glob.glob(os.path.join(ns3_path, "scratch", "**", "*.cc"), + recursive=True) + scratches_file = os.path.join(current_cmake_cache_folder, "ns3scratches") + if os.path.exists(scratches_file): + with open(scratches_file, "r") as f: + previous_scratches_sources = f.read().split('\n') + if previous_scratches_sources != current_scratch_sources: + refresh_cmake(current_cmake_cache_folder, output) + if args.configure: configuration_step(current_cmake_cache_folder, current_cmake_generator, args, output, - args.dry_run + args.dry_run, ) if not project_configured(current_cmake_cache_folder): @@ -1131,7 +1160,7 @@ def main(): target_path = os.sep.join(target_path) return target_path - if not args.check and not args.shell and target_to_run and not ".py" in target_to_run: + if not args.check and not args.shell and target_to_run and ".py" not in target_to_run: target_to_run = remove_overlapping_path(out_dir, target_to_run) # Waf doesn't add version prefix and build type suffix to the scratches, so we remove them diff --git a/scratch/CMakeLists.txt b/scratch/CMakeLists.txt index 15f868afe..34b8ca48e 100644 --- a/scratch/CMakeLists.txt +++ b/scratch/CMakeLists.txt @@ -39,6 +39,7 @@ function(create_scratch source_files) endif() # Get source absolute path and transform into relative path + get_filename_component(scratch_src ${scratch_src} ABSOLUTE) get_filename_component(scratch_absolute_directory ${scratch_src} DIRECTORY) string(REPLACE "${PROJECT_SOURCE_DIR}" "${CMAKE_OUTPUT_DIRECTORY}" scratch_directory ${scratch_absolute_directory} @@ -81,6 +82,17 @@ foreach(entry ${scratch_subdirectories}) endforeach() foreach(subdir ${scratch_subdirectories}) - file(GLOB scratch_sources ${subdir}/*.cc) - create_scratch("${scratch_sources}") + if(EXISTS ${subdir}/CMakeLists.txt) + # If the subdirectory contains a CMakeLists.txt file + # we let the CMake file manage the source files + # + # Use this if you want to link to external libraries + # without creating a module + add_subdirectory(${subdir}) + else() + # Otherwise we pick all the files in the subdirectory + # and create a scratch for them automatically + file(GLOB scratch_sources ${subdir}/*.cc) + create_scratch("${scratch_sources}") + endif() endforeach()