Skip to content

Commit 497a9ec

Browse files
committed
Implement CMake symbols visibility
Explictly mark which symbols are exported. Use HWY_DLLEXPORT since HWY_EXPORT is already used in the codebase. Run clang-format --style=Google for formatting. Make sure that the main *.pc file reflect how highway was built. This should fix #488
1 parent 2f61f9b commit 497a9ec

File tree

9 files changed

+107
-41
lines changed

9 files changed

+107
-41
lines changed

CMakeLists.txt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ set(HWY_SOURCES
7979
hwy/detect_targets.h # private
8080
hwy/foreach_target.h
8181
hwy/highway.h
82+
hwy/highway_export.h
8283
hwy/nanobenchmark.cc
8384
hwy/nanobenchmark.h
8485
hwy/ops/arm_neon-inl.h
@@ -200,22 +201,35 @@ endif() # !MSVC
200201
option(BUILD_SHARED_LIBS "Build shared libraries" OFF)
201202
# only expose shared option to advanced users:
202203
mark_as_advanced(BUILD_SHARED_LIBS)
204+
# Define visibility settings globally:
205+
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
206+
set(CMAKE_VISIBILITY_INLINES_HIDDEN 1)
207+
208+
# This preprocessor define will drive the build, also used in the *.pc files:
209+
if(BUILD_SHARED_LIBS)
210+
set(DLLEXPORT_TO_DEFINE "HWY_SHARED_DEFINE")
211+
else()
212+
set(DLLEXPORT_TO_DEFINE "HWY_STATIC_DEFINE")
213+
endif()
203214

204215
add_library(hwy ${HWY_SOURCES})
216+
target_compile_definitions(hwy PUBLIC "${DLLEXPORT_TO_DEFINE}")
205217
target_compile_options(hwy PRIVATE ${HWY_FLAGS})
206218
set_property(TARGET hwy PROPERTY POSITION_INDEPENDENT_CODE ON)
207219
set_target_properties(hwy PROPERTIES VERSION ${LIBRARY_VERSION} SOVERSION ${LIBRARY_SOVERSION})
208220
target_include_directories(hwy PUBLIC ${CMAKE_CURRENT_LIST_DIR})
209221
target_compile_features(hwy PUBLIC cxx_std_11)
210222

211223
add_library(hwy_contrib ${HWY_CONTRIB_SOURCES})
224+
target_link_libraries(hwy_contrib hwy)
212225
target_compile_options(hwy_contrib PRIVATE ${HWY_FLAGS})
213226
set_property(TARGET hwy_contrib PROPERTY POSITION_INDEPENDENT_CODE ON)
214227
set_target_properties(hwy_contrib PROPERTIES VERSION ${LIBRARY_VERSION} SOVERSION ${LIBRARY_SOVERSION})
215228
target_include_directories(hwy_contrib PUBLIC ${CMAKE_CURRENT_LIST_DIR})
216229
target_compile_features(hwy_contrib PUBLIC cxx_std_11)
217230

218231
add_library(hwy_test ${HWY_TEST_SOURCES})
232+
target_link_libraries(hwy_test hwy)
219233
target_compile_options(hwy_test PRIVATE ${HWY_FLAGS})
220234
set_property(TARGET hwy_test PROPERTY POSITION_INDEPENDENT_CODE ON)
221235
set_target_properties(hwy_test PROPERTIES VERSION ${LIBRARY_VERSION} SOVERSION ${LIBRARY_SOVERSION})

hwy/aligned_allocator.h

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,11 @@
1818
// Memory allocator with support for alignment and offsets.
1919

2020
#include <stddef.h>
21+
2122
#include <memory>
2223

24+
#include "hwy/highway_export.h"
25+
2326
namespace hwy {
2427

2528
// Minimum alignment of allocated memory for use in HWY_ASSUME_ALIGNED, which
@@ -36,15 +39,15 @@ using FreePtr = void (*)(void* opaque, void* memory);
3639
// bytes of newly allocated memory, aligned to the larger of HWY_ALIGNMENT and
3740
// the vector size. Calls `alloc` with the passed `opaque` pointer to obtain
3841
// memory or malloc() if it is null.
39-
void* AllocateAlignedBytes(size_t payload_size, AllocPtr alloc_ptr,
40-
void* opaque_ptr);
42+
HWY_DLLEXPORT void* AllocateAlignedBytes(size_t payload_size,
43+
AllocPtr alloc_ptr, void* opaque_ptr);
4144

4245
// Frees all memory. No effect if `aligned_pointer` == nullptr, otherwise it
4346
// must have been returned from a previous call to `AllocateAlignedBytes`.
4447
// Calls `free_ptr` with the passed `opaque_ptr` pointer to free the memory; if
4548
// `free_ptr` function is null, uses the default free().
46-
void FreeAlignedBytes(const void* aligned_pointer, FreePtr free_ptr,
47-
void* opaque_ptr);
49+
HWY_DLLEXPORT void FreeAlignedBytes(const void* aligned_pointer,
50+
FreePtr free_ptr, void* opaque_ptr);
4851

4952
// Class that deletes the aligned pointer passed to operator() calling the
5053
// destructor before freeing the pointer. This is equivalent to the
@@ -76,8 +79,10 @@ class AlignedDeleter {
7679
// array. TypeArrayDeleter<T> would match this prototype.
7780
using ArrayDeleter = void (*)(void* t_ptr, size_t t_size);
7881

79-
static void DeleteAlignedArray(void* aligned_pointer, FreePtr free_ptr,
80-
void* opaque_ptr, ArrayDeleter deleter);
82+
HWY_DLLEXPORT static void DeleteAlignedArray(void* aligned_pointer,
83+
FreePtr free_ptr,
84+
void* opaque_ptr,
85+
ArrayDeleter deleter);
8186

8287
FreePtr free_;
8388
void* opaque_ptr_;
@@ -107,8 +112,8 @@ template <typename T, typename... Args>
107112
AlignedUniquePtr<T> MakeUniqueAligned(Args&&... args) {
108113
T* ptr = static_cast<T*>(AllocateAlignedBytes(
109114
sizeof(T), /*alloc_ptr=*/nullptr, /*opaque_ptr=*/nullptr));
110-
return AlignedUniquePtr<T>(
111-
new (ptr) T(std::forward<Args>(args)...), AlignedDeleter());
115+
return AlignedUniquePtr<T>(new (ptr) T(std::forward<Args>(args)...),
116+
AlignedDeleter());
112117
}
113118

114119
// Helpers for array allocators (avoids overflow)

hwy/base.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <cfloat>
2525

2626
#include "hwy/detect_compiler_arch.h"
27+
#include "hwy/highway_export.h"
2728

2829
//------------------------------------------------------------------------------
2930
// Compiler-specific definitions
@@ -728,7 +729,7 @@ HWY_API bfloat16_t BF16FromF32(float f) {
728729
return bf;
729730
}
730731

731-
HWY_NORETURN void HWY_FORMAT(3, 4)
732+
HWY_DLLEXPORT HWY_NORETURN void HWY_FORMAT(3, 4)
732733
Abort(const char* file, int line, const char* format, ...);
733734

734735
} // namespace hwy

hwy/contrib/image/image.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,13 @@
2727

2828
#include "hwy/aligned_allocator.h"
2929
#include "hwy/base.h"
30+
#include "hwy/highway_export.h"
3031

3132
namespace hwy {
3233

3334
// Type-independent parts of Image<> - reduces code duplication and facilitates
3435
// moving member function implementations to cc file.
35-
struct ImageBase {
36+
struct HWY_DLLEXPORT ImageBase {
3637
// Returns required alignment in bytes for externally allocated memory.
3738
static size_t VectorSize();
3839

hwy/highway_export.h

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Pseudo-generated file to handle both cmake & bazel build system.
2+
3+
// Initial generation done using cmake code:
4+
// include(GenerateExportHeader)
5+
// generate_export_header(hwy EXPORT_MACRO_NAME HWY_DLLEXPORT EXPORT_FILE_NAME
6+
// hwy/highway_export.h)
7+
// code reformatted using clang-format --style=Google
8+
9+
#ifndef HWY_DLLEXPORT_H
10+
#define HWY_DLLEXPORT_H
11+
12+
#ifdef HWY_STATIC_DEFINE
13+
#define HWY_DLLEXPORT
14+
#define HWY_NO_EXPORT
15+
#else
16+
#ifndef HWY_DLLEXPORT
17+
#if defined(hwy_EXPORTS) || defined(hwy_contrib_EXPORTS) || defined(hwy_test_EXPORTS)
18+
/* We are building this library */
19+
#ifdef _WIN32
20+
#define HWY_DLLEXPORT __declspec(dllexport)
21+
#else
22+
#define HWY_DLLEXPORT __attribute__((visibility("default")))
23+
#endif
24+
#else
25+
/* We are using this library */
26+
#ifdef _WIN32
27+
#define HWY_DLLEXPORT __declspec(dllimport)
28+
#else
29+
#define HWY_DLLEXPORT __attribute__((visibility("default")))
30+
#endif
31+
#endif
32+
#endif
33+
34+
#ifndef HWY_NO_EXPORT
35+
#ifdef _WIN32
36+
#define HWY_NO_EXPORT
37+
#else
38+
#define HWY_NO_EXPORT __attribute__((visibility("hidden")))
39+
#endif
40+
#endif
41+
#endif
42+
43+
#endif /* HWY_DLLEXPORT_H */

hwy/nanobenchmark.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@
4747
#include <stddef.h>
4848
#include <stdint.h>
4949

50+
#include "hwy/highway_export.h"
51+
5052
// Enables sanity checks that verify correct operation at the cost of
5153
// longer benchmark runs.
5254
#ifndef NANOBENCHMARK_ENABLE_CHECKS
@@ -88,7 +90,7 @@ uint64_t TimerResolution();
8890

8991
// Returns 1, but without the compiler knowing what the value is. This prevents
9092
// optimizing out code.
91-
int Unpredictable1();
93+
HWY_DLLEXPORT int Unpredictable1();
9294

9395
// Input influencing the function being measured (e.g. number of bytes to copy).
9496
using FuncInput = size_t;
@@ -164,9 +166,9 @@ struct Result {
164166
// uniform distribution over [0, 4) could be represented as {3,0,2,1}.
165167
// Returns how many Result were written to "results": one per unique input, or
166168
// zero if the measurement failed (an error message goes to stderr).
167-
size_t Measure(const Func func, const uint8_t* arg, const FuncInput* inputs,
168-
const size_t num_inputs, Result* results,
169-
const Params& p = Params());
169+
HWY_DLLEXPORT size_t Measure(const Func func, const uint8_t* arg,
170+
const FuncInput* inputs, const size_t num_inputs,
171+
Result* results, const Params& p = Params());
170172

171173
// Calls operator() of the given closure (lambda function).
172174
template <class Closure>

hwy/targets.h

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,15 @@
2222

2323
#include "hwy/base.h"
2424
#include "hwy/detect_targets.h"
25+
#include "hwy/highway_export.h"
2526

2627
namespace hwy {
2728

2829
// Returns (cached) bitfield of enabled targets that are supported on this CPU.
2930
// Implemented in targets.cc; unconditionally compiled to support the use case
3031
// of binary-only distributions. The HWY_SUPPORTED_TARGETS wrapper may allow
3132
// eliding calls to this function.
32-
uint32_t SupportedTargets();
33+
HWY_DLLEXPORT uint32_t SupportedTargets();
3334

3435
// Evaluates to a function call, or literal if there is a single target.
3536
#if (HWY_TARGETS & (HWY_TARGETS - 1)) == 0
@@ -44,19 +45,19 @@ uint32_t SupportedTargets();
4445
// lower target is desired. For this reason, attempts to disable targets which
4546
// are in HWY_ENABLED_BASELINE have no effect so SupportedTargets() always
4647
// returns at least the baseline target.
47-
void DisableTargets(uint32_t disabled_targets);
48+
HWY_DLLEXPORT void DisableTargets(uint32_t disabled_targets);
4849

4950
// Set the mock mask of CPU supported targets instead of the actual CPU
5051
// supported targets computed in SupportedTargets(). The return value of
5152
// SupportedTargets() will still be affected by the DisableTargets() mask
5253
// regardless of this mock, to prevent accidentally adding targets that are
5354
// known to be buggy in the current CPU. Call with a mask of 0 to disable the
5455
// mock and use the actual CPU supported targets instead.
55-
void SetSupportedTargetsForTest(uint32_t targets);
56+
HWY_DLLEXPORT void SetSupportedTargetsForTest(uint32_t targets);
5657

5758
// Returns whether the SupportedTargets() function was called since the last
5859
// SetSupportedTargetsForTest() call.
59-
bool SupportedTargetsCalledForTest();
60+
HWY_DLLEXPORT bool SupportedTargetsCalledForTest();
6061

6162
// Return the list of targets in HWY_TARGETS supported by the CPU as a list of
6263
// individual HWY_* target macros such as HWY_SCALAR or HWY_NEON. This list
@@ -225,7 +226,7 @@ struct ChosenTarget {
225226
public:
226227
// Update the ChosenTarget mask based on the current CPU supported
227228
// targets.
228-
void Update();
229+
HWY_DLLEXPORT void Update();
229230

230231
// Reset the ChosenTarget to the uninitialized state.
231232
void DeInit() { mask_.store(1); }
@@ -249,7 +250,7 @@ struct ChosenTarget {
249250
std::atomic<uint32_t> mask_{1};
250251
};
251252

252-
extern ChosenTarget chosen_target;
253+
HWY_DLLEXPORT extern ChosenTarget chosen_target;
253254

254255
} // namespace hwy
255256

hwy/tests/test_util.h

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "hwy/aligned_allocator.h"
3030
#include "hwy/base.h"
3131
#include "hwy/highway.h"
32+
#include "hwy/highway_export.h"
3233

3334
namespace hwy {
3435

@@ -70,9 +71,7 @@ static HWY_INLINE uint32_t Random32(RandomState* rng) {
7071
return static_cast<uint32_t>((*rng)());
7172
}
7273

73-
static HWY_INLINE uint64_t Random64(RandomState* rng) {
74-
return (*rng)();
75-
}
74+
static HWY_INLINE uint64_t Random64(RandomState* rng) { return (*rng)(); }
7675

7776
// Prevents the compiler from eliding the computations that led to "output".
7877
// Works by indicating to the compiler that "output" is being read and modified.
@@ -87,8 +86,8 @@ inline void PreventElision(T&& output) {
8786
#endif // HWY_COMPILER_MSVC
8887
}
8988

90-
bool BytesEqual(const void* p1, const void* p2, const size_t size,
91-
size_t* pos = nullptr);
89+
HWY_DLLEXPORT bool BytesEqual(const void* p1, const void* p2, const size_t size,
90+
size_t* pos = nullptr);
9291

9392
void AssertStringEqual(const char* expected, const char* actual,
9493
const char* target_name, const char* filename, int line);
@@ -132,25 +131,25 @@ HWY_INLINE TypeInfo MakeTypeInfo() {
132131
return info;
133132
}
134133

135-
bool IsEqual(const TypeInfo& info, const void* expected_ptr,
136-
const void* actual_ptr);
134+
HWY_DLLEXPORT bool IsEqual(const TypeInfo& info, const void* expected_ptr,
135+
const void* actual_ptr);
137136

138-
void TypeName(const TypeInfo& info, size_t N, char* string100);
137+
HWY_DLLEXPORT void TypeName(const TypeInfo& info, size_t N, char* string100);
139138

140-
void PrintArray(const TypeInfo& info, const char* caption,
141-
const void* array_void, size_t N, size_t lane_u = 0,
142-
size_t max_lanes = 7);
139+
HWY_DLLEXPORT void PrintArray(const TypeInfo& info, const char* caption,
140+
const void* array_void, size_t N,
141+
size_t lane_u = 0, size_t max_lanes = 7);
143142

144-
HWY_NORETURN void PrintMismatchAndAbort(const TypeInfo& info,
145-
const void* expected_ptr,
146-
const void* actual_ptr,
147-
const char* target_name,
148-
const char* filename, int line,
149-
size_t lane = 0, size_t num_lanes = 1);
143+
HWY_DLLEXPORT HWY_NORETURN void PrintMismatchAndAbort(
144+
const TypeInfo& info, const void* expected_ptr, const void* actual_ptr,
145+
const char* target_name, const char* filename, int line, size_t lane = 0,
146+
size_t num_lanes = 1);
150147

151-
void AssertArrayEqual(const TypeInfo& info, const void* expected_void,
152-
const void* actual_void, size_t N,
153-
const char* target_name, const char* filename, int line);
148+
HWY_DLLEXPORT void AssertArrayEqual(const TypeInfo& info,
149+
const void* expected_void,
150+
const void* actual_void, size_t N,
151+
const char* target_name,
152+
const char* filename, int line);
154153

155154
} // namespace detail
156155

libhwy.pc.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@ Name: libhwy
77
Description: Efficient and performance-portable SIMD wrapper
88
Version: @HWY_LIBRARY_VERSION@
99
Libs: -L${libdir} -lhwy
10-
Cflags: -I${includedir}
10+
Cflags: -I${includedir} -D@DLLEXPORT_TO_DEFINE@

0 commit comments

Comments
 (0)