Skip to content

Commit a4af0b6

Browse files
committed
Merge branch 'js/libgit-rust'
Foreign language interface for Rust into our code base has been added. * js/libgit-rust: libgit: add higher-level libgit crate libgit-sys: also export some config_set functions libgit-sys: introduce Rust wrapper for libgit.a common-main: split init and exit code into new files
2 parents 3f3fd0f + 65c10aa commit a4af0b6

24 files changed

+673
-81
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,3 +250,5 @@ Release/
250250
/git.VC.db
251251
*.dSYM
252252
/contrib/buildsystems/out
253+
/contrib/libgit-rs/target
254+
/contrib/libgit-sys/target

Makefile

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,9 @@ include shared.mak
417417
# Define LINK_FUZZ_PROGRAMS if you want `make all` to also build the fuzz test
418418
# programs in oss-fuzz/.
419419
#
420+
# Define INCLUDE_LIBGIT_RS if you want `make all` and `make test` to build and
421+
# test the Rust crates in contrib/libgit-sys and contrib/libgit-rs.
422+
#
420423
# === Optional library: libintl ===
421424
#
422425
# Define NO_GETTEXT if you don't want Git output to be translated.
@@ -658,6 +661,8 @@ CURL_CONFIG = curl-config
658661
GCOV = gcov
659662
STRIP = strip
660663
SPATCH = spatch
664+
LD = ld
665+
OBJCOPY = objcopy
661666

662667
export TCL_PATH TCLTK_PATH
663668

@@ -676,6 +681,7 @@ FUZZ_OBJS =
676681
FUZZ_PROGRAMS =
677682
GIT_OBJS =
678683
LIB_OBJS =
684+
LIBGIT_PUB_OBJS =
679685
SCALAR_OBJS =
680686
OBJECTS =
681687
OTHER_PROGRAMS =
@@ -984,6 +990,8 @@ LIB_OBJS += combine-diff.o
984990
LIB_OBJS += commit-graph.o
985991
LIB_OBJS += commit-reach.o
986992
LIB_OBJS += commit.o
993+
LIB_OBJS += common-exit.o
994+
LIB_OBJS += common-init.o
987995
LIB_OBJS += compat/nonblock.o
988996
LIB_OBJS += compat/obstack.o
989997
LIB_OBJS += compat/terminal.o
@@ -2252,6 +2260,12 @@ ifdef WITH_BREAKING_CHANGES
22522260
BASIC_CFLAGS += -DWITH_BREAKING_CHANGES
22532261
endif
22542262

2263+
ifdef INCLUDE_LIBGIT_RS
2264+
# Enable symbol hiding in contrib/libgit-sys/libgitpub.a without making
2265+
# us rebuild the whole tree every time we run a Rust build.
2266+
BASIC_CFLAGS += -fvisibility=hidden
2267+
endif
2268+
22552269
ifeq ($(TCLTK_PATH),)
22562270
NO_TCLTK = NoThanks
22572271
endif
@@ -2748,6 +2762,10 @@ OBJECTS += $(UNIT_TEST_OBJS)
27482762
OBJECTS += $(CLAR_TEST_OBJS)
27492763
OBJECTS += $(patsubst %,$(UNIT_TEST_DIR)/%.o,$(UNIT_TEST_PROGRAMS))
27502764

