forked from LibRaw/LibRaw
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCMakeLists.txt
More file actions
152 lines (133 loc) · 7.16 KB
/
Copy pathCMakeLists.txt
File metadata and controls
152 lines (133 loc) · 7.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
cmake_minimum_required(VERSION 3.16)
# LibRaw ships no CMake build of its own. `README.cmake` points at
# LibRaw/LibRaw-cmake, a separate repository that upstream stopped supporting in
# October 2014 and that has to be copied into this tree before it works.
#
# This file replaces it rather than vendoring it. That is not a judgement on
# LibRaw-cmake: it is that roughly 700 of its 737 lines are find_package()
# probes for LCMS, JasPer, libjpeg, zlib, OpenMP and RawSpeed -- every one of
# which this build turns off. Carrying that code would mean carrying precisely
# the part most likely to misbehave under `emcmake`, for no benefit. What
# remains once the probes are gone is a source glob and one executable.
#
# There is deliberately no find_package() anywhere below. Nothing outside this
# repository is linked.
project(libraw_tools LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type")
endif()
# --- the library --------------------------------------------------------------
#
# Every optional dependency is off, and stays off, by never defining its macro.
# LibRaw's optional sources self-guard -- `src/integration/dngsdk_glue.cpp` and
# `rawspeed_glue.cpp` are `#ifdef USE_DNGSDK` / `USE_RAWSPEED`, and `src/x3f/*`
# is `#ifdef USE_X3FTOOLS` -- so they compile to nothing and need no exclusion
# from the glob.
#
# A Canon CR2 needs none of them. Its lossless-JPEG payload is decoded by
# LibRaw's own `src/decompressors/losslessjpeg.cpp` rather than by libjpeg, the
# AHD demosaic that `dcraw_emu -q 3` selects lives in `src/demosaic/`, and TIFF
# output is written by `src/write/` rather than by libtiff.
#
# Three of these stay off for licensing rather than technical reasons -- see
# FORK.md.
#
# OpenMP is the one whose absence is load-bearing rather than incidental.
# LibRaw-cmake enables it by default. Threads in a wasm build mean
# SharedArrayBuffer, which means whoever serves the .wasm must send COOP/COEP
# headers. Keeping this build single-threaded is what lets it be hosted on any
# static host with no header configuration, which is the whole point of the
# port.
file(GLOB_RECURSE LIBRAW_SOURCES CONFIGURE_DEPENDS
"${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp")
# The one glob exclusion. `*_ph.cpp` are placeholder translation units whose
# every function returns LIBRAW_NOT_IMPLEMENTED; they exist so LibRaw can be
# built without postprocessing at all, and they define the same symbols as the
# real implementations. Left in, the link fails on ten duplicate symbols --
# which is the good outcome, since a resolution that happened to favour the
# stubs would give a dcraw_emu whose `dcraw_process()` silently does nothing.
list(FILTER LIBRAW_SOURCES EXCLUDE REGEX "_ph\\.cpp$")
add_library(raw STATIC ${LIBRAW_SOURCES})
# Sources include both "libraw/libraw.h" and "../../internal/...", so the one
# include root they all resolve against is the repository root.
target_include_directories(raw PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
# --- the tools ----------------------------------------------------------------
#
# One entry per sample program wanted. Adding another is one line here; the
# source is already in samples/.
set(LIBRAW_TOOLS dcraw_emu)
foreach(_tool ${LIBRAW_TOOLS})
add_executable(${_tool} samples/${_tool}.cpp)
target_link_libraries(${_tool} PRIVATE raw)
install(TARGETS ${_tool} RUNTIME DESTINATION bin)
endforeach()
# --- WebAssembly --------------------------------------------------------------
if(EMSCRIPTEN)
option(LIBRAW_WASM_NODERAWFS
"Use the real filesystem via NODERAWFS (node only, keeps argv/paths native)" ON)
# LibRaw reports every I/O and format error by throwing
# (LIBRAW_EXCEPTION_IO_EOF and friends) and catches in ~78 places. emcc
# disables exception catching by default, which turns each of those catches
# into an abort -- so a truncated or unrecognised file takes the whole
# module down instead of returning an error code. Needed at compile *and*
# link time.
#
# target_compile_options rather than add_compile_options, deliberately:
# add_compile_options only affects targets created *after* it, and this
# block sits below add_library/add_executable, so the directory-scoped form
# silently does nothing. That failure is invisible until a malformed file
# reaches the module, which is exactly when it matters least to discover it.
# PUBLIC propagates the flag from the library to every tool linking it.
target_compile_options(raw PUBLIC -fexceptions)
target_link_options(raw PUBLIC -fexceptions)
# Reproducibility across engines, stated rather than inherited.
#
# wasm MVP has no fused multiply-add, so nothing here contracts a*b+c today
# and this flag changes no output byte (verified: the reference frame's
# digest is unchanged with and without it). But that guarantee currently
# rests on emcc not vectorising by default, not on anything we asked for:
# relaxed SIMD adds f32x4.relaxed_madd, which an engine may fuse or not at
# its own discretion. If -msimd128 or -mrelaxed-simd is ever added here,
# identical output on every browser would quietly stop being guaranteed.
#
# It also makes the native and wasm recipes symmetric: FORK.md's comparison
# is against a native build with this same flag.
target_compile_options(raw PUBLIC -ffp-contract=off)
foreach(_tool ${LIBRAW_TOOLS})
target_link_options(${_tool} PRIVATE
# dcraw's unpack paths carry sizeable automatic arrays; the 64 KB
# default stack is the usual cause of an unexplained early abort.
-sSTACK_SIZE=5MB
-sALLOW_MEMORY_GROWTH=1
# wasm32 hard ceiling.
-sMAXIMUM_MEMORY=4GB
# Propagate the exit code. dcraw_emu returns nonzero on an
# unreadable file, and the pipeline checks it.
-sEXIT_RUNTIME=1
)
if(LIBRAW_WASM_NODERAWFS)
# Same argv and the same real paths as the native binary, which is
# what makes native-vs-wasm a direct A/B. INVOKE_RUN is fine here:
# argv already names real files, so there is nothing to stage first.
target_link_options(${_tool} PRIVATE
-sNODERAWFS=1 -sENVIRONMENT=node -sINVOKE_RUN=1)
else()
# Browser build. INVOKE_RUN must be 0 -- with it on, main() runs at
# instantiation, before JS can write the RAW file into the virtual
# filesystem. FS and callMain must be exported or FORCE_FILESYSTEM
# compiles in a filesystem that JS cannot reach. HEAPU8 is exported
# so callers can read the linear-memory high-water mark, which with
# ALLOW_MEMORY_GROWTH is the only practical way to measure a run
# against the wasm32 ceiling.
target_link_options(${_tool} PRIVATE
-sFORCE_FILESYSTEM=1
-sMODULARIZE=1 -sEXPORT_ES6=1
-sENVIRONMENT=web,worker
-sINVOKE_RUN=0
"-sEXPORTED_RUNTIME_METHODS=['FS','callMain','HEAPU8']")
endif()
set_target_properties(${_tool} PROPERTIES SUFFIX ".js")
endforeach()
endif()