lz4-native-ruby 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.md +48 -0
- data/ext/lz4/extconf.rb +12 -0
- data/ext/lz4/lz4_ext.c +230 -0
- data/lib/lz4/lz4_ext.so +0 -0
- data/lib/lz4/version.rb +3 -0
- data/lib/lz4.rb +60 -0
- data/vendor/lz4/lib/LICENSE +24 -0
- data/vendor/lz4/lib/Makefile +244 -0
- data/vendor/lz4/lib/README.md +193 -0
- data/vendor/lz4/lib/dll/example/Makefile +63 -0
- data/vendor/lz4/lib/dll/example/README.md +69 -0
- data/vendor/lz4/lib/dll/example/fullbench-dll.sln +25 -0
- data/vendor/lz4/lib/dll/example/fullbench-dll.vcxproj +182 -0
- data/vendor/lz4/lib/liblz4-dll.rc.in +35 -0
- data/vendor/lz4/lib/liblz4.pc.in +14 -0
- data/vendor/lz4/lib/lz4.c +2829 -0
- data/vendor/lz4/lib/lz4.h +884 -0
- data/vendor/lz4/lib/lz4file.c +341 -0
- data/vendor/lz4/lib/lz4file.h +93 -0
- data/vendor/lz4/lib/lz4frame.c +2136 -0
- data/vendor/lz4/lib/lz4frame.h +751 -0
- data/vendor/lz4/lib/lz4frame_static.h +47 -0
- data/vendor/lz4/lib/lz4hc.c +2192 -0
- data/vendor/lz4/lib/lz4hc.h +414 -0
- data/vendor/lz4/lib/xxhash.c +1030 -0
- data/vendor/lz4/lib/xxhash.h +328 -0
- metadata +115 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 426ca5882807e6c97b70422e3342d9499eed3ace1486870ccf9ea3efea0f7b2e
|
|
4
|
+
data.tar.gz: a6c5044c3db8d365a750a263c6d5e4382b36c26a194c6637caaecf60470f0247
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 5474a03254be431f670535e56b7281785b353dbff30e9e2150099869ef15f330e3037d754a3140e415e9a55330356fca9949895e5c4e431a0112e3fa5e8aeb26
|
|
7
|
+
data.tar.gz: a88b609ffcff03532d88ce2b4b91f3e76a88a149b635e7502f4cb8ffffdb124c428c4963f8b06e6bcb0ad68bef6e8b25d25bb93c42044d55a2a00f036abedfc8
|
data/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# LZ4-Native-Ruby
|
|
2
|
+
|
|
3
|
+
Ruby bindings for the LZ4 compression library (v1.10.0).
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
Add this line to your application's Gemfile:
|
|
8
|
+
|
|
9
|
+
```ruby
|
|
10
|
+
gem 'lz4-native-ruby'
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
And then execute:
|
|
14
|
+
|
|
15
|
+
$ bundle install
|
|
16
|
+
|
|
17
|
+
Or install it yourself as:
|
|
18
|
+
|
|
19
|
+
$ gem install lz4-native-ruby
|
|
20
|
+
|
|
21
|
+
## Usage
|
|
22
|
+
|
|
23
|
+
```ruby
|
|
24
|
+
require 'lz4'
|
|
25
|
+
|
|
26
|
+
# Compress a file
|
|
27
|
+
LZ4.compress_file('input.txt', 'output.lz4', compression_level: 9)
|
|
28
|
+
|
|
29
|
+
# Decompress a file
|
|
30
|
+
LZ4.decompress_file('output.lz4', 'decompressed.txt')
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Compression Levels
|
|
34
|
+
|
|
35
|
+
LZ4 supports compression levels from 1 to 12:
|
|
36
|
+
- Level 1: Fastest compression
|
|
37
|
+
- Level 9: Default (good balance)
|
|
38
|
+
- Level 12: Best compression
|
|
39
|
+
|
|
40
|
+
## Development
|
|
41
|
+
|
|
42
|
+
After checking out the repo, run `bundle install` to install dependencies. Then, run `rake compile` to build the native extension, and `rake test` to run the tests.
|
|
43
|
+
|
|
44
|
+
## License
|
|
45
|
+
|
|
46
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
|
47
|
+
|
|
48
|
+
LZ4 library is BSD 2-Clause licensed.
|
data/ext/lz4/extconf.rb
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
require "mkmf"
|
|
2
|
+
|
|
3
|
+
# Add LZ4 library source directory to include path
|
|
4
|
+
$INCFLAGS << " -I$(srcdir)/../../vendor/lz4/lib"
|
|
5
|
+
|
|
6
|
+
# Add LZ4 source directory to VPATH so make can find the source files
|
|
7
|
+
$VPATH << "$(srcdir)/../../vendor/lz4/lib"
|
|
8
|
+
|
|
9
|
+
# Add LZ4 source files to be compiled with just the base filenames
|
|
10
|
+
$srcs = ["lz4_ext.c", "lz4.c", "lz4hc.c"]
|
|
11
|
+
|
|
12
|
+
create_makefile("lz4/lz4_ext")
|
data/ext/lz4/lz4_ext.c
ADDED
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
#include <ruby.h>
|
|
2
|
+
#include "lz4.h"
|
|
3
|
+
#include "lz4hc.h"
|
|
4
|
+
#include <stdio.h>
|
|
5
|
+
#include <stdlib.h>
|
|
6
|
+
#include <string.h>
|
|
7
|
+
|
|
8
|
+
static VALUE mLZ4;
|
|
9
|
+
|
|
10
|
+
#define CHUNK_SIZE (16 * 1024) // 16KB chunks
|
|
11
|
+
|
|
12
|
+
/*
|
|
13
|
+
* Compress a file using LZ4
|
|
14
|
+
*
|
|
15
|
+
* @param input_path [String] Path to input file
|
|
16
|
+
* @param output_path [String] Path to output file
|
|
17
|
+
* @param compression_level [Integer] Compression level (1-12)
|
|
18
|
+
* @return [Boolean] true on success
|
|
19
|
+
*/
|
|
20
|
+
static VALUE lz4_compress_file(VALUE self, VALUE input_path, VALUE output_path, VALUE compression_level) {
|
|
21
|
+
Check_Type(input_path, T_STRING);
|
|
22
|
+
Check_Type(output_path, T_STRING);
|
|
23
|
+
Check_Type(compression_level, T_FIXNUM);
|
|
24
|
+
|
|
25
|
+
const char* input_filename = StringValueCStr(input_path);
|
|
26
|
+
const char* output_filename = StringValueCStr(output_path);
|
|
27
|
+
int level = FIX2INT(compression_level);
|
|
28
|
+
|
|
29
|
+
// Validate compression level
|
|
30
|
+
if (level < 1 || level > LZ4HC_CLEVEL_MAX) {
|
|
31
|
+
rb_raise(rb_eArgError, "Compression level must be between 1 and %d", LZ4HC_CLEVEL_MAX);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
FILE* input_file = fopen(input_filename, "rb");
|
|
35
|
+
if (!input_file) {
|
|
36
|
+
rb_raise(rb_eIOError, "Cannot open input file: %s", input_filename);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
FILE* output_file = fopen(output_filename, "wb");
|
|
40
|
+
if (!output_file) {
|
|
41
|
+
fclose(input_file);
|
|
42
|
+
rb_raise(rb_eIOError, "Cannot open output file: %s", output_filename);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Get file size
|
|
46
|
+
fseek(input_file, 0, SEEK_END);
|
|
47
|
+
size_t input_size = ftell(input_file);
|
|
48
|
+
fseek(input_file, 0, SEEK_SET);
|
|
49
|
+
|
|
50
|
+
// Write uncompressed size as header (8 bytes for size_t)
|
|
51
|
+
fwrite(&input_size, sizeof(size_t), 1, output_file);
|
|
52
|
+
|
|
53
|
+
// Allocate buffers
|
|
54
|
+
char* input_buffer = (char*)malloc(CHUNK_SIZE);
|
|
55
|
+
int max_compressed_size = LZ4_compressBound(CHUNK_SIZE);
|
|
56
|
+
char* output_buffer = (char*)malloc(max_compressed_size);
|
|
57
|
+
|
|
58
|
+
if (!input_buffer || !output_buffer) {
|
|
59
|
+
free(input_buffer);
|
|
60
|
+
free(output_buffer);
|
|
61
|
+
fclose(input_file);
|
|
62
|
+
fclose(output_file);
|
|
63
|
+
rb_raise(rb_eNoMemError, "Failed to allocate memory");
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Compress file in chunks
|
|
67
|
+
size_t bytes_read;
|
|
68
|
+
while ((bytes_read = fread(input_buffer, 1, CHUNK_SIZE, input_file)) > 0) {
|
|
69
|
+
int compressed_size;
|
|
70
|
+
|
|
71
|
+
if (level >= LZ4HC_CLEVEL_MIN) {
|
|
72
|
+
compressed_size = LZ4_compress_HC(input_buffer, output_buffer, bytes_read, max_compressed_size, level);
|
|
73
|
+
} else {
|
|
74
|
+
compressed_size = LZ4_compress_default(input_buffer, output_buffer, bytes_read, max_compressed_size);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (compressed_size <= 0) {
|
|
78
|
+
free(input_buffer);
|
|
79
|
+
free(output_buffer);
|
|
80
|
+
fclose(input_file);
|
|
81
|
+
fclose(output_file);
|
|
82
|
+
rb_raise(rb_eRuntimeError, "Compression failed");
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Write chunk header: original size and compressed size
|
|
86
|
+
uint32_t chunk_original = (uint32_t)bytes_read;
|
|
87
|
+
uint32_t chunk_compressed = (uint32_t)compressed_size;
|
|
88
|
+
fwrite(&chunk_original, sizeof(uint32_t), 1, output_file);
|
|
89
|
+
fwrite(&chunk_compressed, sizeof(uint32_t), 1, output_file);
|
|
90
|
+
fwrite(output_buffer, 1, compressed_size, output_file);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
free(input_buffer);
|
|
94
|
+
free(output_buffer);
|
|
95
|
+
fclose(input_file);
|
|
96
|
+
fclose(output_file);
|
|
97
|
+
|
|
98
|
+
return Qtrue;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/*
|
|
102
|
+
* Decompress a file using LZ4
|
|
103
|
+
*
|
|
104
|
+
* @param input_path [String] Path to compressed input file
|
|
105
|
+
* @param output_path [String] Path to output file
|
|
106
|
+
* @return [Boolean] true on success
|
|
107
|
+
*/
|
|
108
|
+
static VALUE lz4_decompress_file(VALUE self, VALUE input_path, VALUE output_path) {
|
|
109
|
+
Check_Type(input_path, T_STRING);
|
|
110
|
+
Check_Type(output_path, T_STRING);
|
|
111
|
+
|
|
112
|
+
const char* input_filename = StringValueCStr(input_path);
|
|
113
|
+
const char* output_filename = StringValueCStr(output_path);
|
|
114
|
+
|
|
115
|
+
FILE* input_file = fopen(input_filename, "rb");
|
|
116
|
+
if (!input_file) {
|
|
117
|
+
rb_raise(rb_eIOError, "Cannot open input file: %s", input_filename);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
FILE* output_file = fopen(output_filename, "wb");
|
|
121
|
+
if (!output_file) {
|
|
122
|
+
fclose(input_file);
|
|
123
|
+
rb_raise(rb_eIOError, "Cannot open output file: %s", output_filename);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Read uncompressed size header
|
|
127
|
+
size_t total_size;
|
|
128
|
+
if (fread(&total_size, sizeof(size_t), 1, input_file) != 1) {
|
|
129
|
+
fclose(input_file);
|
|
130
|
+
fclose(output_file);
|
|
131
|
+
rb_raise(rb_eRuntimeError, "Failed to read file header");
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Allocate buffers
|
|
135
|
+
char* input_buffer = (char*)malloc(LZ4_compressBound(CHUNK_SIZE));
|
|
136
|
+
char* output_buffer = (char*)malloc(CHUNK_SIZE);
|
|
137
|
+
|
|
138
|
+
if (!input_buffer || !output_buffer) {
|
|
139
|
+
free(input_buffer);
|
|
140
|
+
free(output_buffer);
|
|
141
|
+
fclose(input_file);
|
|
142
|
+
fclose(output_file);
|
|
143
|
+
rb_raise(rb_eNoMemError, "Failed to allocate memory");
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Decompress file in chunks
|
|
147
|
+
while (!feof(input_file)) {
|
|
148
|
+
uint32_t chunk_original, chunk_compressed;
|
|
149
|
+
|
|
150
|
+
// Read chunk header
|
|
151
|
+
if (fread(&chunk_original, sizeof(uint32_t), 1, input_file) != 1) {
|
|
152
|
+
break; // End of file
|
|
153
|
+
}
|
|
154
|
+
if (fread(&chunk_compressed, sizeof(uint32_t), 1, input_file) != 1) {
|
|
155
|
+
free(input_buffer);
|
|
156
|
+
free(output_buffer);
|
|
157
|
+
fclose(input_file);
|
|
158
|
+
fclose(output_file);
|
|
159
|
+
rb_raise(rb_eRuntimeError, "Failed to read chunk header");
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Read compressed data
|
|
163
|
+
if (fread(input_buffer, 1, chunk_compressed, input_file) != chunk_compressed) {
|
|
164
|
+
free(input_buffer);
|
|
165
|
+
free(output_buffer);
|
|
166
|
+
fclose(input_file);
|
|
167
|
+
fclose(output_file);
|
|
168
|
+
rb_raise(rb_eRuntimeError, "Failed to read compressed data");
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Decompress
|
|
172
|
+
int decompressed_size = LZ4_decompress_safe(input_buffer, output_buffer, chunk_compressed, chunk_original);
|
|
173
|
+
|
|
174
|
+
if (decompressed_size < 0) {
|
|
175
|
+
free(input_buffer);
|
|
176
|
+
free(output_buffer);
|
|
177
|
+
fclose(input_file);
|
|
178
|
+
fclose(output_file);
|
|
179
|
+
rb_raise(rb_eRuntimeError, "Decompression failed");
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (decompressed_size != chunk_original) {
|
|
183
|
+
free(input_buffer);
|
|
184
|
+
free(output_buffer);
|
|
185
|
+
fclose(input_file);
|
|
186
|
+
fclose(output_file);
|
|
187
|
+
rb_raise(rb_eRuntimeError, "Decompressed size mismatch");
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Write decompressed data
|
|
191
|
+
fwrite(output_buffer, 1, decompressed_size, output_file);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
free(input_buffer);
|
|
195
|
+
free(output_buffer);
|
|
196
|
+
fclose(input_file);
|
|
197
|
+
fclose(output_file);
|
|
198
|
+
|
|
199
|
+
return Qtrue;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/*
|
|
203
|
+
* Get LZ4 version string
|
|
204
|
+
*
|
|
205
|
+
* @return [String] LZ4 version
|
|
206
|
+
*/
|
|
207
|
+
static VALUE lz4_version(VALUE self) {
|
|
208
|
+
int version = LZ4_versionNumber();
|
|
209
|
+
int major = version / 10000;
|
|
210
|
+
int minor = (version % 10000) / 100;
|
|
211
|
+
int patch = version % 100;
|
|
212
|
+
|
|
213
|
+
char version_str[32];
|
|
214
|
+
snprintf(version_str, sizeof(version_str), "%d.%d.%d", major, minor, patch);
|
|
215
|
+
|
|
216
|
+
return rb_str_new_cstr(version_str);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
void Init_lz4_ext(void) {
|
|
220
|
+
mLZ4 = rb_define_module("LZ4");
|
|
221
|
+
|
|
222
|
+
rb_define_singleton_method(mLZ4, "compress_file", lz4_compress_file, 3);
|
|
223
|
+
rb_define_singleton_method(mLZ4, "decompress_file", lz4_decompress_file, 2);
|
|
224
|
+
rb_define_singleton_method(mLZ4, "version", lz4_version, 0);
|
|
225
|
+
|
|
226
|
+
// Define constants
|
|
227
|
+
rb_define_const(mLZ4, "MIN_COMPRESSION_LEVEL", INT2FIX(1));
|
|
228
|
+
rb_define_const(mLZ4, "MAX_COMPRESSION_LEVEL", INT2FIX(LZ4HC_CLEVEL_MAX));
|
|
229
|
+
rb_define_const(mLZ4, "DEFAULT_COMPRESSION_LEVEL", INT2FIX(9));
|
|
230
|
+
}
|
data/lib/lz4/lz4_ext.so
ADDED
|
Binary file
|
data/lib/lz4/version.rb
ADDED
data/lib/lz4.rb
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
require "lz4/lz4_ext"
|
|
2
|
+
require "lz4/version"
|
|
3
|
+
|
|
4
|
+
module LZ4
|
|
5
|
+
class Error < StandardError; end
|
|
6
|
+
class CompressionError < Error; end
|
|
7
|
+
class DecompressionError < Error; end
|
|
8
|
+
|
|
9
|
+
class << self
|
|
10
|
+
# Save references to the C extension methods
|
|
11
|
+
alias_method :_compress_file_ext, :compress_file
|
|
12
|
+
alias_method :_decompress_file_ext, :decompress_file
|
|
13
|
+
|
|
14
|
+
# Compress a file using LZ4
|
|
15
|
+
#
|
|
16
|
+
# @param input_path [String] Path to the input file
|
|
17
|
+
# @param output_path [String] Path to the output file
|
|
18
|
+
# @param compression_level [Integer] Compression level (1-12), default: 9
|
|
19
|
+
# @return [Boolean] true on success
|
|
20
|
+
# @raise [ArgumentError] if compression level is invalid
|
|
21
|
+
# @raise [IOError] if file operations fail
|
|
22
|
+
# @raise [CompressionError] if compression fails
|
|
23
|
+
def compress_file(input_path, output_path, compression_level: DEFAULT_COMPRESSION_LEVEL)
|
|
24
|
+
raise ArgumentError, "input_path must be a String" unless input_path.is_a?(String)
|
|
25
|
+
raise ArgumentError, "output_path must be a String" unless output_path.is_a?(String)
|
|
26
|
+
raise ArgumentError, "Input file does not exist: #{input_path}" unless File.exist?(input_path)
|
|
27
|
+
|
|
28
|
+
compression_level = compression_level.to_i
|
|
29
|
+
|
|
30
|
+
begin
|
|
31
|
+
_compress_file_ext(input_path, output_path, compression_level)
|
|
32
|
+
rescue ArgumentError
|
|
33
|
+
# Let ArgumentError pass through (e.g., invalid compression level)
|
|
34
|
+
raise
|
|
35
|
+
rescue => e
|
|
36
|
+
raise CompressionError, "Failed to compress file: #{e.message}"
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Decompress a file using LZ4
|
|
41
|
+
#
|
|
42
|
+
# @param input_path [String] Path to the compressed input file
|
|
43
|
+
# @param output_path [String] Path to the output file
|
|
44
|
+
# @return [Boolean] true on success
|
|
45
|
+
# @raise [ArgumentError] if arguments are invalid
|
|
46
|
+
# @raise [IOError] if file operations fail
|
|
47
|
+
# @raise [DecompressionError] if decompression fails
|
|
48
|
+
def decompress_file(input_path, output_path)
|
|
49
|
+
raise ArgumentError, "input_path must be a String" unless input_path.is_a?(String)
|
|
50
|
+
raise ArgumentError, "output_path must be a String" unless output_path.is_a?(String)
|
|
51
|
+
raise ArgumentError, "Input file does not exist: #{input_path}" unless File.exist?(input_path)
|
|
52
|
+
|
|
53
|
+
begin
|
|
54
|
+
_decompress_file_ext(input_path, output_path)
|
|
55
|
+
rescue => e
|
|
56
|
+
raise DecompressionError, "Failed to decompress file: #{e.message}"
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
LZ4 Library
|
|
2
|
+
Copyright (c) 2011-2020, Yann Collet
|
|
3
|
+
All rights reserved.
|
|
4
|
+
|
|
5
|
+
Redistribution and use in source and binary forms, with or without modification,
|
|
6
|
+
are permitted provided that the following conditions are met:
|
|
7
|
+
|
|
8
|
+
* Redistributions of source code must retain the above copyright notice, this
|
|
9
|
+
list of conditions and the following disclaimer.
|
|
10
|
+
|
|
11
|
+
* Redistributions in binary form must reproduce the above copyright notice, this
|
|
12
|
+
list of conditions and the following disclaimer in the documentation and/or
|
|
13
|
+
other materials provided with the distribution.
|
|
14
|
+
|
|
15
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
16
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
17
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
18
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
|
19
|
+
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
20
|
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
21
|
+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
22
|
+
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
23
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
24
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
# ################################################################
|
|
2
|
+
# LZ4 library - Makefile
|
|
3
|
+
# Copyright (C) Yann Collet 2011-2023
|
|
4
|
+
# All rights reserved.
|
|
5
|
+
#
|
|
6
|
+
# This Makefile is validated for Linux, macOS, *BSD, Hurd, Solaris, MSYS2 targets
|
|
7
|
+
#
|
|
8
|
+
# BSD license
|
|
9
|
+
# Redistribution and use in source and binary forms, with or without modification,
|
|
10
|
+
# are permitted provided that the following conditions are met:
|
|
11
|
+
#
|
|
12
|
+
# * Redistributions of source code must retain the above copyright notice, this
|
|
13
|
+
# list of conditions and the following disclaimer.
|
|
14
|
+
#
|
|
15
|
+
# * Redistributions in binary form must reproduce the above copyright notice, this
|
|
16
|
+
# list of conditions and the following disclaimer in the documentation and/or
|
|
17
|
+
# other materials provided with the distribution.
|
|
18
|
+
#
|
|
19
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
20
|
+
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
21
|
+
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
22
|
+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
|
23
|
+
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
24
|
+
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
25
|
+
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
26
|
+
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
27
|
+
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
28
|
+
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
29
|
+
#
|
|
30
|
+
# You can contact the author at :
|
|
31
|
+
# - LZ4 source repository : https://github.com/lz4/lz4
|
|
32
|
+
# - LZ4 forum froup : https://groups.google.com/forum/#!forum/lz4c
|
|
33
|
+
# ################################################################
|
|
34
|
+
SED ?= sed
|
|
35
|
+
|
|
36
|
+
# Version numbers
|
|
37
|
+
LIBVER_MAJOR_SCRIPT:=`$(SED) -n '/define[[:blank:]][[:blank:]]*LZ4_VERSION_MAJOR/s/.*[[:blank:]]\([0-9][0-9]*\).*/\1/p' < ./lz4.h`
|
|
38
|
+
LIBVER_MINOR_SCRIPT:=`$(SED) -n '/define[[:blank:]][[:blank:]]*LZ4_VERSION_MINOR/s/.*[[:blank:]]\([0-9][0-9]*\).*/\1/p' < ./lz4.h`
|
|
39
|
+
LIBVER_PATCH_SCRIPT:=`$(SED) -n '/define[[:blank:]][[:blank:]]*LZ4_VERSION_RELEASE/s/.*[[:blank:]]\([0-9][0-9]*\).*/\1/p' < ./lz4.h`
|
|
40
|
+
LIBVER_SCRIPT:= $(LIBVER_MAJOR_SCRIPT).$(LIBVER_MINOR_SCRIPT).$(LIBVER_PATCH_SCRIPT)
|
|
41
|
+
LIBVER_MAJOR := $(shell echo $(LIBVER_MAJOR_SCRIPT))
|
|
42
|
+
LIBVER_MINOR := $(shell echo $(LIBVER_MINOR_SCRIPT))
|
|
43
|
+
LIBVER_PATCH := $(shell echo $(LIBVER_PATCH_SCRIPT))
|
|
44
|
+
LIBVER := $(shell echo $(LIBVER_SCRIPT))
|
|
45
|
+
|
|
46
|
+
BUILD_SHARED:=yes
|
|
47
|
+
BUILD_STATIC:=yes
|
|
48
|
+
|
|
49
|
+
CPPFLAGS+= -DXXH_NAMESPACE=LZ4_
|
|
50
|
+
USERCFLAGS:= -O3 $(CFLAGS)
|
|
51
|
+
DEBUGFLAGS:= -Wall -Wextra -Wcast-qual -Wcast-align -Wshadow \
|
|
52
|
+
-Wswitch-enum -Wdeclaration-after-statement -Wstrict-prototypes \
|
|
53
|
+
-Wundef -Wpointer-arith -Wstrict-aliasing=1
|
|
54
|
+
CFLAGS = $(DEBUGFLAGS) $(USERCFLAGS)
|
|
55
|
+
ALLFLAGS = $(CFLAGS) $(CPPFLAGS) $(LDFLAGS)
|
|
56
|
+
|
|
57
|
+
SRCFILES := $(sort $(wildcard *.c))
|
|
58
|
+
|
|
59
|
+
include ../Makefile.inc
|
|
60
|
+
|
|
61
|
+
# OS X linker doesn't support -soname, and use different extension
|
|
62
|
+
# see : https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/DynamicLibraries/100-Articles/DynamicLibraryDesignGuidelines.html
|
|
63
|
+
ifeq ($(TARGET_OS), Darwin)
|
|
64
|
+
SHARED_EXT = dylib
|
|
65
|
+
SHARED_EXT_MAJOR = $(LIBVER_MAJOR).$(SHARED_EXT)
|
|
66
|
+
SHARED_EXT_VER = $(LIBVER).$(SHARED_EXT)
|
|
67
|
+
SONAME_FLAGS = -install_name $(libdir)/liblz4.$(SHARED_EXT_MAJOR) -compatibility_version $(LIBVER_MAJOR) -current_version $(LIBVER) -dynamiclib
|
|
68
|
+
else
|
|
69
|
+
ifeq ($(WINBASED),yes)
|
|
70
|
+
SHARED_EXT = dll
|
|
71
|
+
SHARED_EXT_VER = $(SHARED_EXT)
|
|
72
|
+
else # posix non-mac
|
|
73
|
+
SONAME_FLAGS = -Wl,-soname=liblz4.$(SHARED_EXT).$(LIBVER_MAJOR)
|
|
74
|
+
SHARED_EXT = so
|
|
75
|
+
SHARED_EXT_MAJOR = $(SHARED_EXT).$(LIBVER_MAJOR)
|
|
76
|
+
SHARED_EXT_VER = $(SHARED_EXT).$(LIBVER)
|
|
77
|
+
endif
|
|
78
|
+
endif
|
|
79
|
+
|
|
80
|
+
.PHONY: default
|
|
81
|
+
default: lib-release
|
|
82
|
+
|
|
83
|
+
# silent mode by default; verbose can be triggered by V=1 or VERBOSE=1
|
|
84
|
+
$(V)$(VERBOSE).SILENT:
|
|
85
|
+
|
|
86
|
+
.PHONY:lib-release
|
|
87
|
+
lib-release: DEBUGFLAGS :=
|
|
88
|
+
lib-release: lib liblz4.pc
|
|
89
|
+
|
|
90
|
+
.PHONY: lib
|
|
91
|
+
lib: liblz4.a liblz4
|
|
92
|
+
|
|
93
|
+
.PHONY: all
|
|
94
|
+
all: lib liblz4.pc
|
|
95
|
+
|
|
96
|
+
.PHONY: all32
|
|
97
|
+
all32: CFLAGS+=-m32
|
|
98
|
+
all32: all
|
|
99
|
+
|
|
100
|
+
CLEAN += liblz4.a
|
|
101
|
+
liblz4.a: $(SRCFILES)
|
|
102
|
+
ifeq ($(BUILD_STATIC),yes) # can be disabled on command line
|
|
103
|
+
@echo compiling static library
|
|
104
|
+
$(COMPILE.c) $^
|
|
105
|
+
$(AR) rcs $@ *.o
|
|
106
|
+
endif
|
|
107
|
+
|
|
108
|
+
ifeq ($(WINBASED),yes)
|
|
109
|
+
|
|
110
|
+
CLEAN += $(liblz4-dll.rc)
|
|
111
|
+
liblz4-dll.rc: liblz4-dll.rc.in
|
|
112
|
+
@echo creating library resource
|
|
113
|
+
$(SED) -e 's|@LIBLZ4@|$(LIBLZ4_NAME)|' \
|
|
114
|
+
-e 's|@LIBVER_MAJOR@|$(LIBVER_MAJOR)|g' \
|
|
115
|
+
-e 's|@LIBVER_MINOR@|$(LIBVER_MINOR)|g' \
|
|
116
|
+
-e 's|@LIBVER_PATCH@|$(LIBVER_PATCH)|g' \
|
|
117
|
+
$< >$@
|
|
118
|
+
|
|
119
|
+
liblz4-dll.o: liblz4-dll.rc
|
|
120
|
+
$(WINDRES) -i liblz4-dll.rc -o liblz4-dll.o
|
|
121
|
+
|
|
122
|
+
CLEAN += $(LIBLZ4_EXP)
|
|
123
|
+
$(LIBLZ4): $(SRCFILES) liblz4-dll.o
|
|
124
|
+
ifeq ($(BUILD_SHARED),yes)
|
|
125
|
+
@echo compiling dynamic library $(LIBVER)
|
|
126
|
+
$(CC) $(ALLFLAGS) -DLZ4_DLL_EXPORT=1 -shared $^ -o $@ -Wl,--out-implib,$(LIBLZ4_EXP)
|
|
127
|
+
endif
|
|
128
|
+
|
|
129
|
+
else # not windows
|
|
130
|
+
|
|
131
|
+
$(LIBLZ4): $(SRCFILES)
|
|
132
|
+
ifeq ($(BUILD_SHARED),yes)
|
|
133
|
+
@echo compiling dynamic library $(LIBVER)
|
|
134
|
+
$(CC) $(ALLFLAGS) -shared $^ -fPIC -fvisibility=hidden $(SONAME_FLAGS) -o $@
|
|
135
|
+
@echo creating versioned links
|
|
136
|
+
$(LN_SF) $@ liblz4.$(SHARED_EXT_MAJOR)
|
|
137
|
+
$(LN_SF) $@ liblz4.$(SHARED_EXT)
|
|
138
|
+
endif
|
|
139
|
+
|
|
140
|
+
endif
|
|
141
|
+
CLEAN += $(LIBLZ4)
|
|
142
|
+
|
|
143
|
+
.PHONY: liblz4
|
|
144
|
+
liblz4: $(LIBLZ4)
|
|
145
|
+
|
|
146
|
+
CLEAN += liblz4.pc
|
|
147
|
+
liblz4.pc: liblz4.pc.in Makefile
|
|
148
|
+
@echo creating pkgconfig
|
|
149
|
+
$(SED) -e 's|@PREFIX@|$(prefix)|' \
|
|
150
|
+
-e 's|@LIBDIR@|$(libdir)|' \
|
|
151
|
+
-e 's|@INCLUDEDIR@|$(includedir)|' \
|
|
152
|
+
-e 's|@VERSION@|$(LIBVER)|' \
|
|
153
|
+
-e 's|=${prefix}/|=$${prefix}/|' \
|
|
154
|
+
$< >$@
|
|
155
|
+
|
|
156
|
+
.PHONY: clean
|
|
157
|
+
clean:
|
|
158
|
+
ifeq ($(WINBASED),yes)
|
|
159
|
+
$(RM) *.rc
|
|
160
|
+
endif
|
|
161
|
+
$(RM) $(CLEAN) core *.o *.a
|
|
162
|
+
$(RM) *.$(SHARED_EXT) *.$(SHARED_EXT_MAJOR) *.$(SHARED_EXT_VER)
|
|
163
|
+
@echo Cleaning library completed
|
|
164
|
+
|
|
165
|
+
#-----------------------------------------------------------------------------
|
|
166
|
+
# make install is validated only for Linux, OSX, BSD, Hurd and Solaris targets
|
|
167
|
+
#-----------------------------------------------------------------------------
|
|
168
|
+
ifeq ($(POSIX_ENV),Yes)
|
|
169
|
+
|
|
170
|
+
.PHONY: listL120
|
|
171
|
+
listL120: # extract lines >= 120 characters in *.{c,h}, by Takayuki Matsuoka (note : $$, for Makefile compatibility)
|
|
172
|
+
find . -type f -name '*.c' -o -name '*.h' | while read -r filename; do awk 'length > 120 {print FILENAME "(" FNR "): " $$0}' $$filename; done
|
|
173
|
+
|
|
174
|
+
DESTDIR ?=
|
|
175
|
+
# directory variables : GNU conventions prefer lowercase
|
|
176
|
+
# see https://www.gnu.org/prep/standards/html_node/Makefile-Conventions.html
|
|
177
|
+
# support both lower and uppercase (BSD), use lower in script
|
|
178
|
+
PREFIX ?= /usr/local
|
|
179
|
+
prefix ?= $(PREFIX)
|
|
180
|
+
EXEC_PREFIX ?= $(prefix)
|
|
181
|
+
exec_prefix ?= $(EXEC_PREFIX)
|
|
182
|
+
BINDIR ?= $(exec_prefix)/bin
|
|
183
|
+
bindir ?= $(BINDIR)
|
|
184
|
+
LIBDIR ?= $(exec_prefix)/lib
|
|
185
|
+
libdir ?= $(LIBDIR)
|
|
186
|
+
INCLUDEDIR ?= $(prefix)/include
|
|
187
|
+
includedir ?= $(INCLUDEDIR)
|
|
188
|
+
|
|
189
|
+
ifneq (,$(filter $(TARGET_OS),OpenBSD FreeBSD NetBSD DragonFly MidnightBSD))
|
|
190
|
+
PKGCONFIGDIR ?= $(prefix)/libdata/pkgconfig
|
|
191
|
+
else
|
|
192
|
+
PKGCONFIGDIR ?= $(libdir)/pkgconfig
|
|
193
|
+
endif
|
|
194
|
+
pkgconfigdir ?= $(PKGCONFIGDIR)
|
|
195
|
+
|
|
196
|
+
.PHONY: install
|
|
197
|
+
install: lib liblz4.pc
|
|
198
|
+
$(MAKE_DIR) $(DESTDIR)$(pkgconfigdir)/ $(DESTDIR)$(includedir)/ $(DESTDIR)$(libdir)/ $(DESTDIR)$(bindir)/
|
|
199
|
+
$(INSTALL_DATA) liblz4.pc $(DESTDIR)$(pkgconfigdir)/
|
|
200
|
+
@echo Installing libraries in $(DESTDIR)$(libdir)
|
|
201
|
+
ifeq ($(BUILD_STATIC),yes)
|
|
202
|
+
$(INSTALL_DATA) liblz4.a $(DESTDIR)$(libdir)/liblz4.a
|
|
203
|
+
$(INSTALL_DATA) lz4frame_static.h $(DESTDIR)$(includedir)/lz4frame_static.h
|
|
204
|
+
$(INSTALL_DATA) lz4file.h $(DESTDIR)$(includedir)/lz4file.h
|
|
205
|
+
endif
|
|
206
|
+
ifeq ($(BUILD_SHARED),yes)
|
|
207
|
+
# Traditionally, one installs the DLLs in the bin directory as programs
|
|
208
|
+
# search them first in their directory. This allows to not pollute system
|
|
209
|
+
# directories (like c:/windows/system32), nor modify the PATH variable.
|
|
210
|
+
ifeq ($(WINBASED),yes)
|
|
211
|
+
$(INSTALL_PROGRAM) $(LIBLZ4) $(DESTDIR)$(bindir)
|
|
212
|
+
$(INSTALL_PROGRAM) $(LIBLZ4_EXP) $(DESTDIR)$(libdir)
|
|
213
|
+
else
|
|
214
|
+
$(INSTALL_PROGRAM) liblz4.$(SHARED_EXT_VER) $(DESTDIR)$(libdir)
|
|
215
|
+
$(LN_SF) liblz4.$(SHARED_EXT_VER) $(DESTDIR)$(libdir)/liblz4.$(SHARED_EXT_MAJOR)
|
|
216
|
+
$(LN_SF) liblz4.$(SHARED_EXT_VER) $(DESTDIR)$(libdir)/liblz4.$(SHARED_EXT)
|
|
217
|
+
endif
|
|
218
|
+
endif
|
|
219
|
+
@echo Installing headers in $(DESTDIR)$(includedir)
|
|
220
|
+
$(INSTALL_DATA) lz4.h $(DESTDIR)$(includedir)/lz4.h
|
|
221
|
+
$(INSTALL_DATA) lz4hc.h $(DESTDIR)$(includedir)/lz4hc.h
|
|
222
|
+
$(INSTALL_DATA) lz4frame.h $(DESTDIR)$(includedir)/lz4frame.h
|
|
223
|
+
@echo lz4 libraries installed
|
|
224
|
+
|
|
225
|
+
.PHONY: uninstall
|
|
226
|
+
uninstall:
|
|
227
|
+
$(RM) $(DESTDIR)$(pkgconfigdir)/liblz4.pc
|
|
228
|
+
ifeq (WINBASED,yes)
|
|
229
|
+
$(RM) $(DESTDIR)$(bindir)/$(LIBLZ4)
|
|
230
|
+
$(RM) $(DESTDIR)$(libdir)/$(LIBLZ4_EXP)
|
|
231
|
+
else
|
|
232
|
+
$(RM) $(DESTDIR)$(libdir)/liblz4.$(SHARED_EXT)
|
|
233
|
+
$(RM) $(DESTDIR)$(libdir)/liblz4.$(SHARED_EXT_MAJOR)
|
|
234
|
+
$(RM) $(DESTDIR)$(libdir)/liblz4.$(SHARED_EXT_VER)
|
|
235
|
+
endif
|
|
236
|
+
$(RM) $(DESTDIR)$(libdir)/liblz4.a
|
|
237
|
+
$(RM) $(DESTDIR)$(includedir)/lz4.h
|
|
238
|
+
$(RM) $(DESTDIR)$(includedir)/lz4hc.h
|
|
239
|
+
$(RM) $(DESTDIR)$(includedir)/lz4frame.h
|
|
240
|
+
$(RM) $(DESTDIR)$(includedir)/lz4frame_static.h
|
|
241
|
+
$(RM) $(DESTDIR)$(includedir)/lz4file.h
|
|
242
|
+
@echo lz4 libraries successfully uninstalled
|
|
243
|
+
|
|
244
|
+
endif
|