2765+
ifdef INCLUDE_LIBGIT_RS
2766+
OBJECTS += contrib/libgit-sys/public_symbol_export.o
2767+
endif
2768+
27512769
ifndef NO_CURL
27522770
OBJECTS += http.o http-walker.o remote-curl.o
27532771
endif
@@ -3743,6 +3761,10 @@ clean: profile-clean coverage-clean cocciclean
37433761
$(RM) $(htmldocs).tar.gz $(manpages).tar.gz
37443762
$(MAKE) -C Documentation/ clean
37453763
$(RM) Documentation/GIT-EXCLUDED-PROGRAMS
3764+
$(RM) -r contrib/libgit-sys/target contrib/libgit-rs/target
3765+
$(RM) contrib/libgit-sys/partial_symbol_export.o
3766+
$(RM) contrib/libgit-sys/hidden_symbol_export.o
3767+
$(RM) contrib/libgit-sys/libgitpub.a
37463768
ifndef NO_PERL
37473769
$(RM) -r perl/build/
37483770
endif
@@ -3904,3 +3926,31 @@ $(CLAR_TEST_PROG): $(UNIT_TEST_DIR)/clar.suite $(CLAR_TEST_OBJS) $(GITLIBS) GIT-
39043926
build-unit-tests: $(UNIT_TEST_PROGS) $(CLAR_TEST_PROG)
39053927
unit-tests: $(UNIT_TEST_PROGS) $(CLAR_TEST_PROG) t/helper/test-tool$X
39063928
$(MAKE) -C t/ unit-tests
3929+
3930+
.PHONY: libgit-sys libgit-rs
3931+
libgit-sys libgit-rs:
3932+
$(QUIET)(\
3933+
cd contrib/$@ && \
3934+
cargo build \
3935+
)
3936+
ifdef INCLUDE_LIBGIT_RS
3937+
all:: libgit-sys libgit-rs
3938+
endif
3939+
3940+
LIBGIT_PUB_OBJS += contrib/libgit-sys/public_symbol_export.o
3941+
LIBGIT_PUB_OBJS += libgit.a
3942+
LIBGIT_PUB_OBJS += reftable/libreftable.a
3943+
LIBGIT_PUB_OBJS += xdiff/lib.a
3944+
3945+
LIBGIT_PARTIAL_EXPORT = contrib/libgit-sys/partial_symbol_export.o
3946+
3947+
LIBGIT_HIDDEN_EXPORT = contrib/libgit-sys/hidden_symbol_export.o
3948+
3949+
$(LIBGIT_PARTIAL_EXPORT): $(LIBGIT_PUB_OBJS)
3950+
$(LD) -r $^ -o $@
3951+
3952+
$(LIBGIT_HIDDEN_EXPORT): $(LIBGIT_PARTIAL_EXPORT)
3953+
$(OBJCOPY) --localize-hidden $^ $@
3954+
3955+
contrib/libgit-sys/libgitpub.a: $(LIBGIT_HIDDEN_EXPORT)
3956+
$(AR) $(ARFLAGS) $@ $^

common-exit.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#include "git-compat-util.h"
2+
#include "trace2.h"
3+
4+
static void check_bug_if_BUG(void)
5+
{
6+
if (!bug_called_must_BUG)
7+
return;
8+
BUG("on exit(): had bug() call(s) in this process without explicit BUG_if_bug()");
9+
}
10+
11+
/* We wrap exit() to call common_exit() in git-compat-util.h */
12+
int common_exit(const char *file, int line, int code)
13+
{
14+
/*
15+
* For non-POSIX systems: Take the lowest 8 bits of the "code"
16+
* to e.g. turn -1 into 255. On a POSIX system this is
17+
* redundant, see exit(3) and wait(2), but as it doesn't harm
18+
* anything there we don't need to guard this with an "ifdef".
19+
*/
20+
code &= 0xff;
21+
22+
check_bug_if_BUG();
23+
trace2_cmd_exit_fl(file, line, code);
24+
25+
return code;
26+
}

common-init.c

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
#define USE_THE_REPOSITORY_VARIABLE
2+
3+
#include "git-compat-util.h"
4+
#include "common-init.h"
5+
#include "exec-cmd.h"
6+
#include "gettext.h"
7+
#include "attr.h"
8+
#include "repository.h"
9+
#include "setup.h"
10+
#include "strbuf.h"
11+
#include "trace2.h"
12+
13+
/*
14+
* Many parts of Git have subprograms communicate via pipe, expect the
15+
* upstream of a pipe to die with SIGPIPE when the downstream of a
16+
* pipe does not need to read all that is written. Some third-party
17+
* programs that ignore or block SIGPIPE for their own reason forget
18+
* to restore SIGPIPE handling to the default before spawning Git and
19+
* break this carefully orchestrated machinery.
20+
*
21+
* Restore the way SIGPIPE is handled to default, which is what we
22+
* expect.
23+
*/
24+
static void restore_sigpipe_to_default(void)
25+
{
26+
sigset_t unblock;
27+
28+
sigemptyset(&unblock);
29+
sigaddset(&unblock, SIGPIPE);
30+
sigprocmask(SIG_UNBLOCK, &unblock, NULL);
31+
signal(SIGPIPE, SIG_DFL);
32+
}
33+
34+
void init_git(const char **argv)
35+
{
36+
struct strbuf tmp = STRBUF_INIT;
37+
38+
trace2_initialize_clock();
39+
40+
/*
41+
* Always open file descriptors 0/1/2 to avoid clobbering files
42+
* in die(). It also avoids messing up when the pipes are dup'ed
43+
* onto stdin/stdout/stderr in the child processes we spawn.
44+
*/
45+
sanitize_stdfds();
46+
restore_sigpipe_to_default();
47+
48+
git_resolve_executable_dir(argv[0]);
49+
50+
setlocale(LC_CTYPE, "");
51+
git_setup_gettext();
52+
53+
initialize_repository(the_repository);
54+
55+
attr_start();
56+
57+
trace2_initialize();
58+
trace2_cmd_start(argv);
59+
trace2_collect_process_info(TRACE2_PROCESS_INFO_STARTUP);
60+
61+
if (!strbuf_getcwd(&tmp))
62+
tmp_original_cwd = strbuf_detach(&tmp, NULL);
63+
}

