1
- #![ cfg_attr( feature = "clippy" , feature( plugin) ) ]
2
- #![ cfg_attr( feature = "clippy" , plugin( clippy) ) ]
3
-
4
1
use fs_extra:: dir:: CopyOptions ;
5
2
use glob:: glob;
6
3
use std:: env;
7
4
use std:: path:: PathBuf ;
8
5
use std:: process:: Command ;
9
6
10
7
static LIBRARY_NAME : & str = "pg_query" ;
11
- static LIBPG_QUERY_REPO : & str = "https://github.com/pganalyze/libpg_query.git" ;
8
+
12
9
fn get_libpg_query_tag ( ) -> & ' static str {
13
10
#[ cfg( feature = "postgres-15" ) ]
14
- return "15-5.3.0 " ;
11
+ return "15-4.2.4 " ;
15
12
#[ cfg( feature = "postgres-16" ) ]
16
- return "16-6.1 .0" ;
13
+ return "16-5.2 .0" ;
17
14
#[ cfg( feature = "postgres-17" ) ]
18
15
return "17-6.1.0" ;
19
16
}
20
17
21
18
fn main ( ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
22
19
let libpg_query_tag = get_libpg_query_tag ( ) ;
23
20
let out_dir = PathBuf :: from ( env:: var ( "OUT_DIR" ) ?) ;
24
- let vendor_dir = out_dir. join ( "vendor" ) ;
25
- let libpg_query_dir = vendor_dir. join ( "libpg_query" ) . join ( libpg_query_tag) ;
26
- let stamp_file = libpg_query_dir. join ( ".stamp" ) ;
21
+ let manifest_dir = PathBuf :: from ( env:: var ( "CARGO_MANIFEST_DIR" ) ?) ;
22
+ let libpg_query_submodule = manifest_dir. join ( "vendor" ) . join ( "libpg_query" ) ;
27
23
28
- let src_dir = PathBuf :: from ( env :: var ( "CARGO_MANIFEST_DIR" ) ? ) . join ( "src" ) ;
24
+ let src_dir = manifest_dir . join ( "src" ) ;
29
25
let target = env:: var ( "TARGET" ) . unwrap ( ) ;
30
26
let is_emscripten = target. contains ( "emscripten" ) ;
31
27
32
- // Configure cargo through stdout
33
28
println ! ( "cargo:rustc-link-search=native={}" , out_dir. display( ) ) ;
34
29
println ! ( "cargo:rustc-link-lib=static={LIBRARY_NAME}" ) ;
35
30
36
- // Clone libpg_query if not already present
37
- if !stamp_file. exists ( ) {
38
- println ! ( "cargo:warning=Cloning libpg_query {}" , libpg_query_tag) ;
31
+ if !libpg_query_submodule. join ( ".git" ) . exists ( ) && !libpg_query_submodule. join ( "src" ) . exists ( ) {
32
+ return Err (
33
+ "libpg_query submodule not found. Please run: git submodule update --init --recursive"
34
+ . into ( ) ,
35
+ ) ;
36
+ }
39
37
40
- // Create vendor directory
41
- std:: fs:: create_dir_all ( & vendor_dir) ?;
38
+ // check if we need to checkout a different tag
39
+ let current_head = Command :: new ( "git" )
40
+ . args ( [ "rev-parse" , "HEAD" ] )
41
+ . current_dir ( & libpg_query_submodule)
42
+ . output ( ) ?;
43
+
44
+ let tag_commit = Command :: new ( "git" )
45
+ . args ( [ "rev-list" , "-n" , "1" , libpg_query_tag] )
46
+ . current_dir ( & libpg_query_submodule)
47
+ . output ( ) ;
48
+
49
+ let needs_checkout = match tag_commit {
50
+ Ok ( output) => {
51
+ let current = String :: from_utf8_lossy ( & current_head. stdout ) ;
52
+ let target = String :: from_utf8_lossy ( & output. stdout ) ;
53
+ current. trim ( ) != target. trim ( )
54
+ }
55
+ Err ( _) => {
56
+ // tag not found locally, try fetching
57
+ let status = Command :: new ( "git" )
58
+ . args ( [ "fetch" , "--tags" ] )
59
+ . current_dir ( & libpg_query_submodule)
60
+ . status ( ) ?;
61
+
62
+ if !status. success ( ) {
63
+ return Err ( "Failed to fetch tags from libpg_query" . into ( ) ) ;
64
+ }
65
+ true
66
+ }
67
+ } ;
42
68
43
- // Clone the repository with partial clone for faster download
69
+ if needs_checkout {
70
+ // checkout the correct tag for the selected postgresql version
71
+ println ! (
72
+ "cargo:warning=Checking out libpg_query tag: {}" ,
73
+ libpg_query_tag
74
+ ) ;
44
75
let status = Command :: new ( "git" )
45
- . args ( [
46
- "clone" ,
47
- "--filter=blob:none" ,
48
- "--depth" ,
49
- "1" ,
50
- "--branch" ,
51
- libpg_query_tag,
52
- LIBPG_QUERY_REPO ,
53
- libpg_query_dir. to_str ( ) . unwrap ( ) ,
54
- ] )
76
+ . args ( [ "checkout" , libpg_query_tag] )
77
+ . current_dir ( & libpg_query_submodule)
55
78
. status ( ) ?;
56
79
57
80
if !status. success ( ) {
58
- return Err ( "Failed to clone libpg_query" . into ( ) ) ;
81
+ return Err ( format ! ( "Failed to checkout libpg_query tag: {}" , libpg_query_tag ) . into ( ) ) ;
59
82
}
60
-
61
- // Create stamp file
62
- std:: fs:: File :: create ( & stamp_file) ?;
63
83
}
64
84
65
- // Tell cargo to rerun if the stamp file is deleted
66
- println ! ( "cargo:rerun-if-changed={}" , stamp_file. display( ) ) ;
85
+ // tell cargo to rerun if the submodule changes
86
+ println ! (
87
+ "cargo:rerun-if-changed={}" ,
88
+ libpg_query_submodule. join( "src" ) . display( )
89
+ ) ;
67
90
68
- // Copy necessary files to OUT_DIR for compilation
91
+ // copy necessary files to out_dir for compilation
69
92
let out_header_path = out_dir. join ( LIBRARY_NAME ) . with_extension ( "h" ) ;
70
93
let out_protobuf_path = out_dir. join ( "protobuf" ) ;
71
94
72
95
let source_paths = vec ! [
73
- libpg_query_dir . join( LIBRARY_NAME ) . with_extension( "h" ) ,
74
- libpg_query_dir . join( "Makefile" ) ,
75
- libpg_query_dir . join( "src" ) ,
76
- libpg_query_dir . join( "protobuf" ) ,
77
- libpg_query_dir . join( "vendor" ) ,
96
+ libpg_query_submodule . join( LIBRARY_NAME ) . with_extension( "h" ) ,
97
+ libpg_query_submodule . join( "Makefile" ) ,
98
+ libpg_query_submodule . join( "src" ) ,
99
+ libpg_query_submodule . join( "protobuf" ) ,
100
+ libpg_query_submodule . join( "vendor" ) ,
78
101
] ;
79
102
80
103
let copy_options = CopyOptions {
@@ -84,17 +107,17 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
84
107
85
108
fs_extra:: copy_items ( & source_paths, & out_dir, & copy_options) ?;
86
109
87
- // Compile the C library.
110
+ // compile the c library.
88
111
let mut build = cc:: Build :: new ( ) ;
89
112
90
- // Configure for Emscripten if needed
113
+ // configure for emscripten if needed
91
114
if is_emscripten {
92
- // Use emcc as the compiler instead of gcc/clang
115
+ // use emcc as the compiler instead of gcc/clang
93
116
build. compiler ( "emcc" ) ;
94
- // Use emar as the archiver instead of ar
117
+ // use emar as the archiver instead of ar
95
118
build. archiver ( "emar" ) ;
96
- // Note: We don't add WASM -specific flags here as this creates a static library
97
- // The final linking flags should be added when building the final WASM module
119
+ // note: we don't add wasm -specific flags here as this creates a static library
120
+ // the final linking flags should be added when building the final wasm module
98
121
}
99
122
100
123
build
@@ -115,7 +138,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
115
138
. include ( out_dir. join ( "./vendor" ) )
116
139
. include ( out_dir. join ( "./src/postgres/include" ) )
117
140
. include ( out_dir. join ( "./src/include" ) )
118
- . warnings ( false ) ; // Avoid unnecessary warnings, as they are already considered as part of libpg_query development
141
+ . warnings ( false ) ; // avoid unnecessary warnings, as they are already considered as part of libpg_query development
119
142
if env:: var ( "PROFILE" ) . unwrap ( ) == "debug" || env:: var ( "DEBUG" ) . unwrap ( ) == "1" {
120
143
build. define ( "USE_ASSERT_CHECKING" , None ) ;
121
144
}
0 commit comments