blob: 6b7e5d9dcaea702ea1cefe38efa99ce450a3eb84 [file] [log] [blame]
Evan Nemerson93ef13f2016-06-20 13:07:35 -07001# Ubuntu 12.04 LTS has CMake 2.8.7, and is an important target since
2# several CI services, such as Travis and Drone, use it. Solaris 11
3# has 2.8.6, and it's not difficult to support if you already have to
4# support 2.8.7.
5cmake_minimum_required(VERSION 2.8.6)
6
7project(brotli)
8
9# If Brotli is being bundled in another project, we don't want to
10# install anything. However, we want to let people override this, so
11# we'll use the BROTLI_BUNDLED_MODE variable to let them do that; just
12# set it to OFF in your project before you add_subdirectory(brotli).
13get_directory_property(BROTLI_PARENT_DIRECTORY PARENT_DIRECTORY)
14if(BROTLI_BUNDLED_MODE STREQUAL "")
15 # Bundled mode hasn't been set one way or the other, set the default
16 # depending on whether or not we are the top-level project.
17 if(BROTLI_PARENT_DIRECTORY)
18 set(BROTLI_BUNDLED_MODE OFF)
19 else()
20 set(BROTLI_BUNDLED_MODE ON)
21 endif()
22endif()
23mark_as_advanced(BROTLI_BUNDLED_MODE)
24
Eugene Kliuchnikov2c2d5572016-08-22 15:44:12 +020025# Parse version information from common/version.h. Normally we would
Evan Nemerson93ef13f2016-06-20 13:07:35 -070026# define these values here and write them out to configuration file(s)
27# (i.e., config.h), but in this case we parse them from
Eugene Kliuchnikov2c2d5572016-08-22 15:44:12 +020028# common/version.h to be less intrusive.
29function(hex_to_dec HEXADECIMAL DECIMAL)
30 string(TOUPPER "${HEXADECIMAL}" _tail)
31 set(_decimal 0)
32 string(LENGTH "${_tail}" _tail_length)
33 while (_tail_length GREATER 0)
34 math(EXPR _decimal "${_decimal} * 16")
35 string(SUBSTRING "${_tail}" 0 1 _digit)
36 string(SUBSTRING "${_tail}" 1 -1 _tail)
37 if (_digit STREQUAL "A")
38 math(EXPR _decimal "${_decimal} + 10")
39 elseif (_digit STREQUAL "B")
40 math(EXPR _decimal "${_decimal} + 11")
41 elseif (_digit STREQUAL "C")
42 math(EXPR _decimal "${_decimal} + 12")
43 elseif (_digit STREQUAL "D")
44 math(EXPR _decimal "${_decimal} + 13")
45 elseif (_digit STREQUAL "E")
46 math(EXPR _decimal "${_decimal} + 14")
47 elseif (_digit STREQUAL "F")
48 math(EXPR _decimal "${_decimal} + 15")
49 else()
50 math(EXPR _decimal "${_decimal} + ${_digit}")
51 endif()
52 string(LENGTH "${_tail}" _tail_length)
53 endwhile()
54 set(${DECIMAL} ${_decimal} PARENT_SCOPE)
55endfunction(hex_to_dec)
56
57file(STRINGS "common/version.h" _brotli_version_line REGEX "^#define BROTLI_VERSION (0x[0-9a-fA-F]+)$")
58string(REGEX REPLACE "^#define BROTLI_VERSION 0x([0-9a-fA-F]+)$" "\\1" _brotli_version_hex "${_brotli_version_line}")
59hex_to_dec("${_brotli_version_hex}" _brotli_version)
60math(EXPR BROTLI_VERSION_MAJOR "${_brotli_version} >> 24")
61math(EXPR BROTLI_VERSION_MINOR "(${_brotli_version} >> 12) & 4095")
62math(EXPR BROTLI_VERSION_REVISION "${_brotli_version} & 4095")
Evan Nemerson93ef13f2016-06-20 13:07:35 -070063mark_as_advanced(BROTLI_VERSION_MAJOR BROTLI_VERSION_MINOR BROTLI_VERSION_REVISION)
64
Evan Nemerson37be4e32016-06-28 20:35:16 -070065if (ENABLE_SANITIZER)
66 set(CMAKE_C_FLAGS " ${CMAKE_C_FLAGS} -fsanitize=${ENABLE_SANITIZER}")
67 set(CMAKE_CXX_FLAGS " ${CMAKE_CXX_FLAGS} -fsanitize=${ENABLE_SANITIZER}")
68 set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=${ENABLE_SANITIZER}")
Evan Nemerson26a59352016-07-26 08:22:58 -070069
70 # By default, brotli depends on undefined behavior, but setting
71 # BROTLI_BUILD_PORTABLE should result in a build which does not.
72 if(ENABLE_SANITIZER STREQUAL "undefined")
73 add_definitions(-DBROTLI_BUILD_PORTABLE)
74 endif()
Evan Nemerson37be4e32016-06-28 20:35:16 -070075endif ()
76
Evan Nemersonc1ec7ba2016-07-29 11:52:15 -070077include(CheckFunctionExists)
78set(LIBM_LIBRARY)
79CHECK_FUNCTION_EXISTS(log2 LOG2_RES)
80if(NOT LOG2_RES)
Evan Nemersonc1ec7ba2016-07-29 11:52:15 -070081 set(orig_req_libs "${CMAKE_REQUIRED_LIBRARIES}")
82 set(CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES};m")
Evan Nemersonfe0e1532016-08-04 18:51:20 -070083 CHECK_FUNCTION_EXISTS(log2 LOG2_LIBM_RES)
84 if(LOG2_LIBM_RES)
Evan Nemersonc1ec7ba2016-07-29 11:52:15 -070085 set(LIBM_LIBRARY "m")
86 else()
87 message(FATAL_ERROR "log2() not found")
88 endif()
89
90 set(CMAKE_REQUIRED_LIBRARIES "${orig_req_libs}")
Evan Nemersonfe0e1532016-08-04 18:51:20 -070091 unset(LOG2_LIBM_RES)
Evan Nemersonc1ec7ba2016-07-29 11:52:15 -070092 unset(orig_req_libs)
93endif()
94unset(LOG2_RES)
95
Eugene Kliuchnikov3dcc3c02016-08-23 14:49:37 +020096set(BROTLI_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/include")
Evan Nemersonc1ec7ba2016-07-29 11:52:15 -070097set(BROTLI_LIBRARIES brotli_enc brotli_dec brotli_common ${LIBM_LIBRARY})
Evan Nemerson93ef13f2016-06-20 13:07:35 -070098mark_as_advanced(BROTLI_INCLUDE_DIRS BROTLI_LIBRARIES)
99
100if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
101 add_definitions(-DOS_LINUX)
102elseif(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
103 add_definitions(-DOS_FREEBSD)
104elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
105 add_definitions(-DOS_MACOSX)
106endif()
107
108add_library(brotli_common STATIC
109 common/dictionary.c)
110add_library(brotli_dec STATIC
111 dec/bit_reader.c
112 dec/decode.c
113 dec/huffman.c
114 dec/state.c)
115add_library(brotli_enc STATIC
116 enc/backward_references.c
117 enc/bit_cost.c
118 enc/block_splitter.c
119 enc/brotli_bit_stream.c
120 enc/cluster.c
121 enc/compress_fragment.c
122 enc/compress_fragment_two_pass.c
123 enc/encode.c
124 enc/entropy_encode.c
125 enc/histogram.c
126 enc/literal_cost.c
127 enc/memory.c
128 enc/metablock.c
129 enc/static_dict.c
130 enc/utf8_util.c)
131
Eugene Kliuchnikov532921b2016-08-23 15:35:54 +0200132# Older CMake versions does not understand INCLUDE_DIRECTORIES property.
133include_directories(${BROTLI_INCLUDE_DIRS})
134
Evan Nemerson93ef13f2016-06-20 13:07:35 -0700135foreach(lib brotli_common brotli_dec brotli_enc)
Evan Nemersonc1ec7ba2016-07-29 11:52:15 -0700136 target_link_libraries(${lib} ${LIBM_LIBRARY})
Evan Nemerson93ef13f2016-06-20 13:07:35 -0700137 set_property(TARGET ${lib} APPEND PROPERTY INCLUDE_DIRECTORIES ${BROTLI_INCLUDE_DIRS})
138 set_target_properties(${lib} PROPERTIES
139 VERSION ${BROTLI_VERSION_MAJOR}.${BROTLI_VERSION_MINOR}.${BROTLI_VERSION_REVISION}
140 POSITION_INDEPENDENT_CODE TRUE)
141
142 set_property(TARGET ${lib} APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${BROTLI_INCLUDE_DIRS}")
143endforeach()
144
145# For projects stuck on older versions of CMake, this will set the
146# BROTLI_INCLUDE_DIRS and BROTLI_LIBRARIES variables so they still
147# have a relatively easy way to use Brotli:
148#
149# include_directories(${BROTLI_INCLUDE_DIRS})
150# target_link_libraries(foo ${BROTLI_LIBRARIES})
151if(BROTLI_PARENT_DIRECTORY)
152 set(BROTLI_INCLUDE_DIRS "${BROTLI_INCLUDE_DIRS}" PARENT_SCOPE)
153 set(BROTLI_LIBRARIES "${BROTLI_LIBRARIES}" PARENT_SCOPE)
154endif()
155
156# Build the bro executable
157add_executable(bro tools/bro.c)
158target_link_libraries(bro ${BROTLI_LIBRARIES})
159
160# Installation
161if(NOT BROTLI_BUNDLE_MODE)
162 include(GNUInstallDirs)
163
164 install (TARGETS bro RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
165endif()
166
167# Tests
Evan Nemerson03657e82016-07-28 13:31:09 -0700168
169# If we're targeting Windows but not running on Windows, we need Wine
170# to run the tests...
171if(NOT BROTLI_DISABLE_TESTS)
172 if(WIN32 AND NOT CMAKE_HOST_WIN32)
173 find_program(BROTLI_WINE NAMES wine)
Evan Nemerson03657e82016-07-28 13:31:09 -0700174
Evan Nemersonc1ec7ba2016-07-29 11:52:15 -0700175 if(NOT BROTLI_WINE)
176 message(STATUS "wine not found, disabling tests")
177 set(BROTLI_DISABLE_TESTS TRUE)
178 endif()
Evan Nemerson03657e82016-07-28 13:31:09 -0700179 endif()
180endif()
181
Evan Nemerson93ef13f2016-06-20 13:07:35 -0700182if(NOT BROTLI_DISABLE_TESTS)
183 include(CTest)
184 enable_testing()
185
186 set(ROUNDTRIP_INPUTS
187 tests/testdata/alice29.txt
188 tests/testdata/asyoulik.txt
189 tests/testdata/lcet10.txt
190 tests/testdata/plrabn12.txt
191 enc/encode.c
192 common/dictionary.h
193 dec/decode.c)
194
195 foreach(INPUT ${ROUNDTRIP_INPUTS})
Evan Nemerson03657e82016-07-28 13:31:09 -0700196 get_filename_component(OUTPUT_NAME "${INPUT}" NAME)
197
198 set(OUTPUT_FILE "${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_NAME}")
199 set(INPUT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/${INPUT}")
200
Evan Nemerson93ef13f2016-06-20 13:07:35 -0700201 foreach(quality 1 6 9 11)
202 add_test(NAME "${BROTLI_TEST_PREFIX}roundtrip/${INPUT}/${quality}"
203 COMMAND "${CMAKE_COMMAND}"
Evan Nemerson03657e82016-07-28 13:31:09 -0700204 -DBROTLI_WRAPPER=${BROTLI_WINE}
Evan Nemerson93ef13f2016-06-20 13:07:35 -0700205 -DBROTLI_CLI=$<TARGET_FILE:bro>
206 -DQUALITY=${quality}
Evan Nemerson03657e82016-07-28 13:31:09 -0700207 -DINPUT=${INPUT_FILE}
208 -DOUTPUT=${OUTPUT_FILE}.${quality}
Evan Nemerson93ef13f2016-06-20 13:07:35 -0700209 -P ${CMAKE_CURRENT_SOURCE_DIR}/tests/run-roundtrip-test.cmake)
210 endforeach()
211 endforeach()
212
213 file(GLOB_RECURSE
214 COMPATIBILITY_INPUTS
215 RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
216 tests/testdata/*.compressed*)
217
218 foreach(INPUT ${COMPATIBILITY_INPUTS})
219 add_test(NAME "${BROTLI_TEST_PREFIX}compatibility/${INPUT}"
220 COMMAND "${CMAKE_COMMAND}"
Evan Nemerson03657e82016-07-28 13:31:09 -0700221 -DBROTLI_WRAPPER=${BROTLI_WINE}
Evan Nemerson93ef13f2016-06-20 13:07:35 -0700222 -DBROTLI_CLI=$<TARGET_FILE:bro>
223 -DINPUT=${CMAKE_CURRENT_SOURCE_DIR}/${INPUT}
224 -P ${CMAKE_CURRENT_SOURCE_DIR}/tests/run-compatibility-test.cmake)
225 endforeach()
226endif()