Skip to content

Commit 52225e1

Browse files
committed
Add macOS packaging, CMake/linking, config path
Add macOS packaging and notarization support (Info.plist template, entitlements, packaging script that builds .app and signed/.notarized DMG). Improve CMake handling: bump project version to 2.7.5, better detection and linking for freetype/openjph/pugixml/uhdr/bzip2, add helper solidify_link_oiio_static_tail, handle dnd_glfw macOS target or source file, and tidy platform-specific link logic. Implement config path resolution (resolveConfigPath + configPathFromExecutable) and expose settingsConfigPath so the app loads sldf_config.toml from application bundle or executable location; UI and settings use the new variable. Add unit tests for settings (tests/solidify_settings_tests.cpp) and test target in CMake. Misc: bump VERSION_MINOR/PATCH macros, small GLFW macOS context hints, and add .DS_Store to .gitignore.
1 parent a667c0e commit 52225e1

11 files changed

Lines changed: 660 additions & 46 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,3 +365,4 @@ MigrationBackup/
365365
# Fody - auto-generated XML schema
366366
FodyWeavers.xsd
367367
/tmp
368+
.DS_Store

CMakeLists.txt

Lines changed: 116 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
cmake_minimum_required(VERSION 3.20)
22

3-
project(Solidify LANGUAGES CXX C VERSION 0.1.0)
3+
project(Solidify LANGUAGES CXX C VERSION 2.7.5)
44

55
set(CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING "Available build configurations" FORCE)
66

@@ -84,6 +84,25 @@ if(NOT EXISTS "${DND_GLFW_INCLUDE_DIR}/dnd_glfw.h")
8484
message(FATAL_ERROR "dnd_glfw.h not found. Set DND_GLFW_INCLUDE_DIR to its location.")
8585
endif()
8686

