From 5adb469f1c099a9f06f2f107173a03a1fc617e21 Mon Sep 17 00:00:00 2001
From: Junghyun Kim <jh0822.kim@samsung.com>
Date: Tue, 27 Sep 2016 13:05:28 +0900
Subject: [PATCH] Sort list of files for aux_source_directory() and
 file(glob,*).

If aux_source_directory(. SRCS) or file(glob SRCS "*.c") is used, files in SRCS are not sorted.
This can cause a list of files that has different order across machines.

Even though it does not have any correctness issue, there may be a problem.
If we have a build infrastructure (e.g., OBS), the result binaries can be different on each machine.
In this case, build results can be different on two different machines even if we have the same source files.
For example,
1. ld -o liba.a a.o b.o     SRCS=a.c b.c
2. ld -o libb.a b.o a.o     SRCS=b.c a.c
Then, liba.a and libb.a are different.

REASON
This is because of the system call readdir().
The system call readdir() returns a file in the directory in any order.

SOLUTION
Intead of readdir(), scandir() is used with alphasort().
This makes the list of files are sorted alphabetically.

Signed-off-by: Junghyun Kim <jh0822.kim@samsung.com>
---
 Source/kwsys/Directory.cxx | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/Source/kwsys/Directory.cxx b/Source/kwsys/Directory.cxx
index 15480e1..2cebf09 100644
--- a/Source/kwsys/Directory.cxx
+++ b/Source/kwsys/Directory.cxx
@@ -210,6 +210,8 @@ unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name)
 
 #include <sys/types.h>
 #include <dirent.h>
+#include <stdio.h>
+#include <malloc.h>
 
 // PGI with glibc has trouble with dirent and large file support:
 //  http://www.pgroup.com/userforum/viewtopic.php?
@@ -232,19 +234,22 @@ bool Directory::Load(const std::string& name)
 {
   this->Clear();
    
-  DIR* dir = opendir(name.c_str());
-
-  if (!dir)
+  struct dirent** namelist;
+  int num_entries = scandir(name.c_str(), &namelist, NULL, alphasort);
+  if (num_entries == -1)
     {
+    perror("scandir");
     return 0;
     }
 
-  for (kwsys_dirent* d = readdir(dir); d; d = readdir(dir) )
+  for(int i = 0; i < num_entries; ++i) 
     {
-    this->Internal->Files.push_back(d->d_name);
+    this->Internal->Files.push_back(namelist[i]->d_name);
+    free(namelist[i]);
     }
+
+  free(namelist);
   this->Internal->Path = name;
-  closedir(dir);
   return 1;
 }
 
-- 
1.9.1

