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 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.
@@ -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
+ }
Binary file
@@ -0,0 +1,3 @@
1
+ module LZ4
2
+ VERSION = "0.1.1"
3
+ end
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