From 1703a6d2c46cc7981dd80bd18d7c2e82ec5d9f82 Mon Sep 17 00:00:00 2001 From: Geoff Viola Date: Sun, 24 Apr 2016 13:47:48 -0600 Subject: [PATCH] GHS: Fix handling of duplicate source filenames (#16046) Green Hills MULTI project files must specify explicitly distinct object file names for source files with the same name. --- Source/cmGhsMultiTargetGenerator.cxx | 42 +++++++++++++++++++ Source/cmGhsMultiTargetGenerator.h | 2 + Tests/CMakeLists.txt | 11 +++++ .../CMakeLists.txt | 10 +++++ Tests/GhsMultiDuplicateSourceFilenames/main.c | 9 ++++ .../subfolder/test.c | 5 +++ Tests/GhsMultiDuplicateSourceFilenames/test.c | 5 +++ 7 files changed, 84 insertions(+) create mode 100644 Tests/GhsMultiDuplicateSourceFilenames/CMakeLists.txt create mode 100644 Tests/GhsMultiDuplicateSourceFilenames/main.c create mode 100644 Tests/GhsMultiDuplicateSourceFilenames/subfolder/test.c create mode 100644 Tests/GhsMultiDuplicateSourceFilenames/test.c diff --git a/Source/cmGhsMultiTargetGenerator.cxx b/Source/cmGhsMultiTargetGenerator.cxx index 1f17f8f89..12e2eee01 100644 --- a/Source/cmGhsMultiTargetGenerator.cxx +++ b/Source/cmGhsMultiTargetGenerator.cxx @@ -481,9 +481,46 @@ void cmGhsMultiTargetGenerator::WriteCustomCommandsHelper( } } +std::map +cmGhsMultiTargetGenerator::GetObjectNames( + const std::vector &objectSources) +{ + bool found_duplicate = false; + std::set filenames; + for(std::vector::const_iterator + sf = objectSources.begin(); sf != objectSources.end(); ++sf) + { + const std::string filename = + cmSystemTools::GetFilenameName((*sf)->GetFullPath()); + const std::string lower_filename = cmSystemTools::LowerCase(filename); + if (filenames.end() != filenames.find(lower_filename)) + { + found_duplicate = true; + } + filenames.insert(lower_filename); + } + + std::map objectNames; + if (found_duplicate) + { + for(std::vector::const_iterator + sf = objectSources.begin(); sf != objectSources.end(); ++sf) + { + std::string full_filename = (*sf)->GetFullPath(); + cmsys::SystemTools::ReplaceString(full_filename, ":/", "_"); + cmsys::SystemTools::ReplaceString(full_filename, "/", "_"); + objectNames[*sf] = full_filename; + } + } + + return objectNames; +} + void cmGhsMultiTargetGenerator::WriteSources( std::vector const &objectSources) { + std::map objectNames = + cmGhsMultiTargetGenerator::GetObjectNames(objectSources); for (std::vector::const_iterator si = objectSources.begin(); si != objectSources.end(); ++si) { @@ -515,6 +552,11 @@ void cmGhsMultiTargetGenerator::WriteSources( "bsp" != (*si)->GetExtension()) { this->WriteObjectLangOverride(this->FolderBuildStreams[sgPath], (*si)); + if (objectNames.end() != objectNames.find(*si)) + { + *this->FolderBuildStreams[sgPath] << " -o \"" << + objectNames.find(*si)->second << ".o\"" << std::endl; + } this->WriteObjectDir(this->FolderBuildStreams[sgPath], this->AbsBuildFilePath + sgPath); diff --git a/Source/cmGhsMultiTargetGenerator.h b/Source/cmGhsMultiTargetGenerator.h index e85e41272..3a1360051 100644 --- a/Source/cmGhsMultiTargetGenerator.h +++ b/Source/cmGhsMultiTargetGenerator.h @@ -88,6 +88,8 @@ private: WriteCustomCommandsHelper(std::vector const &commandsSet, cmTarget::CustomCommandType commandType); void WriteSources(std::vector const &objectSources); + static std::map + GetObjectNames(const std::vector &objectSources); static void WriteObjectLangOverride(cmGeneratedFileStream *fileStream, cmSourceFile *sourceFile); static void WriteObjectDir(cmGeneratedFileStream *fileStream, diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 8a256bf19..2db5deda3 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -2103,6 +2103,17 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release endmacro () add_test_GhsMulti("arm_integrity_simarm" "arm_integrity.tgt" "simarm") add_test_GhsMulti("arm64_integrity_simarm" "arm64_integrity.tgt" "simarm") + add_test(NAME GhsMulti.duplicate_source_filenames + COMMAND ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/GhsMultiDuplicateSourceFilenames" + "${CMake_BINARY_DIR}/Tests/GhsMultiDuplicateSourceFilenames" + --build-generator "Green Hills MULTI" + --build-project ReturnNum + --build-config $ + --build-options -DGHS_PRIMARY_TARGET="arm_integrity.tgt" + -DGHS_BSP_NAME="simarm" + ) endif () if(tegra AND NOT "${CMake_SOURCE_DIR};${CMake_BINARY_DIR}" MATCHES " ") diff --git a/Tests/GhsMultiDuplicateSourceFilenames/CMakeLists.txt b/Tests/GhsMultiDuplicateSourceFilenames/CMakeLists.txt new file mode 100644 index 000000000..ffdb5827f --- /dev/null +++ b/Tests/GhsMultiDuplicateSourceFilenames/CMakeLists.txt @@ -0,0 +1,10 @@ +cmake_minimum_required(VERSION 3.5) +project(demo C) + +add_library(libdemo test.c subfolder/test.c) + +add_executable(demo main.c) +target_link_libraries(demo libdemo) +if(GHSMULTI) + target_compile_options(demo PUBLIC "-non_shared") +endif() diff --git a/Tests/GhsMultiDuplicateSourceFilenames/main.c b/Tests/GhsMultiDuplicateSourceFilenames/main.c new file mode 100644 index 000000000..2779d684a --- /dev/null +++ b/Tests/GhsMultiDuplicateSourceFilenames/main.c @@ -0,0 +1,9 @@ +int test_a(void); +int test_b(void); + +int main(int argc, char *argv[]) +{ + test_a(); + test_b(); + return 0; +} diff --git a/Tests/GhsMultiDuplicateSourceFilenames/subfolder/test.c b/Tests/GhsMultiDuplicateSourceFilenames/subfolder/test.c new file mode 100644 index 000000000..e1372b9c4 --- /dev/null +++ b/Tests/GhsMultiDuplicateSourceFilenames/subfolder/test.c @@ -0,0 +1,5 @@ + +int test_b() +{ + return 2; +} diff --git a/Tests/GhsMultiDuplicateSourceFilenames/test.c b/Tests/GhsMultiDuplicateSourceFilenames/test.c new file mode 100644 index 000000000..60286ddd1 --- /dev/null +++ b/Tests/GhsMultiDuplicateSourceFilenames/test.c @@ -0,0 +1,5 @@ + +int test_a() +{ + return 1; +}