common-init.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#ifndef COMMON_INIT_H
2+
#define COMMON_INIT_H
3+
4+
void init_git(const char **argv);
5+
6+
#endif /* COMMON_INIT_H */

common-main.c

Lines changed: 2 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,92 +1,13 @@
1-
#define USE_THE_REPOSITORY_VARIABLE
2-
31
#include "git-compat-util.h"
4-
#include "exec-cmd.h"
5-
#include "gettext.h"
6-
#include "attr.h"
7-
#include "repository.h"
8-
#include "setup.h"
9-
#include "strbuf.h"
10-
#include "trace2.h"
11-
12-
/*
13-
* Many parts of Git have subprograms communicate via pipe, expect the
14-
* upstream of a pipe to die with SIGPIPE when the downstream of a
15-
* pipe does not need to read all that is written. Some third-party
16-
* programs that ignore or block SIGPIPE for their own reason forget
17-
* to restore SIGPIPE handling to the default before spawning Git and
18-
* break this carefully orchestrated machinery.
19-
*
20-
* Restore the way SIGPIPE is handled to default, which is what we
21-
* expect.
22-
*/
23-
static void restore_sigpipe_to_default(void)
24-
{
25-
sigset_t unblock;
26-
27-
sigemptyset(&unblock);
28-
sigaddset(&unblock, SIGPIPE);
29-
sigprocmask(SIG_UNBLOCK, &unblock, NULL);
30-
signal(SIGPIPE, SIG_DFL);
31-
}
2+
#include "common-init.h"
323

334
int main(int argc, const char **argv)
345
{
356
int result;
36-
struct strbuf tmp = STRBUF_INIT;
37-
38-
trace2_initialize_clock();
39-
40-
/*
41-
* Always open file descriptors 0/1/2 to avoid clobbering files
42-
* in die(). It also avoids messing up when the pipes are dup'ed
43-
* onto stdin/stdout/stderr in the child processes we spawn.
44-
*/
45-
sanitize_stdfds();
46-
restore_sigpipe_to_default();
47-
48-
git_resolve_executable_dir(argv[0]);
49-
50-
setlocale(LC_CTYPE, "");
51-
git_setup_gettext();
52-
53-
initialize_repository(the_repository);
54-
55-
attr_start();
56-
57-
trace2_initialize();
58-
trace2_cmd_start(argv);
59-
trace2_collect_process_info(TRACE2_PROCESS_INFO_STARTUP);
60-
61-
if (!strbuf_getcwd(&tmp))
62-
tmp_original_cwd = strbuf_detach(&tmp, NULL);
637

8+
init_git(argv);
649
result = cmd_main(argc, argv);
6510

6611
/* Not exit(3), but a wrapper calling our common_exit() */
6712
exit(result);
6813
}
69-
70-
static void check_bug_if_BUG(void)
71-
{
72-
if (!bug_called_must_BUG)
73-
return;
74-
BUG("on exit(): had bug() call(s) in this process without explicit BUG_if_bug()");
75-
}
76-
77-
/* We wrap exit() to call common_exit() in git-compat-util.h */
78-
int common_exit(const char *file, int line, int code)
79-
{
80-
/*
81-
* For non-POSIX systems: Take the lowest 8 bits of the "code"
82-
* to e.g. turn -1 into 255. On a POSIX system this is
83-
* redundant, see exit(3) and wait(2), but as it doesn't harm
84-
* anything there we don't need to guard this with an "ifdef".
85-
*/
86-
code &= 0xff;
87-
88-
check_bug_if_BUG();
89-
trace2_cmd_exit_fl(file, line, code);
90-
91-
return code;
92-
}

contrib/libgit-rs/Cargo.lock

Lines changed: 77 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

contrib/libgit-rs/Cargo.toml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
[package]
2+
name = "libgit"
3+
version = "0.1.0"
4+
edition = "2021"
5+
build = "build.rs"
6+
rust-version = "1.63" # TODO: Once we hit 1.84 or newer, we may want to remove Cargo.lock from
7+
# version control. See https://lore.kernel.org/git/[email protected]/
8+
9+
10+
[lib]
11+
path = "src/lib.rs"
12+
13+
[dependencies]
14+
libgit-sys = { version = "0.1.0", path = "../libgit-sys" }
15+
16+
[build-dependencies]
17+
autocfg = "1.4.0"

0 commit comments

Comments
 (0)