Skip to content

Commit d1fa6d1

Browse files
committed
Initial support for Apple Frameworks
1 parent 4c197bf commit d1fa6d1

File tree

6 files changed

+97
-5
lines changed

6 files changed

+97
-5
lines changed

.github/workflows/cppcmake.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ jobs:
3939
- {name: "ubuntu-24.04", os: "ubuntu-24.04", cmake_extra: "-DLSL_BUNDLED_PUGIXML=OFF" }
4040
- {name: "windows-x64", os: "windows-latest", cmake_extra: "-T v142,host=x86"}
4141
- {name: "windows-32", os: "windows-latest", cmake_extra: "-T v142,host=x86 -A Win32"}
42-
- {name: "macOS-latest", os: "macOS-latest", cmake_extra: "-DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 -DCMAKE_OSX_ARCHITECTURES=x86_64;arm64 DCMAKE_SYSTEM_NAME=Darwin -G Xcode" }
42+
- {name: "macOS-latest", os: "macOS-latest", cmake_extra: "-DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 -DCMAKE_OSX_ARCHITECTURES=x86_64;arm64 DCMAKE_SYSTEM_NAME=Darwin -DLSL_FRAMEWORK=ON -G Xcode" }
4343

4444
# runs all steps in the container configured in config.docker or as subprocesses when empty
4545
container: ${{ matrix.config.docker }}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# This script is executed at install time.
2+
# It was generated from CreateFrameworkSymlinks.cmake.in
3+
4+
set(FRAMEWORK_DIR "${CMAKE_INSTALL_PREFIX}/@CMAKE_INSTALL_FRAMEWORK_DIR@/lsl.framework")
5+
6+
message(STATUS "Executing configured symlink script.")
7+
message(STATUS " -- Target Directory='${FRAMEWORK_DIR}'")
8+
9+
if(NOT EXISTS "${FRAMEWORK_DIR}")
10+
message(FATAL_ERROR "Framework version directory does not exist. Cannot create symlink.")
11+
endif()
12+
13+
message(STATUS " -- Framework version directory exists. Creating symlink...")
14+
15+
execute_process(
16+
COMMAND ln -sf include Headers
17+
WORKING_DIRECTORY "${FRAMEWORK_DIR}/Versions/A"
18+
RESULT_VARIABLE result
19+
ERROR_VARIABLE error
20+
)
21+
if(NOT result EQUAL 0)
22+
message(FATAL_ERROR "Failed to create Headers->include symlink: ${error}")
23+
endif()
24+
25+
execute_process(
26+
COMMAND ln -sf Versions/Current/Headers
27+
WORKING_DIRECTORY "${FRAMEWORK_DIR}"
28+
RESULT_VARIABLE result
29+
ERROR_VARIABLE error
30+
)
31+
if(NOT result EQUAL 0)
32+
message(FATAL_ERROR "Failed to create <root>Headers->Versions/Current/Headers symlink: ${error}")
33+
endif()
34+
35+
if(NOT result EQUAL 0)
36+
message(FATAL_ERROR "Failed to create Headers symlink in framework: ${error}")
37+
endif()
38+
39+
message(STATUS " -- Framework symlink created successfully.")

cmake/Installation.cmake

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,22 @@ include(CMakePackageConfigHelpers)
44
# Paths
55
if(LSL_UNIXFOLDERS)
66
include(GNUInstallDirs)
7+
set(CMAKE_INSTALL_FRAMEWORK_DIR Library/Frameworks CACHE PATH "Install directory for frameworks on macOS")
78
else()
89
set(CMAKE_INSTALL_BINDIR LSL)
910
set(CMAKE_INSTALL_LIBDIR LSL)
1011
set(CMAKE_INSTALL_INCLUDEDIR LSL/include)
12+
set(CMAKE_INSTALL_FRAMEWORK_DIR LSL/Frameworks CACHE PATH "Install directory for frameworks on macOS")
13+
endif()
14+
15+
# For Apple frameworks, we need to next the install directories within the framework.
16+
if(APPLE AND LSL_FRAMEWORK)
17+
# For the includes, this is insufficient. Later we will create more accessible symlinks.
18+
set(LSL_INSTALL_INCLUDEDIR ${CMAKE_INSTALL_FRAMEWORK_DIR}/lsl.framework/Versions/A/include)
19+
set(LSL_CONFIG_INSTALL_DIR ${CMAKE_INSTALL_FRAMEWORK_DIR}/lsl.framework/Resources/CMake)
20+
else()
21+
set(LSL_INSTALL_INCLUDEDIR ${CMAKE_INSTALL_INCLUDEDIR})
22+
set(LSL_CONFIG_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/lsl)
1123
endif()
1224

