Skip to content

Commit ff5a015

Browse files
committed
Add BUILD_SHARED_LIBS support (fix dacap#23)
1 parent 99da25e commit ff5a015

File tree

10 files changed

+140
-62
lines changed

10 files changed

+140
-62
lines changed

.github/workflows/build.yml

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ jobs:
77
fail-fast: false
88
matrix:
99
os: [windows-latest, macos-latest, ubuntu-latest]
10-
enable_image: [on, off]
10+
sanitize: [address, none]
11+
shared: [shared, static]
12+
enable_image: [with_image, text_only]
1113
steps:
1214
- uses: actions/checkout@v4
1315
- uses: ilammy/msvc-dev-cmd@v1
@@ -21,14 +23,39 @@ jobs:
2123
- name: Generating Makefiles
2224
shell: bash
2325
run: |
26+
if [[ "${{ matrix.shared }}" == "shared" ]] ; then
27+
shared=on
28+
else
29+
shared=off
30+
fi
31+
if [[ "${{ matrix.enable_image }}" == "with_image" ]] ; then
32+
with_image=on
33+
else
34+
with_image=off
35+
fi
2436
if [[ "${{ runner.os }}" == "Windows" ]] ; then
25-
cmake . -G "NMake Makefiles" \
26-
-DCLIP_ENABLE_IMAGE=${{ matrix.enable_image }} \
27-
"-DCMAKE_CXX_FLAGS:STRING=-DWIN32 -D_WINDOWS -GR -EHsc -fsanitize=address" \
28-
"-DCMAKE_EXE_LINKER_FLAGS:STRING=-machine:x64 -fsanitize=address"
37+
if [[ "${{ runner.sanitize }}" == "address" ]] ; then
38+
cmake . -G "NMake Makefiles" \
39+
-DCLIP_ENABLE_IMAGE=${{ matrix.enable_image }} \
40+
"-DCMAKE_CXX_FLAGS:STRING=-DWIN32 -D_WINDOWS -GR -EHsc -fsanitize=address" \
41+
"-DCMAKE_EXE_LINKER_FLAGS:STRING=-machine:x64 -fsanitize=address"
42+
else
43+
cmake . -G "NMake Makefiles" \
44+
-DCLIP_ENABLE_IMAGE=${{ matrix.enable_image }} \
45+
-DBUILD_SHARED_LIBS=$shared
46+
fi
2947
else
30-
cmake . -G "Unix Makefiles" \
31-
-DCLIP_ENABLE_IMAGE=${{ matrix.enable_image }}
48+
if [[ "${{ runner.sanitize }}" == "address" ]] ; then
49+
cmake . -G "Unix Makefiles" \
50+
-DCLIP_ENABLE_IMAGE=${{ matrix.enable_image }} \
51+
"-DCMAKE_CXX_FLAGS:STRING=-fsanitize=address" \
52+
"-DCMAKE_EXE_LINKER_FLAGS:STRING=-fsanitize=address" \
53+
-DBUILD_SHARED_LIBS=$shared
54+
else
55+
cmake . -G "Unix Makefiles" \
56+
"-DCLIP_ENABLE_IMAGE=$with_image" \
57+
-DBUILD_SHARED_LIBS=$shared
58+
fi
3259
fi
3360
- name: Compiling
3461
shell: bash

CMakeLists.txt

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
# Clip Library
2-
# Copyright (c) 2015-2025 David Capello
2+
# Copyright (c) 2015-2026 David Capello
33

44
cmake_minimum_required(VERSION 3.15)
55

66
project(clip LANGUAGES CXX)
77

88
set(CMAKE_CXX_STANDARD 11)
99
set(CMAKE_CXX_STANDARD_REQUIRED ON)
10-
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
1110

1211
if(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
1312
# Use libc++ explicitly so we can compile for
1413
# CMAKE_OSX_DEPLOYMENT_TARGET=10.7 or 10.8
1514
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
1615
endif()
1716

17+
option(BUILD_SHARED_LIBS "Build clip as a shared library" off)
1818
option(CLIP_ENABLE_IMAGE "Compile with support to copy/paste images" on)
1919
if(WIN32)
2020
option(CLIP_ENABLE_LIST_FORMATS "Compile with support to list clipboard formats" off)
@@ -29,6 +29,10 @@ endif()
2929
add_library(clip clip.cpp)
3030

3131
target_include_directories(clip INTERFACE $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
32+
target_compile_definitions(clip PRIVATE -DCLIP_BUILDING_LIB=1)
33+
if(BUILD_SHARED_LIBS)
34+
target_compile_definitions(clip PUBLIC -DCLIP_SHARED=1)
35+
endif()
3236

3337
if(CLIP_ENABLE_IMAGE)
3438
target_sources(clip PRIVATE image.cpp)
@@ -102,11 +106,27 @@ endif()
102106

103107
if(CLIP_EXAMPLES)
104108
add_subdirectory(examples)
109+
if(WIN32 AND BUILD_SHARED_LIBS)
110+
add_custom_command(
111+
TARGET clip
112+
BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/examples/clip.dll
113+
POST_BUILD
114+
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:clip> ${CMAKE_CURRENT_BINARY_DIR}/examples
115+
COMMENT "Copy DLL to examples directory")
116+
endif()
105117
endif()
106118

107119
if(CLIP_TESTS)
108120
enable_testing()
109121
add_subdirectory(tests)
122+
if(WIN32 AND BUILD_SHARED_LIBS)
123+
add_custom_command(
124+
TARGET clip
125+
BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/tests/clip.dll
126+
POST_BUILD
127+
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:clip> ${CMAKE_CURRENT_BINARY_DIR}/tests
128+
COMMENT "Copy DLL to tests directory")
129+
endif()
110130
endif()
111131

112132
if(CLIP_INSTALL)

LICENSE.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Copyright (c) 2015-2025 David Capello
1+
Copyright (c) 2015-2026 David Capello
22

33
Permission is hereby granted, free of charge, to any person obtaining
44
a copy of this software and associated documentation files (the

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Clip Library
2-
*Copyright (c) 2015-2025 David Capello*
2+
*Copyright (c) 2015-2026 David Capello*
33

44
[![build](https://github.com/dacap/clip/workflows/build/badge.svg)](https://github.com/dacap/clip/actions?query=workflow%3Abuild)
55
[![MIT Licensed](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE.txt)

clip.h

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// Clip Library
2-
// Copyright (c) 2015-2024 David Capello
2+
// Copyright (c) 2015-2026 David Capello
33
//
44
// This file is released under the terms of the MIT license.
55
// Read LICENSE.txt for more information.
@@ -13,6 +13,8 @@
1313
#include <string>
1414
#include <vector>
1515

16+
#include "clip_base.h"
17+
1618
namespace clip {
1719

1820
// ======================================================================
@@ -28,7 +30,7 @@ namespace clip {
2830
#endif // CLIP_ENABLE_IMAGE
2931

3032
#if CLIP_ENABLE_LIST_FORMATS
31-
struct format_info {
33+
struct CLIP_EXTERN format_info {
3234
format id = 0;
3335
std::string name;
3436
format_info(const format id,
@@ -39,7 +41,7 @@ namespace clip {
3941
};
4042
#endif // CLIP_ENABLE_LIST_FORMATS
4143

42-
class lock {
44+
class CLIP_EXTERN lock {
4345
public:
4446
// You can give your current HWND as the "native_window_handle."
4547
// Windows clipboard functions use this handle to open/close
@@ -84,24 +86,24 @@ namespace clip {
8486
std::unique_ptr<impl> p;
8587
};
8688

87-
format register_format(const std::string& name);
89+
CLIP_EXTERN format register_format(const std::string& name);
8890

8991
// This format is when the clipboard has no content.
90-
format empty_format();
92+
CLIP_EXTERN format empty_format();
9193

9294
// When the clipboard has UTF8 text.
93-
format text_format();
95+
CLIP_EXTERN format text_format();
9496

9597
#if CLIP_ENABLE_IMAGE
9698
// When the clipboard has an image.
97-
format image_format();
99+
CLIP_EXTERN format image_format();
98100
#endif
99101

100102
// Returns true if the clipboard has content of the given type.
101-
bool has(format f);
103+
CLIP_EXTERN bool has(format f);
102104

103105
// Clears the clipboard content.
104-
bool clear();
106+
CLIP_EXTERN bool clear();
105107

106108
// ======================================================================
107109
// Error handling
@@ -116,25 +118,25 @@ namespace clip {
116118

117119
typedef void (*error_handler)(ErrorCode code);
118120

119-
void set_error_handler(error_handler f);
120-
error_handler get_error_handler();
121+
CLIP_EXTERN void set_error_handler(error_handler f);
122+
CLIP_EXTERN error_handler get_error_handler();
121123

122124
// ======================================================================
123125
// Text
124126
// ======================================================================
125127

126128
// High-level API to put/get UTF8 text in/from the clipboard. These
127129
// functions returns false in case of error.
128-
bool set_text(const std::string& value);
129-
bool get_text(std::string& value);
130+
CLIP_EXTERN bool set_text(const std::string& value);
131+
CLIP_EXTERN bool get_text(std::string& value);
130132

131133
// ======================================================================
132134
// Image
133135
// ======================================================================
134136

135137
#if CLIP_ENABLE_IMAGE
136138

137-
struct image_spec {
139+
struct CLIP_EXTERN image_spec {
138140
unsigned long width = 0;
139141
unsigned long height = 0;
140142
unsigned long bits_per_pixel = 0;
@@ -161,7 +163,7 @@ namespace clip {
161163
// automatically. macOS handles straight alpha directly, so there is
162164
// no conversion at all. Linux/X11 images are transferred in
163165
// image/png format which are specified in straight alpha.
164-
class image {
166+
class CLIP_EXTERN image {
165167
public:
166168
image();
167169
image(const image_spec& spec);
@@ -190,9 +192,9 @@ namespace clip {
190192

191193
// High-level API to set/get an image in/from the clipboard. These
192194
// functions returns false in case of error.
193-
bool set_image(const image& img);
194-
bool get_image(image& img);
195-
bool get_image_spec(image_spec& spec);
195+
CLIP_EXTERN bool set_image(const image& img);
196+
CLIP_EXTERN bool get_image(image& img);
197+
CLIP_EXTERN bool get_image_spec(image_spec& spec);
196198

197199
#endif // CLIP_ENABLE_IMAGE
198200

@@ -203,8 +205,8 @@ namespace clip {
203205
// Only for X11: Sets the time (in milliseconds) that we must wait
204206
// for the selection/clipboard owner to receive the content. This
205207
// value is 1000 (one second) by default.
206-
void set_x11_wait_timeout(int msecs);
207-
int get_x11_wait_timeout();
208+
CLIP_EXTERN void set_x11_wait_timeout(int msecs);
209+
CLIP_EXTERN int get_x11_wait_timeout();
208210

209211
} // namespace clip
210212

clip_base.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Clip Library
2+
// Copyright (C) 2026 David Capello
3+
//
4+
// This file is released under the terms of the MIT license.
5+
// Read LICENSE.txt for more information.
6+
7+
#ifndef CLIP_BASE_H_INCLUDED
8+
#define CLIP_BASE_H_INCLUDED
9+
#pragma once
10+
11+
#if defined(_WIN32) && defined(CLIP_SHARED)
12+
#ifdef CLIP_BUILDING_LIB
13+
#define CLIP_EXTERN __declspec(dllexport)
14+
#else
15+
#define CLIP_EXTERN __declspec(dllimport)
16+
#endif
17+
#else
18+
#define CLIP_EXTERN
19+
#endif
20+
21+
#endif // CLIP_H_INCLUDED

clip_osx.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// Clip Library
2-
// Copyright (c) 2024 David Capello
2+
// Copyright (c) 2024-2026 David Capello
33
//
44
// This file is released under the terms of the MIT license.
55
// Read LICENSE.txt for more information.
@@ -12,6 +12,8 @@
1212

1313
#include <Cocoa/Cocoa.h>
1414

15+
#include "clip_base.h"
16+
1517
namespace clip {
1618

1719
class image;
@@ -21,9 +23,9 @@ namespace osx {
2123

2224
#if CLIP_ENABLE_IMAGE
2325

24-
bool get_image_from_clipboard(NSPasteboard* pasteboard,
25-
image* output_img,
26-
image_spec* output_spec);
26+
CLIP_EXTERN bool get_image_from_clipboard(NSPasteboard* pasteboard,
27+
image* output_img,
28+
image_spec* output_spec);
2729

2830
#endif // CLIP_ENABLE_IMAGE
2931

clip_win_bmp.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// Clip Library
2-
// Copyright (c) 2015-2025 David Capello
2+
// Copyright (c) 2015-2026 David Capello
33
//
44
// This file is released under the terms of the MIT license.
55
// Read LICENSE.txt for more information.
@@ -16,14 +16,16 @@
1616

1717
#include <windows.h>
1818

19+
#include "clip_base.h"
20+
1921
namespace clip {
2022

2123
class image;
2224
struct image_spec;
2325

2426
namespace win {
2527

26-
struct BitmapInfo {
28+
struct CLIP_EXTERN BitmapInfo {
2729
BITMAPV5HEADER* b5 = nullptr;
2830
BITMAPINFO* bi = nullptr;
2931
int width = 0;
@@ -60,7 +62,7 @@ struct BitmapInfo {
6062
// Returns a handle to the HGLOBAL memory reserved to create a DIBV5
6163
// based on the image passed by parameter. Returns null if it cannot
6264
// create the handle.
63-
HGLOBAL create_dibv5(const image& image);
65+
CLIP_EXTERN HGLOBAL create_dibv5(const image& image);
6466

6567
} // namespace win
6668
} // namespace clip

clip_win_hglobal.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// Clip Library
2-
// Copyright (c) 2025 David Capello
2+
// Copyright (c) 2025-2026 David Capello
33
//
44
// This file is released under the terms of the MIT license.
55
// Read LICENSE.txt for more information.
@@ -12,11 +12,13 @@
1212

1313
#include <algorithm>
1414

15+
#include "clip_base.h"
16+
1517
namespace clip {
1618
namespace win {
1719

1820
// Scoped GlobalLock / GlobalUnlock wrapper
19-
class HglobalLock {
21+
class CLIP_EXTERN HglobalLock {
2022
public:
2123
HglobalLock() = delete;
2224
HglobalLock(const HglobalLock& other) = delete;
@@ -53,7 +55,7 @@ class HglobalLock {
5355
};
5456

5557
// Scoped GlobalAlloc / GlobalFree wrapper
56-
class Hglobal {
58+
class CLIP_EXTERN Hglobal {
5759
public:
5860
Hglobal() : m_handle(nullptr) {
5961
}

0 commit comments

Comments
 (0)