87+
set(SOLIDIFY_DND_GLFW_TARGET "")
88+
set(SOLIDIFY_DND_GLFW_SOURCE "")
89+
if(APPLE)
90+
enable_language(OBJCXX)
91+
if(NOT TARGET dnd_glfw AND EXISTS "${DND_GLFW_INCLUDE_DIR}/CMakeLists.txt")
92+
add_subdirectory("${DND_GLFW_INCLUDE_DIR}" "${CMAKE_CURRENT_BINARY_DIR}/dnd_glfw")
93+
endif()
94+
if(TARGET dnd_glfw)
95+
if(TARGET dnd_glfw_macos)
96+
target_link_libraries(dnd_glfw_macos PUBLIC glfw3::glfw3)
97+
endif()
98+
set(SOLIDIFY_DND_GLFW_TARGET dnd_glfw)
99+
elseif(EXISTS "${DND_GLFW_INCLUDE_DIR}/dnd_glfw_macos.mm")
100+
set(SOLIDIFY_DND_GLFW_SOURCE "${DND_GLFW_INCLUDE_DIR}/dnd_glfw_macos.mm")
101+
else()
102+
message(FATAL_ERROR "dnd_glfw macOS implementation not found. Expected dnd_glfw_macos.mm or a dnd_glfw CMake target.")
103+
endif()
104+
endif()
105+
87106
if(NOT SOLIDIFY_TOML11_DIR)
88107
find_path(TOML11_INCLUDE_DIR
89108
NAMES toml.hpp toml11/toml.hpp
@@ -200,6 +219,22 @@ if(NOT TARGET BZip2::BZip2)
200219
endif()
201220
endif()
202221

222+
find_package(freetype CONFIG QUIET)
223+
if(NOT TARGET Freetype::Freetype AND NOT TARGET freetype)
224+
find_package(Freetype QUIET)
225+
endif()
226+
if(NOT TARGET Freetype::Freetype AND NOT TARGET freetype)
227+
find_library(FREETYPE_LIBRARY NAMES freetype libfreetype HINTS ${CMAKE_LIBRARY_PATH})
228+
find_path(FREETYPE_INCLUDE_DIR NAMES ft2build.h PATH_SUFFIXES freetype2 HINTS ${CMAKE_INCLUDE_PATH})
229+
if(FREETYPE_LIBRARY)
230+
add_library(Freetype::Freetype UNKNOWN IMPORTED)
231+
set_target_properties(Freetype::Freetype PROPERTIES IMPORTED_LOCATION "${FREETYPE_LIBRARY}")
232+
if(FREETYPE_INCLUDE_DIR)
233+
set_target_properties(Freetype::Freetype PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${FREETYPE_INCLUDE_DIR}")
234+
endif()
235+
endif()
236+
endif()
237+
203238
find_package(dng_sdk CONFIG QUIET)
204239
if(NOT TARGET dng_sdk::dng_sdk)
205240
find_library(DNG_SDK_LIBRARY NAMES dng_sdk HINTS ${CMAKE_LIBRARY_PATH})
@@ -245,6 +280,71 @@ if(NOT TARGET hwy::hwy)
245280
endif()
246281
find_package(spdlog CONFIG REQUIRED)
247282

283+
find_library(SOLIDIFY_OPENJPH_LINK_LIBRARY NAMES openjph libopenjph HINTS ${CMAKE_LIBRARY_PATH})
284+
find_library(SOLIDIFY_BZIP2_LINK_LIBRARY NAMES bz2_static bz2 bzip2 HINTS ${CMAKE_LIBRARY_PATH})
285+
find_library(SOLIDIFY_PUGIXML_LINK_LIBRARY NAMES pugixml HINTS ${CMAKE_LIBRARY_PATH})
286+
find_library(SOLIDIFY_UHDR_LINK_LIBRARY NAMES uhdr libuhdr HINTS ${CMAKE_LIBRARY_PATH})
287+
288+
set(SOLIDIFY_FREETYPE_LINK_ITEM "")
289+
if(TARGET Freetype::Freetype)
290+
set(SOLIDIFY_FREETYPE_LINK_ITEM Freetype::Freetype)
291+
elseif(TARGET freetype)
292+
set(SOLIDIFY_FREETYPE_LINK_ITEM freetype)
293+
endif()
294+
295+
set(SOLIDIFY_OPENJPH_LINK_ITEM "")
296+
if(SOLIDIFY_OPENJPH_LINK_LIBRARY)
297+
set(SOLIDIFY_OPENJPH_LINK_ITEM "${SOLIDIFY_OPENJPH_LINK_LIBRARY}")
298+
elseif(TARGET openjph)
299+
set(SOLIDIFY_OPENJPH_LINK_ITEM openjph)
300+
endif()
301+
302+
set(SOLIDIFY_PUGIXML_LINK_ITEM "")
303+
if(TARGET pugixml::pugixml)
304+
set(SOLIDIFY_PUGIXML_LINK_ITEM pugixml::pugixml)
305+
elseif(SOLIDIFY_PUGIXML_LINK_LIBRARY)
306+
set(SOLIDIFY_PUGIXML_LINK_ITEM "${SOLIDIFY_PUGIXML_LINK_LIBRARY}")
307+
endif()
308+
309+
set(SOLIDIFY_UHDR_LINK_ITEM "")
310+
if(TARGET libuhdr::libuhdr)
311+
set(SOLIDIFY_UHDR_LINK_ITEM libuhdr::libuhdr)
312+
elseif(SOLIDIFY_UHDR_LINK_LIBRARY)
313+
set(SOLIDIFY_UHDR_LINK_ITEM "${SOLIDIFY_UHDR_LINK_LIBRARY}")
314+
endif()
315+
316+
set(SOLIDIFY_BZIP2_LINK_ITEM "")
317+
if(TARGET BZip2::BZip2)
318+
set(SOLIDIFY_BZIP2_LINK_ITEM BZip2::BZip2)
319+
elseif(SOLIDIFY_BZIP2_LINK_LIBRARY)
320+
set(SOLIDIFY_BZIP2_LINK_ITEM "${SOLIDIFY_BZIP2_LINK_LIBRARY}")
321+
endif()
322+
323+
function(solidify_link_oiio_static_tail target_name)
324+
target_link_libraries(${target_name} PRIVATE
325+
${SOLIDIFY_FREETYPE_LINK_ITEM}
326+
${SOLIDIFY_PUGIXML_LINK_ITEM}
327+
${SOLIDIFY_UHDR_LINK_ITEM}
328+
${SOLIDIFY_BZIP2_LINK_ITEM}
329+
)
330+
331+
if(APPLE AND SOLIDIFY_OPENJPH_LINK_LIBRARY)
332+
target_link_libraries(${target_name} PRIVATE
333+
"-Wl,-force_load,${SOLIDIFY_OPENJPH_LINK_LIBRARY}"
334+
)
335+
elseif(SOLIDIFY_OPENJPH_LINK_ITEM)
336+
target_link_libraries(${target_name} PRIVATE ${SOLIDIFY_OPENJPH_LINK_ITEM})
337+
endif()
338+
339+
if(UNIX AND NOT APPLE AND SOLIDIFY_BZIP2_LINK_LIBRARY)
340+
target_link_libraries(${target_name} PRIVATE
341+
"-Wl,--whole-archive"
342+
"${SOLIDIFY_BZIP2_LINK_LIBRARY}"
343+
"-Wl,--no-whole-archive"
344+
)
345+
endif()
346+
endfunction()
347+
248348
file(GLOB IMGUI_SOURCES CONFIGURE_DEPENDS
249349
"${IMGUI_INCLUDE_DIR}/imgui.cpp"
250350
"${IMGUI_INCLUDE_DIR}/imgui_draw.cpp"
@@ -285,6 +385,7 @@ set(SOLIDIFY_SOURCES
285385
Solidify/src/pushpull.cpp
286386
Solidify/src/solidify.cpp
287387
Solidify/src/pch.cpp
388+
${SOLIDIFY_DND_GLFW_SOURCE}
288389
${SOLIDIFY_EMBEDDED_FONT_SOURCE}
289390
)
290391

@@ -312,14 +413,16 @@ target_link_libraries(Solidify PRIVATE
312413
OpenGL::GL
313414
)
314415

416+
if(SOLIDIFY_DND_GLFW_TARGET)
417+
target_link_libraries(Solidify PRIVATE "${SOLIDIFY_DND_GLFW_TARGET}")
418+
endif()
419+
420+
solidify_link_oiio_static_tail(Solidify)
421+
315422
if(UNIX AND NOT APPLE)
316423
target_link_libraries(Solidify PRIVATE
317424
dl
318425
m
319-
$<$<TARGET_EXISTS:pugixml::pugixml>:pugixml::pugixml>
320-
$<$<TARGET_EXISTS:libuhdr::libuhdr>:libuhdr::libuhdr>
321-
$<$<TARGET_EXISTS:openjph>:openjph>
322-
$<$<TARGET_EXISTS:BZip2::BZip2>:BZip2::BZip2>
323426
${X11_LIBRARIES}
324427
${X11_Xrandr_LIB}
325428
${X11_Xinerama_LIB}
@@ -330,27 +433,6 @@ if(UNIX AND NOT APPLE)
330433
if(OpenMP_CXX_FOUND)
331434
target_link_libraries(Solidify PRIVATE OpenMP::OpenMP_CXX)
332435
endif()
333-
334-
find_library(SOLIDIFY_OPENJPH_LINK_LIBRARY NAMES openjph libopenjph HINTS ${CMAKE_LIBRARY_PATH})
335-
find_library(SOLIDIFY_BZIP2_LINK_LIBRARY NAMES bz2_static bz2 bzip2 HINTS ${CMAKE_LIBRARY_PATH})
336-
find_library(SOLIDIFY_PUGIXML_LINK_LIBRARY NAMES pugixml HINTS ${CMAKE_LIBRARY_PATH})
337-
find_library(SOLIDIFY_UHDR_LINK_LIBRARY NAMES uhdr libuhdr HINTS ${CMAKE_LIBRARY_PATH})
338-
foreach(_solidify_tail_lib
339-
${SOLIDIFY_OPENJPH_LINK_LIBRARY}
340-
${SOLIDIFY_BZIP2_LINK_LIBRARY}
341-
${SOLIDIFY_PUGIXML_LINK_LIBRARY}
342-
${SOLIDIFY_UHDR_LINK_LIBRARY})
343-
if(_solidify_tail_lib)
344-
target_link_libraries(Solidify PRIVATE "${_solidify_tail_lib}")
345-
endif()
346-
endforeach()
347-
if(SOLIDIFY_BZIP2_LINK_LIBRARY)
348-
target_link_libraries(Solidify PRIVATE
349-
"-Wl,--whole-archive"
350-
"${SOLIDIFY_BZIP2_LINK_LIBRARY}"
351-
"-Wl,--no-whole-archive"
352-
)
353-
endif()
354436
endif()
355437

356438
if(WIN32)
@@ -403,25 +485,12 @@ function(solidify_configure_image_tool target_name)
403485
hwy::hwy
404486
spdlog::spdlog
405487
)
488+
solidify_link_oiio_static_tail(${target_name})
406489
if(UNIX AND NOT APPLE)
407490
target_link_libraries(${target_name} PRIVATE
408491
dl
409492
m
410-
$<$<TARGET_EXISTS:pugixml::pugixml>:pugixml::pugixml>
411-
$<$<TARGET_EXISTS:libuhdr::libuhdr>:libuhdr::libuhdr>
412-
$<$<TARGET_EXISTS:openjph>:openjph>
413-
$<$<TARGET_EXISTS:BZip2::BZip2>:BZip2::BZip2>
414-
${SOLIDIFY_OPENJPH_LINK_LIBRARY}
415-
${SOLIDIFY_PUGIXML_LINK_LIBRARY}
416-
${SOLIDIFY_UHDR_LINK_LIBRARY}
417493
)
418-
if(SOLIDIFY_BZIP2_LINK_LIBRARY)
419-
target_link_libraries(${target_name} PRIVATE
420-
"-Wl,--whole-archive"
421-
"${SOLIDIFY_BZIP2_LINK_LIBRARY}"
422-
"-Wl,--no-whole-archive"
423-
)
424-
endif()
425494
endif()
426495
endfunction()
427496

@@ -441,6 +510,13 @@ if(BUILD_TESTING)
441510
solidify_configure_image_tool(solidify_pushpull_tests)
442511
add_test(NAME solidify_pushpull_tests COMMAND solidify_pushpull_tests)
443512

513+
add_executable(solidify_settings_tests
514+
tests/solidify_settings_tests.cpp
515+
Solidify/src/settings.cpp
516+
)
517+
solidify_configure_image_tool(solidify_settings_tests)
518+
add_test(NAME solidify_settings_tests COMMAND solidify_settings_tests)
519+
444520
add_executable(solidify_pushpull_bench
445521
tests/solidify_pushpull_bench.cpp
446522
Solidify/src/pushpull.cpp

Solidify/src/UI.CPP

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,7 @@ AppMenuBar()
389389
if (ImGui::BeginMenuBar()) {
390390
if (ImGui::BeginMenu("Files")) {
391391
if (ImGui::MenuItem("Reload Config")) {
392-
if (loadSettingsDefaults("sldf_config.toml")) {
392+
if (loadSettingsDefaults(settingsConfigPath)) {
393393
ApplyConsoleVisibility();
394394
ApplyVerbosity();
395395
printSettings(settings);

Solidify/src/main.cpp

Lines changed: 94 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,13 @@
1818

1919
#include "pch.h"
2020

21+
#if defined(__APPLE__)
22+
# include <limits.h>
23+
# include <mach-o/dyld.h>
24+
#elif !defined(_WIN32)
25+
# include <limits.h>
26+
#endif
27+
2128
#ifdef _WIN32
2229
# include "../resource.h"
2330
#endif
@@ -36,6 +43,79 @@ glfw_error_callback(int error, const char* description)
3643
spdlog::error("Glfw Error {}: {}", error, description);
3744
}
3845

46+
static bool
47+
configPathFromExecutable(const std::filesystem::path& executablePath, std::string* outPath)
48+
{
49+
if (outPath == nullptr || executablePath.empty()) {
50+
return false;
51+
}
52+
53+
std::error_code ec;
54+
std::filesystem::path absolutePath = std::filesystem::absolute(executablePath, ec);
55+
if (ec) {
56+
absolutePath = executablePath;
57+
}
58+
59+
const std::filesystem::path executableDir = absolutePath.parent_path();
60+
std::filesystem::path candidate = executableDir.parent_path() / "Resources" / "sldf_config.toml";
61+
ec.clear();
62+
if (std::filesystem::exists(candidate, ec)) {
63+
*outPath = candidate.string();
64+
return true;
65+
}
66+
67+
candidate = executableDir / "sldf_config.toml";
68+
ec.clear();
69+
if (std::filesystem::exists(candidate, ec)) {
70+
*outPath = candidate.string();
71+
return true;
72+
}
73+
74+
return false;
75+
}
76+
77+
static std::string
78+
resolveConfigPath(const char* argv0)
79+
{
80+
std::string resolvedPath;
81+
82+
#ifdef _WIN32
83+
char executablePath[MAX_PATH] = {};
84+
const DWORD length = GetModuleFileNameA(nullptr, executablePath, static_cast<DWORD>(sizeof(executablePath)));
85+
if (length > 0 && length < static_cast<DWORD>(sizeof(executablePath))
86+
&& configPathFromExecutable(std::filesystem::path(executablePath), &resolvedPath)) {
87+
return resolvedPath;
88+
}
89+
#elif defined(__APPLE__)
90+
uint32_t bufferSize = PATH_MAX;
91+
std::vector<char> executablePath(bufferSize);
92+
int result = _NSGetExecutablePath(executablePath.data(), &bufferSize);
93+
if (result == -1) {
94+
executablePath.assign(bufferSize, '\0');
95+
result = _NSGetExecutablePath(executablePath.data(), &bufferSize);
96+
}
97+
if (result == 0 && configPathFromExecutable(std::filesystem::path(executablePath.data()), &resolvedPath)) {
98+
return resolvedPath;
99+
}
100+
#else
101+
char executablePath[PATH_MAX] = {};
102+
const ssize_t length = readlink("/proc/self/exe", executablePath, sizeof(executablePath) - 1u);
103+
if (length > 0) {
104+
executablePath[length] = '\0';
105+
if (configPathFromExecutable(std::filesystem::path(executablePath), &resolvedPath)) {
106+
return resolvedPath;
107+
}
108+
}
109+
#endif
110+
111+
if (argv0 != nullptr && argv0[0] != '\0'
112+
&& configPathFromExecutable(std::filesystem::path(argv0), &resolvedPath)) {
113+
return resolvedPath;
114+
}
115+
116+
return "sldf_config.toml";
117+
}
118+
39119
static void
40120
onDragEnter(GLFWwindow* window, const dnd_glfw::DragEvent& event, void* userData)
41121
{
@@ -107,7 +187,6 @@ int
107187
main(int argc, char* argv[])
108188
{
109189
(void)argc;
110-
(void)argv;
111190

112191
#ifdef _WIN32
113192
AllocConsole();
@@ -126,8 +205,10 @@ main(int argc, char* argv[])
126205
spdlog::info("Build from: {} {}", __DATE__, __TIME__);
127206
spdlog::info("Log started at: {}", ctime(&timestamp));
128207

129-
if (!loadSettingsDefaults("sldf_config.toml")) {
130-
spdlog::error("Can not load [sldf_config.toml]. Using default settings.");
208+
settingsConfigPath = resolveConfigPath(argv != nullptr && argc > 0 ? argv[0] : nullptr);
209+
spdlog::info("Config path: {}", settingsConfigPath);
210+
if (!loadSettingsDefaults(settingsConfigPath)) {
211+
spdlog::error("Can not load [{}]. Using default settings.", settingsConfigPath);
131212
settings.reSettings();
132213
settingsDefaults = settings;
133214
}
@@ -144,9 +225,19 @@ main(int argc, char* argv[])
144225
return 1;
145226
}
146227

228+
#if defined(__APPLE__)
229+
const char* glsl_version = "#version 150";
230+
glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API);
231+
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
232+
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
233+
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
234+
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
235+
#else
147236
const char* glsl_version = "#version 130";
237+
glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API);
148238
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
149239
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
240+
#endif
150241
glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
151242
glfwWindowHint(GLFW_FLOATING, GLFW_TRUE);
152243

Solidify/src/settings.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
Settings settings;
2424
Settings settingsDefaults;
25+
std::string settingsConfigPath = "sldf_config.toml";
2526

2627
template<typename T>
2728
static void

Solidify/src/settings.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ struct Settings {
155155

156156
extern Settings settings;
157157
extern Settings settingsDefaults;
158+
extern std::string settingsConfigPath;
158159

159160
bool
160161
loadSettings(Settings& settings, const std::string& filename);

0 commit comments

Comments
 (0)