The first version of git appeared in 2005. For curiosity and learning purposes, I'm trying to get it to run. Source code here. There are very few files, so it seems reasonable, however I'm getting stuck due to lack of knowledge of C-specifics.
What step-by-step instructions will get this to run on macOS (preferably) or FreeBSD, modifying the files as needed?
Attempt 1
Using macOS Big Sur:
- in
Makefile
, changeinstall $(PROG) $(HOME)/bin/
toinstall $(PROG) ./bin/
This is to let binaries resides in the local directory. - in
cache.h
, add the lines#include <string.h>
and#include <unistd.h>
. brew install openssl
ln -s ../opt/openssl/include/openssl .
make install
Result: Wall of errors and warnings including "no member named 'st_ctim' in 'struct stat'"
, "no member named 'st_mtim' in 'struct stat'"
, etc.
Attempt 2
Using FreeBSD 12:
- in
Makefile
, changeinstall $(PROG) $(HOME)/bin/
toinstall $(PROG) ./bin/
This is to let binaries resides in the local directory. - in
cache.h
, add the lines#include <string.h>
and#include <unistd.h>
. make install
Linker errors:
/usr/local/bin/ld: read-cache.o:cache.h:64: multiple definition of `sha1_file_directory'; update-cache.o:cache.h:64: first defined here
/usr/local/bin/ld: read-cache.o:cache.h:65: multiple definition of `active_cache'; update-cache.o:cache.h:65: first defined here
/usr/local/bin/ld: read-cache.o:cache.h:66: multiple definition of `active_nr'; update-cache.o:cache.h:66: first defined here
/usr/local/bin/ld: read-cache.o:cache.h:66: multiple definition of `active_alloc'; update-cache.o:cache.h:66: first defined here
/usr/local/bin/ld: update-cache.o: undefined reference to symbol 'SHA1_Init@@OPENSSL_1_1_0'
/usr/local/bin/ld: /lib/libcrypto.so.111: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
*** Error code 1
I'm hitting a wall, because I notice my knowledge of C and gcc is too limited to proceed. What are some pointers to make this work for macOS (preferably) or FreeBSD (otherwise)?
CodePudding user response:
The original version of Git was almost certainly only targeted toward Linux and not toward any other systems. Consequently, portability issues were probably not resolved.
This is, at most, a partial solution to your problems — it should help you with one aspect of the troubles you identify.
You say:
Result: Wall of errors and warnings including "
no member named 'st_ctim' in 'struct stat'
", "no member named 'st_mtim' in 'struct stat'
", etc.
That feature requires a macOS-specific macro to be defined:
/* To get the 64-bit inode structure with struct timespec elements on Mac OS X */
#define _DARWIN_USE_64_BIT_INODE
The names of the structure elements are not consistent with POSIX. In my code, I use:
#define ST_ATIME st_atimespec
#define ST_BTIME st_birthtimespec
#define ST_CTIME st_ctimespec
#define ST_MTIME st_mtimespec
The POSIX variants use (file birth time is not part of POSIX):
#define ST_ATIME st_atim
#define ST_CTIME st_ctim
#define ST_MTIME st_mtim
For systems other than macOS and POSIX-compliant systems, I use these (and the type of the members is time_t
, not struct timespec
):
#define ST_ATIME st_atime
#define ST_CTIME st_ctime
#define ST_MTIME st_mtime
That's one part of the issue — you also have to find where st_ctim
etc are used and revise the code to handle the portability issues. For example, one piece of code reads:
struct stat *sb;
…
case 'a':
pr_format_date(sb->ST_ATIME);
break;
case 'c':
pr_format_date(sb->ST_CTIME);
break;
case 'm':
pr_format_date(sb->ST_MTIME);
break;
The called function is passed a Time *
, where the code has one of these in effect:
typedef struct timespec Time;
typedef time_t Time;
The body of the function has different code for when Time
is a struct timespec
and when it is a time_t
.