1325
# Generate a version file for the package.
@@ -27,20 +39,20 @@ install(TARGETS ${LSLTargets}
2739
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
2840
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
2941
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
30-
FILE_SET HEADERS DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
42+
FILE_SET HEADERS DESTINATION ${LSL_INSTALL_INCLUDEDIR}
3143
)
3244

3345
# Generate the LSLConfig.cmake file and mark it for installation
3446
install(EXPORT LSLTargets
3547
FILE LSLConfig.cmake
3648
COMPONENT liblsl
3749
NAMESPACE "LSL::"
38-
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/LSL
50+
DESTINATION ${LSL_CONFIG_INSTALL_DIR}
3951
)
4052
# A common alternative to installing the exported package config file is to generate it from a template.
4153
#configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/lslConfig.cmake.in
4254
# ${CMAKE_CURRENT_BINARY_DIR}/LSLConfig.cmake
43-
# INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/lsl)
55+
# INSTALL_DESTINATION ${LSL_CONFIG_INSTALL_DIR})
4456
# If we use this method, then we need a corresponding install(FILES ...) command to install the generated file.
4557

4658
# Install the version file and the helper CMake script.
@@ -49,5 +61,17 @@ install(
4961
cmake/LSLCMake.cmake
5062
${CMAKE_CURRENT_BINARY_DIR}/LSLConfigVersion.cmake
5163
COMPONENT liblsl
52-
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/LSL
64+
DESTINATION ${LSL_CONFIG_INSTALL_DIR}
5365
)
66+
67+
if(APPLE AND LSL_FRAMEWORK)
68+
# Create symlinks for the framework. The variables we want to use to identify the symlink locations
69+
# are not available at install time. Instead, we create a script during configuration time that will
70+
# be run at install time to create the symlinks.
71+
configure_file(
72+
${CMAKE_CURRENT_SOURCE_DIR}/cmake/CreateFrameworkSymlinks.cmake.in
73+
${CMAKE_CURRENT_BINARY_DIR}/CreateFrameworkSymlinks.cmake
74+
@ONLY
75+
)
76+
install(SCRIPT ${CMAKE_CURRENT_BINARY_DIR}/CreateFrameworkSymlinks.cmake COMPONENT liblsl)
77+
endif()

cmake/ProjectOptions.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
option(LSL_DEBUGLOG "Enable (lots of) additional debug messages" OFF)
33
option(LSL_UNIXFOLDERS "Use the unix folder layout for install targets" ON)
44
option(LSL_BUILD_STATIC "Build LSL as a static library." OFF)
5+
option(LSL_FRAMEWORK "Build LSL as an Apple Framework (Mac only)" ON)
56
option(LSL_LEGACY_CPP_ABI "Build legacy C++ ABI into lsl-static" OFF)
67
option(LSL_OPTIMIZATIONS "Enable some more compiler optimizations" ON)
78
option(LSL_BUNDLED_BOOST "Use the bundled Boost by default" ON)

cmake/TargetLib.cmake

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,15 @@ if(APPLE)
6666
XCODE_ATTRIBUTE_OTHER_CODE_SIGN_FLAGS "--deep"
6767
)
6868
endif()
69+
# Configure Apple Framework
70+
if(LSL_FRAMEWORK)
71+
set_target_properties(lsl PROPERTIES
72+
FRAMEWORK TRUE
73+
FRAMEWORK_VERSION A
74+
MACOSX_FRAMEWORK_IDENTIFIER "org.labstreaminglayer.liblsl"
75+
MACOSX_FRAMEWORK_SHORT_VERSION_STRING "${liblsl_VERSION_MAJOR}.${liblsl_VERSION_MINOR}"
76+
MACOSX_FRAMEWORK_BUNDLE_VERSION ${PROJECT_VERSION}
77+
XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS "${CMAKE_CURRENT_SOURCE_DIR}/lsl.entitlements"
78+
)
79+
endif(LSL_FRAMEWORK)
6980
endif(APPLE)

lsl.entitlements

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<!-- Required for allowing outgoing network connections (TCP and UDP). -->
6+
<key>com.apple.security.network.client</key>
7+
<true/>
8+
9+
<!-- Required for allowing your framework to listen for incoming connections. -->
10+
<key>com.apple.security.network.server</key>
11+
<true/>
12+
13+
<!-- Specifically required for sending and receiving UDP multicast traffic used in stream advertising. -->
14+
<key>com.apple.security.network.multicast</key>
15+
<true/>
16+
</dict>
17+
</plist>

0 commit comments

Comments
 (0)