@@ -15,10 +15,6 @@ DESTDIR ?= | |||
# -------------------------------------------------------------- | |||
HAVE_PROJM = $(shell pkg-config --exists libprojectM && echo true) | |||
# -------------------------------------------------------------- | |||
ifneq ($(CROSS_COMPILING),true) | |||
CAN_GENERATE_TTL = true | |||
else ifneq ($(EXE_WRAPPER),) | |||
@@ -60,10 +56,8 @@ ifeq ($(HAVE_OPENGL),true) | |||
# glBars (needs OpenGL) | |||
$(MAKE) all -C plugins/glBars | |||
ifeq ($(HAVE_PROJM),true) | |||
# ProM (needs OpenGL + ProjectM) | |||
$(MAKE) all -C plugins/ProM | |||
endif # HAVE_PROJM | |||
endif # HAVE_OPENGL | |||
gen: plugins dpf/utils/lv2_ttl_generator | |||
@@ -153,9 +147,6 @@ endif # MACOS | |||
install -m 755 bin/MaPitchshift$(APP_EXT) $(DESTDIR)$(PREFIX)/bin/ | |||
ifeq ($(HAVE_OPENGL),true) | |||
install -m 755 bin/glBars$(APP_EXT) $(DESTDIR)$(PREFIX)/bin/ | |||
ifeq ($(HAVE_PROJM),true) | |||
install -m 755 bin/ProM$(APP_EXT) $(DESTDIR)$(PREFIX)/bin/ | |||
endif # HAVE_PROJM | |||
endif # HAVE_OPENGL | |||
# -------------------------------------------------------------- | |||
@@ -8,6 +8,13 @@ AR ?= ar | |||
CC ?= gcc | |||
CXX ?= g++ | |||
# --------------------------------------------------------------------------------------------------------------------- | |||
# Protect against multiple inclusion | |||
ifneq ($(DPF_MAKEFILE_BASE_INCLUDED),true) | |||
DPF_MAKEFILE_BASE_INCLUDED = true | |||
# --------------------------------------------------------------------------------------------------------------------- | |||
# Auto-detect OS if not defined | |||
@@ -227,7 +234,9 @@ endif | |||
# Check for required libraries | |||
HAVE_CAIRO = $(shell $(PKG_CONFIG) --exists cairo && echo true) | |||
HAVE_VULKAN = $(shell $(PKG_CONFIG) --exists vulkan && echo true) | |||
# Vulkan is not supported yet | |||
# HAVE_VULKAN = $(shell $(PKG_CONFIG) --exists vulkan && echo true) | |||
ifeq ($(MACOS_OR_WINDOWS),true) | |||
HAVE_OPENGL = true | |||
@@ -485,3 +494,8 @@ features: | |||
$(call print_available,HAVE_XRANDR) | |||
# --------------------------------------------------------------------------------------------------------------------- | |||
# Protect against multiple inclusion | |||
endif # DPF_MAKEFILE_BASE_INCLUDED | |||
# --------------------------------------------------------------------------------------------------------------------- |
@@ -73,7 +73,7 @@ public: | |||
Returning true means there's no event-loop running at the moment (or it's just about to stop). | |||
This function is thread-safe. | |||
*/ | |||
bool isQuiting() const noexcept; | |||
bool isQuitting() const noexcept; | |||
/** | |||
Check if the application is standalone, otherwise running as a module or plugin. | |||
@@ -13,6 +13,10 @@ BUILD_CXX_FLAGS += $(DGL_FLAGS) -I. -Isrc -DDONT_SET_USING_DGL_NAMESPACE -Wno-un | |||
BUILD_CXX_FLAGS += -Isrc/pugl-upstream/include | |||
LINK_FLAGS += $(DGL_LIBS) | |||
ifeq ($(USE_OPENGL3),true) | |||
BUILD_CXX_FLAGS += -DDGL_USE_OPENGL3 | |||
endif | |||
# TODO fix these after pugl-upstream is done | |||
BUILD_CXX_FLAGS += -Wno-attributes -Wno-extra -Wno-missing-field-initializers | |||
ifneq ($(MACOS),true) | |||
@@ -67,13 +67,20 @@ | |||
// OpenGL includes | |||
#ifdef DISTRHO_OS_MAC | |||
# include <OpenGL/gl.h> | |||
# ifdef DGL_USE_OPENGL3 | |||
# include <OpenGL/gl3.h> | |||
# include <OpenGL/gl3ext.h> | |||
# else | |||
# include <OpenGL/gl.h> | |||
# endif | |||
#else | |||
# ifndef DISTRHO_OS_WINDOWS | |||
# define GL_GLEXT_PROTOTYPES | |||
# endif | |||
# include <GL/gl.h> | |||
# include <GL/glext.h> | |||
# ifndef __GLEW_H__ | |||
# include <GL/gl.h> | |||
# include <GL/glext.h> | |||
# endif | |||
#endif | |||
// ----------------------------------------------------------------------- | |||
@@ -70,10 +70,6 @@ public: | |||
const char* startDir; | |||
/** File browser dialog window title, uses "FileBrowser" if null */ | |||
const char* title; | |||
/** File browser dialog window width */ | |||
uint width; | |||
/** File browser dialog window height */ | |||
uint height; | |||
// TODO file filter | |||
/** | |||
@@ -98,8 +94,6 @@ public: | |||
FileBrowserOptions() | |||
: startDir(nullptr), | |||
title(nullptr), | |||
width(0), | |||
height(0), | |||
buttons() {} | |||
}; | |||
#endif // DGL_FILE_BROWSER_DISABLED | |||
@@ -128,17 +122,17 @@ public: | |||
``` | |||
This struct is necessary because we cannot automatically make the window leave the OpenGL context in custom code. | |||
We must always cleanly enter and leave the OpenGL context. | |||
In order to avoid messing up the global host context, this class is used around widget creation. | |||
And we must always cleanly enter and leave the OpenGL context. | |||
So in order to avoid messing up the global host context, this class is used around widget creation. | |||
*/ | |||
class ScopedGraphicsContext | |||
struct ScopedGraphicsContext | |||
{ | |||
Window& window; | |||
public: | |||
explicit ScopedGraphicsContext(Window& window); | |||
~ScopedGraphicsContext(); | |||
DISTRHO_DECLARE_NON_COPYABLE(ScopedGraphicsContext) | |||
DISTRHO_PREVENT_HEAP_ALLOCATION | |||
private: | |||
Window& window; | |||
}; | |||
/** | |||
@@ -190,7 +184,7 @@ public: | |||
bool isVisible() const noexcept; | |||
/** | |||
Set windows visible (or not) according to @a visible. | |||
Set window visible (or not) according to @a visible. | |||
Only valid for standalones, embed windows are always visible. | |||
@see isVisible(), hide(), show() | |||
*/ | |||
@@ -453,6 +447,15 @@ private: | |||
friend class PluginWindow; | |||
friend class TopLevelWidget; | |||
/** @internal */ | |||
explicit Window(Application& app, | |||
uintptr_t parentWindowHandle, | |||
uint width, | |||
uint height, | |||
double scaleFactor, | |||
bool resizable, | |||
bool doPostInit); | |||
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(Window); | |||
}; | |||
@@ -48,7 +48,7 @@ void Application::quit() | |||
pData->quit(); | |||
} | |||
bool Application::isQuiting() const noexcept | |||
bool Application::isQuitting() const noexcept | |||
{ | |||
return pData->isQuitting || pData->isQuittingInNextCycle; | |||
} | |||
@@ -151,6 +151,7 @@ void Application::PrivateData::quit() | |||
void Application::PrivateData::setClassName(const char* const name) | |||
{ | |||
DISTRHO_SAFE_ASSERT_RETURN(world != nullptr,); | |||
DISTRHO_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0',); | |||
puglSetClassName(world, name); | |||
@@ -54,6 +54,15 @@ DGL_EXT(PFNGLUNIFORM4FVPROC, glUniform4fv) | |||
DGL_EXT(PFNGLUSEPROGRAMPROC, glUseProgram) | |||
DGL_EXT(PFNGLVERTEXATTRIBPOINTERPROC, glVertexAttribPointer) | |||
DGL_EXT(PFNGLBLENDFUNCSEPARATEPROC, glBlendFuncSeparate) | |||
# ifdef DGL_USE_OPENGL3 | |||
DGL_EXT(PFNGLBINDBUFFERRANGEPROC, glBindBufferRange) | |||
DGL_EXT(PFNGLBINDVERTEXARRAYPROC, glBindVertexArray) | |||
DGL_EXT(PFNGLDELETEVERTEXARRAYSPROC, glDeleteVertexArrays) | |||
DGL_EXT(PFNGLGENERATEMIPMAPPROC, glGenerateMipmap) | |||
DGL_EXT(PFNGLGETUNIFORMBLOCKINDEXPROC, glGetUniformBlockIndex) | |||
DGL_EXT(PFNGLGENVERTEXARRAYSPROC, glGenVertexArrays) | |||
DGL_EXT(PFNGLUNIFORMBLOCKBINDINGPROC, glUniformBlockBinding) | |||
# endif | |||
# undef DGL_EXT | |||
#endif | |||
@@ -61,7 +70,18 @@ DGL_EXT(PFNGLBLENDFUNCSEPARATEPROC, glBlendFuncSeparate) | |||
// Include NanoVG OpenGL implementation | |||
//#define STB_IMAGE_STATIC | |||
#define NANOVG_GL2_IMPLEMENTATION | |||
#ifdef DGL_USE_OPENGL3 | |||
# define NANOVG_GL3_IMPLEMENTATION | |||
#else | |||
# define NANOVG_GL2_IMPLEMENTATION | |||
#endif | |||
#if defined(DISTRHO_OS_MAC) && defined(NANOVG_GL3_IMPLEMENTATION) | |||
# define glBindVertexArray glBindVertexArrayAPPLE | |||
# define glDeleteVertexArrays glDeleteVertexArraysAPPLE | |||
# define glGenVertexArrays glGenVertexArraysAPPLE | |||
#endif | |||
#include "nanovg/nanovg_gl.h" | |||
#if defined(NANOVG_GL2) | |||
@@ -125,6 +145,15 @@ DGL_EXT(PFNGLUNIFORM4FVPROC, glUniform4fv) | |||
DGL_EXT(PFNGLUSEPROGRAMPROC, glUseProgram) | |||
DGL_EXT(PFNGLVERTEXATTRIBPOINTERPROC, glVertexAttribPointer) | |||
DGL_EXT(PFNGLBLENDFUNCSEPARATEPROC, glBlendFuncSeparate) | |||
# ifdef DGL_USE_OPENGL3 | |||
DGL_EXT(PFNGLBINDBUFFERRANGEPROC, glBindBufferRange) | |||
DGL_EXT(PFNGLBINDVERTEXARRAYPROC, glBindVertexArray) | |||
DGL_EXT(PFNGLDELETEVERTEXARRAYSPROC, glDeleteVertexArrays) | |||
DGL_EXT(PFNGLGENERATEMIPMAPPROC, glGenerateMipmap) | |||
DGL_EXT(PFNGLGETUNIFORMBLOCKINDEXPROC, glGetUniformBlockIndex) | |||
DGL_EXT(PFNGLGENVERTEXARRAYSPROC, glGenVertexArrays) | |||
DGL_EXT(PFNGLUNIFORMBLOCKBINDINGPROC, glUniformBlockBinding) | |||
# endif | |||
# undef DGL_EXT | |||
needsInit = false; | |||
# if defined(__GNUC__) && (__GNUC__ >= 9) | |||
@@ -269,12 +298,12 @@ NanoVG::~NanoVG() | |||
void NanoVG::beginFrame(const uint width, const uint height, const float scaleFactor) | |||
{ | |||
if (fContext == nullptr) return; | |||
DISTRHO_SAFE_ASSERT_RETURN(scaleFactor > 0.0f,); | |||
DISTRHO_SAFE_ASSERT_RETURN(! fInFrame,); | |||
fInFrame = true; | |||
nvgBeginFrame(fContext, static_cast<int>(width), static_cast<int>(height), scaleFactor); | |||
if (fContext != nullptr) | |||
nvgBeginFrame(fContext, static_cast<int>(width), static_cast<int>(height), scaleFactor); | |||
} | |||
void NanoVG::beginFrame(Widget* const widget) | |||
@@ -69,6 +69,19 @@ Window::Window(Application& app, | |||
pData->initPost(); | |||
} | |||
Window::Window(Application& app, | |||
const uintptr_t parentWindowHandle, | |||
const uint width, | |||
const uint height, | |||
const double scaleFactor, | |||
const bool resizable, | |||
const bool doPostInit) | |||
: pData(new PrivateData(app, this, parentWindowHandle, width, height, scaleFactor, resizable)) | |||
{ | |||
if (doPostInit) | |||
pData->initPost(); | |||
} | |||
Window::~Window() | |||
{ | |||
delete pData; | |||
@@ -119,6 +132,8 @@ void Window::setResizable(const bool resizable) | |||
uint Window::getWidth() const noexcept | |||
{ | |||
DISTRHO_SAFE_ASSERT_RETURN(pData->view != nullptr, 0); | |||
const double width = puglGetFrame(pData->view).width; | |||
DISTRHO_SAFE_ASSERT_RETURN(width >= 0.0, 0); | |||
return static_cast<uint>(width + 0.5); | |||
@@ -126,6 +141,8 @@ uint Window::getWidth() const noexcept | |||
uint Window::getHeight() const noexcept | |||
{ | |||
DISTRHO_SAFE_ASSERT_RETURN(pData->view != nullptr, 0); | |||
const double height = puglGetFrame(pData->view).height; | |||
DISTRHO_SAFE_ASSERT_RETURN(height >= 0.0, 0); | |||
return static_cast<uint>(height + 0.5); | |||
@@ -133,6 +150,8 @@ uint Window::getHeight() const noexcept | |||
Size<uint> Window::getSize() const noexcept | |||
{ | |||
DISTRHO_SAFE_ASSERT_RETURN(pData->view != nullptr, Size<uint>()); | |||
const PuglRect rect = puglGetFrame(pData->view); | |||
DISTRHO_SAFE_ASSERT_RETURN(rect.width >= 0.0, Size<uint>()); | |||
DISTRHO_SAFE_ASSERT_RETURN(rect.height >= 0.0, Size<uint>()); | |||
@@ -201,7 +220,8 @@ const char* Window::getTitle() const noexcept | |||
void Window::setTitle(const char* const title) | |||
{ | |||
puglSetWindowTitle(pData->view, title); | |||
if (pData->view != nullptr) | |||
puglSetWindowTitle(pData->view, title); | |||
} | |||
bool Window::isIgnoringKeyRepeat() const noexcept | |||
@@ -264,11 +284,17 @@ bool Window::openFileBrowser(const FileBrowserOptions& options) | |||
void Window::repaint() noexcept | |||
{ | |||
if (pData->view == nullptr) | |||
return; | |||
puglPostRedisplay(pData->view); | |||
} | |||
void Window::repaint(const Rectangle<uint>& rect) noexcept | |||
{ | |||
if (pData->view == nullptr) | |||
return; | |||
PuglRect prect = { | |||
static_cast<double>(rect.getX()), | |||
static_cast<double>(rect.getY()), | |||
@@ -305,6 +331,9 @@ void Window::setGeometryConstraints(const uint minimumWidth, | |||
pData->autoScaling = automaticallyScale; | |||
pData->keepAspectRatio = keepAspectRatio; | |||
if (pData->view == nullptr) | |||
return; | |||
const double scaleFactor = pData->scaleFactor; | |||
puglSetGeometryConstraints(pData->view, | |||
@@ -70,7 +70,10 @@ static double getDesktopScaleFactor(const PuglView* const view) | |||
if (const char* const scale = getenv("DPF_SCALE_FACTOR")) | |||
return std::max(1.0, std::atof(scale)); | |||
return puglGetDesktopScaleFactor(view); | |||
if (view != nullptr) | |||
return puglGetDesktopScaleFactor(view); | |||
return 1.0; | |||
} | |||
// ----------------------------------------------------------------------- | |||
@@ -162,11 +165,11 @@ Window::PrivateData::PrivateData(Application& a, Window* const s, | |||
: app(a), | |||
appData(a.pData), | |||
self(s), | |||
view(puglNewView(appData->world)), | |||
view(appData->world != nullptr ? puglNewView(appData->world) : nullptr), | |||
transientParentView(nullptr), | |||
topLevelWidgets(), | |||
isClosed(parentWindowHandle == 0), | |||
isVisible(parentWindowHandle != 0), | |||
isVisible(parentWindowHandle != 0 && view != nullptr), | |||
isEmbed(parentWindowHandle != 0), | |||
scaleFactor(scale != 0.0 ? scale : getDesktopScaleFactor(view)), | |||
autoScaling(false), | |||
@@ -187,6 +190,12 @@ Window::PrivateData::PrivateData(Application& a, Window* const s, | |||
Window::PrivateData::~PrivateData() | |||
{ | |||
appData->idleCallbacks.remove(this); | |||
appData->windows.remove(self); | |||
if (view == nullptr) | |||
return; | |||
if (isEmbed) | |||
{ | |||
#ifdef HAVE_X11 | |||
@@ -198,16 +207,12 @@ Window::PrivateData::~PrivateData() | |||
isVisible = false; | |||
} | |||
appData->idleCallbacks.remove(this); | |||
appData->windows.remove(self); | |||
#ifdef DISTRHO_OS_WINDOWS | |||
if (win32SelectedFile != nullptr && win32SelectedFile != kWin32SelectedFileCancelled) | |||
std::free(const_cast<char*>(win32SelectedFile)); | |||
#endif | |||
if (view != nullptr) | |||
puglFreeView(view); | |||
puglFreeView(view); | |||
} | |||
// ----------------------------------------------------------------------- | |||
@@ -220,7 +225,7 @@ void Window::PrivateData::initPre(const uint width, const uint height, const boo | |||
if (view == nullptr) | |||
{ | |||
DGL_DBG("Failed to create Pugl view, everything will fail!\n"); | |||
d_stderr2("Failed to create Pugl view, everything will fail!"); | |||
return; | |||
} | |||
@@ -234,14 +239,26 @@ void Window::PrivateData::initPre(const uint width, const uint height, const boo | |||
puglSetViewHint(view, PUGL_IGNORE_KEY_REPEAT, PUGL_FALSE); | |||
puglSetViewHint(view, PUGL_DEPTH_BITS, 16); | |||
puglSetViewHint(view, PUGL_STENCIL_BITS, 8); | |||
#ifdef DGL_USE_OPENGL3 | |||
puglSetViewHint(view, PUGL_USE_COMPAT_PROFILE, PUGL_FALSE); | |||
puglSetViewHint(view, PUGL_CONTEXT_VERSION_MAJOR, 3); | |||
#endif | |||
// PUGL_SAMPLES ?? | |||
puglSetEventFunc(view, puglEventCallback); | |||
} | |||
void Window::PrivateData::initPost() | |||
bool Window::PrivateData::initPost() | |||
{ | |||
if (view == nullptr) | |||
return false; | |||
// create view now, as a few methods we allow devs to use require it | |||
puglRealize(view); | |||
if (puglRealize(view) != PUGL_SUCCESS) | |||
{ | |||
view = nullptr; | |||
d_stderr2("Failed to realize Pugl view, everything will fail!"); | |||
return false; | |||
} | |||
if (isEmbed) | |||
{ | |||
@@ -252,6 +269,8 @@ void Window::PrivateData::initPost() | |||
// give context back to transient parent window | |||
if (transientParentView != nullptr) | |||
puglBackendEnter(transientParentView); | |||
return true; | |||
} | |||
// ----------------------------------------------------------------------- | |||
@@ -286,6 +305,9 @@ void Window::PrivateData::show() | |||
DGL_DBG("Window show called\n"); | |||
if (view == nullptr) | |||
return; | |||
if (isClosed) | |||
{ | |||
isClosed = false; | |||
@@ -343,6 +365,9 @@ void Window::PrivateData::hide() | |||
void Window::PrivateData::focus() | |||
{ | |||
if (view == nullptr) | |||
return; | |||
if (! isEmbed) | |||
puglRaiseWindow(view); | |||
@@ -42,7 +42,7 @@ struct Window::PrivateData : IdleCallback { | |||
Window* const self; | |||
/** Pugl view instance. */ | |||
PuglView* const view; | |||
PuglView* view; | |||
/** Pugl view instance of the transient parent window. */ | |||
PuglView* const transientParentView; | |||
@@ -126,7 +126,7 @@ struct Window::PrivateData : IdleCallback { | |||
/** Helper initialization function called at the end of all this class constructors. */ | |||
void initPre(uint width, uint height, bool resizable); | |||
/** Helper initialization function called on the Window constructor after we are done. */ | |||
void initPost(); | |||
bool initPost(); | |||
/** Hide window and notify application of a window close event. | |||
* Does nothing if window is embed (that is, not standalone). | |||
@@ -40,7 +40,9 @@ enum NVGcreateFlags { | |||
#elif defined NANOVG_GL3_IMPLEMENTATION | |||
# define NANOVG_GL3 1 | |||
# define NANOVG_GL_IMPLEMENTATION 1 | |||
# define NANOVG_GL_USE_UNIFORMBUFFER 1 | |||
# ifndef __APPLE__ | |||
# define NANOVG_GL_USE_UNIFORMBUFFER 1 | |||
# endif | |||
#elif defined NANOVG_GLES2_IMPLEMENTATION | |||
# define NANOVG_GLES2 1 | |||
# define NANOVG_GL_IMPLEMENTATION 1 | |||
@@ -29,6 +29,10 @@ | |||
#include <stdlib.h> | |||
#ifndef __MAC_10_9 | |||
typedef NSUInteger NSEventSubtype; | |||
#endif | |||
#ifndef __MAC_10_10 | |||
typedef NSUInteger NSEventModifierFlags; | |||
#endif | |||
@@ -366,12 +366,16 @@ puglRealize(PuglView* const view) | |||
} | |||
#ifdef HAVE_XRANDR | |||
// Set refresh rate hint to the real refresh rate | |||
XRRScreenConfiguration* conf = XRRGetScreenInfo(display, parent); | |||
short current_rate = XRRConfigCurrentRate(conf); | |||
view->hints[PUGL_REFRESH_RATE] = current_rate; | |||
XRRFreeScreenConfigInfo(conf); | |||
int ignored; | |||
if (XRRQueryExtension(display, &ignored, &ignored)) | |||
{ | |||
// Set refresh rate hint to the real refresh rate | |||
XRRScreenConfiguration* conf = XRRGetScreenInfo(display, parent); | |||
short current_rate = XRRConfigCurrentRate(conf); | |||
view->hints[PUGL_REFRESH_RATE] = current_rate; | |||
XRRFreeScreenConfigInfo(conf); | |||
} | |||
#endif | |||
updateSizeHints(view); | |||
@@ -62,6 +62,7 @@ | |||
# include <X11/X.h> | |||
# include <X11/Xatom.h> | |||
# include <X11/Xlib.h> | |||
# include <X11/Xresource.h> | |||
# include <X11/Xutil.h> | |||
# include <X11/keysym.h> | |||
# ifdef HAVE_XCURSOR | |||
@@ -112,7 +113,6 @@ START_NAMESPACE_DGL | |||
# endif | |||
# ifndef __MAC_10_9 | |||
# define NSModalResponseOK NSOKButton | |||
typedef NSUInteger NSEventSubtype; | |||
# endif | |||
# pragma clang diagnostic push | |||
# pragma clang diagnostic ignored "-Wdeprecated-declarations" | |||
@@ -207,12 +207,59 @@ double puglGetDesktopScaleFactor(const PuglView* const view) | |||
: [view->impl->wrapperView window]) | |||
return [window screen].backingScaleFactor; | |||
return [NSScreen mainScreen].backingScaleFactor; | |||
#else | |||
return 1.0; | |||
#elif defined(DISTRHO_OS_WINDOWS) | |||
if (const HMODULE Shcore = LoadLibraryA("Shcore.dll")) | |||
{ | |||
typedef HRESULT(WINAPI* PFN_GetProcessDpiAwareness)(HANDLE, DWORD*); | |||
typedef HRESULT(WINAPI* PFN_GetScaleFactorForMonitor)(HMONITOR, DWORD*); | |||
const PFN_GetProcessDpiAwareness GetProcessDpiAwareness | |||
= (PFN_GetProcessDpiAwareness)GetProcAddress(Shcore, "GetProcessDpiAwareness"); | |||
const PFN_GetScaleFactorForMonitor GetScaleFactorForMonitor | |||
= (PFN_GetScaleFactorForMonitor)GetProcAddress(Shcore, "GetScaleFactorForMonitor"); | |||
DWORD dpiAware = 0; | |||
if (GetProcessDpiAwareness && GetScaleFactorForMonitor | |||
&& GetProcessDpiAwareness(NULL, &dpiAware) == 0 && dpiAware != 0) | |||
{ | |||
const HMONITOR hMon = MonitorFromWindow(view->impl->hwnd, MONITOR_DEFAULTTOPRIMARY); | |||
DWORD scaleFactor = 0; | |||
if (GetScaleFactorForMonitor(hMon, &scaleFactor) == 0 && scaleFactor != 0) | |||
{ | |||
FreeLibrary(Shcore); | |||
return static_cast<double>(scaleFactor) / 100.0; | |||
} | |||
} | |||
FreeLibrary(Shcore); | |||
} | |||
#elif defined(HAVE_X11) | |||
XrmInitialize(); | |||
if (char* const rms = XResourceManagerString(view->world->impl->display)) | |||
{ | |||
if (const XrmDatabase sdb = XrmGetStringDatabase(rms)) | |||
{ | |||
char* type = nullptr; | |||
XrmValue ret; | |||
if (XrmGetResource(sdb, "Xft.dpi", "String", &type, &ret) | |||
&& ret.addr != nullptr | |||
&& type != nullptr | |||
&& std::strncmp("String", type, 6) == 0) | |||
{ | |||
if (const double dpi = std::atof(ret.addr)) | |||
return dpi / 96; | |||
} | |||
} | |||
} | |||
#else | |||
// unused | |||
(void)view; | |||
#endif | |||
return 1.0; | |||
} | |||
// -------------------------------------------------------------------------------------------------------------------- | |||
@@ -596,7 +643,7 @@ bool sofdFileDialogShow(PuglView* const view, | |||
x_fib_cfg_buttons(2, options.buttons.showPlaces-1); | |||
*/ | |||
return (x_fib_show(sofd_display, view->impl->win, 0, 0, scaleFactor) == 0); | |||
return (x_fib_show(sofd_display, view->impl->win, 0, 0, scaleFactor + 0.5) == 0); | |||
} | |||
// -------------------------------------------------------------------------------------------------------------------- | |||
@@ -405,7 +405,7 @@ struct ParameterEnumerationValues { | |||
Array of @ParameterEnumerationValue items.@n | |||
This pointer must be null or have been allocated on the heap with `new ParameterEnumerationValue[count]`. | |||
*/ | |||
const ParameterEnumerationValue* values; | |||
ParameterEnumerationValue* values; | |||
/** | |||
Default constructor, for zero enumeration values. | |||
@@ -419,7 +419,7 @@ struct ParameterEnumerationValues { | |||
Constructor using custom values.@n | |||
The pointer to @values must have been allocated on the heap with `new`. | |||
*/ | |||
ParameterEnumerationValues(uint32_t c, bool r, const ParameterEnumerationValue* v) noexcept | |||
ParameterEnumerationValues(uint32_t c, bool r, ParameterEnumerationValue* v) noexcept | |||
: count(c), | |||
restrictedMode(r), | |||
values(v) {} | |||
@@ -250,7 +250,6 @@ protected: | |||
*/ | |||
virtual void sampleRateChanged(double newSampleRate); | |||
#if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||
/* -------------------------------------------------------------------------------------------------------- | |||
* UI Callbacks (optional) */ | |||
@@ -262,6 +261,16 @@ protected: | |||
*/ | |||
virtual void uiIdle() {} | |||
/** | |||
Window scale factor function, called when the scale factor changes. | |||
This function is for plugin UIs to be able to override Window::onScaleFactorChanged(double). | |||
The default implementation does nothing. | |||
WARNING function needs a proper name | |||
*/ | |||
virtual void uiScaleFactorChanged(double scaleFactor); | |||
#if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||
/** | |||
Windows focus function, called when the window gains or loses the keyboard focus. | |||
This function is for plugin UIs to be able to override Window::onFocus(bool, CrossingMode). | |||
@@ -275,22 +284,13 @@ protected: | |||
This function is for plugin UIs to be able to override Window::onReshape(uint, uint). | |||
The plugin UI size will be set right after this function. | |||
The default implementation sets up drawing context where necessary. | |||
The default implementation sets up the drawing context where necessary. | |||
You should almost never need to override this function. | |||
The most common exception is custom OpenGL setup, but only really needed for custom OpenGL drawing code. | |||
*/ | |||
virtual void uiReshape(uint width, uint height); | |||
/** | |||
Window scale factor function, called when the scale factor changes. | |||
This function is for plugin UIs to be able to override Window::onScaleFactorChanged(double). | |||
The default implementation does nothing. | |||
WARNING function needs a proper name | |||
*/ | |||
virtual void uiScaleFactorChanged(double scaleFactor); | |||
# ifndef DGL_FILE_BROWSER_DISABLED | |||
/** | |||
Window file selected function, called when a path is selected by the user, as triggered by openFileBrowser(). | |||
@@ -313,7 +313,7 @@ protected: | |||
@see Widget::onResize(const ResizeEvent&) | |||
*/ | |||
void onResize(const ResizeEvent& ev) override; | |||
#endif | |||
#endif // !DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||
// ------------------------------------------------------------------------------------------------------- | |||
@@ -1,6 +1,6 @@ | |||
/* | |||
* DISTRHO Plugin Framework (DPF) | |||
* Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com> | |||
* Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com> | |||
* | |||
* Permission to use, copy, modify, and/or distribute this software for any purpose with | |||
* or without fee is hereby granted, provided that the above copyright notice and this | |||
@@ -33,164 +33,506 @@ START_NAMESPACE_DISTRHO | |||
// ----------------------------------------------------------------------- | |||
// ExternalWindow class | |||
/** | |||
External Window class. | |||
This is a standalone TopLevelWidget/Window-compatible class, but without any real event handling. | |||
Being compatible with TopLevelWidget/Window, it allows to be used as DPF UI target. | |||
It can be used to embed non-DPF things or to run a tool in a new process as the "UI". | |||
The uiIdle() function will be called at regular intervals to keep UI running. | |||
There are helper methods in place to launch external tools and keep track of its running state. | |||
External windows can be setup to run in 3 different modes: | |||
* Embed: | |||
Embed into the host UI, even-loop driven by the host. | |||
This is basically working as a regular plugin UI, as you typically expect them to. | |||
The plugin side does not get control over showing, hiding or closing the window (as usual for plugins). | |||
No restrictions on supported plugin format, everything should work. | |||
Requires DISTRHO_PLUGIN_HAS_EMBED_UI to be set to 1. | |||
* Semi-external: | |||
The UI is not embed into the host, but the even-loop is still driven by it. | |||
In this mode the host does not have control over the UI except for showing, hiding and setting transient parent. | |||
It is possible to close the window from the plugin, the host will be notified of such case. | |||
Host regularly calls isQuitting() to check if the UI got closed by the user or plugin side. | |||
This mode is only possible in LV2 plugin formats, using lv2ui:showInterface extension. | |||
* Standalone: | |||
The UI is not embed into the host or uses its event-loop, basically running as standalone. | |||
The host only has control over showing and hiding the window, nothing else. | |||
The UI is still free to close itself at any point. | |||
DPF will keep calling isRunning() to check if it should keep the event-loop running. | |||
Only possible in JACK and DSSI targets, as the UIs are literally standalone applications there. | |||
Please note that for non-embed windows, you cannot show the window yourself. | |||
The plugin window is only allowed to hide or close itself, a "show" action needs to come from the host. | |||
A few callbacks are provided so that implementations do not need to care about checking for state changes. | |||
They are not called on construction, but will be everytime something changes either by the host or the window itself. | |||
*/ | |||
class ExternalWindow | |||
{ | |||
public: | |||
ExternalWindow(const uint w = 1, const uint h = 1, const char* const t = "") | |||
: width(w), | |||
height(h), | |||
title(t), | |||
transientWinId(0), | |||
visible(false), | |||
pid(0) {} | |||
struct PrivateData; | |||
public: | |||
/** | |||
Constructor. | |||
*/ | |||
explicit ExternalWindow() | |||
: pData() {} | |||
/** | |||
Constructor for DPF internal use. | |||
*/ | |||
explicit ExternalWindow(const PrivateData& data) | |||
: pData(data) {} | |||
/** | |||
Destructor. | |||
*/ | |||
virtual ~ExternalWindow() | |||
{ | |||
terminateAndWaitForProcess(); | |||
DISTRHO_SAFE_ASSERT(!pData.visible); | |||
} | |||
/* -------------------------------------------------------------------------------------------------------- | |||
* ExternalWindow specific calls - Host side calls that you can reimplement for fine-grained funtionality */ | |||
/** | |||
Check if main-loop is running. | |||
This is used under standalone mode to check whether to keep things running. | |||
Returning false from this function will stop the event-loop and close the window. | |||
*/ | |||
virtual bool isRunning() const | |||
{ | |||
if (ext.inUse) | |||
return ext.isRunning(); | |||
return isVisible(); | |||
} | |||
/** | |||
Check if we are about to close. | |||
This is used when the event-loop is provided by the host to check if it should close the window. | |||
It is also used in standalone mode right after isRunning() returns false to verify if window needs to be closed. | |||
*/ | |||
virtual bool isQuitting() const | |||
{ | |||
return ext.inUse ? ext.isQuitting : pData.isQuitting; | |||
} | |||
/** | |||
Get the "native" window handle. | |||
This can be reimplemented in order to pass the native window to hosts that can use such informaton. | |||
Returned value type depends on the platform: | |||
- HaikuOS: This is a pointer to a `BView`. | |||
- MacOS: This is a pointer to an `NSView*`. | |||
- Windows: This is a `HWND`. | |||
- Everything else: This is an [X11] `Window`. | |||
@note Only available to override if DISTRHO_PLUGIN_HAS_EMBED_UI is set to 1. | |||
*/ | |||
virtual uintptr_t getNativeWindowHandle() const noexcept | |||
{ | |||
return 0; | |||
} | |||
/** | |||
Grab the keyboard input focus. | |||
Typically you would setup OS-native methods to bring the window to front and give it focus. | |||
Default implementation does nothing. | |||
*/ | |||
virtual void focus() {} | |||
/* -------------------------------------------------------------------------------------------------------- | |||
* TopLevelWidget-like calls - Information, can be called by either host or plugin */ | |||
#if DISTRHO_PLUGIN_HAS_EMBED_UI | |||
/** | |||
Whether this Window is embed into another (usually not DGL-controlled) Window. | |||
*/ | |||
bool isEmbed() const noexcept | |||
{ | |||
return pData.parentWindowHandle != 0; | |||
} | |||
#endif | |||
/** | |||
Check if this window is visible. | |||
@see setVisible(bool) | |||
*/ | |||
bool isVisible() const noexcept | |||
{ | |||
return pData.visible; | |||
} | |||
/** | |||
Whether this Window is running as standalone, that is, without being coupled to a host event-loop. | |||
When in standalone mode, isRunning() is called to check if the event-loop should keep running. | |||
*/ | |||
bool isStandalone() const noexcept | |||
{ | |||
return pData.isStandalone; | |||
} | |||
/** | |||
Get width of this window. | |||
Only relevant to hosts when the UI is embedded. | |||
*/ | |||
uint getWidth() const noexcept | |||
{ | |||
return width; | |||
return pData.width; | |||
} | |||
/** | |||
Get height of this window. | |||
Only relevant to hosts when the UI is embedded. | |||
*/ | |||
uint getHeight() const noexcept | |||
{ | |||
return height; | |||
return pData.height; | |||
} | |||
/** | |||
Get the scale factor requested for this window. | |||
This is purely informational, and up to developers to choose what to do with it. | |||
*/ | |||
double getScaleFactor() const noexcept | |||
{ | |||
return pData.scaleFactor; | |||
} | |||
/** | |||
Get the title of the window previously set with setTitle(). | |||
This is typically displayed in the title bar or in window switchers. | |||
*/ | |||
const char* getTitle() const noexcept | |||
{ | |||
return title; | |||
return pData.title; | |||
} | |||
uintptr_t getTransientWinId() const noexcept | |||
#if DISTRHO_PLUGIN_HAS_EMBED_UI | |||
/** | |||
Get the "native" window handle that this window should embed itself into. | |||
Returned value type depends on the platform: | |||
- HaikuOS: This is a pointer to a `BView`. | |||
- MacOS: This is a pointer to an `NSView*`. | |||
- Windows: This is a `HWND`. | |||
- Everything else: This is an [X11] `Window`. | |||
*/ | |||
uintptr_t getParentWindowHandle() const noexcept | |||
{ | |||
return transientWinId; | |||
return pData.parentWindowHandle; | |||
} | |||
#endif | |||
bool isVisible() const noexcept | |||
/** | |||
Get the transient window that we should attach ourselves to. | |||
TODO what id? also NSView* on macOS, or NSWindow? | |||
*/ | |||
uintptr_t getTransientWindowId() const noexcept | |||
{ | |||
return visible; | |||
return pData.transientWinId; | |||
} | |||
bool isRunning() noexcept | |||
/* -------------------------------------------------------------------------------------------------------- | |||
* TopLevelWidget-like calls - actions called by either host or plugin */ | |||
/** | |||
Hide window. | |||
This is the same as calling setVisible(false). | |||
Embed windows should never call this! | |||
@see isVisible(), setVisible(bool) | |||
*/ | |||
void hide() | |||
{ | |||
if (pid <= 0) | |||
return false; | |||
setVisible(false); | |||
} | |||
const pid_t p = ::waitpid(pid, nullptr, WNOHANG); | |||
/** | |||
Hide the UI and gracefully terminate. | |||
Embed windows should never call this! | |||
*/ | |||
virtual void close() | |||
{ | |||
pData.isQuitting = true; | |||
hide(); | |||
if (p == pid || (p == -1 && errno == ECHILD)) | |||
{ | |||
printf("NOTICE: Child process exited while idle\n"); | |||
pid = 0; | |||
return false; | |||
} | |||
if (ext.inUse) | |||
terminateAndWaitForExternalProcess(); | |||
} | |||
/** | |||
Set width of this window. | |||
Can trigger a sizeChanged callback. | |||
Only relevant to hosts when the UI is embedded. | |||
*/ | |||
void setWidth(uint width) | |||
{ | |||
setSize(width, getHeight()); | |||
} | |||
/** | |||
Set height of this window. | |||
Can trigger a sizeChanged callback. | |||
Only relevant to hosts when the UI is embedded. | |||
*/ | |||
void setHeight(uint height) | |||
{ | |||
setSize(getWidth(), height); | |||
} | |||
/** | |||
Set size of this window using @a width and @a height values. | |||
Can trigger a sizeChanged callback. | |||
Only relevant to hosts when the UI is embedded. | |||
*/ | |||
void setSize(uint width, uint height) | |||
{ | |||
DISTRHO_SAFE_ASSERT_UINT2_RETURN(width > 1 && height > 1, width, height,); | |||
return true; | |||
if (pData.width == width || pData.height == height) | |||
return; | |||
pData.width = width; | |||
pData.height = height; | |||
sizeChanged(width, height); | |||
} | |||
virtual void setSize(uint w, uint h) | |||
/** | |||
Set the title of the window, typically displayed in the title bar or in window switchers. | |||
Can trigger a titleChanged callback. | |||
Only relevant to hosts when the UI is not embedded. | |||
*/ | |||
void setTitle(const char* title) | |||
{ | |||
width = w; | |||
height = h; | |||
if (pData.title == title) | |||
return; | |||
pData.title = title; | |||
titleChanged(title); | |||
} | |||
virtual void setTitle(const char* const t) | |||
/* -------------------------------------------------------------------------------------------------------- | |||
* TopLevelWidget-like calls - actions called by the host */ | |||
/** | |||
Show window. | |||
This is the same as calling setVisible(true). | |||
@see isVisible(), setVisible(bool) | |||
*/ | |||
void show() | |||
{ | |||
title = t; | |||
setVisible(true); | |||
} | |||
virtual void setTransientWinId(const uintptr_t winId) | |||
/** | |||
Set window visible (or not) according to @a visible. | |||
@see isVisible(), hide(), show() | |||
*/ | |||
void setVisible(bool visible) | |||
{ | |||
transientWinId = winId; | |||
if (pData.visible == visible) | |||
return; | |||
pData.visible = visible; | |||
visibilityChanged(visible); | |||
} | |||
virtual void setVisible(const bool yesNo) | |||
/** | |||
Called by the host to set the transient parent window that we should attach ourselves to. | |||
TODO what id? also NSView* on macOS, or NSWindow? | |||
*/ | |||
void setTransientWindowId(uintptr_t winId) | |||
{ | |||
visible = yesNo; | |||
if (pData.transientWinId == winId) | |||
return; | |||
pData.transientWinId = winId; | |||
transientParentWindowChanged(winId); | |||
} | |||
protected: | |||
/* -------------------------------------------------------------------------------------------------------- | |||
* ExternalWindow special calls for running externals tools */ | |||
bool startExternalProcess(const char* args[]) | |||
{ | |||
terminateAndWaitForProcess(); | |||
ext.inUse = true; | |||
pid = vfork(); | |||
return ext.start(args); | |||
} | |||
switch (pid) | |||
{ | |||
case 0: | |||
execvp(args[0], (char**)args); | |||
_exit(1); | |||
return false; | |||
void terminateAndWaitForExternalProcess() | |||
{ | |||
ext.isQuitting = true; | |||
ext.terminateAndWait(); | |||
} | |||
case -1: | |||
printf("Could not start external ui\n"); | |||
return false; | |||
/* -------------------------------------------------------------------------------------------------------- | |||
* ExternalWindow specific callbacks */ | |||
default: | |||
return true; | |||
} | |||
/** | |||
A callback for when the window size changes. | |||
@note WIP this might need to get fed back into the host somehow. | |||
*/ | |||
virtual void sizeChanged(uint width, uint height) | |||
{ | |||
// unused, meant for custom implementations | |||
return; (void)width; (void)height; | |||
} | |||
void terminateAndWaitForProcess() | |||
/** | |||
A callback for when the window title changes. | |||
@note WIP this might need to get fed back into the host somehow. | |||
*/ | |||
virtual void titleChanged(const char* title) | |||
{ | |||
if (pid <= 0) | |||
return; | |||
// unused, meant for custom implementations | |||
return; (void)title; | |||
} | |||
printf("Waiting for previous process to stop,,,\n"); | |||
/** | |||
A callback for when the window visibility changes. | |||
@note WIP this might need to get fed back into the host somehow. | |||
*/ | |||
virtual void visibilityChanged(bool visible) | |||
{ | |||
// unused, meant for custom implementations | |||
return; (void)visible; | |||
} | |||
/** | |||
A callback for when the transient parent window changes. | |||
*/ | |||
virtual void transientParentWindowChanged(uintptr_t winId) | |||
{ | |||
// unused, meant for custom implementations | |||
return; (void)winId; | |||
} | |||
private: | |||
friend class PluginWindow; | |||
friend class UI; | |||
struct ExternalProcess { | |||
bool inUse; | |||
bool isQuitting; | |||
mutable pid_t pid; | |||
bool sendTerm = true; | |||
ExternalProcess() | |||
: inUse(false), | |||
isQuitting(false), | |||
pid(0) {} | |||
for (pid_t p;;) | |||
bool isRunning() const noexcept | |||
{ | |||
p = ::waitpid(pid, nullptr, WNOHANG); | |||
if (pid <= 0) | |||
return false; | |||
const pid_t p = ::waitpid(pid, nullptr, WNOHANG); | |||
switch (p) | |||
if (p == pid || (p == -1 && errno == ECHILD)) | |||
{ | |||
d_stdout("NOTICE: Child process exited while idle"); | |||
pid = 0; | |||
return false; | |||
} | |||
return true; | |||
} | |||
bool start(const char* args[]) | |||
{ | |||
terminateAndWait(); | |||
pid = vfork(); | |||
switch (pid) | |||
{ | |||
case 0: | |||
if (sendTerm) | |||
{ | |||
sendTerm = false; | |||
::kill(pid, SIGTERM); | |||
} | |||
break; | |||
execvp(args[0], (char**)args); | |||
_exit(1); | |||
return false; | |||
case -1: | |||
if (errno == ECHILD) | |||
{ | |||
printf("Done! (no such process)\n"); | |||
pid = 0; | |||
return; | |||
} | |||
break; | |||
d_stderr("Could not start external ui"); | |||
return false; | |||
default: | |||
if (p == pid) | |||
return true; | |||
} | |||
} | |||
void terminateAndWait() | |||
{ | |||
if (pid <= 0) | |||
return; | |||
d_stdout("Waiting for external process to stop,,,"); | |||
bool sendTerm = true; | |||
for (pid_t p;;) | |||
{ | |||
p = ::waitpid(pid, nullptr, WNOHANG); | |||
switch (p) | |||
{ | |||
printf("Done! (clean wait)\n"); | |||
pid = 0; | |||
return; | |||
case 0: | |||
if (sendTerm) | |||
{ | |||
sendTerm = false; | |||
::kill(pid, SIGTERM); | |||
} | |||
break; | |||
case -1: | |||
if (errno == ECHILD) | |||
{ | |||
d_stdout("Done! (no such process)"); | |||
pid = 0; | |||
return; | |||
} | |||
break; | |||
default: | |||
if (p == pid) | |||
{ | |||
d_stdout("Done! (clean wait)"); | |||
pid = 0; | |||
return; | |||
} | |||
break; | |||
} | |||
break; | |||
} | |||
// 5 msec | |||
usleep(5*1000); | |||
// 5 msec | |||
usleep(5*1000); | |||
} | |||
} | |||
} | |||
private: | |||
uint width; | |||
uint height; | |||
String title; | |||
uintptr_t transientWinId; | |||
bool visible; | |||
pid_t pid; | |||
friend class UIExporter; | |||
} ext; | |||
struct PrivateData { | |||
uintptr_t parentWindowHandle; | |||
uintptr_t transientWinId; | |||
uint width; | |||
uint height; | |||
double scaleFactor; | |||
String title; | |||
bool isQuitting; | |||
bool isStandalone; | |||
bool visible; | |||
PrivateData() | |||
: parentWindowHandle(0), | |||
transientWinId(0), | |||
width(1), | |||
height(1), | |||
scaleFactor(1.0), | |||
title(), | |||
isQuitting(false), | |||
isStandalone(false), | |||
visible(false) {} | |||
} pData; | |||
DISTRHO_DECLARE_NON_COPYABLE(ExternalWindow) | |||
}; | |||
@@ -206,6 +206,8 @@ public: | |||
jackbridge_activate(fClient); | |||
std::fflush(stdout); | |||
#if DISTRHO_PLUGIN_HAS_UI | |||
if (const char* const name = jackbridge_get_client_name(fClient)) | |||
fUI.setWindowTitle(name); | |||
@@ -22,7 +22,7 @@ | |||
# define DISTRHO_PLUGIN_HAS_UI 0 | |||
#endif | |||
#if DISTRHO_PLUGIN_HAS_UI && ! defined(HAVE_DGL) | |||
#if DISTRHO_PLUGIN_HAS_UI && ! defined(HAVE_DGL) && ! DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||
# undef DISTRHO_PLUGIN_HAS_UI | |||
# define DISTRHO_PLUGIN_HAS_UI 0 | |||
#endif | |||
@@ -189,8 +189,7 @@ public: | |||
nullptr, // TODO file request | |||
nullptr, | |||
plugin->getInstancePointer(), | |||
scaleFactor), | |||
fHasScaleFactor(d_isNotZero(scaleFactor)) | |||
scaleFactor) | |||
# if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||
, fKeyboardModifiers(0) | |||
# endif | |||
@@ -400,13 +399,11 @@ protected: | |||
void setSize(uint width, uint height) | |||
{ | |||
// figure out scale factor ourselves if the host doesn't support it | |||
if (! fHasScaleFactor) | |||
{ | |||
const double scaleFactor = fUI.getScaleFactor(); | |||
width /= scaleFactor; | |||
height /= scaleFactor; | |||
} | |||
# ifdef DISTRHO_OS_MAC | |||
const double scaleFactor = fUI.getScaleFactor(); | |||
width /= scaleFactor; | |||
height /= scaleFactor; | |||
# endif | |||
hostCallback(audioMasterSizeWindow, width, height); | |||
} | |||
@@ -438,7 +435,6 @@ private: | |||
// Plugin UI | |||
UIExporter fUI; | |||
const bool fHasScaleFactor; | |||
# if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||
uint16_t fKeyboardModifiers; | |||
# endif | |||
@@ -688,13 +684,11 @@ public: | |||
{ | |||
fVstRect.right = fVstUI->getWidth(); | |||
fVstRect.bottom = fVstUI->getHeight(); | |||
// figure out scale factor ourselves if the host doesn't support it | |||
if (fLastScaleFactor == 0.0f) | |||
{ | |||
const double scaleFactor = fVstUI->getScaleFactor(); | |||
fVstRect.right /= scaleFactor; | |||
fVstRect.bottom /= scaleFactor; | |||
} | |||
# ifdef DISTRHO_OS_MAC | |||
const double scaleFactor = fVstUI->getScaleFactor(); | |||
fVstRect.right /= scaleFactor; | |||
fVstRect.bottom /= scaleFactor; | |||
# endif | |||
} | |||
else | |||
{ | |||
@@ -703,13 +697,11 @@ public: | |||
fPlugin.getInstancePointer(), fLastScaleFactor); | |||
fVstRect.right = tmpUI.getWidth(); | |||
fVstRect.bottom = tmpUI.getHeight(); | |||
// figure out scale factor ourselves if the host doesn't support it | |||
if (fLastScaleFactor == 0.0f) | |||
{ | |||
const double scaleFactor = tmpUI.getScaleFactor(); | |||
fVstRect.right /= scaleFactor; | |||
fVstRect.bottom /= scaleFactor; | |||
} | |||
# ifdef DISTRHO_OS_MAC | |||
const double scaleFactor = tmpUI.getScaleFactor(); | |||
fVstRect.right /= scaleFactor; | |||
fVstRect.bottom /= scaleFactor; | |||
# endif | |||
tmpUI.quit(); | |||
} | |||
*(ERect**)ptr = &fVstRect; | |||
@@ -1003,6 +995,10 @@ public: | |||
fUsingNsView = true; | |||
return 0xbeef0000; | |||
} | |||
#endif | |||
#ifndef DISTRHO_OS_MAC | |||
if (std::strcmp(canDo, "supportsViewDpiScaling") == 0) | |||
return 1; | |||
#endif | |||
if (std::strcmp(canDo, "receiveVstEvents") == 0 || | |||
std::strcmp(canDo, "receiveVstMidiEvent") == 0) | |||
@@ -1028,7 +1024,7 @@ public: | |||
break; | |||
case effVendorSpecific: | |||
#if DISTRHO_PLUGIN_HAS_UI | |||
#if DISTRHO_PLUGIN_HAS_UI && !defined(DISTRHO_OS_MAC) | |||
if (index == CCONST('P', 'r', 'e', 'S') && value == CCONST('A', 'e', 'C', 's')) | |||
{ | |||
if (d_isEqual(fLastScaleFactor, opt)) | |||
@@ -36,11 +36,28 @@ const char* g_nextBundlePath = nullptr; | |||
UI::PrivateData* UI::PrivateData::s_nextPrivateData = nullptr; | |||
PluginWindow& UI::PrivateData::createNextWindow(UI* const ui, const uint width, const uint height) | |||
#if DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||
ExternalWindow::PrivateData | |||
#else | |||
PluginWindow& | |||
#endif | |||
UI::PrivateData::createNextWindow(UI* const ui, const uint width, const uint height) | |||
{ | |||
UI::PrivateData* const pData = s_nextPrivateData; | |||
#if DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||
pData->window = new PluginWindow(ui, pData->app); | |||
ExternalWindow::PrivateData ewData; | |||
ewData.parentWindowHandle = pData->winId; | |||
ewData.width = width; | |||
ewData.height = height; | |||
ewData.scaleFactor = pData->scaleFactor; | |||
ewData.title = DISTRHO_PLUGIN_NAME; | |||
ewData.isStandalone = DISTRHO_UI_IS_STANDALONE; | |||
return ewData; | |||
#else | |||
pData->window = new PluginWindow(ui, pData->app, pData->winId, width, height, pData->scaleFactor); | |||
return pData->window.getObject(); | |||
#endif | |||
} | |||
/* ------------------------------------------------------------------------------------------------------------ | |||
@@ -58,6 +75,9 @@ UI::UI(const uint width, const uint height, const bool automaticallyScale) | |||
if (automaticallyScale) | |||
setGeometryConstraints(width, height, true, true); | |||
} | |||
#else | |||
// unused | |||
return; (void)automaticallyScale; | |||
#endif | |||
} | |||
@@ -71,7 +91,11 @@ UI::~UI() | |||
bool UI::isResizable() const noexcept | |||
{ | |||
#if DISTRHO_UI_USER_RESIZABLE | |||
# if DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||
return true; | |||
# else | |||
return uiData->window->isResizable(); | |||
# endif | |||
#else | |||
return false; | |||
#endif | |||
@@ -153,7 +177,7 @@ uintptr_t UI::getNextWindowId() noexcept | |||
return g_nextWindowId; | |||
} | |||
# endif | |||
#endif | |||
#endif // DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||
/* ------------------------------------------------------------------------------------------------------------ | |||
* DSP/Plugin Callbacks (optional) */ | |||
@@ -162,10 +186,14 @@ void UI::sampleRateChanged(double) | |||
{ | |||
} | |||
#if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||
/* ------------------------------------------------------------------------------------------------------------ | |||
* UI Callbacks (optional) */ | |||
void UI::uiScaleFactorChanged(double) | |||
{ | |||
} | |||
#if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||
void UI::uiFocus(bool, DGL_NAMESPACE::CrossingMode) | |||
{ | |||
} | |||
@@ -176,10 +204,6 @@ void UI::uiReshape(uint, uint) | |||
pData->fallbackOnResize(); | |||
} | |||
void UI::uiScaleFactorChanged(double) | |||
{ | |||
} | |||
# ifndef DGL_FILE_BROWSER_DISABLED | |||
void UI::uiFileBrowserSelected(const char*) | |||
{ | |||
@@ -19,10 +19,6 @@ | |||
#include "DistrhoUIPrivateData.hpp" | |||
#if DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||
# include "../extra/Sleep.hpp" | |||
#endif | |||
START_NAMESPACE_DISTRHO | |||
// ----------------------------------------------------------------------- | |||
@@ -70,10 +66,8 @@ public: | |||
uiData->bgColor = bgColor; | |||
uiData->fgColor = fgColor; | |||
#if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||
uiData->scaleFactor = scaleFactor; | |||
uiData->winId = winId; | |||
#endif | |||
uiData->callbacksPtr = callbacksPtr; | |||
uiData->editParamCallbackFunc = editParamCall; | |||
@@ -197,45 +191,13 @@ public: | |||
// ------------------------------------------------------------------- | |||
#if DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||
void exec(DGL_NAMESPACE::IdleCallback* const cb) | |||
{ | |||
DISTRHO_SAFE_ASSERT_RETURN(cb != nullptr,); | |||
DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr,); | |||
ui->setVisible(true); | |||
cb->idleCallback(); | |||
while (ui->isRunning()) | |||
{ | |||
d_msleep(10); | |||
cb->idleCallback(); | |||
} | |||
} | |||
bool idle() | |||
{ | |||
return true; | |||
} | |||
void focus() | |||
{ | |||
} | |||
void quit() | |||
{ | |||
DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr,); | |||
ui->setVisible(false); | |||
ui->terminateAndWaitForProcess(); | |||
} | |||
#else | |||
# if DISTRHO_UI_IS_STANDALONE | |||
#if DISTRHO_UI_IS_STANDALONE | |||
void exec(DGL_NAMESPACE::IdleCallback* const cb) | |||
{ | |||
DISTRHO_SAFE_ASSERT_RETURN(cb != nullptr,); | |||
uiData->window->show(); | |||
uiData->window->focus(); | |||
uiData->app.addIdleCallback(cb); | |||
uiData->app.exec(); | |||
} | |||
@@ -246,16 +208,16 @@ public: | |||
ui->uiIdle(); | |||
} | |||
# else | |||
#else | |||
bool plugin_idle() | |||
{ | |||
DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr, false); | |||
uiData->app.idle(); | |||
ui->uiIdle(); | |||
return ! uiData->app.isQuiting(); | |||
return ! uiData->app.isQuitting(); | |||
} | |||
# endif | |||
#endif | |||
void focus() | |||
{ | |||
@@ -269,50 +231,22 @@ public: | |||
if (uiData->app.isStandalone()) | |||
uiData->app.quit(); | |||
} | |||
#endif | |||
// ------------------------------------------------------------------- | |||
#if DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||
void setWindowTitle(const char* const uiTitle) | |||
{ | |||
DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr,); | |||
ui->setTitle(uiTitle); | |||
} | |||
void setWindowSize(const uint width, const uint height) | |||
{ | |||
DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr,); | |||
ui->setSize(width, height); | |||
} | |||
void setWindowTransientWinId(const uintptr_t winId) | |||
{ | |||
DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr,); | |||
ui->setTransientWinId(winId); | |||
} | |||
bool setWindowVisible(const bool yesNo) | |||
{ | |||
DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr, false); | |||
ui->setVisible(yesNo); | |||
return ui->isRunning(); | |||
} | |||
#else | |||
void setWindowTitle(const char* const uiTitle) | |||
{ | |||
uiData->window->setTitle(uiTitle); | |||
} | |||
void setWindowTransientWinId(const uintptr_t /*winId*/) | |||
void setWindowTransientWinId(const uintptr_t winId) | |||
{ | |||
#if 0 /* TODO */ | |||
#if DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||
ui->setTransientWindowId(winId); | |||
#elif 0 /* TODO */ | |||
glWindow.setTransientWinId(winId); | |||
#else | |||
(void)winId; | |||
#endif | |||
} | |||
@@ -320,9 +254,10 @@ public: | |||
{ | |||
uiData->window->setVisible(yesNo); | |||
return ! uiData->app.isQuiting(); | |||
return ! uiData->app.isQuitting(); | |||
} | |||
#if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||
bool handlePluginKeyboard(const bool press, const uint key, const uint16_t mods) | |||
{ | |||
// TODO also trigger Character input event | |||
@@ -18,9 +18,11 @@ | |||
#define DISTRHO_UI_PRIVATE_DATA_HPP_INCLUDED | |||
#include "../DistrhoUI.hpp" | |||
#include "../../dgl/Application.hpp" | |||
#if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||
#if DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||
# include "../extra/Sleep.hpp" | |||
#else | |||
# include "../../dgl/Application.hpp" | |||
# include "../../dgl/src/WindowPrivateData.hpp" | |||
# include "../../dgl/src/pugl.hpp" | |||
#endif | |||
@@ -31,18 +33,69 @@ | |||
# define DISTRHO_UI_IS_STANDALONE 0 | |||
#endif | |||
#if defined(DISTRHO_PLUGIN_TARGET_VST2) | |||
#if defined(DISTRHO_PLUGIN_TARGET_VST2) || defined(DISTRHO_PLUGIN_TARGET_VST3) | |||
# undef DISTRHO_UI_USER_RESIZABLE | |||
# define DISTRHO_UI_USER_RESIZABLE 0 | |||
#endif | |||
// ----------------------------------------------------------------------- | |||
#if DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||
START_NAMESPACE_DISTRHO | |||
#else | |||
START_NAMESPACE_DGL | |||
#endif | |||
// ----------------------------------------------------------------------- | |||
// Plugin Application, will set class name based on plugin details | |||
#if DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||
struct PluginApplication | |||
{ | |||
IdleCallback* idleCallback; | |||
UI* ui; | |||
explicit PluginApplication() | |||
: idleCallback(nullptr), | |||
ui(nullptr) {} | |||
void addIdleCallback(IdleCallback* const cb) | |||
{ | |||
DISTRHO_SAFE_ASSERT_RETURN(cb != nullptr,); | |||
DISTRHO_SAFE_ASSERT_RETURN(idleCallback == nullptr,); | |||
idleCallback = cb; | |||
} | |||
bool isQuitting() const noexcept | |||
{ | |||
return ui->isQuitting(); | |||
} | |||
bool isStandalone() const noexcept | |||
{ | |||
return DISTRHO_UI_IS_STANDALONE; | |||
} | |||
void exec() | |||
{ | |||
while (ui->isRunning()) | |||
{ | |||
d_msleep(30); | |||
idleCallback->idleCallback(); | |||
} | |||
if (! ui->isQuitting()) | |||
ui->close(); | |||
} | |||
// these are not needed | |||
void idle() {} | |||
void quit() {} | |||
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PluginApplication) | |||
}; | |||
#else | |||
class PluginApplication : public Application | |||
{ | |||
public: | |||
@@ -62,52 +115,46 @@ public: | |||
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PluginApplication) | |||
}; | |||
#endif | |||
// ----------------------------------------------------------------------- | |||
// Plugin Window, will pass some Window events to UI | |||
#if DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||
// TODO external ui stuff | |||
class PluginWindow | |||
{ | |||
DISTRHO_NAMESPACE::UI* const ui; | |||
UI* const ui; | |||
public: | |||
explicit PluginWindow(DISTRHO_NAMESPACE::UI* const uiPtr, | |||
PluginApplication& app, | |||
const uintptr_t parentWindowHandle, | |||
const uint width, | |||
const uint height, | |||
const double scaleFactor) | |||
: Window(app, parentWindowHandle, width, height, scaleFactor, DISTRHO_UI_USER_RESIZABLE), | |||
ui(uiPtr) {} | |||
uint getWidth() const noexcept | |||
{ | |||
return ui->getWidth(); | |||
} | |||
uint getHeight() const noexcept | |||
{ | |||
return ui->getHeight(); | |||
} | |||
bool isVisible() const noexcept | |||
explicit PluginWindow(UI* const uiPtr, PluginApplication& app) | |||
: ui(uiPtr) | |||
{ | |||
return ui->isRunning(); | |||
app.ui = ui; | |||
} | |||
uintptr_t getNativeWindowHandle() const noexcept | |||
{ | |||
return 0; | |||
} | |||
// fetch cached data | |||
uint getWidth() const noexcept { return ui->pData.width; } | |||
uint getHeight() const noexcept { return ui->pData.height; } | |||
double getScaleFactor() const noexcept { return ui->pData.scaleFactor; } | |||
// direct mappings | |||
void close() { ui->close(); } | |||
void focus() { ui->focus(); } | |||
void show() { ui->show(); } | |||
bool isResizable() const noexcept { return ui->isResizable(); } | |||
bool isVisible() const noexcept { return ui->isVisible(); } | |||
void setTitle(const char* const title) { ui->setTitle(title); } | |||
void setVisible(const bool visible) { ui->setVisible(visible); } | |||
uintptr_t getNativeWindowHandle() const noexcept { return ui->getNativeWindowHandle(); } | |||
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PluginWindow) | |||
}; | |||
#else | |||
#else // DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||
class PluginWindow : public Window | |||
{ | |||
DISTRHO_NAMESPACE::UI* const ui; | |||
bool initializing; | |||
bool receivedReshapeDuringInit; | |||
public: | |||
explicit PluginWindow(DISTRHO_NAMESPACE::UI* const uiPtr, | |||
@@ -116,14 +163,27 @@ public: | |||
const uint width, | |||
const uint height, | |||
const double scaleFactor) | |||
: Window(app, parentWindowHandle, width, height, scaleFactor, DISTRHO_UI_USER_RESIZABLE), | |||
ui(uiPtr) | |||
: Window(app, parentWindowHandle, width, height, scaleFactor, DISTRHO_UI_USER_RESIZABLE, false), | |||
ui(uiPtr), | |||
initializing(true), | |||
receivedReshapeDuringInit(false) | |||
{ | |||
puglBackendEnter(pData->view); | |||
if (pData->view == nullptr) | |||
return; | |||
if (pData->initPost()) | |||
puglBackendEnter(pData->view); | |||
} | |||
void leaveContext() | |||
{ | |||
if (pData->view == nullptr) | |||
return; | |||
if (receivedReshapeDuringInit) | |||
ui->uiReshape(getWidth(), getHeight()); | |||
initializing = false; | |||
puglBackendLeave(pData->view); | |||
} | |||
@@ -132,6 +192,9 @@ protected: | |||
{ | |||
DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr,); | |||
if (initializing) | |||
return; | |||
ui->uiFocus(focus, mode); | |||
} | |||
@@ -139,6 +202,12 @@ protected: | |||
{ | |||
DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr,); | |||
if (initializing) | |||
{ | |||
receivedReshapeDuringInit = true; | |||
return; | |||
} | |||
ui->uiReshape(width, height); | |||
} | |||
@@ -146,6 +215,9 @@ protected: | |||
{ | |||
DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr,); | |||
if (initializing) | |||
return; | |||
ui->uiScaleFactorChanged(scaleFactor); | |||
} | |||
@@ -155,16 +227,22 @@ protected: | |||
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PluginWindow) | |||
}; | |||
#endif // !DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||
#endif // DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||
#if DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||
END_NAMESPACE_DISTRHO | |||
#else | |||
END_NAMESPACE_DGL | |||
#endif | |||
// ----------------------------------------------------------------------- | |||
START_NAMESPACE_DISTRHO | |||
#if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||
using DGL_NAMESPACE::PluginApplication; | |||
using DGL_NAMESPACE::PluginWindow; | |||
#endif | |||
// ----------------------------------------------------------------------- | |||
// UI callbacks | |||
@@ -192,12 +270,10 @@ struct UI::PrivateData { | |||
// UI | |||
uint bgColor; | |||
uint fgColor; | |||
#if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||
double scaleFactor; | |||
uintptr_t winId; | |||
# ifndef DGL_FILE_BROWSER_DISABLED | |||
#if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI && !defined(DGL_FILE_BROWSER_DISABLED) | |||
char* uiStateFileKeyRequest; | |||
# endif | |||
#endif | |||
// Callbacks | |||
@@ -211,20 +287,16 @@ struct UI::PrivateData { | |||
PrivateData() noexcept | |||
: app(), | |||
#if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||
window(nullptr), | |||
#endif | |||
sampleRate(0), | |||
parameterOffset(0), | |||
dspPtr(nullptr), | |||
bgColor(0), | |||
fgColor(0xffffffff), | |||
#if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||
scaleFactor(1.0), | |||
winId(0), | |||
# ifndef DGL_FILE_BROWSER_DISABLED | |||
#if !DISTRHO_PLUGIN_HAS_EXTERNAL_UI && !defined(DGL_FILE_BROWSER_DISABLED) | |||
uiStateFileKeyRequest(nullptr), | |||
# endif | |||
#endif | |||
callbacksPtr(nullptr), | |||
editParamCallbackFunc(nullptr), | |||
@@ -292,7 +364,11 @@ struct UI::PrivateData { | |||
bool fileRequestCallback(const char* const key); | |||
static UI::PrivateData* s_nextPrivateData; | |||
#if DISTRHO_PLUGIN_HAS_EXTERNAL_UI | |||
static ExternalWindow::PrivateData createNextWindow(UI* ui, uint width, uint height); | |||
#else | |||
static PluginWindow& createNextWindow(UI* ui, uint width, uint height); | |||
#endif | |||
}; | |||
// ----------------------------------------------------------------------- | |||
@@ -332,6 +408,9 @@ inline void PluginWindow::onFileSelected(const char* const filename) | |||
{ | |||
DISTRHO_SAFE_ASSERT_RETURN(ui != nullptr,); | |||
if (initializing) | |||
return; | |||
# if DISTRHO_PLUGIN_WANT_STATEFILES | |||
if (char* const key = ui->uiData->uiStateFileKeyRequest) | |||
{ | |||
@@ -51,15 +51,15 @@ int main() | |||
Application app(true); | |||
IdleCallbackCounter idleCounter; | |||
app.addIdleCallback(&idleCounter); | |||
DISTRHO_ASSERT_EQUAL(app.isQuiting(), false, "app MUST NOT be set as quitting during init"); | |||
DISTRHO_ASSERT_EQUAL(app.isQuitting(), false, "app MUST NOT be set as quitting during init"); | |||
DISTRHO_ASSERT_EQUAL(idleCounter.counter, 0, "app MUST NOT have triggered idle callbacks yet"); | |||
app.idle(); | |||
DISTRHO_ASSERT_EQUAL(app.isQuiting(), false, "app MUST NOT be set as quitting after idle()"); | |||
DISTRHO_ASSERT_EQUAL(app.isQuitting(), false, "app MUST NOT be set as quitting after idle()"); | |||
DISTRHO_ASSERT_EQUAL(idleCounter.counter, 1, "app MUST have triggered 1 idle callback"); | |||
app.idle(); | |||
DISTRHO_ASSERT_EQUAL(idleCounter.counter, 2, "app MUST have triggered 2 idle callbacks"); | |||
app.quit(); | |||
DISTRHO_ASSERT_EQUAL(app.isQuiting(), true, "app MUST be set as quitting after quit()"); | |||
DISTRHO_ASSERT_EQUAL(app.isQuitting(), true, "app MUST be set as quitting after quit()"); | |||
DISTRHO_ASSERT_EQUAL(idleCounter.counter, 2, "app MUST have triggered only 2 idle callbacks in its lifetime"); | |||
} | |||
@@ -149,13 +149,6 @@ clean: | |||
# --------------------------------------------------------------------------------------------------------------------- | |||
-include $(OBJS:%.o=%.d) | |||
-include ../build/tests/Demo.cpp.cairo.d | |||
-include ../build/tests/Demo.cpp.opengl.d | |||
-include ../build/tests/Demo.cpp.vulkan.d | |||
-include ../build/tests/Window.cpp.cairo.d | |||
-include ../build/tests/Window.cpp.opengl.d | |||
-include ../build/tests/Window.cpp.stub.d | |||
-include ../build/tests/Window.cpp.vulkan.d | |||
-include $(ALL_OBJS:%.o=%.d) | |||
# --------------------------------------------------------------------------------------------------------------------- |
@@ -132,8 +132,11 @@ public: | |||
{ | |||
const uint targetWidth = 400; | |||
const uint targetHeight = 400; | |||
const double scaleFactor = getScaleFactor(); | |||
setSize(targetWidth, targetHeight); | |||
setGeometryConstraints(targetWidth, targetHeight, true); | |||
setResizable(true); | |||
setSize(targetWidth * scaleFactor, targetHeight * scaleFactor); | |||
setTitle("NanoVG SubWidgets test"); | |||
} | |||
@@ -16,7 +16,7 @@ cd repos | |||
git clone --depth 1 --recursive -b develop git://github.com/DISTRHO/DPF | |||
for PLUGIN in ${PLUGINS[@]}; do | |||
git clone --depth 1 git://github.com/DISTRHO/$PLUGIN | |||
git clone --depth 1 --recursive git://github.com/DISTRHO/$PLUGIN | |||
done | |||
cd .. | |||
@@ -1,6 +1,6 @@ | |||
/* | |||
* DISTRHO ProM Plugin | |||
* Copyright (C) 2015 Filipe Coelho <falktx@falktx.com> | |||
* Copyright (C) 2015-2021 Filipe Coelho <falktx@falktx.com> | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
@@ -22,8 +22,9 @@ | |||
#define DISTRHO_PLUGIN_URI "http://distrho.sf.net/plugins/ProM" | |||
#define DISTRHO_PLUGIN_HAS_UI 1 | |||
#define DISTRHO_PLUGIN_NUM_INPUTS 1 | |||
#define DISTRHO_PLUGIN_NUM_OUTPUTS 1 | |||
#define DISTRHO_PLUGIN_NUM_INPUTS 2 | |||
#define DISTRHO_PLUGIN_NUM_OUTPUTS 2 | |||
#define DISTRHO_UI_USER_RESIZABLE 1 | |||
// required by projectM | |||
#define DISTRHO_PLUGIN_WANT_DIRECT_ACCESS 1 | |||
@@ -57,11 +57,15 @@ void DistrhoPluginProM::setParameterValue(uint32_t, float) | |||
void DistrhoPluginProM::run(const float** inputs, float** outputs, uint32_t frames) | |||
{ | |||
const float* in = inputs[0]; | |||
float* out = outputs[0]; | |||
const float* in1 = inputs[0]; | |||
const float* in2 = inputs[1]; | |||
float* out1 = outputs[0]; | |||
float* out2 = outputs[1]; | |||
if (out != in) | |||
std::memcpy(out, in, sizeof(float)*frames); | |||
if (out1 != in1) | |||
std::memcpy(out1, in1, sizeof(float)*frames); | |||
if (out2 != in2) | |||
std::memcpy(out2, in2, sizeof(float)*frames); | |||
const MutexLocker csm(fMutex); | |||
@@ -69,7 +73,7 @@ void DistrhoPluginProM::run(const float** inputs, float** outputs, uint32_t fram | |||
return; | |||
if (PCM* const pcm = const_cast<PCM*>(fPM->pcm())) | |||
pcm->addPCMfloat(in, frames); | |||
pcm->addPCMfloat(in1, frames); | |||
} | |||
// ----------------------------------------------------------------------- | |||
@@ -1,6 +1,6 @@ | |||
/* | |||
* DISTRHO ProM Plugin | |||
* Copyright (C) 2015 Filipe Coelho <falktx@falktx.com> | |||
* Copyright (C) 2015-2021 Filipe Coelho <falktx@falktx.com> | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
@@ -14,41 +14,84 @@ | |||
* For a full copy of the license see the LICENSE file. | |||
*/ | |||
#include "libprojectM/projectM-opengl.h" | |||
#include "libprojectM/projectM.hpp" | |||
#include "DistrhoPluginProM.hpp" | |||
#include "DistrhoUIProM.hpp" | |||
#include "libprojectM/projectM.hpp" | |||
#ifndef DISTRHO_OS_WINDOWS | |||
# include <dlfcn.h> | |||
#endif | |||
#ifdef DISTRHO_OS_WINDOWS | |||
static HINSTANCE hInstance = nullptr; | |||
DISTRHO_PLUGIN_EXPORT | |||
BOOL WINAPI DllMain(HINSTANCE hInst, DWORD reason, LPVOID) | |||
{ | |||
if (reason == DLL_PROCESS_ATTACH) | |||
hInstance = hInst; | |||
return 1; | |||
} | |||
#endif | |||
START_NAMESPACE_DISTRHO | |||
// ----------------------------------------------------------------------- | |||
#if 0 | |||
static const projectM::Settings kSettings = { | |||
/* meshX */ 32, | |||
/* meshY */ 24, | |||
/* fps */ 35, | |||
/* textureSize */ 1024, | |||
/* windowWidth */ 512, | |||
/* windowHeight */ 512, | |||
/* presetURL */ "/usr/share/projectM/presets", | |||
/* titleFontURL */ "/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf", | |||
/* menuFontURL */ "/usr/share/fonts/truetype/ttf-dejavu/DejaVuSansMono.ttf", | |||
/* smoothPresetDuration */ 5, | |||
/* presetDuration */ 30, | |||
/* beatSensitivity */ 10.0f, | |||
/* aspectCorrection */ true, | |||
/* easterEgg */ 1.0f, | |||
/* shuffleEnabled */ true, | |||
/* softCutRatingsEnabled */ false | |||
}; | |||
static String getCurrentExecutableDataDir() | |||
{ | |||
static String datadir; | |||
if (datadir.isNotEmpty()) | |||
return datadir; | |||
#ifdef DISTRHO_OS_WINDOWS | |||
CHAR filename[MAX_PATH + 256]; | |||
filename[0] = '\0'; | |||
GetModuleFileName(hInstance, filename, sizeof(filename)); | |||
datadir = String(filename); | |||
datadir.truncate(datadir.rfind('\\')); | |||
#else | |||
Dl_info info; | |||
dladdr((void*)getCurrentExecutableDataDir, &info); | |||
datadir = String(info.dli_fname); | |||
datadir.truncate(datadir.rfind('/')); | |||
# ifdef DISTRHO_OS_MAC | |||
if (datadir.endsWith("/MacOS")) | |||
{ | |||
datadir.truncate(datadir.rfind('/')); | |||
datadir += "/Resources"; | |||
} | |||
else | |||
# endif | |||
#endif | |||
{ | |||
datadir += "/resources"; | |||
} | |||
return datadir; | |||
} | |||
// ----------------------------------------------------------------------- | |||
DistrhoUIProM::DistrhoUIProM() | |||
: UI(512, 512) | |||
: UI(512, 512), | |||
fPM(nullptr), | |||
fResizeHandle(this) | |||
{ | |||
// const double scaleFactor = getScaleFactor(); | |||
// if (d_isNotZero(scaleFactor)) | |||
// setSize(512*scaleFactor, 512*scaleFactor) | |||
setGeometryConstraints(256, 256, true); | |||
// no need to show resize handle if window is user-resizable | |||
// if (isResizable()) | |||
// fResizeHandle.hide(); | |||
} | |||
DistrhoUIProM::~DistrhoUIProM() | |||
@@ -89,33 +132,24 @@ void DistrhoUIProM::uiIdle() | |||
void DistrhoUIProM::uiReshape(uint width, uint height) | |||
{ | |||
glEnable(GL_BLEND); | |||
glEnable(GL_LINE_SMOOTH); | |||
glEnable(GL_POINT_SMOOTH); | |||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | |||
glShadeModel(GL_SMOOTH); | |||
glMatrixMode(GL_TEXTURE); | |||
glLoadIdentity(); | |||
glMatrixMode(GL_PROJECTION); | |||
glLoadIdentity(); | |||
glOrtho(0, width, height, 0, 0.0f, 1.0f); | |||
glViewport(0, 0, width, height); | |||
glMatrixMode(GL_MODELVIEW); | |||
glLoadIdentity(); | |||
glDrawBuffer(GL_BACK); | |||
glReadBuffer(GL_BACK); | |||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); | |||
glLineStipple(2, 0xAAAA); | |||
UI::uiReshape(width, height); | |||
if (fPM == nullptr) | |||
//fPM = new projectM(kSettings); | |||
fPM = new projectM("/usr/share/projectM/config.inp"); | |||
{ | |||
#ifdef PROJECTM_DATA_DIR | |||
fPM = new projectM(PROJECTM_DATA_DIR "/config.inp"); | |||
#else | |||
const String datadir(getCurrentExecutableDataDir()); | |||
d_stdout("ProM datadir: '%s'", datadir.buffer()); | |||
projectM::Settings settings; | |||
settings.presetURL = datadir + DISTRHO_OS_SEP_STR "presets"; | |||
settings.titleFontURL = datadir + DISTRHO_OS_SEP_STR "fonts" DISTRHO_OS_SEP_STR "Vera.ttf"; | |||
settings.menuFontURL = datadir + DISTRHO_OS_SEP_STR "fonts" DISTRHO_OS_SEP_STR "VeraMono.ttf"; | |||
settings.datadir = datadir; | |||
fPM = new projectM(settings); | |||
#endif | |||
} | |||
fPM->projectM_resetGL(width, height); | |||
} | |||
@@ -129,6 +163,84 @@ void DistrhoUIProM::onDisplay() | |||
return; | |||
fPM->renderFrame(); | |||
// turn off shaders at the end of the drawing cycle, so other things can draw properly | |||
glUseProgram(0); | |||
} | |||
static projectMKeycode dgl2pmkey(const DGL_NAMESPACE::Key key) noexcept | |||
{ | |||
switch (key) | |||
{ | |||
case DGL_NAMESPACE::kKeyBackspace: | |||
return PROJECTM_K_BACKSPACE; | |||
case DGL_NAMESPACE::kKeyEscape: | |||
return PROJECTM_K_ESCAPE; | |||
case DGL_NAMESPACE::kKeyDelete: | |||
return PROJECTM_K_DELETE; | |||
case DGL_NAMESPACE::kKeyF1: | |||
return PROJECTM_K_F1; | |||
case DGL_NAMESPACE::kKeyF2: | |||
return PROJECTM_K_F2; | |||
case DGL_NAMESPACE::kKeyF3: | |||
return PROJECTM_K_F3; | |||
case DGL_NAMESPACE::kKeyF4: | |||
return PROJECTM_K_F4; | |||
case DGL_NAMESPACE::kKeyF5: | |||
return PROJECTM_K_F5; | |||
case DGL_NAMESPACE::kKeyF6: | |||
return PROJECTM_K_F6; | |||
case DGL_NAMESPACE::kKeyF7: | |||
return PROJECTM_K_F7; | |||
case DGL_NAMESPACE::kKeyF8: | |||
return PROJECTM_K_F8; | |||
case DGL_NAMESPACE::kKeyF9: | |||
return PROJECTM_K_F9; | |||
case DGL_NAMESPACE::kKeyF10: | |||
return PROJECTM_K_F10; | |||
case DGL_NAMESPACE::kKeyF11: | |||
return PROJECTM_K_F11; | |||
case DGL_NAMESPACE::kKeyF12: | |||
return PROJECTM_K_F12; | |||
case DGL_NAMESPACE::kKeyLeft: | |||
return PROJECTM_K_LEFT; | |||
case DGL_NAMESPACE::kKeyUp: | |||
return PROJECTM_K_UP; | |||
case DGL_NAMESPACE::kKeyRight: | |||
return PROJECTM_K_RIGHT; | |||
case DGL_NAMESPACE::kKeyDown: | |||
return PROJECTM_K_DOWN; | |||
case DGL_NAMESPACE::kKeyPageUp: | |||
return PROJECTM_K_PAGEUP; | |||
case DGL_NAMESPACE::kKeyPageDown: | |||
return PROJECTM_K_PAGEDOWN; | |||
case DGL_NAMESPACE::kKeyHome: | |||
return PROJECTM_K_HOME; | |||
case DGL_NAMESPACE::kKeyEnd: | |||
return PROJECTM_K_END; | |||
case DGL_NAMESPACE::kKeyInsert: | |||
return PROJECTM_K_INSERT; | |||
case DGL_NAMESPACE::kKeyShiftL: | |||
return PROJECTM_K_LSHIFT; | |||
case DGL_NAMESPACE::kKeyShiftR: | |||
return PROJECTM_K_RSHIFT; | |||
case DGL_NAMESPACE::kKeyControlL: | |||
return PROJECTM_K_LCTRL; | |||
case DGL_NAMESPACE::kKeyControlR: | |||
case DGL_NAMESPACE::kKeyAltL: | |||
case DGL_NAMESPACE::kKeyAltR: | |||
case DGL_NAMESPACE::kKeySuperL: | |||
case DGL_NAMESPACE::kKeySuperR: | |||
case DGL_NAMESPACE::kKeyMenu: | |||
case DGL_NAMESPACE::kKeyCapsLock: | |||
case DGL_NAMESPACE::kKeyScrollLock: | |||
case DGL_NAMESPACE::kKeyNumLock: | |||
case DGL_NAMESPACE::kKeyPrintScreen: | |||
case DGL_NAMESPACE::kKeyPause: | |||
break; | |||
} | |||
return PROJECTM_K_NONE; | |||
} | |||
bool DistrhoUIProM::onKeyboard(const KeyboardEvent& ev) | |||
@@ -136,6 +248,7 @@ bool DistrhoUIProM::onKeyboard(const KeyboardEvent& ev) | |||
if (fPM == nullptr) | |||
return false; | |||
#if 0 | |||
if (ev.press && (ev.key == '1' || ev.key == '+' || ev.key == '-')) | |||
{ | |||
if (ev.key == '1') | |||
@@ -160,40 +273,84 @@ bool DistrhoUIProM::onKeyboard(const KeyboardEvent& ev) | |||
return true; | |||
} | |||
#endif | |||
// special handling for text | |||
if (fPM->isTextInputActive(true) && !ev.press) | |||
{ | |||
if (ev.key >= ' ' && ev.key <= 'z') | |||
{ | |||
std::string key; | |||
key += static_cast<char>(ev.key); | |||
fPM->setSearchText(key); | |||
return true; | |||
} | |||
else if (ev.key == DGL_NAMESPACE::kKeyBackspace) | |||
{ | |||
fPM->deleteSearchText(); | |||
return true; | |||
} | |||
} | |||
projectMKeycode pmKey = PROJECTM_K_NONE; | |||
projectMModifier pmMod = PROJECTM_KMOD_LSHIFT; | |||
projectMKeycode pmKey = PROJECTM_K_NONE; | |||
if ((ev.key >= PROJECTM_K_0 && ev.key <= PROJECTM_K_9) || | |||
(ev.key >= PROJECTM_K_A && ev.key <= PROJECTM_K_Z) || | |||
(ev.key >= PROJECTM_K_a && ev.key <= PROJECTM_K_z)) | |||
if (ev.key >= kKeyF1) | |||
{ | |||
pmKey = dgl2pmkey(static_cast<DGL_NAMESPACE::Key>(ev.key)); | |||
} | |||
else if ((ev.key >= PROJECTM_K_0 && ev.key <= PROJECTM_K_9) || | |||
(ev.key >= PROJECTM_K_A && ev.key <= PROJECTM_K_Z) || | |||
(ev.key >= PROJECTM_K_a && ev.key <= PROJECTM_K_z)) | |||
{ | |||
pmKey = static_cast<projectMKeycode>(ev.key); | |||
if (ev.key >= PROJECTM_K_A && ev.key <= PROJECTM_K_Z && (ev.mod & DGL_NAMESPACE::kModifierShift)) | |||
pmKey = static_cast<projectMKeycode>(pmKey + (PROJECTM_K_a - PROJECTM_K_A)); | |||
} | |||
else | |||
{ | |||
/* missing: | |||
* PROJECTM_K_CAPSLOCK | |||
*/ | |||
switch (ev.key) | |||
{ | |||
case DGL_NAMESPACE::kCharBackspace: | |||
case DGL_NAMESPACE::kKeyBackspace: | |||
pmKey = PROJECTM_K_BACKSPACE; | |||
break; | |||
case DGL_NAMESPACE::kCharEscape: | |||
case DGL_NAMESPACE::kKeyEscape: | |||
pmKey = PROJECTM_K_ESCAPE; | |||
break; | |||
case DGL_NAMESPACE::kCharDelete: | |||
case DGL_NAMESPACE::kKeyDelete: | |||
pmKey = PROJECTM_K_DELETE; | |||
break; | |||
case '\r': | |||
pmKey = PROJECTM_K_RETURN; | |||
break; | |||
case '/': | |||
pmKey = PROJECTM_K_SLASH; | |||
break; | |||
case '\\': | |||
pmKey = PROJECTM_K_BACKSLASH; | |||
break; | |||
case '+': | |||
pmKey = PROJECTM_K_PLUS; | |||
break; | |||
case '-': | |||
pmKey = PROJECTM_K_MINUS; | |||
break; | |||
case '=': | |||
pmKey = PROJECTM_K_EQUALS; | |||
break; | |||
default: | |||
// d_stdout("Unhandled key %u %u %c", ev.keycode, ev.key, ev.key); | |||
break; | |||
} | |||
} | |||
if (pmKey == PROJECTM_K_NONE) | |||
return false; | |||
if (ev.mod & DGL_NAMESPACE::kModifierControl) | |||
pmMod = PROJECTM_KMOD_LCTRL; | |||
fPM->key_handler(ev.press ? PROJECTM_KEYUP : PROJECTM_KEYDOWN, pmKey, pmMod); | |||
fPM->default_key_handler(ev.press ? PROJECTM_KEYUP : PROJECTM_KEYDOWN, pmKey); | |||
return true; | |||
} | |||
@@ -202,93 +359,12 @@ bool DistrhoUIProM::onSpecial(const SpecialEvent& ev) | |||
if (fPM == nullptr) | |||
return false; | |||
projectMKeycode pmKey = PROJECTM_K_NONE; | |||
projectMModifier pmMod = PROJECTM_KMOD_LSHIFT; | |||
switch (ev.key) | |||
{ | |||
case DGL_NAMESPACE::kKeyF1: | |||
pmKey = PROJECTM_K_F1; | |||
break; | |||
case DGL_NAMESPACE::kKeyF2: | |||
pmKey = PROJECTM_K_F2; | |||
break; | |||
case DGL_NAMESPACE::kKeyF3: | |||
pmKey = PROJECTM_K_F3; | |||
break; | |||
case DGL_NAMESPACE::kKeyF4: | |||
pmKey = PROJECTM_K_F4; | |||
break; | |||
case DGL_NAMESPACE::kKeyF5: | |||
pmKey = PROJECTM_K_F5; | |||
break; | |||
case DGL_NAMESPACE::kKeyF6: | |||
pmKey = PROJECTM_K_F6; | |||
break; | |||
case DGL_NAMESPACE::kKeyF7: | |||
pmKey = PROJECTM_K_F7; | |||
break; | |||
case DGL_NAMESPACE::kKeyF8: | |||
pmKey = PROJECTM_K_F8; | |||
break; | |||
case DGL_NAMESPACE::kKeyF9: | |||
pmKey = PROJECTM_K_F9; | |||
break; | |||
case DGL_NAMESPACE::kKeyF10: | |||
pmKey = PROJECTM_K_F10; | |||
break; | |||
case DGL_NAMESPACE::kKeyF11: | |||
pmKey = PROJECTM_K_F11; | |||
break; | |||
case DGL_NAMESPACE::kKeyF12: | |||
pmKey = PROJECTM_K_F12; | |||
break; | |||
case DGL_NAMESPACE::kKeyLeft: | |||
pmKey = PROJECTM_K_LEFT; | |||
break; | |||
case DGL_NAMESPACE::kKeyUp: | |||
pmKey = PROJECTM_K_UP; | |||
break; | |||
case DGL_NAMESPACE::kKeyRight: | |||
pmKey = PROJECTM_K_RIGHT; | |||
break; | |||
case DGL_NAMESPACE::kKeyDown: | |||
pmKey = PROJECTM_K_DOWN; | |||
break; | |||
case DGL_NAMESPACE::kKeyPageUp: | |||
pmKey = PROJECTM_K_PAGEUP; | |||
break; | |||
case DGL_NAMESPACE::kKeyPageDown: | |||
pmKey = PROJECTM_K_PAGEDOWN; | |||
break; | |||
case DGL_NAMESPACE::kKeyHome: | |||
pmKey = PROJECTM_K_HOME; | |||
break; | |||
case DGL_NAMESPACE::kKeyEnd: | |||
pmKey = PROJECTM_K_END; | |||
break; | |||
case DGL_NAMESPACE::kKeyInsert: | |||
pmKey = PROJECTM_K_INSERT; | |||
break; | |||
case DGL_NAMESPACE::kKeyShift: | |||
pmKey = PROJECTM_K_LSHIFT; | |||
break; | |||
case DGL_NAMESPACE::kKeyControl: | |||
pmKey = PROJECTM_K_LCTRL; | |||
break; | |||
case DGL_NAMESPACE::kKeyAlt: | |||
case DGL_NAMESPACE::kKeySuper: | |||
break; | |||
} | |||
const projectMKeycode pmKey = dgl2pmkey(ev.key); | |||
if (pmKey == PROJECTM_K_NONE) | |||
return false; | |||
if (ev.mod & DGL_NAMESPACE::kModifierControl) | |||
pmMod = PROJECTM_KMOD_LCTRL; | |||
fPM->key_handler(ev.press ? PROJECTM_KEYUP : PROJECTM_KEYDOWN, pmKey, pmMod); | |||
fPM->default_key_handler(ev.press ? PROJECTM_KEYUP : PROJECTM_KEYDOWN, pmKey); | |||
return true; | |||
} | |||
@@ -1,6 +1,6 @@ | |||
/* | |||
* DISTRHO ProM Plugin | |||
* Copyright (C) 2015 Filipe Coelho <falktx@falktx.com> | |||
* Copyright (C) 2015-2021 Filipe Coelho <falktx@falktx.com> | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
@@ -18,6 +18,7 @@ | |||
#define DISTRHO_UI_PROM_HPP_INCLUDED | |||
#include "DistrhoUI.hpp" | |||
#include "ResizeHandle.hpp" | |||
class projectM; | |||
@@ -52,6 +53,7 @@ protected: | |||
private: | |||
ScopedPointer<projectM> fPM; | |||
ResizeHandle fResizeHandle; | |||
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(DistrhoUIProM) | |||
}; | |||
@@ -18,6 +18,90 @@ FILES_DSP = \ | |||
FILES_UI = \ | |||
DistrhoUIProM.cpp | |||
# -------------------------------------------------------------- | |||
# Check for system-wide projectM | |||
HAVE_PROJECTM = $(shell pkg-config --exists libprojectM && echo true) | |||
# -------------------------------------------------------------- | |||
# Import base definitions | |||
include ../../dpf/Makefile.base.mk | |||
# -------------------------------------------------------------- | |||
# Use local copy if needed | |||
ifneq ($(HAVE_PROJECTM),true) | |||
FILES_UI += \ | |||
projectM/src/libprojectM/ConfigFile.cpp \ | |||
projectM/src/libprojectM/FileScanner.cpp \ | |||
projectM/src/libprojectM/KeyHandler.cpp \ | |||
projectM/src/libprojectM/PCM.cpp \ | |||
projectM/src/libprojectM/PipelineMerger.cpp \ | |||
projectM/src/libprojectM/Preset.cpp \ | |||
projectM/src/libprojectM/PresetChooser.cpp \ | |||
projectM/src/libprojectM/PresetFactory.cpp \ | |||
projectM/src/libprojectM/PresetFactoryManager.cpp \ | |||
projectM/src/libprojectM/PresetLoader.cpp \ | |||
projectM/src/libprojectM/TimeKeeper.cpp \ | |||
projectM/src/libprojectM/fftsg.cpp \ | |||
projectM/src/libprojectM/projectM.cpp \ | |||
projectM/src/libprojectM/timer.cpp \ | |||
projectM/src/libprojectM/wipemalloc.cpp \ | |||
projectM/src/libprojectM/MilkdropPresetFactory/BuiltinFuncs.cpp \ | |||
projectM/src/libprojectM/MilkdropPresetFactory/BuiltinParams.cpp \ | |||
projectM/src/libprojectM/MilkdropPresetFactory/CustomShape.cpp \ | |||
projectM/src/libprojectM/MilkdropPresetFactory/CustomWave.cpp \ | |||
projectM/src/libprojectM/MilkdropPresetFactory/Eval.cpp \ | |||
projectM/src/libprojectM/MilkdropPresetFactory/Expr.cpp \ | |||
projectM/src/libprojectM/MilkdropPresetFactory/Func.cpp \ | |||
projectM/src/libprojectM/MilkdropPresetFactory/IdlePreset.cpp \ | |||
projectM/src/libprojectM/MilkdropPresetFactory/InitCond.cpp \ | |||
projectM/src/libprojectM/MilkdropPresetFactory/MilkdropPreset.cpp \ | |||
projectM/src/libprojectM/MilkdropPresetFactory/MilkdropPresetFactory.cpp \ | |||
projectM/src/libprojectM/MilkdropPresetFactory/Param.cpp \ | |||
projectM/src/libprojectM/MilkdropPresetFactory/Parser.cpp \ | |||
projectM/src/libprojectM/MilkdropPresetFactory/PerFrameEqn.cpp \ | |||
projectM/src/libprojectM/MilkdropPresetFactory/PerPixelEqn.cpp \ | |||
projectM/src/libprojectM/MilkdropPresetFactory/PerPointEqn.cpp \ | |||
projectM/src/libprojectM/MilkdropPresetFactory/PresetFrameIO.cpp \ | |||
projectM/src/libprojectM/NativePresetFactory/NativePresetFactory.cpp \ | |||
projectM/src/libprojectM/Renderer/BeatDetect.cpp \ | |||
projectM/src/libprojectM/Renderer/Renderable.cpp \ | |||
projectM/src/libprojectM/Renderer/Filters.cpp \ | |||
projectM/src/libprojectM/Renderer/Renderer.cpp \ | |||
projectM/src/libprojectM/Renderer/MilkdropWaveform.cpp \ | |||
projectM/src/libprojectM/Renderer/Shader.cpp \ | |||
projectM/src/libprojectM/Renderer/PerPixelMesh.cpp \ | |||
projectM/src/libprojectM/Renderer/ShaderEngine.cpp \ | |||
projectM/src/libprojectM/Renderer/PerlinNoise.cpp \ | |||
projectM/src/libprojectM/Renderer/StaticGlShaders.cpp \ | |||
projectM/src/libprojectM/Renderer/PerlinNoiseWithAlpha.cpp \ | |||
projectM/src/libprojectM/Renderer/Texture.cpp \ | |||
projectM/src/libprojectM/Renderer/Pipeline.cpp \ | |||
projectM/src/libprojectM/Renderer/TextureManager.cpp \ | |||
projectM/src/libprojectM/Renderer/PipelineContext.cpp \ | |||
projectM/src/libprojectM/Renderer/VideoEcho.cpp \ | |||
projectM/src/libprojectM/Renderer/RenderItemDistanceMetric.cpp \ | |||
projectM/src/libprojectM/Renderer/Waveform.cpp \ | |||
projectM/src/libprojectM/Renderer/RenderItemMatcher.cpp \ | |||
projectM/src/libprojectM/Renderer/hlslparser/src/CodeWriter.cpp \ | |||
projectM/src/libprojectM/Renderer/hlslparser/src/HLSLParser.cpp \ | |||
projectM/src/libprojectM/Renderer/hlslparser/src/Engine.cpp \ | |||
projectM/src/libprojectM/Renderer/hlslparser/src/HLSLTokenizer.cpp \ | |||
projectM/src/libprojectM/Renderer/hlslparser/src/GLSLGenerator.cpp \ | |||
projectM/src/libprojectM/Renderer/hlslparser/src/HLSLTree.cpp \ | |||
projectM/src/libprojectM/Renderer/SOIL2/SOIL2.c \ | |||
projectM/src/libprojectM/Renderer/SOIL2/image_DXT.c \ | |||
projectM/src/libprojectM/Renderer/SOIL2/etc1_utils.c \ | |||
projectM/src/libprojectM/Renderer/SOIL2/image_helper.c | |||
ifeq ($(WINDOWS),true) | |||
FILES_UI += \ | |||
projectM/msvc/dlfcn.c \ | |||
projectM/msvc/GL/glew.c | |||
endif # WINDOWS | |||
endif # !HAVE_PROJECTM | |||
# -------------------------------------------------------------- | |||
# Do some magic | |||
@@ -26,13 +110,91 @@ include ../../dpf/Makefile.plugins.mk | |||
# -------------------------------------------------------------- | |||
# Extra flags | |||
ifeq ($(HAVE_PROJECTM),true) | |||
BASE_FLAGS += -DPROJECTM_DATA_DIR='"$(shell pkg-config --variable=pkgdatadir libprojectM)"' | |||
BASE_FLAGS += $(shell pkg-config --cflags libprojectM) | |||
LINK_FLAGS += $(shell pkg-config --libs libprojectM) -lpthread | |||
LINK_FLAGS += $(shell pkg-config --libs libprojectM) | |||
else # HAVE_PROJECTM | |||
# compiler macros | |||
BASE_FLAGS += -DUSE_TEXT_MENU=1 | |||
BASE_FLAGS += -DUSE_THREADS=1 | |||
# GLES stuff | |||
# BASE_FLAGS += -DUSE_GLES=1 | |||
# Experimental | |||
# BASE_FLAGS += -DHAVE_LLVM=1 | |||
ifeq ($(WINDOWS),true) | |||
BASE_FLAGS += -DDLLEXPORT= | |||
BASE_FLAGS += -DprojectM_FONT_TITLE='"fonts/Vera.tff"' | |||
BASE_FLAGS += -DprojectM_FONT_MENU='"fonts/VeraMono.ttf"' | |||
BASE_FLAGS += -DSTBI_NO_DDS=1 | |||
else # WINDOWS | |||
BASE_FLAGS += -DDATADIR_PATH='"."' | |||
BASE_FLAGS += -DHAVE_ALIGNED_ALLOC=1 | |||
BASE_FLAGS += -DHAVE_FTS_H=1 | |||
BASE_FLAGS += -DHAVE_POSIX_MEMALIGN=1 | |||
endif # WINDOWS | |||
# include dirs | |||
BASE_FLAGS += -IprojectM/src | |||
BASE_FLAGS += -IprojectM/src/libprojectM | |||
BASE_FLAGS += -IprojectM/src/libprojectM/Renderer | |||
BASE_FLAGS += -IprojectM/src/libprojectM/Renderer/hlslparser/src | |||
BASE_FLAGS += -IprojectM/src/libprojectM/MilkdropPresetFactory | |||
BASE_FLAGS += -IprojectM/src/libprojectM/NativePresetFactory | |||
BASE_FLAGS += -IprojectM/vendor | |||
ifeq ($(WINDOWS),true) | |||
BASE_FLAGS += -IprojectM/msvc | |||
endif # WINDOWS | |||
# silence projectM warnings | |||
BASE_FLAGS += -Wno-ignored-qualifiers | |||
BASE_FLAGS += -Wno-implicit-fallthrough | |||
BASE_FLAGS += -Wno-overflow | |||
BASE_FLAGS += -Wno-shift-negative-value | |||
BASE_FLAGS += -Wno-sign-compare | |||
BASE_FLAGS += -Wno-unused-parameter | |||
BASE_FLAGS += -Wno-unused-variable | |||
ifeq ($(MACOS),true) | |||
BASE_FLAGS += -Wno-constant-conversion | |||
BASE_FLAGS += -Wno-delete-non-abstract-non-virtual-dtor | |||
BASE_FLAGS += -Wno-mismatched-tags | |||
else | |||
BASE_FLAGS += -Wno-maybe-uninitialized | |||
BASE_FLAGS += -Wno-unused-but-set-variable | |||
endif # MACOS | |||
ifeq ($(WINDOWS),true) | |||
BASE_FLAGS += -Wno-cast-function-type | |||
BASE_FLAGS += -Wno-unknown-pragmas | |||
else | |||
BASE_FLAGS += -Wno-unused-function | |||
endif # WINDOWS | |||
# openmp (optional) | |||
ifeq ($(DISABLE_OPENMP),) | |||
ifneq ($(MACOS),true) | |||
CUSTOM_BUILD_FLAGS += -D_OPENMP -fopenmp | |||
CUSTOM_LINK_FLAGS += -fopenmp | |||
endif # MACOS | |||
endif # DISABLE_OPENMP | |||
# extra linker flags | |||
ifneq ($(HAIKU_OR_MACOS_OR_WINDOWS),true) | |||
LINK_FLAGS += -ldl | |||
endif | |||
ifeq ($(WINDOWS),true) | |||
LINK_FLAGS += -lpsapi | |||
endif | |||
endif # HAVE_PROJECTM | |||
LINK_FLAGS += -lpthread | |||
# -------------------------------------------------------------- | |||
# Enable all possible plugin types | |||
TARGETS += jack | |||
TARGETS += lv2 | |||
TARGETS += vst | |||
@@ -0,0 +1,180 @@ | |||
/* | |||
* Resize handle for DPF | |||
* Copyright (C) 2021 Filipe Coelho <falktx@falktx.com> | |||
* | |||
* Permission to use, copy, modify, and/or distribute this software for any purpose with | |||
* or without fee is hereby granted, provided that the above copyright notice and this | |||
* permission notice appear in all copies. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD | |||
* TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN | |||
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | |||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER | |||
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | |||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |||
*/ | |||
#pragma once | |||
#include "TopLevelWidget.hpp" | |||
#include "Color.hpp" | |||
START_NAMESPACE_DGL | |||
/** Resize handle for DPF windows, will sit on bottom-right. */ | |||
class ResizeHandle : public TopLevelWidget | |||
{ | |||
public: | |||
/** Constructor for placing this handle on top of a window. */ | |||
explicit ResizeHandle(Window& window) | |||
: TopLevelWidget(window), | |||
handleSize(16), | |||
resizing(false) | |||
{ | |||
resetArea(); | |||
} | |||
/** Overloaded constructor, will fetch the window from an existing top-level widget. */ | |||
explicit ResizeHandle(TopLevelWidget* const tlw) | |||
: TopLevelWidget(tlw->getWindow()), | |||
handleSize(16), | |||
resizing(false) | |||
{ | |||
resetArea(); | |||
} | |||
/** Set the handle size, minimum 16. */ | |||
void setHandleSize(const uint size) | |||
{ | |||
handleSize = std::max(16u, size); | |||
resetArea(); | |||
} | |||
protected: | |||
void onDisplay() override | |||
{ | |||
const GraphicsContext& context(getGraphicsContext()); | |||
const double lineWidth = 1.0 * getScaleFactor(); | |||
// draw white lines, 1px wide | |||
Color(1.0f, 1.0f, 1.0f).setFor(context); | |||
l1.draw(context, lineWidth); | |||
l2.draw(context, lineWidth); | |||
l3.draw(context, lineWidth); | |||
// draw black lines, offset by 1px and 1px wide | |||
Color(0.0f, 0.0f, 0.0f).setFor(context); | |||
Line<double> l1b(l1), l2b(l2), l3b(l3); | |||
l1b.moveBy(lineWidth, lineWidth); | |||
l2b.moveBy(lineWidth, lineWidth); | |||
l3b.moveBy(lineWidth, lineWidth); | |||
l1b.draw(context, lineWidth); | |||
l2b.draw(context, lineWidth); | |||
l3b.draw(context, lineWidth); | |||
} | |||
bool onMouse(const MouseEvent& ev) override | |||
{ | |||
if (ev.button != 1) | |||
return false; | |||
if (ev.press && area.contains(ev.pos)) | |||
{ | |||
resizing = true; | |||
resizingSize = Size<double>(getWidth(), getHeight()); | |||
lastResizePoint = ev.pos; | |||
return true; | |||
} | |||
if (resizing && ! ev.press) | |||
{ | |||
resizing = false; | |||
return true; | |||
} | |||
return false; | |||
} | |||
bool onMotion(const MotionEvent& ev) override | |||
{ | |||
if (! resizing) | |||
return false; | |||
const Size<double> offset(ev.pos.getX() - lastResizePoint.getX(), | |||
ev.pos.getY() - lastResizePoint.getY()); | |||
resizingSize += offset; | |||
lastResizePoint = ev.pos; | |||
// TODO min width, min height | |||
const uint minWidth = 16; | |||
const uint minHeight = 16; | |||
if (resizingSize.getWidth() < minWidth) | |||
resizingSize.setWidth(minWidth); | |||
if (resizingSize.getWidth() > 16384) | |||
resizingSize.setWidth(16384); | |||
if (resizingSize.getHeight() < minHeight) | |||
resizingSize.setHeight(minHeight); | |||
if (resizingSize.getHeight() > 16384) | |||
resizingSize.setHeight(16384); | |||
setSize(resizingSize.getWidth(), resizingSize.getHeight()); | |||
return true; | |||
} | |||
void onResize(const ResizeEvent& ev) override | |||
{ | |||
TopLevelWidget::onResize(ev); | |||
resetArea(); | |||
} | |||
private: | |||
Rectangle<uint> area; | |||
Line<double> l1, l2, l3; | |||
uint handleSize; | |||
// event handling state | |||
bool resizing; | |||
Point<double> lastResizePoint; | |||
Size<double> resizingSize; | |||
void resetArea() | |||
{ | |||
const double scaleFactor = getScaleFactor(); | |||
const uint margin = 0.0 * scaleFactor; | |||
const uint size = handleSize * scaleFactor; | |||
area = Rectangle<uint>(getWidth() - size - margin, | |||
getHeight() - size - margin, | |||
size, size); | |||
recreateLines(area.getX(), area.getY(), size); | |||
} | |||
void recreateLines(const uint x, const uint y, const uint size) | |||
{ | |||
uint linesize = size; | |||
uint offset = 0; | |||
// 1st line, full diagonal size | |||
l1.setStartPos(x + size, y); | |||
l1.setEndPos(x, y + size); | |||
// 2nd line, bit more to the right and down, cropped | |||
offset += size / 3; | |||
linesize -= size / 3; | |||
l2.setStartPos(x + linesize + offset, y + offset); | |||
l2.setEndPos(x + offset, y + linesize + offset); | |||
// 3rd line, even more right and down | |||
offset += size / 3; | |||
linesize -= size / 3; | |||
l3.setStartPos(x + linesize + offset, y + offset); | |||
l3.setEndPos(x + offset, y + linesize + offset); | |||
} | |||
DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ResizeHandle) | |||
}; | |||
END_NAMESPACE_DGL |
@@ -0,0 +1,15 @@ | |||
/* | |||
* DISTRHO ProM Plugin | |||
* Copyright (C) 2015-2021 Filipe Coelho <falktx@falktx.com> | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU Lesser General Public License for more details. | |||
* | |||
* For a full copy of the license see the LICENSE file. | |||
*/ |
@@ -0,0 +1,184 @@ | |||
# AppVeyor build configuration | |||
# https://www.appveyor.com/docs/build-configuration | |||
# https://www.appveyor.com/docs/appveyor-yml/ | |||
#---------------------------------# | |||
# general configuration # | |||
#---------------------------------# | |||
# version format | |||
version: 1.0.1.0.0.7.{build}-{branch} | |||
#---------------------------------# | |||
# environment configuration # | |||
#---------------------------------# | |||
# Build worker image (VM template) | |||
image: Visual Studio 2019 | |||
# Enable Windows RDP Client Access to Build Worker | |||
init: | |||
- ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) | |||
#---------------------------------# | |||
# build configuration # | |||
#---------------------------------# | |||
# add several platforms to build matrix: | |||
platform: | |||
- x64 | |||
# - ARM | |||
# - Win32 | |||
# add several configurations to build matrix: | |||
configuration: | |||
- Release | |||
# - Debug | |||
# - AnalysisRelease | |||
matrix: | |||
allow_failures: | |||
- platform: ARM | |||
- platform: Win32 | |||
- configuration: Debug | |||
# scripts to run before build | |||
before_build: | |||
# packages from nuget | |||
- nuget restore %APPVEYOR_BUILD_FOLDER%\msvc\projectM.sln | |||
- nuget restore %APPVEYOR_BUILD_FOLDER%\src\EyeTune.WindowsUniversal.Application.sln | |||
# use custom build_script | |||
build_script: | |||
- ECHO BUILD %CONFIGURATION% %PLATFORM% | |||
- ps: msbuild $env:APPVEYOR_BUILD_FOLDER\msvc\projectM.sln /m /p:Configuration=$env:CONFIGURATION /p:Platform=$env:PLATFORM /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" | |||
- ps: msbuild $env:APPVEYOR_BUILD_FOLDER\src\EyeTune.WindowsUniversal.Application.sln /m /p:Configuration=$env:CONFIGURATION /p:Platform=$env:PLATFORM /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" /p:AppxPackage=false | |||
# scripts to run after build | |||
after_build: | |||
# zip the bench archive | |||
- tree /F %APPVEYOR_BUILD_FOLDER%\msvc | |||
- 7z a projectM-sdl-%CONFIGURATION%-%PLATFORM%-%APPVEYOR_REPO_COMMIT%.zip %APPVEYOR_BUILD_FOLDER%\msvc\projectM-sdl | |||
# zip the build archive | |||
- tree /F build-win\%CONFIGURATION%\%PLATFORM% | |||
- 7z a libprojectM-%CONFIGURATION%-%PLATFORM%-%APPVEYOR_REPO_COMMIT%.zip %APPVEYOR_BUILD_FOLDER%\msvc\libprojectM | |||
#---------------------------------# | |||
# tests configuration # | |||
#---------------------------------# | |||
# to disable automatic tests | |||
test: off | |||
#---------------------------------# | |||
# artifacts configuration # | |||
#---------------------------------# | |||
#specify artifacts to upload | |||
artifacts: | |||
- path: projectM-sdl-%CONFIGURATION%-%PLATFORM%-%APPVEYOR_REPO_COMMIT%.zip | |||
name: projectM-sdl-%CONFIGURATION%-%PLATFORM% | |||
- path: libprojectM-%CONFIGURATION%-%PLATFORM%-%APPVEYOR_REPO_COMMIT%.zip | |||
name: libprojectM-%CONFIGURATION%-%PLATFORM% | |||
- path: msvc\Setup\%CONFIGURATION%\%PLATFORM%\* | |||
name: projectM-Setup-%CONFIGURATION%-%PLATFORM% | |||
#---------------------------------# | |||
# deployment configuration # | |||
#---------------------------------# | |||
# to disable deployment | |||
deploy: off | |||
#---------------------------------# | |||
# global handlers # | |||
#---------------------------------# | |||
# on successful build | |||
on_success: | |||
- ECHO "BUILD VICTORY" | |||
# on build failure | |||
on_failure: | |||
- ECHO "TRY AND TRY AGAIN" | |||
# after build failure or success | |||
on_finish: | |||
# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) | |||
# https://www.appveyor.com/docs/environment-variables/ | |||
# Environment variables that are set by AppVeyor for every build: | |||
# APPVEYOR - True if build runs in AppVeyor environment; | |||
- ECHO %APPVEYOR% | |||
# CI - True if build runs in AppVeyor environment; | |||
- ECHO %CI% | |||
# APPVEYOR_API_URL - AppVeyor Build Agent API URL; | |||
- ECHO %APPVEYOR_API_URL% | |||
# APPVEYOR_ACCOUNT_NAME - account name; | |||
- ECHO %APPVEYOR_ACCOUNT_NAME% | |||
# APPVEYOR_PROJECT_ID - AppVeyor unique project ID; | |||
- ECHO %APPVEYOR_PROJECT_ID% | |||
# APPVEYOR_PROJECT_NAME - project name; | |||
- ECHO %APPVEYOR_PROJECT_NAME% | |||
# APPVEYOR_PROJECT_SLUG - project slug (as seen in project details URL); | |||
- ECHO %APPVEYOR_PROJECT_SLUG% | |||
# APPVEYOR_BUILD_FOLDER - path to clone directory; | |||
- ECHO %APPVEYOR_BUILD_FOLDER% | |||
# APPVEYOR_BUILD_ID - AppVeyor unique build ID; | |||
- ECHO %APPVEYOR_BUILD_ID% | |||
# APPVEYOR_BUILD_NUMBER - build number; | |||
- ECHO %APPVEYOR_BUILD_NUMBER% | |||
# APPVEYOR_BUILD_VERSION - build version; | |||
- ECHO %APPVEYOR_BUILD_VERSION% | |||
# APPVEYOR_PULL_REQUEST_NUMBER - GitHub Pull Request number; | |||
- ECHO %APPVEYOR_PULL_REQUEST_NUMBER% | |||
# APPVEYOR_PULL_REQUEST_TITLE - GitHub Pull Request title | |||
- ECHO %APPVEYOR_PULL_REQUEST_TITLE% | |||
# APPVEYOR_JOB_ID - AppVeyor unique job ID; | |||
- ECHO %APPVEYOR_JOB_ID% | |||
# APPVEYOR_JOB_NAME - job name; | |||
- ECHO %APPVEYOR_JOB_NAME% | |||
# APPVEYOR_REPO_PROVIDER - github, bitbucket, kiln, vso or gitlab; | |||
- ECHO %APPVEYOR_REPO_PROVIDER% | |||
# APPVEYOR_REPO_SCM - git or mercurial; | |||
- ECHO %APPVEYOR_REPO_SCM% | |||
# APPVEYOR_REPO_NAME - repository name in format owner-name/repo-name; | |||
- ECHO %APPVEYOR_REPO_NAME% | |||
# APPVEYOR_REPO_BRANCH - build branch. For Pull Request commits it is base branch PR is merging into; | |||
- ECHO %APPVEYOR_REPO_BRANCH% | |||
# APPVEYOR_REPO_TAG - true if build has started by pushed tag; otherwise false; | |||
- ECHO %APPVEYOR_REPO_TAG% | |||
# APPVEYOR_REPO_TAG_NAME - contains tag name for builds started by tag; otherwise this variable is undefined; | |||
- ECHO %APPVEYOR_REPO_TAG_NAME% | |||
# APPVEYOR_REPO_COMMIT - commit ID (SHA); | |||
- ECHO %APPVEYOR_REPO_COMMIT% | |||
# APPVEYOR_REPO_COMMIT_AUTHOR - commit author’s name; | |||
- ECHO %APPVEYOR_REPO_COMMIT_AUTHOR% | |||
# APPVEYOR_REPO_COMMIT_AUTHOR_EMAIL - commit author’s email address; | |||
- ECHO %APPVEYOR_REPO_COMMIT_AUTHOR_EMAIL% | |||
# APPVEYOR_REPO_COMMIT_TIMESTAMP - commit date/time; | |||
- ECHO %APPVEYOR_REPO_COMMIT_TIMESTAMP% | |||
# | |||
# commit message disabled; can cause false failure | |||
# | |||
# APPVEYOR_REPO_COMMIT_MESSAGE - commit message; | |||
# - ECHO %APPVEYOR_REPO_COMMIT_MESSAGE% | |||
# APPVEYOR_REPO_COMMIT_MESSAGE_EXTENDED - the rest of commit message after line break (if exists); | |||
# - ECHO %APPVEYOR_REPO_COMMIT_MESSAGE_EXTENDED% | |||
# APPVEYOR_SCHEDULED_BUILD - True if the build runs by scheduler; | |||
- ECHO %APPVEYOR_SCHEDULED_BUILD% | |||
# APPVEYOR_FORCED_BUILD (True or undefined) - builds started by “New build” button or from the same API; | |||
- ECHO %APPVEYOR_FORCED_BUILD% | |||
# APPVEYOR_RE_BUILD (True or undefined) - build started by “Re-build commit/PR” button of from the same API; | |||
- ECHO %APPVEYOR_RE_BUILD% | |||
# PLATFORM - platform name set on Build tab of project settings (or through platform parameter in appveyor.yml); | |||
- ECHO %PLATFORM% | |||
# CONFIGURATION - configuration name set on Build tab of project settings (or through configuration parameter in appveyor.yml); | |||
- ECHO %CONFIGURATION% | |||
#---------------------------------# | |||
# notifications # | |||
#---------------------------------# | |||
notifications: | |||
- provider: Email | |||
to: | |||
- RobertPancoast77@gmail.com | |||
@@ -0,0 +1,40 @@ | |||
# https://circleci.com/docs/2.0/ | |||
version: 2 | |||
jobs: | |||
build-and-pack: | |||
macos: | |||
xcode: "8.3.3" | |||
working_directory: ~/projectm/ | |||
steps: | |||
- checkout | |||
- run: | |||
name: Dependencies | |||
command: | | |||
brew update | |||
brew install llvm qt5 gsl lzo jpeg libpng libtiff libsndfile tree p7zip wget | |||
- run: | |||
name: Build | |||
command: | | |||
export QTDIR="/usr/local/opt/qt5" | |||
export PATH="$QTDIR/bin:$PATH" | |||
export LDFLAGS="-L$QTDIR/lib $LDFLAGS" | |||
export CPPFLAGS="-I$QTDIR/include $CPPFLAGS" | |||
sh ~/projectm/projectm/mac/build_deploy.sh | |||
- run: | |||
name: Pack | |||
command: | | |||
mkdir -p ~/projectm/build/artifacts/ | |||
cd ~/projectm/build/ && 7z a artifacts/projectm-macOS-$CIRCLE_SHA1.zip projectm.app | |||
mv ~/projectm/build/projectm.dmg ~/projectm/build/artifacts/projectm-macOS-$CIRCLE_SHA1.dmg | |||
cd ~/projectm/build/ && tree . | |||
- store_artifacts: | |||
path: ~/projectm/build/artifacts/ | |||
workflows: | |||
version: 2 | |||
build-and-deploy: | |||
jobs: | |||
- build-and-pack | |||
@@ -0,0 +1,66 @@ | |||
# Generated from CLion C/C++ Code Style settings | |||
BasedOnStyle: LLVM | |||
AccessModifierOffset: -4 | |||
AlignAfterOpenBracket: Align | |||
AlignConsecutiveAssignments: None | |||
AlignOperands: Align | |||
AllowAllArgumentsOnNextLine: false | |||
AllowAllConstructorInitializersOnNextLine: false | |||
AllowAllParametersOfDeclarationOnNextLine: false | |||
AllowShortBlocksOnASingleLine: Always | |||
AllowShortCaseLabelsOnASingleLine: false | |||
AllowShortFunctionsOnASingleLine: None | |||
AllowShortIfStatementsOnASingleLine: Never | |||
AllowShortLambdasOnASingleLine: All | |||
AllowShortLoopsOnASingleLine: false | |||
AlwaysBreakAfterReturnType: None | |||
AlwaysBreakTemplateDeclarations: Yes | |||
BreakBeforeBraces: Custom | |||
BraceWrapping: | |||
AfterCaseLabel: false | |||
AfterClass: true | |||
AfterControlStatement: Always | |||
AfterEnum: true | |||
AfterFunction: true | |||
AfterNamespace: false | |||
AfterUnion: true | |||
BeforeCatch: true | |||
BeforeElse: true | |||
IndentBraces: false | |||
SplitEmptyFunction: true | |||
SplitEmptyRecord: true | |||
BreakBeforeBinaryOperators: None | |||
BreakBeforeTernaryOperators: true | |||
BreakConstructorInitializers: BeforeComma | |||
BreakInheritanceList: BeforeColon | |||
ColumnLimit: 0 | |||
CompactNamespaces: false | |||
ContinuationIndentWidth: 4 | |||
IndentCaseLabels: true | |||
IndentPPDirectives: None | |||
IndentWidth: 4 | |||
KeepEmptyLinesAtTheStartOfBlocks: true | |||
MaxEmptyLinesToKeep: 2 | |||
NamespaceIndentation: None | |||
ObjCSpaceAfterProperty: false | |||
ObjCSpaceBeforeProtocolList: true | |||
PointerAlignment: Left | |||
ReflowComments: false | |||
SpaceAfterCStyleCast: true | |||
SpaceAfterLogicalNot: false | |||
SpaceAfterTemplateKeyword: false | |||
SpaceBeforeAssignmentOperators: true | |||
SpaceBeforeCpp11BracedList: false | |||
SpaceBeforeCtorInitializerColon: true | |||
SpaceBeforeInheritanceColon: true | |||
SpaceBeforeParens: ControlStatements | |||
SpaceBeforeRangeBasedForLoopColon: true | |||
SpaceInEmptyParentheses: false | |||
SpacesBeforeTrailingComments: 0 | |||
SpacesInAngles: false | |||
SpacesInCStyleCastParentheses: false | |||
SpacesInContainerLiterals: false | |||
SpacesInParentheses: false | |||
SpacesInSquareBrackets: false | |||
TabWidth: 4 | |||
UseTab: Never |
@@ -0,0 +1,12 @@ | |||
# These are supported funding model platforms | |||
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] | |||
patreon: # Replace with a single Patreon username | |||
open_collective: projectm | |||
ko_fi: # Replace with a single Ko-fi username | |||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel | |||
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry | |||
liberapay: # Replace with a single Liberapay username | |||
issuehunt: # Replace with a single IssueHunt username | |||
otechie: # Replace with a single Otechie username | |||
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] |
@@ -0,0 +1,25 @@ | |||
--- | |||
name: Bug report | |||
about: Create a report to help us improve | |||
title: '' | |||
labels: '' | |||
assignees: '' | |||
--- | |||
<!-- Please note: the Android and iOS apps are not a part of this open source project and are not maintained by it. We don't know how to help you. --> | |||
**Describe the bug** | |||
<!-- A clear and concise description of what the bug is. --> | |||
**Screenshots** | |||
If applicable, add screenshots to help explain your problem. | |||
**Desktop (please complete the following information):** | |||
- Application: [e.g. Steam, SDL, pulseaudio] | |||
- OS: [e.g. macOS, linux, windows] | |||
- Version [e.g. 3.1.12] | |||
**Additional context** | |||
Add any other context about the problem here. |
@@ -0,0 +1,20 @@ | |||
--- | |||
name: Feature request | |||
about: Suggest an idea for this project | |||
title: '' | |||
labels: '' | |||
assignees: '' | |||
--- | |||
**Is your feature request related to a problem? Please describe.** | |||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] | |||
**Describe the solution you'd like** | |||
A clear and concise description of what you want to happen. | |||
**Describe alternatives you've considered** | |||
A clear and concise description of any alternative solutions or features you've considered. | |||
**Additional context** | |||
Add any other context or screenshots about the feature request here. |
@@ -0,0 +1,24 @@ | |||
if("${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "Windows") | |||
execute_process(COMMAND "${CMAKE_COMMAND}" --build "$ENV{GITHUB_WORKSPACE}/cmake-build" | |||
--config $ENV{BUILD_TYPE} | |||
RESULT_VARIABLE result | |||
) | |||
elseif("${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "Linux") | |||
execute_process(COMMAND "${CMAKE_COMMAND}" --build "$ENV{GITHUB_WORKSPACE}/cmake-build" | |||
-- -j 3 | |||
RESULT_VARIABLE result | |||
) | |||
elseif("${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "Darwin") | |||
execute_process(COMMAND "${CMAKE_COMMAND}" --build "$ENV{GITHUB_WORKSPACE}/cmake-build" | |||
--config $ENV{BUILD_TYPE} | |||
-- -j 5 | |||
RESULT_VARIABLE result | |||
) | |||
endif() | |||
if(NOT result EQUAL 0) | |||
message(FATAL_ERROR "CMake returned bad exit status") | |||
endif() |
@@ -0,0 +1,37 @@ | |||
name: CMake Build | |||
on: [ push, pull_request ] | |||
env: | |||
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) | |||
BUILD_TYPE: Release | |||
jobs: | |||
build: | |||
runs-on: ${{ matrix.os }} | |||
strategy: | |||
fail-fast: false | |||
matrix: | |||
os: [ windows-latest, ubuntu-latest, macos-latest ] | |||
steps: | |||
- uses: actions/checkout@v2 | |||
- name: Install Prerequisites | |||
run: cmake -P ${{ github.workspace }}/.github/workflows/install_prerequisites.cmake | |||
- name: Configure CMake | |||
run: cmake -P ${{ github.workspace }}/.github/workflows/configure.cmake | |||
- name: Build | |||
run: cmake -P ${{ github.workspace }}/.github/workflows/build.cmake | |||
- name: Package | |||
run: cmake -P ${{ github.workspace }}/.github/workflows/package.cmake | |||
- name: Upload Artifact | |||
uses: actions/upload-artifact@v2 | |||
with: | |||
name: ${{ matrix.os }} | |||
path: package/projectM-* |
@@ -0,0 +1,39 @@ | |||
if("${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "Windows") | |||
execute_process(COMMAND "${CMAKE_COMMAND}" | |||
-G "Visual Studio 16 2019" | |||
-A "X64" | |||
-S "$ENV{GITHUB_WORKSPACE}" | |||
-B "$ENV{GITHUB_WORKSPACE}/cmake-build" | |||
-DTARGET_TRIPLET=x64-windows | |||
-DCMAKE_VERBOSE_MAKEFILE=YES | |||
"-DCMAKE_INSTALL_PREFIX=$ENV{GITHUB_WORKSPACE}/cmake-install" | |||
"-DCMAKE_TOOLCHAIN_FILE=$ENV{VCPKG_INSTALLATION_ROOT}/scripts/buildsystems/vcpkg.cmake" | |||
RESULT_VARIABLE result | |||
) | |||
elseif("${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "Linux") | |||
execute_process(COMMAND "${CMAKE_COMMAND}" | |||
-G "Unix Makefiles" | |||
-S "$ENV{GITHUB_WORKSPACE}" | |||
-B "$ENV{GITHUB_WORKSPACE}/cmake-build" | |||
-DCMAKE_VERBOSE_MAKEFILE=YES | |||
-DCMAKE_BUILD_TYPE=$ENV{BUILD_TYPE} | |||
"-DCMAKE_INSTALL_PREFIX=$ENV{GITHUB_WORKSPACE}/cmake-install" | |||
RESULT_VARIABLE result | |||
) | |||
elseif("${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "Darwin") | |||
execute_process(COMMAND "${CMAKE_COMMAND}" | |||
-G "Unix Makefiles" | |||
-S "$ENV{GITHUB_WORKSPACE}" | |||
-B "$ENV{GITHUB_WORKSPACE}/cmake-build" | |||
-DCMAKE_VERBOSE_MAKEFILE=YES | |||
"-DCMAKE_INSTALL_PREFIX=$ENV{GITHUB_WORKSPACE}/cmake-install" | |||
RESULT_VARIABLE result | |||
) | |||
endif() | |||
if(NOT result EQUAL 0) | |||
message(FATAL_ERROR "CMake returned bad exit status") | |||
endif() |
@@ -0,0 +1,47 @@ | |||
message(STATUS "Using host CMake version: ${CMAKE_VERSION}") | |||
if("${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "Windows") | |||
# On Windows, using vcpkg to install and build is the best practice. | |||
set(VCPKG "$ENV{VCPKG_INSTALLATION_ROOT}/vcpkg.exe") | |||
execute_process(COMMAND "${VCPKG}" --triplet=x64-windows install glew sdl2 | |||
RESULT_VARIABLE result | |||
) | |||
elseif("${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "Linux") | |||
# On Ubuntu, installing the required dev packages is sufficient | |||
message(STATUS "Updating apt package sources") | |||
execute_process(COMMAND sudo apt-get update | |||
COMMAND sudo apt-get -f install | |||
RESULT_VARIABLE result | |||
) | |||
if(NOT result EQUAL 0) | |||
message(FATAL_ERROR "Could not update apt package lists") | |||
endif() | |||
execute_process(COMMAND sudo apt-get install | |||
libgl1-mesa-dev | |||
mesa-common-dev | |||
libsdl2-dev | |||
libglm-dev | |||
qtbase5-dev | |||
llvm-dev | |||
libvisual-0.4-dev | |||
libjack-jackd2-dev | |||
RESULT_VARIABLE result | |||
) | |||
elseif("${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "Darwin") | |||
# macOS uses Homebrew to install additional software packages. | |||
execute_process(COMMAND brew update | |||
COMMAND brew install sdl2 | |||
RESULT_VARIABLE result | |||
) | |||
endif() | |||
if(NOT result EQUAL 0) | |||
message(FATAL_ERROR "A command returned bad exit status") | |||
endif() |
@@ -0,0 +1,21 @@ | |||
if("${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "Windows") | |||
execute_process(COMMAND "${CMAKE_CPACK_COMMAND}" | |||
-G ZIP | |||
--config "$ENV{GITHUB_WORKSPACE}/cmake-build/CPackConfig.cmake" | |||
-B "$ENV{GITHUB_WORKSPACE}/package" | |||
RESULT_VARIABLE result | |||
) | |||
else("${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "Linux") | |||
execute_process(COMMAND "${CMAKE_CPACK_COMMAND}" | |||
-G TGZ | |||
--config "$ENV{GITHUB_WORKSPACE}/cmake-build/CPackConfig.cmake" | |||
-B "$ENV{GITHUB_WORKSPACE}/package" | |||
RESULT_VARIABLE result | |||
) | |||
endif() | |||
if(NOT result EQUAL 0) | |||
message(FATAL_ERROR "CPack returned bad exit status") | |||
endif() |
@@ -0,0 +1,60 @@ | |||
build_logs/ | |||
xcuserdata | |||
src/libprojectM/config.inp | |||
src/libprojectM/config.inp.b | |||
src/libprojectM/config.inp.in | |||
src/projectM-emscripten/build/presets | |||
presets/custom | |||
project.xcworkspace | |||
*.o | |||
*.lo | |||
*.la | |||
*.a | |||
projectM-*.tar.gz | |||
.deps/ | |||
.libs/ | |||
Makefile | |||
Makefile.in | |||
/aclocal.m4 | |||
/autom4te.cache | |||
/build-aux | |||
/config.h | |||
/config.h.in | |||
/configure | |||
/libtool | |||
/stamp-h1 | |||
.dirstamp | |||
/src/libprojectM/config.h | |||
ar-lib | |||
compile | |||
depcomp | |||
install-sh | |||
ltmain.sh | |||
missing | |||
m4/libtool.m4 | |||
m4/ltoptions.m4 | |||
m4/ltsugar.m4 | |||
m4/ltversion.m4 | |||
m4/lt~obsolete.m4 | |||
/t | |||
/src/libprojectM/libprojectM.pc | |||
/build | |||
/dist | |||
# Visual Studio w/CMake | |||
/out | |||
/.vs | |||
/CMakeSettings.json | |||
_sync.bat | |||
_sync.sh | |||
to_sync/ | |||
.DS_Store | |||
src/projectM-sdl/build/ | |||
src/libprojectM/build/ | |||
*.pkg | |||
# CLion | |||
cmake-build-* | |||
.idea |
@@ -0,0 +1,78 @@ | |||
language: cpp | |||
compiler: | |||
- clang | |||
- gcc | |||
before_script: | |||
- ./autogen.sh | |||
before_install: | |||
- eval "${MATRIX_EVAL}" | |||
- if [ $TRAVIS_OS_NAME == "osx" ]; then sudo sntp -sS time.apple.com; fi | |||
addons: | |||
apt: | |||
packages: | |||
- libc++-dev | |||
- libsdl2-dev | |||
- libgl1-mesa-dev | |||
script: | |||
- ./configure $PM_OPTS --prefix=$PWD/local && make -j6 && make install # build from checkout | |||
- export PMVER=$(./configure --version | cut -d ' ' -f 3 | grep -m 1 .) # get pM version | |||
- make dist && tar -zxf projectM-${PMVER}.tar.gz && cd projectM-${PMVER} && ./configure $PM_OPTS --prefix=$PWD/dist_install && make -j6 && make install # build from dist | |||
- echo "PWD=$PWD" | |||
- ls . | |||
- test -e src/projectM-sdl/projectMSDL | |||
- test -e src/libprojectM/libprojectM.la | |||
- test -e dist_install/share/projectM/fonts/Vera.ttf | |||
- test -d dist_install/share/projectM/presets | |||
- test -e dist_install/lib/libprojectM.la | |||
- test -e dist_install/include/libprojectM/projectM.hpp | |||
- test -e dist_install/include/libprojectM/Common.hpp | |||
- test -e dist_install/include/libprojectM/PCM.hpp | |||
- dist_install/bin/projectM-unittest | |||
# test on GCC and Clang | |||
matrix: | |||
include: | |||
# qt/pulseaudio/jack/sdl | |||
- os: linux | |||
dist: bionic | |||
addons: | |||
apt: | |||
packages: | |||
- qt5-default | |||
- qtdeclarative5-dev | |||
- libqt5opengl5-dev | |||
- libjack-dev | |||
- libpulse-dev | |||
- libc++-dev | |||
- libsdl2-dev | |||
env: | |||
- MATRIX_EVAL="PM_OPTS=\"--enable-qt --enable-jack --enable-pulseaudio --enable-sdl\"" | |||
- os: linux | |||
dist: xenial | |||
addons: | |||
apt: | |||
packages: | |||
- qt5-default | |||
- qtdeclarative5-dev | |||
- libqt5opengl5-dev | |||
- libjack-dev | |||
- libpulse-dev | |||
- libc++-dev | |||
- libsdl2-dev | |||
env: | |||
- MATRIX_EVAL="PM_OPTS=\"--enable-qt --enable-jack --enable-pulseaudio --enable-sdl\"" | |||
# osx/xcode/clang | |||
- os: osx | |||
osx_image: xcode12.2 | |||
env: | |||
- MATRIX_EVAL="brew update && brew install sdl2" | |||
notifications: | |||
email: | |||
on_success: never | |||
on_failure: change |
@@ -0,0 +1,60 @@ | |||
projectM -- Milkdrop-esque visualisation SDK | |||
Copyright (C)2003-2019 projectM Team | |||
This library is free software; you can redistribute it and/or | |||
modify it under the terms of the GNU Lesser General Public | |||
License as published by the Free Software Foundation; either | |||
version 2.1 of the License, or (at your option) any later version. | |||
This library is distributed in the hope that it will be useful, | |||
but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
Lesser General Public License for more details. | |||
You should have received a copy of the GNU Lesser General Public | |||
License along with this library; if not, write to the Free Software | |||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |||
See 'LICENSE.txt' included within this release | |||
For the purposes of the copyright statement in the preamble of each source | |||
code file comprising projectM, the projectM team are: | |||
Carmelo Piccione | |||
Parser | |||
Evaluator | |||
Pulse Audio support (projectM-pulseaudio) | |||
Qt GUI (projectM-qt) | |||
Peter Sperl | |||
Beat Detection | |||
Rendering | |||
XMMS Support (projectM-xmms) | |||
libvisual Support (projectM-libvisual) | |||
Alligator Descartes | |||
Media Player Support (iTunes, Winamp, Windows Media Player) | |||
Test application frameworks (projectM-wxvis, projectM-sdlvis) | |||
DVD application (projectM-movie) | |||
Win32 screensaver (projectM-screensaver) | |||
Roger Dannenburg | |||
Advice & Support | |||
Matthias Klumpp | |||
CMake build system | |||
Distro integration | |||
Bug fixes | |||
Mischa Spiegelmock | |||
OSX native iTunes visualization plugin | |||
Preliminary web support (projectM-emscripten) | |||
cmake improvements for OSX and Linux | |||
SDL | |||
OpenGLES | |||
Robert Pancoast | |||
Modernize win32 Build | |||
Windows Universal Application | |||
Provide XBOX Support | |||
Input Windows Audio Loopback with WASAPI | |||
@@ -0,0 +1,297 @@ | |||
# Building with CMake | |||
This file contains in-depth information for building with the CMake build system. | |||
## Quickstart | |||
Want to build it fast? | |||
Required tools: `cmake`. | |||
```shell | |||
mkdir build | |||
cd build | |||
cmake .. | |||
make -j8 | |||
``` | |||
Output binaries will be in `build/src/...`. | |||
SDL2 binary can be found in `build/src/projectM-sdl/projectMSDL`. | |||
## Selecting a specific project file generator | |||
To specify a CMake generator, use the `-G` switch, followed by the generator name. Some newer generators take an | |||
additional architecture using the `-A` switch. To list all available generators available on your current platform, | |||
leave out the generator name: | |||
```shell | |||
cmake -G | |||
``` | |||
Additional information on the supported generators can be | |||
found [in the CMake documentation](https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html). | |||
### Popular generators | |||
By default, CMake will use the [`Unix Makefiles`](https://cmake.org/cmake/help/latest/generator/Unix%20Makefiles.html) | |||
generator on Linux and macOS, which is a good choice and should work. Yet in some circumstances, you might want to | |||
generate project files for a specific build tool or IDE: | |||
```shell | |||
cmake -G "Unix Makefiles" -S /path/to/source/dir -B /path/to/build/dir | |||
``` | |||
A common alternative is the [`Ninja`](https://cmake.org/cmake/help/latest/generator/Ninja.html) generator, which | |||
requires `ninja` to be installed. It is mostly a `make` | |||
replacement with less overhead and should work equally well. It is supported on all major platforms, including Windows: | |||
```shell | |||
cmake -G Ninja -S /path/to/source/dir -B /path/to/build/dir | |||
``` | |||
On macOS, CMake also supports the [`Xcode`](https://cmake.org/cmake/help/latest/generator/Xcode.html) generator. It will | |||
create an `.xcodeproj` bundle which you can open in Xcode. It also adds support for automatic code signing, which might | |||
be required if your application using projectM needs to be notarized for store deployment. | |||
```shell | |||
cmake -G Xcode -S /path/to/source/dir -B /path/to/build/dir | |||
``` | |||
If you develop on Windows, you will possibly use Visual Studio. While recent visual Studio versions have CMake support | |||
built-in, you can still pre-generate the solution and project files and open the `.sln` file from the build directory. | |||
CMake provides a separate generator for each Visual Studio release. For Visual Studio 2019 you would use | |||
the [`Visual Studio 16 2019`](https://cmake.org/cmake/help/latest/generator/Visual%20Studio%2016%202019.html) generator | |||
and provide an additional architecture parameter: | |||
```shell | |||
cmake -G "Visual Studio 16 2019" -A "X64" -S /path/to/source/dir -B /path/to/build/dir | |||
``` | |||
It is not possible to generate multi-arch solutions with CMake though. You need to create separate build directories and | |||
use the respective `-A` switch for each. | |||
## Project-specific configuration options | |||
CMake has no built-in way of printing all available configuration options. You can either refer to the | |||
top-level `CMakeLists.txt` which contains a block of `option` and `cmake_dependent_option` commands, or use one of the | |||
available CMake UIs which will display the options after configuring the project once. | |||
### Boolean switches | |||
The following table also gives you an overview of the available options and their defaults. All options accept a boolean | |||
value (`YES`/`NO`, `TRUE`/`FALSE`, `ON`/`OFF` or `1`/`0`) and can be provided on the configuration-phase command line | |||
using the `-D` switch. | |||
| CMake option | Default | Required dependencies | Description | | |||
|-------------------------|---------|-----------------------|------------------------------------------------------------------------------------------------------------| | |||
| `ENABLE_DEBUG_PREFIX` | `ON` | | Adds `d` to the name of any binary file in debug builds. | | |||
| `ENABLE_EMSCRIPTEN` | `OFF` | `GLES`, `Emscripten` | Build for the web using Emscripten. | | |||
| `ENABLE_SDL` | `ON` | `SDL2` | Builds and installs the standalone SDL visualizer application. Also required for Emscripten and the tests. | | |||
| `ENABLE_GLES` | `OFF` | `GLES` | Use OpenGL ES 3 profile for rendering instead of the Core profile. | | |||
| `ENABLE_THREADING` | `ON` | `pthreads` | Enable multithreading support. If enabled, will cause an error if pthreads are not available. | | |||
| `ENABLE_NATIVE_PRESETS` | `OFF` | | Builds and installs the binary (native) preset libraries. | | |||
| `ENABLE_PRESETS` | `ON` | | Installs several thousand shipped presets. | | |||
| `ENABLE_PULSEAUDIO` | `OFF` | `Qt5`, `Pulseaudio` | Build the Qt5-based Pulseaudio visualizer application. | | |||
| `ENABLE_JACK` | `OFF` | `Qt5`, `JACK` | Build the Qt5-based JACK visualizer application. | | |||
| `ENABLE_LIBVISUAL` | `OFF` | `libvisual-0.4` | Build the libvisual plug-in/actor library. | | |||
| `ENABLE_TESTING` | `OFF` | `SDL2` | Builds the unit tests. | | |||
| `ENABLE_LLVM` | `OFF` | `LLVM` | Enables experimental LLVM JIT support. | | |||
### Path options | |||
There are also a few textual parameters that can be used to fine-tune the installation directories. Relative paths in | |||
the following options are appended to the value | |||
of [`CMAKE_INSTALL_PREFIX`](https://cmake.org/cmake/help/latest/variable/CMAKE_INSTALL_PREFIX.html) (which, on most UNIX | |||
platforms, defaults to `/usr/local`): | |||
| CMake option | Default | Description | | |||
|-------------------------|------------------|----------------------------------------------------------------------------------| | |||
| `PROJECTM_BIN_DIR` | `bin` | Directory where executables (e.g. the SDL standalone application) are installed. | | |||
| `PROJECTM_LIB_DIR` | `lib` | Directory where libprojectM is installed[<sup>[*]</sup>](#libvisual-path). | | |||
| `PROJECTM_INCLUDE_DIR` | `include` | Directory where the libprojectM include files will be installed under. | | |||
| `PROJECTM_DATADIR_PATH` | `share/projectM` | Directory where the default configuration and presets are installed under. | | |||
<a name="libvisual-path"></a>[*]: The libvisual projectM plug-in install location is determined automatically via | |||
pkgconfig and not influenced by this option. | |||
## Always perform out-of-tree builds! | |||
Most classic IDEs and build systems directly make use of the source tree and create project files, temporary build | |||
artifacts (e.g. object files) and the final binaries in the same directory structure as the source files. An advantage | |||
of this approach is that you can find all compiled binaries side-by-side with their sources and generated headers are | |||
already in the same directories as the source files including them. This approach has some drawbacks though: | |||
- Only a single build configuration is supported as files are overwritten in-place. | |||
- A lot of noise is created in the source directory, making it hard to distinguish between generated and original source | |||
files. | |||
- A very large `.gitignore` file is required to cover all unwanted files. | |||
- Mistakes in the build scripts can overwrite source files, causing errors and destroy uncommitted work. | |||
Some of these can be mitigated by providing additional targets (`make clean` and `make distclean`) or creating | |||
subdirectories for Debug/Release build configurations. | |||
While CMake also supports in-tree builds, it is "discouraged" in the official documentation, for the above reasons. | |||
Building out-of-tree allows it to create multiple build directories with different configurations which do not influence | |||
each other in any way. If a build directory contains unwanted artifacts, and you want to start fresh, simply delete and | |||
recreate the whole directory - no work is lost. | |||
This project follow this principle by treating the original source tree as read-only and avoiding potential conflicts: | |||
- Everything under [`CMAKE_SOURCE_DIR`](https://cmake.org/cmake/help/latest/variable/CMAKE_SOURCE_DIR.html) must only be | |||
read, never changed or written to. | |||
- Everything under [`CMAKE_BINARY_DIR`](https://cmake.org/cmake/help/latest/variable/CMAKE_BINARY_DIR.html) is temporary | |||
and related to the current build configuration. | |||
- When generating configuration-dependent files, | |||
use [`CMAKE_CONFIGURATION_TYPES`](https://cmake.org/cmake/help/latest/variable/CMAKE_CONFIGURATION_TYPES.html) | |||
and [`CMAKE_BUILD_TYPE`](https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html) to create non-conflicting | |||
files in the build tree. | |||
While this project will not force you to build out-of-tree, there is no mechanism to clean up the generated files after | |||
running cmake in-tree. | |||
## CMake build directory layout | |||
If you are new to CMake, the way of how CMake creates the build directory and where it creates the build targets might | |||
be confusing. Here is a summary of what's in the build directory and how it is structured in general. | |||
### Using files from the build tree | |||
It is generally not good practice to directly take binaries and other files from the build tree for packaging, for | |||
several reasons: | |||
1. The directory structure is generated by CMake and depends on the generator used. The layout might change between | |||
CMake versions, even for the same generator. | |||
2. On platforms with RPATH support, CMake will store absolute paths in executables and shared libraries which point to | |||
the absolute paths of any linked dependencies, either from the build tree or external libraries as well. These | |||
binaries are not relocatable and will most certainly not work if run on any other computer (or even on the same after | |||
deleting the build directory). | |||
3. For some configurations, even Release build artifacts may contain debug symbols until they are installed. | |||
It is fine to build and run executables from the build directory for development and debugging. For packaging, always | |||
use the `install` target and copy files from there. | |||
### Generated files | |||
In the top-level build directory, CMake creates a few files that are present on any platform: | |||
- `CMakeCache.txt`: This file contains all variables and build settings CMake needs to remember from the first | |||
configuration run. This file can be edited on demand either manually or using a CMake UI to change any values. On the | |||
next build, CMake will regenerate the project files if this file has been modified. | |||
- `cmake_install.cmake`: Contains generated install-related settings. | |||
- `install_manifest.txt`: After installing the project, this file contains a list with absolute filenames of all | |||
installed files. It can be used for packaging or deleting installed files as CMake doesn't define an `uninstall` | |||
target. | |||
- The top-level project file for use with the selected build toolset, e.g. `Makefile`, `build.ninja`, `projectm.sln` | |||
or `projectm.xcodeproj`, plus additional toolset-specific files. | |||
The projectM build files generate additional files used in the build and install phases: | |||
- `config.inp`: The default configuration file, by default installed to `<prefix>/share/projectM`. | |||
- `libprojectM.pc`: Package configuration file for use with `pkgconfig`. | |||
- `include/config.h`: A forced include file that contains macro definitions to enable or disable certain code features | |||
based on the build configuration and availability of platform headers and features. Similar to the | |||
autoheader-generated file. | |||
### Subdirectory structure | |||
The rest of the directory structure generally resembles the source tree. Source directories containing | |||
a `CMakeLists.txt` file will also be created in the build tree with the same relative path. Each of these subdirectories | |||
contains a `CMakeFiles` directory with CMake-internal data, generated project files for the select toolset, e.g. | |||
makefiles and any temporary compile artifacts. | |||
### Executable and library locations | |||
Build targets - shared/static libraries and executables - are created in the same subdirectory in the build tree as | |||
the `CMakeLists.txt` file that defines the target in the source tree (which, in most cases, resides in the same | |||
directory as the source files). Depending on the generator used, the binaries are created directly in the directory for | |||
single-configuration generators (like `Unix Makefiles` or `Ninja`) and in a subdirectory with the configuration name, | |||
e.g. `Debug` or `Release`, for multi-configuration generators like `Xcode` or `Visual Studio 16 2019`. | |||
You may also find additional files and symbolic links in the same location depending on the platform, e.g. `.pdb` files | |||
on Windows. | |||
## Using libprojectM in other CMake projects | |||
The projectM library can be used as a static library and, on non-Windows platforms, as a shared library in other | |||
CMake-based projects to provide embedded audio visualization. There are two ways: | |||
- Importing the library CMake targets directly from the build tree without installation. | |||
- Using the library from an installed location or package with the provided CMake package config files. | |||
### Importing libprojectM targets from the build tree | |||
This approach is useful for projects that either require more in-depth access to the projectM library files, especially | |||
to headers that are not installed as part of the public API. This might cause issues if the internal headers change, but | |||
gives a broader set of features and more control to the developer. | |||
To use the targets, follow these steps: | |||
- Configure the build directory as needed. | |||
- Build the required library targets `projectM_static` and `projectM_shared` as needed, or simply everything. | |||
- Include the file `src/libprojectM/projectM-exports.cmake` from the projectM build tree in your project. | |||
All targets and their interface properties are now defined and can be used. | |||
#### Example | |||
```cmake | |||
# libprojectM.a/.lib is already built. | |||
set(PROJECTM_BUILD_DIR "/some/path/to/projectM/build") | |||
include("${PROJECTM_BUILD_DIR}/src/libprojectM/projectM-exports.cmake") | |||
add_executable(MyApp main.cpp) | |||
target_link_libraries(MyApp PRIVATE libprojectM::static) | |||
``` | |||
This will also add all projectM include directories to the target's source files, pointing to the respective projectM | |||
source directories. | |||
Look at the generated file in the build tree if you need more details about the available targets. | |||
### Importing libprojectM targets from an installed version | |||
This is the recommended way of importing libprojectM in your project. This project installs a set of CMake files | |||
in `<PREFIX>/<LIBDIR>/cmake/libprojectM`, containing target definitions, version and dependency checks as well as any | |||
additional libraries required for linking. Other projects then use CMake's `find_package` command to search for these | |||
files in [different locations](https://cmake.org/cmake/help/latest/command/find_package.html#search-procedure). | |||
In the case projectM libraries and headers are not installed in any system search path, you need to add either the | |||
install prefix path (the top-level install dir) or the directory containing the libraries (the `lib` dir by default) to | |||
the [`CMAKE_PREFIX_PATH`](https://cmake.org/cmake/help/latest/variable/CMAKE_PREFIX_PATH.html) list. | |||
If the package was found, you can then link against one of these provided targets: | |||
- `libprojectM::static` - The static library (`.a` or `.lib`). | |||
- `libprojectM::shared` - The shared library (`.so`, `.dylib` or `.dll`). | |||
Note that the availability of the targets depend on the platform and build configuration, so only one of those might be | |||
available. You can check with `if(TARGET libprojectM::static)` and `if(TARGET libprojectM::shared)` to select the | |||
available or preferred one. | |||
Depending on how the package was built, targets might be available for multiple configurations or only `Release`. CMake | |||
will automatically select the most appropriate one to link. | |||
Include dirs, additional link dependencies and possible compiler options will be propagated to any target the library is | |||
linked to. | |||
#### Example | |||
Links the shared library preferably, with fallback to static: | |||
```cmake | |||
find_package(libprojectM REQUIRED) | |||
if(TARGET libprojectM::shared) | |||
set(PROJECTM_LINK_TARGET libprojectM::shared) | |||
else() | |||
# If this target is also unavailable, CMake will error out on target_link_libraries(). | |||
set(PROJECTM_LINK_TARGET libprojectM::static) | |||
endif() | |||
add_executable(MyApp main.cpp) | |||
target_link_libraries(MyApp PRIVATE ${PROJECTM_LINK_TARGET}) | |||
``` |
@@ -0,0 +1,415 @@ | |||
# Building projectM from source | |||
Suggested: use CMake. See [BUILDING-cmake.md](./BUILDING-cmake.md). | |||
This document describes the deprecated GNU Autotools setup. | |||
## Quick Start (Debian / Ubuntu) | |||
For other operating systems (Windows/macOS), see the OS-specific sections below. | |||
### Install the build tools and dependencies | |||
Mandatory packages: | |||
```bash | |||
sudo apt install build-essential libgl1-mesa-dev mesa-common-dev libsdl2-dev libglm-dev | |||
``` | |||
Optional packages for additional features: | |||
```bash | |||
sudo apt install qtbase5-dev # For building Qt-based UIs | |||
sudo apt install llvm-dev # for using the experimental LLVM Jit | |||
sudo apt install libvisual-0.4-dev # To build the libvisual plug-in | |||
sudo apt install libjack-jackd2-dev # To build the JACK visualizer application | |||
``` | |||
### Download the projectM sources | |||
If you want to use a stable version of projectM, download the latest release from | |||
the [Releases page on GitHub](https://github.com/projectM-visualizer/projectm/releases) and unpack it. You can then skip | |||
to the next step. | |||
If you prefer a bleeding-edge version or want to modify the code, clone the Git repository: | |||
```bash | |||
sudo apt install git # Probably already installed | |||
git clone https://github.com/projectM-visualizer/projectm.git /path/to/local/repo | |||
cd /path/to/local/repo | |||
git fetch --all --tags | |||
``` | |||
### Build and install projectM | |||
Older projectM releases use autoconf/automake for building. If your repository has a `CMakeLists.txt` file on the top | |||
level, skip to the CMake part right below. | |||
Replace `/usr/local` with your preferred installation prefix. | |||
#### Configure the project using autoconf | |||
```bash | |||
sudo apt install autoconf automake libtool | |||
./autogen.sh | |||
./configure --prefix=/usr/local | |||
``` | |||
#### Configure the project using CMake | |||
```bash | |||
sudo apt install cmake | |||
mkdir build | |||
cd build | |||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local .. | |||
``` | |||
#### Build and install | |||
Independent of the method of configuration, this will build projectM and install it to /usr/local or the configured | |||
installation prefix set in the step before: | |||
```bash | |||
make -j && sudo make install | |||
``` | |||
**Note**: You won't need to use `sudo` if the install prefix is writeable by your non-privileged user. | |||
#### Test projectM | |||
If you have a desktop environment installed, you can now run `[prefix]/bin/projectMSDL`. | |||
## Dependencies | |||
Depending on the OS/distribution and packaging system, libraries might be split into separate packages with binaries and | |||
development files. To build projectM, both binaries and development files need to be installed. | |||
#### General build dependencies for all platforms: | |||
* A working build toolchain. | |||
* **OpenGL**: 3D graphics library. Used to render the visualizations. | |||
* **GLES3**: OpenGL libraries for embedded systems, version 3. Required to build projectM on mobile devices, Raspberry | |||
Pi and Emscripten. | |||
* [**glm**](https://github.com/g-truc/glm): OpenGL Mathematics library. Optional, will use a bundled version with | |||
autotools or if not installed. | |||
* [**SDL2**](https://github.com/libsdl-org/SDL): Simple Directmedia Layer. Version 2.0.5 or higher is required to build | |||
the standalone visualizer application (projectMSDL). | |||
* [**LLVM**](https://llvm.org/): Low-Level Virtual Machine. Optional and **experimental**, used to speed up preset | |||
execution by leveraging the LLVM JIT compiler. | |||
#### Only relevant for Linux distributions, FreeBSD and macOS: | |||
* **pkgconfig**: Required to find some library dependencies. | |||
* [**Qt5**](https://www.qt.io/): Qt cross-platform UI framework. Used to build the Pulseaudio and JACK visualizer | |||
applications. Requires the `Gui` and `OpenGL` component libraries/frameworks. | |||
* [**Pulseaudio**](https://www.freedesktop.org/wiki/Software/PulseAudio/): Sound system for POSIX platforms. Required to | |||
build the Pulseaudio visualizer application. | |||
* [**JACK**](https://jackaudio.org/): Real-time audio server. Required to build the JACK visualizer application. | |||
* [**libvisual 0.4**](http://libvisual.org/): Audio visualization library with plug-in support. Required to build the | |||
projectM libvisual plug-in. | |||
#### When using the classic autotools-based build system on UNIX platforms: | |||
* **GNU [automake](https://www.gnu.org/software/automake/) and [autoconf](https://www.gnu.org/software/autoconf/)**: | |||
Used to create the configuration script and generate the Makefiles. | |||
* [**libtool**](https://www.gnu.org/software/libtool/): Optional. Used by autoconf is available. | |||
* [**which**](https://carlowood.github.io/which/): Determines full paths of shell executables. Should already be | |||
installed by default on the majority of POSIX-compliant OSes. | |||
#### When using the new CMake-based build system: | |||
* [**CMake**](https://cmake.org/): Used to generate platform-specific build files. | |||
### Only relevant for Windows: | |||
* [**vcpkg**](https://github.com/microsoft/vcpkg): C++ Library Manager for Windows. Optional, but recommended to install | |||
the aforementioned library dependencies and/or using CMake to configure the build. | |||
* [**NuGet**](https://www.nuget.org/): Dependency manager for .NET. Optional, but recommended when building with the | |||
pre-created Visual Studio solutions. | |||
* [**GLEW**](http://glew.sourceforge.net/): The OpenGL Extension Wrangler Library. Only required if using CMake to | |||
configure the build, the pre-created solutions use a bundled copy of GLEW. | |||
## Building on Linux and macOS | |||
### Installing dependencies | |||
- Linux distributions will have packages available for most (if not all) required libraries. The package names and | |||
commands to install them vary widely between distributions (and even versions of the same distribution). Please refer | |||
to the documentation of your build OS on how to find and install the required libraries. | |||
- On *BSD, install the appropriate Ports with `pkg install`. | |||
- On macOS, using [Homebrew](https://brew.sh/) is the recommended way of installing any dependencies not supplied by | |||
Xcode. | |||
### Building with CMake | |||
--- | |||
:exclamation: **IMPORTANT NOTE**: Currently, CMake build support is still in active development and considered | |||
unfinished. It is working and produces running binaries, but there are still some features, build internals and whole | |||
targets missing. While testing the CMake build files on any platform and feedback on this is strongly encouraged, | |||
CMake-based builds should not yet be used in any production environment until this message is gone. | |||
--- | |||
The steps documented below are a bare minimum quickstart guide on how to build and install the project. If you want to | |||
configure the build to your needs, require more in-depth information about the build process and available tweaks, or on | |||
how to use libprojectM in your own CMake-based projects, see [BUILDING-cmake.md](BUILDING-cmake.md). | |||
Using CMake is the recommended and future-proof way of building projectM. CMake is a platform-independent tool that is | |||
able to generate files for multiple build systems and toolsets while using only a single set of build instructions. | |||
CMake support is still new and in development, but will replace the other project files (automake/autoconf scripts, | |||
Visual Studio solutions and Xcode projects) in this repository once mature and stable. | |||
Building the project with CMake requires two steps: | |||
- Configure the build and generate project files. | |||
- Build and install the project using the selected build tools. | |||
**Note:** When building with CMake, the build directory should always be separate from the source directory. Generating | |||
the build files directly inside the source tree is possible, but strongly discouraged. Using a subdirectory, | |||
e.g. `cmake-build` inside the source directory is fine though. | |||
This documentation only covers project-specific information. CMake is way too versatile and feature-rich to cover any | |||
possible platform- and toolset-specific configuration details here. If you are not experienced in using CMake, please | |||
first read the [official CMake documentation](https://cmake.org/cmake/help/latest/) (at least | |||
the [User Interaction Guide](https://cmake.org/cmake/help/latest/guide/user-interaction/index.html)) for basic usage | |||
instructions. | |||
#### Configure the build | |||
Configuring a non-debug build with default options and install prefix (`/usr/local`) can be done with these commands, | |||
building in a subdirectory inside the source directory: | |||
```shell | |||
cd /path/to/source | |||
mkdir cmake-build | |||
cd cmake-build | |||
cmake -DCMAKE_BUILD_TYPE=Release .. | |||
``` | |||
CMake will check all required dependencies and display any errors. If configuration was successful, a summary of the | |||
build configuration is printed and CMake should display a `Generating done` line. The project is now ready to build. | |||
#### Compile and install the project | |||
Depending on your generator choice, you can use your selected toolset as usual to build and install projectM: | |||
- With `Unix Makefiles`, run `make && sudo make install`. | |||
- With `Ninja`, run `ninja && sudo ninja install`. | |||
- With `Xcode`, select the appropriate target and configuration in Xcode and build it, or `INSTALL` to install the | |||
project. | |||
You can also use CMake's build mode to run the selected toolset and build any specified target. CMake knows which | |||
command to call and which parameters to pass, so the syntax works on all platforms with all generators. If you've | |||
already set the top-level build directory as working directory, simply pass `.` as `/path/to/build/dir`: | |||
```shell | |||
cmake --build /path/to/build/dir --config Release | |||
sudo cmake --build /path/to/build/dir --config Release --target install | |||
``` | |||
If you don't need root permissions to install running the second command without `sudo` is sufficient. | |||
If you want to provide arguments directly to the toolset command, add `--` at the end of the CMake command line followed | |||
by any additional arguments. CMake will pass these *unchanged and unchecked* to the subcommand: | |||
```shell | |||
cmake --build /path/to/build/dir --config Release -- -j 4 | |||
``` | |||
### Building with automake/autoconf | |||
projectM ships with a set of scripts to check build dependencies and configure the build according to the user's | |||
preferences and toolchain. | |||
**Note**: These scripts might be removed in the future in favor of using CMake as the sole build system tool on all | |||
platforms, so if you're planning to base new work on the projectM libraries, consider using CMake instead. | |||
The source distribution only contains templates for the configure script and other files, so these need to be generated | |||
first. `cd` into the top-level source directory and execute: | |||
```shell | |||
./autogen.sh | |||
``` | |||
You should now have an executable `configure` script ready. This will be used to check the platform and dependencies and | |||
finally configure the Makefiles for the actual build. The script accepts numerous parameters to customize the build. The | |||
most important ones and their requirements are listed in the table below. To get a full list of available parameters, | |||
options and influential environment variables, run `./configure --help`. | |||
#### Important build options and their requirements: | |||
| Configure flag | Required dependencies | Produced binary | | |||
|-----------------------|-----------------------|-----------------------| | |||
| `--enable-sdl` | `SDL2` | `projectMSDL` | | |||
| `--enable-pulseaudio` | `Qt5`, `Pulseaudio` | `projectM-pulseaudio` | | |||
| `--enable-jack` | `Qt5`, `JACK` | `projectM-jack` | | |||
| `--enable-threading` | `pthreads` | | | |||
| `--enable-llvm` | `LLVM` | | | |||
| `--enable-gles` | `GLES3` | | | |||
For example, to configure the project to build and install only the libprojectM libraries and the SDL-based standalone | |||
visualizer in the default location (`/usr/local`), run the following commands: | |||
```shell | |||
./configure --enable-sdl # supply additional options here, info in Dependencies | |||
make | |||
sudo make install | |||
``` | |||
## Building on Windows | |||
### Using the provided project files | |||
Windows build bypasses the autogen/configure pipeline and uses manually created Visual Studio/MSVC project files | |||
in `msvc/`. See `.appveyor.yml` for command line building. | |||
Some dependencies are included verbatim (GLEW), while others leverage the NuGet ecosystem and are downloaded | |||
automatically (SDL2). | |||
The Visual Studio solution is quite old and unmaintained. If you experience issues importing it, try using CMake to | |||
generate the solution for your Visual Studio version instead. | |||
### With CMake | |||
To build the projectM library and the SDL-based standalone application, CMake can be used as on any other platform. | |||
Using vcpkg to pull in the build dependencies is highly recommended, as CMake can't use NuGet (NuGet pulls in | |||
dependencies using the project files, while CMake requires the libraries before creating the project files). | |||
#### Installing the dependencies with vcpkg | |||
As stated above, using vcpkg is the easiest way to get the required dependencies. First, | |||
install [vcpkg from GitHub](https://github.com/microsoft/vcpkg) by following the official guide. Then install the | |||
following packages for your desired architecture (called "triplet"): | |||
- `glew` | |||
- `sdl2` | |||
The `glew` package will also pull in the `opengl` libraries. | |||
Example to install the libraries for the x64 architecture, run from a Visual Studio command prompt: | |||
```commandline | |||
vcpkg install glew:x64-windows sdl2:x64-windows | |||
``` | |||
#### Creating the Visual Studio solution | |||
CMake provides separate generators for different Visual Studio versions. Newer CMake versions will support recent Visual | |||
Studio releases, but may remove generators for older ones. To get a list of available generators from the command line, | |||
use the `-G` switch without an argument. The CMake GUI will present you a dropdown list you can easily select from. | |||
To set the build architecture in Visual Studio builds, use the `-A` switch and specify either `Win32` or `X64` as the | |||
argument. If you want to build for both architectures, create separate build directories and configure them accordingly. | |||
To make CMake aware of the installed vcpkg packages, simply use the provided toolchain file when configuring the | |||
projectM build by | |||
pointing [`CMAKE_TOOLCHAIN_FILE`](https://cmake.org/cmake/help/latest/variable/CMAKE_TOOLCHAIN_FILE.html) to it. | |||
Here is a full command line example to create a Visual Studio 2019 solution for X64: | |||
```commandline | |||
cmake -G "Visual Studio 16 2019" -A "X64" -DCMAKE_TOOLCHAIN_FILE="<path to vcpkg>/scripts/buildsystems/vcpkg.cmake" -S "<path to source dir>" -B "<path to build dir>" | |||
``` | |||
If you use the CMake GUI, check the "Specify toolchain file for cross-compiling" option in the first page of the | |||
configuration assistant, then select the above `vcpkg.cmake` file on the second page. | |||
Another option is to open the project folder in a recent Visual Studio version as a CMake project and configure CMake | |||
using Visual Studio's JSON-based settings file. | |||
#### Building the solution | |||
To build the project, open the generated solution in Visual Studio and build it like any other solution. Each time the | |||
CMake files are changed, Visual Studio will automatically regenerate the CMake build files and reload the solution | |||
before continuing the build. Be aware that in old Visual Studio versions (2015 and earlier) the reload-and-continue | |||
might not work properly. | |||
You can also build the solution with msbuild via the command line, or use CMake's build wrapper to do that for you: | |||
```commandline | |||
cmake --build "<path to build dir>" --config Release | |||
``` | |||
#### Using Ninja to build | |||
The Ninja build system is shipped with Visual Studio since version 2019 and used by default if loading a CMake project | |||
directly from within the IDE. Ninja can also be [installed separately](https://github.com/ninja-build/ninja/releases). | |||
To configure the build directory for Ninja, pass `Ninja` or `Ninja Multi-Config` as the argument for the `-G` switch. | |||
The difference between both generators is that the former uses `CMAKE_BUILD_TYPE` to specify the configuration ( | |||
e.g. `Debug` or `Release`) while the latter supports all configurations in a single build directory, specified during | |||
build time. | |||
The architecture is determined from the toolset, so make sure to run the commands in the correct Visual Studio command | |||
prompt, e.g. "Native Tools for X64". | |||
Configure and build for a single-configuration Release build with vcpkg: | |||
```commandline | |||
cmake -G "Ninja" -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE="<path to vcpkg>/scripts/buildsystems/vcpkg.cmake" -S "<path to source dir>" -B "<path to build dir>" | |||
cmake --build "<path to build dir>" | |||
``` | |||
Same, but using the multi-configuration generator: | |||
```commandline | |||
cmake -G "Ninja Multi-Config" -DCMAKE_TOOLCHAIN_FILE="<path to vcpkg>/scripts/buildsystems/vcpkg.cmake" -S "<path to source dir>" -B "<path to build dir>" | |||
cmake --build "<path to build dir>" --config Release | |||
``` | |||
## Notes on other platforms and features | |||
### Raspberry Pi (and other embedded systems) | |||
* projectM is arch-independent, although there are some SSE2 enhancements for x86 | |||
* [Notes on running on raspberry pi](https://github.com/projectM-visualizer/projectm/issues/115) | |||
### Build using NDK for Android | |||
Install Android Studio, launch SDK Manager and install NDK | |||
```sh | |||
./autogen.sh | |||
./configure-ndk | |||
make && make install-strip | |||
``` | |||
Now you should be able to copy ./src/libprojectM/.libs/libprojectM.so and appropriate headers to projectm-android, and | |||
build it using Android Studio | |||
### LLVM JIT | |||
There are some optimizations for parsing preset equations that leverage the LLVM JIT. You can | |||
try `./compile --enable--llvm` to enable them. They may not work with newer version of | |||
LLVM (https://github.com/projectM-visualizer/projectm/pull/360) | |||
## libprojectM | |||
`libprojectM` is the core library. It is made up of three sub-libraries: | |||
#### Renderer | |||
Made up of everything in `src/libprojectM/Renderer`. These files compose the `libRenderer` sub-library. | |||
#### MilkdropPresetFactory / NativePresetFactory | |||
From their respective folders. Native presets are visualizations that are implemented in C++ instead of `.milk` preset | |||
files. They are completely optional. Milkdrop presets are technically optional but the whole thing is basically useless | |||
without them. | |||
If you don't want native presets, and you probably don't, don't bother with them. Ideally there should be a configure | |||
option to disable them, probably on by default (at this time this is needed for | |||
autoconf: https://github.com/projectM-visualizer/projectm/issues/99). | |||
### Assets | |||
`libprojectM` can either have a configuration hard-coded or load from a configuration file. It's up to each application | |||
to decide how to load the config file. The config file can have paths defined specifying where to load fonts and presets | |||
from. | |||
You will want to install the config file and presets somewhere, and then define that path for the application you're | |||
trying to build. |
@@ -0,0 +1 @@ | |||
See: https://github.com/projectM-visualizer/projectm/releases |
@@ -0,0 +1,271 @@ | |||
cmake_minimum_required(VERSION 3.14 FATAL_ERROR) | |||
if(CMAKE_VERSION VERSION_LESS 3.19 AND CMAKE_GENERATOR STREQUAL "Xcode") | |||
message(AUTHOR_WARNING "Using a CMake version before 3.19 with a recent Xcode SDK and the Xcode generator " | |||
"will likely result in CMake failing to find the AppleClang compiler. Either upgrade CMake to at least " | |||
"version 3.19 or use a different generator, e.g. \"Unix Makefiles\" or \"Ninja\".") | |||
endif() | |||
include(CMakeDependentOption) | |||
include(CheckSymbolExists) | |||
set(CMAKE_CXX_STANDARD 14) | |||
set(CMAKE_CXX_STANDARD_REQUIRED YES) | |||
set(CMAKE_POSITION_INDEPENDENT_CODE YES) | |||
set_property(GLOBAL PROPERTY USE_FOLDERS ON) | |||
option(ENABLE_DEBUG_POSTFIX "Add \"d\" after library names for debug builds" ON) | |||
if(ENABLE_DEBUG_POSTFIX) | |||
set(CMAKE_DEBUG_POSTFIX d) | |||
endif() | |||
# The API (SO) and detailed library versions for the shared library. | |||
set(PROJECTM_SO_VERSION "3") | |||
set(PROJECTM_LIB_VERSION "3.1.1") | |||
project(projectm | |||
LANGUAGES C CXX | |||
VERSION 3.1.13 | |||
) | |||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") | |||
set(PROJECTM_BIN_DIR "bin" CACHE STRING "Executable installation directory, relative to the install prefix.") | |||
set(PROJECTM_DATADIR_PATH "share/projectM" CACHE STRING "Default (absolute) path to the projectM data files (presets etc.)") | |||
set(PROJECTM_LIB_DIR "lib" CACHE STRING "Library installation directory, relative to the install prefix.") | |||
set(PROJECTM_INCLUDE_DIR "include" CACHE STRING "Header installation directory, relative to the install prefix.") | |||
# Feature options, including dependencies. | |||
option(ENABLE_STATIC_LIB "Build and install libprojectM as a static library" ON) | |||
cmake_dependent_option(ENABLE_SHARED_LIB "Build and install libprojectM as a shared library" ON "NOT CMAKE_SYSTEM_NAME STREQUAL Windows" OFF) | |||
cmake_dependent_option(ENABLE_SHARED_LINKING "Link all built UI applications against the shared library." OFF "ENABLE_SHARED_LIB" OFF) | |||
option(ENABLE_DOXYGEN "Build and install Doxygen source code documentation in PROJECTM_DATADIR_PATH/docs." OFF) | |||
option(ENABLE_CXX_INTERFACE "Enable exporting all C++ symbols, not only the C API, in the shared library. Warning: This is not very portable." OFF) | |||
option(ENABLE_PRESETS "Build and install bundled presets" ON) | |||
option(ENABLE_NATIVE_PRESETS "Build and install native libraries written in C/C++" OFF) | |||
option(ENABLE_TESTING "Build and install the projectM test suite" OFF) | |||
option(ENABLE_EMSCRIPTEN "Build for web with emscripten" OFF) | |||
cmake_dependent_option(ENABLE_SDL "Enable SDL2 support" ON "NOT ENABLE_EMSCRIPTEN;NOT ENABLE_TESTING" ON) | |||
cmake_dependent_option(ENABLE_SDL_UI "Build the SDL2-based reference UI" ON "NOT ENABLE_EMSCRIPTEN" OFF) | |||
cmake_dependent_option(ENABLE_GLES "Enable OpenGL ES support" OFF "NOT ENABLE_EMSCRIPTEN" ON) | |||
cmake_dependent_option(ENABLE_THREADING "Enable multithreading support" ON "NOT ENABLE_EMSCRIPTEN;NOT CMAKE_SYSTEM_NAME STREQUAL Windows" OFF) | |||
cmake_dependent_option(ENABLE_PULSEAUDIO "Build PulseAudio-based Qt UI" OFF "NOT ENABLE_EMSCRIPTEN;CMAKE_SYSTEM_NAME STREQUAL Linux" OFF) | |||
cmake_dependent_option(ENABLE_JACK "Build JACK-based Qt and SDL UIs" OFF "NOT ENABLE_EMSCRIPTEN;CMAKE_SYSTEM_NAME STREQUAL Linux" OFF) | |||
cmake_dependent_option(ENABLE_QT "Build Qt UI library" OFF "NOT ENABLE_PULSEAUDIO;NOT ENABLE_JACK" ON) | |||
cmake_dependent_option(ENABLE_LLVM "Enable LLVM JIT support" OFF "NOT ENABLE_EMSCRIPTEN" OFF) | |||
cmake_dependent_option(ENABLE_LIBVISUAL "Build and install the projectM libvisual plug-in" OFF "NOT ENABLE_EMSCRIPTEN;CMAKE_SYSTEM_NAME STREQUAL Linux" OFF) | |||
if(NOT ENABLE_STATIC_LIB AND NOT ENABLE_SHARED_LIB) | |||
message(FATAL_ERROR "At least one of either ENABLE_STATIC_LIB or ENABLE_SHARED_LIB options must be set to ON.") | |||
endif() | |||
if(ENABLE_DOXYGEN) | |||
find_package(Doxygen REQUIRED) | |||
endif() | |||
find_package(GLM) | |||
if(NOT TARGET GLM::GLM) | |||
add_library(GLM::GLM INTERFACE IMPORTED) | |||
set_target_properties(GLM::GLM PROPERTIES | |||
INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_SOURCE_DIR}/vendor" | |||
) | |||
message(STATUS "GLM library not found, using bundled version.") | |||
set(USE_SYSTEM_GLM OFF) | |||
else() | |||
set(USE_SYSTEM_GLM ON) | |||
endif() | |||
if(ENABLE_EMSCRIPTEN) | |||
message(STATUS "${CMAKE_C_COMPILER}") | |||
check_symbol_exists(__EMSCRIPTEN__ "" HAVE_EMSCRIPTEN) | |||
if(NOT HAVE_EMSCRIPTEN) | |||
message(FATAL_ERROR "You are not using an emscripten compiler.") | |||
endif() | |||
endif() | |||
if(ENABLE_SDL) | |||
find_package(SDL2 REQUIRED) | |||
# Apply some fixes, as SDL2's CMake support is new and still a WiP. | |||
include(SDL2Target) | |||
endif() | |||
if(ENABLE_GLES) | |||
# Might be implemented in the CMake OpenGL module. | |||
# We may provide a find module in the future, and add support for CMake's own module later: | |||
# https://gitlab.kitware.com/cmake/cmake/-/blob/3fc3b43933d0b486aa4eb5d63fc257475feff348/Modules/FindOpenGL.cmake#L520 | |||
message(FATAL_ERROR "GLES support is currently not implemented for CMake builds.") | |||
find_package(GLES3 REQUIRED) | |||
else() | |||
find_package(OpenGL REQUIRED) | |||
set(PROJECTM_OPENGL_LIBRARIES OpenGL::GL) | |||
# GLX is required by SOIL2 on platforms with the X Window System (e.g. most Linux distributions) | |||
if(TARGET OpenGL::GLX) | |||
list(APPEND PROJECTM_OPENGL_LIBRARIES OpenGL::GLX) | |||
endif() | |||
if(CMAKE_SYSTEM_NAME STREQUAL "Windows") | |||
find_package(GLEW REQUIRED) | |||
list(APPEND PROJECTM_OPENGL_LIBRARIES GLEW::glew) | |||
endif() | |||
endif() | |||
if(ENABLE_THREADING) | |||
set(CMAKE_THREAD_PREFER_PTHREAD YES) | |||
find_package(Threads REQUIRED) | |||
if(NOT CMAKE_USE_PTHREADS_INIT) | |||
message(FATAL_ERROR "Threading support requested - pthread support is required, but not available.") | |||
endif() | |||
set(USE_THREADS YES) | |||
endif() | |||
if(ENABLE_LLVM) | |||
find_package(LLVM REQUIRED) | |||
if(LLVM_VERSION VERSION_LESS 10.0) | |||
message(FATAL_ERROR "LLVM JIT support requires at least version 10.0, but only ${LLVM_VERSION} was found.") | |||
endif() | |||
set(HAVE_LLVM TRUE) | |||
else() | |||
unset(HAVE_LLVM) | |||
endif() | |||
if(ENABLE_PULSEAUDIO) | |||
find_package(Pulseaudio REQUIRED) | |||
endif() | |||
if(ENABLE_JACK) | |||
find_package(JACK REQUIRED) | |||
endif() | |||
if(ENABLE_PULSEAUDIO OR ENABLE_JACK) | |||
set(QT_REQUIRED_COMPONENTS Gui Widgets OpenGL Xml) | |||
if(DEFINED QT_VERSION) | |||
find_package(Qt${QT_VERSION} REQUIRED COMPONENTS ${QT_REQUIRED_COMPONENTS}) | |||
else() | |||
# Try to determine the Qt version available, starting with Qt6 | |||
message(STATUS "Determining Qt version. To use a specific version, set QT_VERSION to either 5 or 6.") | |||
find_package(Qt6 QUIET COMPONENTS ${QT_REQUIRED_COMPONENTS}) | |||
if(TARGET Qt6::Core) | |||
set(QT_VERSION 6) | |||
else() | |||
find_package(Qt5 QUIET COMPONENTS ${QT_REQUIRED_COMPONENTS}) | |||
if(TARGET Qt5::Core) | |||
set(QT_VERSION 5) | |||
else() | |||
message(FATAL_ERROR "Could not find either Qt 5 or 6, one is required to build the PulseAudio or JACK UIs.") | |||
endif() | |||
endif() | |||
endif() | |||
# OpenGLWidgets were put into their own component since Qt 6. | |||
if(QT_VERSION EQUAL 6) | |||
list(APPEND QT_REQUIRED_COMPONENTS OpenGLWidgets) | |||
find_package(Qt6 REQUIRED COMPONENTS OpenGLWidgets) | |||
endif() | |||
set(QT_LINK_TARGETS "") | |||
foreach(component ${QT_REQUIRED_COMPONENTS}) | |||
list(APPEND QT_LINK_TARGETS Qt${QT_VERSION}::${component}) | |||
endforeach() | |||
endif() | |||
if(ENABLE_LIBVISUAL) | |||
find_package(libvisual REQUIRED) | |||
set(PROJECTM_LIBVISUAL_DIR "${LIBVISUAL_PLUGINSBASEDIR}/actor" CACHE STRING "Installation directory for the libvisual plug-in library.") | |||
endif() | |||
if(ENABLE_CXX_INTERFACE) | |||
set(CMAKE_C_VISIBILITY_PRESET default) | |||
set(CMAKE_CXX_VISIBILITY_PRESET default) | |||
set(CMAKE_VISIBILITY_INLINES_HIDDEN OFF) | |||
else() | |||
set(CMAKE_C_VISIBILITY_PRESET hidden) | |||
set(CMAKE_CXX_VISIBILITY_PRESET hidden) | |||
set(CMAKE_VISIBILITY_INLINES_HIDDEN ON) | |||
endif() | |||
include(features.cmake) | |||
add_subdirectory(presets) | |||
add_subdirectory(src) | |||
message(STATUS "") | |||
message(STATUS "projectM v${PROJECT_VERSION}") | |||
message(STATUS "==============================================") | |||
message(STATUS "") | |||
message(STATUS " prefix: ${CMAKE_INSTALL_PREFIX}") | |||
message(STATUS " libdir: ${PROJECTM_LIB_DIR}") | |||
message(STATUS " includedir: ${PROJECTM_INCLUDE_DIR}") | |||
message(STATUS " bindir: ${PROJECTM_BIN_DIR}") | |||
message(STATUS " libvisual plugin dir: ${PROJECTM_LIBVISUAL_DIR}") | |||
message(STATUS "") | |||
message(STATUS " compiler: ${CMAKE_CXX_COMPILER}") | |||
message(STATUS " cflags: ${CMAKE_C_FLAGS}") | |||
message(STATUS " cxxflags: ${CMAKE_CXX_FLAGS}") | |||
message(STATUS " ldflags: ${CMAKE_SHARED_LINKER_FLAGS}") | |||
message(STATUS "") | |||
message(STATUS " DATADIR_PATH: ${PROJECTM_DATADIR_PATH}") | |||
message(STATUS "") | |||
message(STATUS "Features:") | |||
message(STATUS "==============================================") | |||
message(STATUS "") | |||
message(STATUS " Presets: ${ENABLE_PRESETS}") | |||
message(STATUS " Native presets: ${ENABLE_NATIVE_PRESETS}") | |||
message(STATUS " Threading: ${ENABLE_THREADING}") | |||
message(STATUS " SDL2: ${ENABLE_SDL}") | |||
if(ENABLE_SDL) | |||
message(STATUS " SDL2 version: ${SDL2_VERSION}") | |||
endif() | |||
message(STATUS " OpenGLES: ${ENABLE_GLES}") | |||
message(STATUS " Emscripten: ${ENABLE_EMSCRIPTEN}") | |||
message(STATUS " LLVM JIT: ${ENABLE_LLVM}") | |||
if(ENABLE_LLVM) | |||
message(STATUS " LLVM version: ${LLVM_VERSION}") | |||
endif() | |||
message(STATUS " Use system GLM: ${USE_SYSTEM_GLM}") | |||
message(STATUS " Link UI with shared lib: ${ENABLE_SHARED_LINKING}") | |||
message(STATUS "") | |||
message(STATUS "Targets and applications:") | |||
message(STATUS "==============================================") | |||
message(STATUS "") | |||
message(STATUS " libprojectM static: ${ENABLE_STATIC_LIB}") | |||
message(STATUS " libprojectM shared: ${ENABLE_SHARED_LIB}") | |||
message(STATUS " SDL2 UI: ${ENABLE_SDL_UI}") | |||
message(STATUS " Doxygen API docs: ${ENABLE_DOXYGEN}") | |||
message(STATUS " Tests: ${ENABLE_TESTING}") | |||
message(STATUS " PulseAudio UI: ${ENABLE_PULSEAUDIO}") | |||
if(ENABLE_PULSEAUDIO) | |||
message(STATUS " PulseAudio version: ${PULSEAUDIO_VERSION}") | |||
endif() | |||
message(STATUS " JACK UI: ${ENABLE_JACK}") | |||
if(ENABLE_JACK) | |||
message(STATUS " JACK version: ${JACK_VERSION}") | |||
endif() | |||
if(ENABLE_PULSEAUDIO OR ENABLE_JACK) | |||
message(STATUS " Qt version: ${Qt${QT_VERSION}_VERSION}") | |||
endif() | |||
message(STATUS " libvisual plug-in: ${ENABLE_LIBVISUAL}") | |||
message(STATUS "") | |||
message(AUTHOR_WARNING | |||
"The CMake build scripts for projectM are still in active development.\n" | |||
"This means that build parameters, exported target names and other things can change " | |||
"at any time until the new build system is officially documented and announced to be " | |||
"fully supported.\n" | |||
"DO NOT base any production work on it yet!\n" | |||
) | |||
if(ENABLE_CXX_INTERFACE) | |||
message(AUTHOR_WARNING "This build is configured to export all C++ symbols in the shared library.\n" | |||
"Using C++ STL types across library borders only works if all components were built " | |||
"with the exact same toolchain and C++ language level, otherwise it will cause crashes.\n" | |||
"Enabling this option will not export additional symbols in Windows DLL builds.\n" | |||
"Only use this if you know what you're doing. You have been warned!" | |||
) | |||
endif() | |||
# Create CPack configuration | |||
set(CPACK_PACKAGE_NAME "projectM") | |||
set(CPACK_VERBATIM_VARIABLES YES) | |||
include(CPack) |
@@ -0,0 +1,285 @@ | |||
// !$*UTF8*$! | |||
{ | |||
archiveVersion = 1; | |||
classes = { | |||
}; | |||
objectVersion = 54; | |||
objects = { | |||
/* Begin PBXAggregateTarget section */ | |||
16C866C825D81A3200907F43 /* ProjectM Installer */ = { | |||
isa = PBXAggregateTarget; | |||
buildConfigurationList = 16C866C925D81A3200907F43 /* Build configuration list for PBXAggregateTarget "ProjectM Installer" */; | |||
buildPhases = ( | |||
165E796125D81A7C004711AA /* CopyFiles */, | |||
165E796A25D81A9A004711AA /* Generate Combined Installer Package */, | |||
); | |||
dependencies = ( | |||
165E796025D81A78004711AA /* PBXTargetDependency */, | |||
165E795D25D81A6E004711AA /* PBXTargetDependency */, | |||
); | |||
name = "ProjectM Installer"; | |||
productName = "Installer Aggregate"; | |||
}; | |||
/* End PBXAggregateTarget section */ | |||
/* Begin PBXBuildFile section */ | |||
16CF110C25E1B35F00B4A951 /* Distribution.xml in CopyFiles */ = {isa = PBXBuildFile; fileRef = 16CF110B25E1B35F00B4A951 /* Distribution.xml */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; | |||
/* End PBXBuildFile section */ | |||
/* Begin PBXContainerItemProxy section */ | |||
1648A64525D7FD520075B8FC /* PBXContainerItemProxy */ = { | |||
isa = PBXContainerItemProxy; | |||
containerPortal = 1648A64025D7FD520075B8FC /* SDLprojectM.xcodeproj */; | |||
proxyType = 2; | |||
remoteGlobalIDString = C34521441BF02294001707D2; | |||
remoteInfo = SDLprojectM; | |||
}; | |||
1648A64725D7FD520075B8FC /* PBXContainerItemProxy */ = { | |||
isa = PBXContainerItemProxy; | |||
containerPortal = 1648A64025D7FD520075B8FC /* SDLprojectM.xcodeproj */; | |||
proxyType = 2; | |||
remoteGlobalIDString = 168F714921120210001806E7; | |||
remoteInfo = Installer; | |||
}; | |||
165E795C25D81A6E004711AA /* PBXContainerItemProxy */ = { | |||
isa = PBXContainerItemProxy; | |||
containerPortal = 168E975025D7FDDA0073B1B8 /* Music Plugin.xcodeproj */; | |||
proxyType = 1; | |||
remoteGlobalIDString = C3F9D7AE17B82CC3009E58CB; | |||
remoteInfo = "Music Plugin Installer"; | |||
}; | |||
165E795F25D81A78004711AA /* PBXContainerItemProxy */ = { | |||
isa = PBXContainerItemProxy; | |||
containerPortal = 1648A64025D7FD520075B8FC /* SDLprojectM.xcodeproj */; | |||
proxyType = 1; | |||
remoteGlobalIDString = 168F714821120210001806E7; | |||
remoteInfo = ProjectM; | |||
}; | |||
168E975525D7FDDA0073B1B8 /* PBXContainerItemProxy */ = { | |||
isa = PBXContainerItemProxy; | |||
containerPortal = 168E975025D7FDDA0073B1B8 /* Music Plugin.xcodeproj */; | |||
proxyType = 2; | |||
remoteGlobalIDString = C3F9D7AF17B82CC3009E58CB; | |||
remoteInfo = "Music Plugin"; | |||
}; | |||
/* End PBXContainerItemProxy section */ | |||
/* Begin PBXCopyFilesBuildPhase section */ | |||
165E796125D81A7C004711AA /* CopyFiles */ = { | |||
isa = PBXCopyFilesBuildPhase; | |||
buildActionMask = 2147483647; | |||
dstPath = ""; | |||
dstSubfolderSpec = 16; | |||
files = ( | |||
16CF110C25E1B35F00B4A951 /* Distribution.xml in CopyFiles */, | |||
); | |||
runOnlyForDeploymentPostprocessing = 0; | |||
}; | |||
/* End PBXCopyFilesBuildPhase section */ | |||
/* Begin PBXFileReference section */ | |||
1648A64025D7FD520075B8FC /* SDLprojectM.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = SDLprojectM.xcodeproj; path = "src/projectM-sdl/SDLprojectM.xcodeproj"; sourceTree = "<group>"; }; | |||
168E975025D7FDDA0073B1B8 /* Music Plugin.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = "Music Plugin.xcodeproj"; path = "src/projectM-MusicPlugin/Music Plugin.xcodeproj"; sourceTree = "<group>"; }; | |||
168E976E25D800F90073B1B8 /* ProjectM-MusicPlugin.pkg */ = {isa = PBXFileReference; lastKnownFileType = file; name = "ProjectM-MusicPlugin.pkg"; path = "src/projectM-MusicPlugin/ProjectM-MusicPlugin.pkg"; sourceTree = "<group>"; }; | |||
16CF110B25E1B35F00B4A951 /* Distribution.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; name = Distribution.xml; path = mac/Distribution.xml; sourceTree = "<group>"; }; | |||
16F25E9C25D81737002EC64E /* ProjectM-SDL.pkg */ = {isa = PBXFileReference; lastKnownFileType = file; name = "ProjectM-SDL.pkg"; path = "src/projectM-sdl/ProjectM-SDL.pkg"; sourceTree = "<group>"; }; | |||
/* End PBXFileReference section */ | |||
/* Begin PBXGroup section */ | |||
1648A5E725D7FB650075B8FC = { | |||
isa = PBXGroup; | |||
children = ( | |||
16CF110B25E1B35F00B4A951 /* Distribution.xml */, | |||
16F25E9C25D81737002EC64E /* ProjectM-SDL.pkg */, | |||
168E976E25D800F90073B1B8 /* ProjectM-MusicPlugin.pkg */, | |||
168E975025D7FDDA0073B1B8 /* Music Plugin.xcodeproj */, | |||
1648A64025D7FD520075B8FC /* SDLprojectM.xcodeproj */, | |||
1648A5F325D7FBA80075B8FC /* Products */, | |||
); | |||
sourceTree = "<group>"; | |||
}; | |||
1648A5F325D7FBA80075B8FC /* Products */ = { | |||
isa = PBXGroup; | |||
children = ( | |||
); | |||
name = Products; | |||
sourceTree = "<group>"; | |||
}; | |||
1648A64125D7FD520075B8FC /* Products */ = { | |||
isa = PBXGroup; | |||
children = ( | |||
1648A64625D7FD520075B8FC /* SDLprojectM */, | |||
1648A64825D7FD520075B8FC /* ProjectM.app */, | |||
); | |||
name = Products; | |||
sourceTree = "<group>"; | |||
}; | |||
168E975125D7FDDA0073B1B8 /* Products */ = { | |||
isa = PBXGroup; | |||
children = ( | |||
168E975625D7FDDA0073B1B8 /* ProjectM.bundle */, | |||
); | |||
name = Products; | |||
sourceTree = "<group>"; | |||
}; | |||
/* End PBXGroup section */ | |||
/* Begin PBXProject section */ | |||
1648A5E825D7FB650075B8FC /* Project object */ = { | |||
isa = PBXProject; | |||
attributes = { | |||
BuildIndependentTargetsInParallel = YES; | |||
LastUpgradeCheck = 1240; | |||
TargetAttributes = { | |||
16C866C825D81A3200907F43 = { | |||
CreatedOnToolsVersion = 12.4; | |||
}; | |||
}; | |||
}; | |||
buildConfigurationList = 1648A5EB25D7FB650075B8FC /* Build configuration list for PBXProject "Installer" */; | |||
compatibilityVersion = "Xcode 9.3"; | |||
developmentRegion = en; | |||
hasScannedForEncodings = 0; | |||
knownRegions = ( | |||
en, | |||
Base, | |||
); | |||
mainGroup = 1648A5E725D7FB650075B8FC; | |||
productRefGroup = 1648A5F325D7FBA80075B8FC /* Products */; | |||
projectDirPath = ""; | |||
projectReferences = ( | |||
{ | |||
ProductGroup = 168E975125D7FDDA0073B1B8 /* Products */; | |||
ProjectRef = 168E975025D7FDDA0073B1B8 /* Music Plugin.xcodeproj */; | |||
}, | |||
{ | |||
ProductGroup = 1648A64125D7FD520075B8FC /* Products */; | |||
ProjectRef = 1648A64025D7FD520075B8FC /* SDLprojectM.xcodeproj */; | |||
}, | |||
); | |||
projectRoot = ""; | |||
targets = ( | |||
16C866C825D81A3200907F43 /* ProjectM Installer */, | |||
); | |||
}; | |||
/* End PBXProject section */ | |||
/* Begin PBXReferenceProxy section */ | |||
1648A64625D7FD520075B8FC /* SDLprojectM */ = { | |||
isa = PBXReferenceProxy; | |||
fileType = "compiled.mach-o.executable"; | |||
path = SDLprojectM; | |||
remoteRef = 1648A64525D7FD520075B8FC /* PBXContainerItemProxy */; | |||
sourceTree = BUILT_PRODUCTS_DIR; | |||
}; | |||
1648A64825D7FD520075B8FC /* ProjectM.app */ = { | |||
isa = PBXReferenceProxy; | |||
fileType = wrapper.cfbundle; | |||
path = ProjectM.app; | |||
remoteRef = 1648A64725D7FD520075B8FC /* PBXContainerItemProxy */; | |||
sourceTree = BUILT_PRODUCTS_DIR; | |||
}; | |||
168E975625D7FDDA0073B1B8 /* ProjectM.bundle */ = { | |||
isa = PBXReferenceProxy; | |||
fileType = wrapper.cfbundle; | |||
path = ProjectM.bundle; | |||
remoteRef = 168E975525D7FDDA0073B1B8 /* PBXContainerItemProxy */; | |||
sourceTree = BUILT_PRODUCTS_DIR; | |||
}; | |||
/* End PBXReferenceProxy section */ | |||
/* Begin PBXShellScriptBuildPhase section */ | |||
165E796A25D81A9A004711AA /* Generate Combined Installer Package */ = { | |||
isa = PBXShellScriptBuildPhase; | |||
alwaysOutOfDate = 1; | |||
buildActionMask = 12; | |||
files = ( | |||
); | |||
inputFileListPaths = ( | |||
); | |||
inputPaths = ( | |||
); | |||
name = "Generate Combined Installer Package"; | |||
outputFileListPaths = ( | |||
); | |||
outputPaths = ( | |||
); | |||
runOnlyForDeploymentPostprocessing = 0; | |||
shellPath = /bin/sh; | |||
shellScript = "set -euxo pipefail\n\necho BUILT_PRODUCTS_DIR $BUILT_PRODUCTS_DIR\nls \"$BUILT_PRODUCTS_DIR\"\n\nmkdir -p \"$TEMP_DIR\"\n\nSDL_PKG=\"$BUILT_PRODUCTS_DIR/ProjectM-SDL.pkg\"\nMUSIC_PLUGIN_PKG=\"$BUILT_PRODUCTS_DIR/ProjectM-MusicPlugin.pkg\"\n\n\n#productbuild --timestamp --sign '5926VBQM6Y' --package $SDL_PKG --package $MUSIC_PLUGIN_PKG \"$BUILT_PRODUCTS_DIR/ProjectM.pkg\"\nproductbuild --timestamp --sign '5926VBQM6Y' --distribution mac/Distribution.xml --package-path \"$BUILT_PRODUCTS_DIR\" \"$BUILT_PRODUCTS_DIR/ProjectM.pkg\"\n#productbuild --package \"$SDL_PKG\" --package \"$MUSIC_PLUGIN_PKG\" \"$BUILT_PRODUCTS_DIR/ProjectM.pkg\"\n\necho \"Created installer package $BUILT_PRODUCTS_DIR/ProjectM.pkg\"\n\ncp -rp \"$BUILT_PRODUCTS_DIR/ProjectM.pkg\" \"$SRCROOT/\"\n"; | |||
showEnvVarsInLog = 0; | |||
}; | |||
/* End PBXShellScriptBuildPhase section */ | |||
/* Begin PBXTargetDependency section */ | |||
165E795D25D81A6E004711AA /* PBXTargetDependency */ = { | |||
isa = PBXTargetDependency; | |||
name = "Music Plugin Installer"; | |||
targetProxy = 165E795C25D81A6E004711AA /* PBXContainerItemProxy */; | |||
}; | |||
165E796025D81A78004711AA /* PBXTargetDependency */ = { | |||
isa = PBXTargetDependency; | |||
name = ProjectM; | |||
targetProxy = 165E795F25D81A78004711AA /* PBXContainerItemProxy */; | |||
}; | |||
/* End PBXTargetDependency section */ | |||
/* Begin XCBuildConfiguration section */ | |||
1648A5EC25D7FB650075B8FC /* Debug */ = { | |||
isa = XCBuildConfiguration; | |||
buildSettings = { | |||
MACOSX_DEPLOYMENT_TARGET = 10.9; | |||
}; | |||
name = Debug; | |||
}; | |||
1648A5ED25D7FB650075B8FC /* Release */ = { | |||
isa = XCBuildConfiguration; | |||
buildSettings = { | |||
MACOSX_DEPLOYMENT_TARGET = 10.9; | |||
}; | |||
name = Release; | |||
}; | |||
16C866CA25D81A3200907F43 /* Debug */ = { | |||
isa = XCBuildConfiguration; | |||
buildSettings = { | |||
CODE_SIGN_STYLE = Automatic; | |||
DEVELOPMENT_TEAM = 5926VBQM6Y; | |||
PRODUCT_NAME = "$(TARGET_NAME)"; | |||
}; | |||
name = Debug; | |||
}; | |||
16C866CB25D81A3200907F43 /* Release */ = { | |||
isa = XCBuildConfiguration; | |||
buildSettings = { | |||
CODE_SIGN_STYLE = Automatic; | |||
DEVELOPMENT_TEAM = 5926VBQM6Y; | |||
PRODUCT_NAME = "$(TARGET_NAME)"; | |||
}; | |||
name = Release; | |||
}; | |||
/* End XCBuildConfiguration section */ | |||
/* Begin XCConfigurationList section */ | |||
1648A5EB25D7FB650075B8FC /* Build configuration list for PBXProject "Installer" */ = { | |||
isa = XCConfigurationList; | |||
buildConfigurations = ( | |||
1648A5EC25D7FB650075B8FC /* Debug */, | |||
1648A5ED25D7FB650075B8FC /* Release */, | |||
); | |||
defaultConfigurationIsVisible = 0; | |||
defaultConfigurationName = Release; | |||
}; | |||
16C866C925D81A3200907F43 /* Build configuration list for PBXAggregateTarget "ProjectM Installer" */ = { | |||
isa = XCConfigurationList; | |||
buildConfigurations = ( | |||
16C866CA25D81A3200907F43 /* Debug */, | |||
16C866CB25D81A3200907F43 /* Release */, | |||
); | |||
defaultConfigurationIsVisible = 0; | |||
defaultConfigurationName = Release; | |||
}; | |||
/* End XCConfigurationList section */ | |||
}; | |||
rootObject = 1648A5E825D7FB650075B8FC /* Project object */; | |||
} |
@@ -0,0 +1,67 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<Scheme | |||
LastUpgradeVersion = "1240" | |||
version = "1.3"> | |||
<BuildAction | |||
parallelizeBuildables = "YES" | |||
buildImplicitDependencies = "YES"> | |||
<BuildActionEntries> | |||
<BuildActionEntry | |||
buildForTesting = "YES" | |||
buildForRunning = "YES" | |||
buildForProfiling = "YES" | |||
buildForArchiving = "YES" | |||
buildForAnalyzing = "YES"> | |||
<BuildableReference | |||
BuildableIdentifier = "primary" | |||
BlueprintIdentifier = "16C866C825D81A3200907F43" | |||
BuildableName = "ProjectM Installer" | |||
BlueprintName = "ProjectM Installer" | |||
ReferencedContainer = "container:Installer.xcodeproj"> | |||
</BuildableReference> | |||
</BuildActionEntry> | |||
</BuildActionEntries> | |||
</BuildAction> | |||
<TestAction | |||
buildConfiguration = "Debug" | |||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" | |||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" | |||
shouldUseLaunchSchemeArgsEnv = "YES"> | |||
<Testables> | |||
</Testables> | |||
</TestAction> | |||
<LaunchAction | |||
buildConfiguration = "Debug" | |||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" | |||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" | |||
launchStyle = "0" | |||
useCustomWorkingDirectory = "NO" | |||
ignoresPersistentStateOnLaunch = "NO" | |||
debugDocumentVersioning = "YES" | |||
debugServiceExtension = "internal" | |||
allowLocationSimulation = "YES"> | |||
</LaunchAction> | |||
<ProfileAction | |||
buildConfiguration = "Release" | |||
shouldUseLaunchSchemeArgsEnv = "YES" | |||
savedToolIdentifier = "" | |||
useCustomWorkingDirectory = "NO" | |||
debugDocumentVersioning = "YES"> | |||
<MacroExpansion> | |||
<BuildableReference | |||
BuildableIdentifier = "primary" | |||
BlueprintIdentifier = "16C866C825D81A3200907F43" | |||
BuildableName = "ProjectM Installer" | |||
BlueprintName = "ProjectM Installer" | |||
ReferencedContainer = "container:Installer.xcodeproj"> | |||
</BuildableReference> | |||
</MacroExpansion> | |||
</ProfileAction> | |||
<AnalyzeAction | |||
buildConfiguration = "Debug"> | |||
</AnalyzeAction> | |||
<ArchiveAction | |||
buildConfiguration = "Release" | |||
revealArchiveInOrganizer = "YES"> | |||
</ArchiveAction> | |||
</Scheme> |
@@ -0,0 +1,460 @@ | |||
GNU LESSER GENERAL PUBLIC LICENSE | |||
Version 2.1, February 1999 | |||
Copyright (C) 1991, 1999 Free Software Foundation, Inc. | |||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |||
Everyone is permitted to copy and distribute verbatim copies | |||
of this license document, but changing it is not allowed. | |||
[This is the first released version of the Lesser GPL. It also counts | |||
as the successor of the GNU Library Public License, version 2, hence | |||
the version number 2.1.] | |||
Preamble | |||
The licenses for most software are designed to take away your | |||
freedom to share and change it. By contrast, the GNU General Public | |||
Licenses are intended to guarantee your freedom to share and change | |||
free software--to make sure the software is free for all its users. | |||
This license, the Lesser General Public License, applies to some | |||
specially designated software packages--typically libraries--of the | |||
Free Software Foundation and other authors who decide to use it. You | |||
can use it too, but we suggest you first think carefully about whether | |||
this license or the ordinary General Public License is the better | |||
strategy to use in any particular case, based on the explanations below. | |||
When we speak of free software, we are referring to freedom of use, | |||
not price. Our General Public Licenses are designed to make sure that | |||
you have the freedom to distribute copies of free software (and charge | |||
for this service if you wish); that you receive source code or can get | |||
it if you want it; that you can change the software and use pieces of | |||
it in new free programs; and that you are informed that you can do | |||
these things. | |||
To protect your rights, we need to make restrictions that forbid | |||
distributors to deny you these rights or to ask you to surrender these | |||
rights. These restrictions translate to certain responsibilities for | |||
you if you distribute copies of the library or if you modify it. | |||
For example, if you distribute copies of the library, whether gratis | |||
or for a fee, you must give the recipients all the rights that we gave | |||
you. You must make sure that they, too, receive or can get the source | |||
code. If you link other code with the library, you must provide | |||
complete object files to the recipients, so that they can relink them | |||
with the library after making changes to the library and recompiling | |||
it. And you must show them these terms so they know their rights. | |||
We protect your rights with a two-step method: (1) we copyright the | |||
library, and (2) we offer you this license, which gives you legal | |||
permission to copy, distribute and/or modify the library. | |||
To protect each distributor, we want to make it very clear that | |||
there is no warranty for the free library. Also, if the library is | |||
modified by someone else and passed on, the recipients should know | |||
that what they have is not the original version, so that the original | |||
author's reputation will not be affected by problems that might be | |||
introduced by others. | |||
Finally, software patents pose a constant threat to the existence of | |||
any free program. We wish to make sure that a company cannot | |||
effectively restrict the users of a free program by obtaining a | |||
restrictive license from a patent holder. Therefore, we insist that | |||
any patent license obtained for a version of the library must be | |||
consistent with the full freedom of use specified in this license. | |||
Most GNU software, including some libraries, is covered by the | |||
ordinary GNU General Public License. This license, the GNU Lesser | |||
General Public License, applies to certain designated libraries, and | |||
is quite different from the ordinary General Public License. We use | |||
this license for certain libraries in order to permit linking those | |||
libraries into non-free programs. | |||
When a program is linked with a library, whether statically or using | |||
a shared library, the combination of the two is legally speaking a | |||
combined work, a derivative of the original library. The ordinary | |||
General Public License therefore permits such linking only if the | |||
entire combination fits its criteria of freedom. The Lesser General | |||
Public License permits more lax criteria for linking other code with | |||
the library. | |||
We call this license the "Lesser" General Public License because it | |||
does Less to protect the user's freedom than the ordinary General | |||
Public License. It also provides other free software developers Less | |||
of an advantage over competing non-free programs. These disadvantages | |||
are the reason we use the ordinary General Public License for many | |||
libraries. However, the Lesser license provides advantages in certain | |||
special circumstances. | |||
For example, on rare occasions, there may be a special need to | |||
encourage the widest possible use of a certain library, so that it becomes | |||
a de-facto standard. To achieve this, non-free programs must be | |||
allowed to use the library. A more frequent case is that a free | |||
library does the same job as widely used non-free libraries. In this | |||
case, there is little to gain by limiting the free library to free | |||
software only, so we use the Lesser General Public License. | |||
In other cases, permission to use a particular library in non-free | |||
programs enables a greater number of people to use a large body of | |||
free software. For example, permission to use the GNU C Library in | |||
non-free programs enables many more people to use the whole GNU | |||
operating system, as well as its variant, the GNU/Linux operating | |||
system. | |||
Although the Lesser General Public License is Less protective of the | |||
users' freedom, it does ensure that the user of a program that is | |||
linked with the Library has the freedom and the wherewithal to run | |||
that program using a modified version of the Library. | |||
The precise terms and conditions for copying, distribution and | |||
modification follow. Pay close attention to the difference between a | |||
"work based on the library" and a "work that uses the library". The | |||
former contains code derived from the library, whereas the latter must | |||
be combined with the library in order to run. | |||
GNU LESSER GENERAL PUBLIC LICENSE | |||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION | |||
0. This License Agreement applies to any software library or other | |||
program which contains a notice placed by the copyright holder or | |||
other authorized party saying it may be distributed under the terms of | |||
this Lesser General Public License (also called "this License"). | |||
Each licensee is addressed as "you". | |||
A "library" means a collection of software functions and/or data | |||
prepared so as to be conveniently linked with application programs | |||
(which use some of those functions and data) to form executables. | |||
The "Library", below, refers to any such software library or work | |||
which has been distributed under these terms. A "work based on the | |||
Library" means either the Library or any derivative work under | |||
copyright law: that is to say, a work containing the Library or a | |||
portion of it, either verbatim or with modifications and/or translated | |||
straightforwardly into another language. (Hereinafter, translation is | |||
included without limitation in the term "modification".) | |||
"Source code" for a work means the preferred form of the work for | |||
making modifications to it. For a library, complete source code means | |||
all the source code for all modules it contains, plus any associated | |||
interface definition files, plus the scripts used to control compilation | |||
and installation of the library. | |||
Activities other than copying, distribution and modification are not | |||
covered by this License; they are outside its scope. The act of | |||
running a program using the Library is not restricted, and output from | |||
such a program is covered only if its contents constitute a work based | |||
on the Library (independent of the use of the Library in a tool for | |||
writing it). Whether that is true depends on what the Library does | |||
and what the program that uses the Library does. | |||
1. You may copy and distribute verbatim copies of the Library's | |||
complete source code as you receive it, in any medium, provided that | |||
you conspicuously and appropriately publish on each copy an | |||
appropriate copyright notice and disclaimer of warranty; keep intact | |||
all the notices that refer to this License and to the absence of any | |||
warranty; and distribute a copy of this License along with the | |||
Library. | |||
You may charge a fee for the physical act of transferring a copy, | |||
and you may at your option offer warranty protection in exchange for a | |||
fee. | |||
2. You may modify your copy or copies of the Library or any portion | |||
of it, thus forming a work based on the Library, and copy and | |||
distribute such modifications or work under the terms of Section 1 | |||
above, provided that you also meet all of these conditions: | |||
a) The modified work must itself be a software library. | |||
b) You must cause the files modified to carry prominent notices | |||
stating that you changed the files and the date of any change. | |||
c) You must cause the whole of the work to be licensed at no | |||
charge to all third parties under the terms of this License. | |||
d) If a facility in the modified Library refers to a function or a | |||
table of data to be supplied by an application program that uses | |||
the facility, other than as an argument passed when the facility | |||
is invoked, then you must make a good faith effort to ensure that, | |||
in the event an application does not supply such function or | |||
table, the facility still operates, and performs whatever part of | |||
its purpose remains meaningful. | |||
(For example, a function in a library to compute square roots has | |||
a purpose that is entirely well-defined independent of the | |||
application. Therefore, Subsection 2d requires that any | |||
application-supplied function or table used by this function must | |||
be optional: if the application does not supply it, the square | |||
root function must still compute square roots.) | |||
These requirements apply to the modified work as a whole. If | |||
identifiable sections of that work are not derived from the Library, | |||
and can be reasonably considered independent and separate works in | |||
themselves, then this License, and its terms, do not apply to those | |||
sections when you distribute them as separate works. But when you | |||
distribute the same sections as part of a whole which is a work based | |||
on the Library, the distribution of the whole must be on the terms of | |||
this License, whose permissions for other licensees extend to the | |||
entire whole, and thus to each and every part regardless of who wrote | |||
it. | |||
Thus, it is not the intent of this section to claim rights or contest | |||
your rights to work written entirely by you; rather, the intent is to | |||
exercise the right to control the distribution of derivative or | |||
collective works based on the Library. | |||
In addition, mere aggregation of another work not based on the Library | |||
with the Library (or with a work based on the Library) on a volume of | |||
a storage or distribution medium does not bring the other work under | |||
the scope of this License. | |||
3. You may opt to apply the terms of the ordinary GNU General Public | |||
License instead of this License to a given copy of the Library. To do | |||
this, you must alter all the notices that refer to this License, so | |||
that they refer to the ordinary GNU General Public License, version 2, | |||
instead of to this License. (If a newer version than version 2 of the | |||
ordinary GNU General Public License has appeared, then you can specify | |||
that version instead if you wish.) Do not make any other change in | |||
these notices. | |||
Once this change is made in a given copy, it is irreversible for | |||
that copy, so the ordinary GNU General Public License applies to all | |||
subsequent copies and derivative works made from that copy. | |||
This option is useful when you wish to copy part of the code of | |||
the Library into a program that is not a library. | |||
4. You may copy and distribute the Library (or a portion or | |||
derivative of it, under Section 2) in object code or executable form | |||
under the terms of Sections 1 and 2 above provided that you accompany | |||
it with the complete corresponding machine-readable source code, which | |||
must be distributed under the terms of Sections 1 and 2 above on a | |||
medium customarily used for software interchange. | |||
If distribution of object code is made by offering access to copy | |||
from a designated place, then offering equivalent access to copy the | |||
source code from the same place satisfies the requirement to | |||
distribute the source code, even though third parties are not | |||
compelled to copy the source along with the object code. | |||
5. A program that contains no derivative of any portion of the | |||
Library, but is designed to work with the Library by being compiled or | |||
linked with it, is called a "work that uses the Library". Such a | |||
work, in isolation, is not a derivative work of the Library, and | |||
therefore falls outside the scope of this License. | |||
However, linking a "work that uses the Library" with the Library | |||
creates an executable that is a derivative of the Library (because it | |||
contains portions of the Library), rather than a "work that uses the | |||
library". The executable is therefore covered by this License. | |||
Section 6 states terms for distribution of such executables. | |||
When a "work that uses the Library" uses material from a header file | |||
that is part of the Library, the object code for the work may be a | |||
derivative work of the Library even though the source code is not. | |||
Whether this is true is especially significant if the work can be | |||
linked without the Library, or if the work is itself a library. The | |||
threshold for this to be true is not precisely defined by law. | |||
If such an object file uses only numerical parameters, data | |||
structure layouts and accessors, and small macros and small inline | |||
functions (ten lines or less in length), then the use of the object | |||
file is unrestricted, regardless of whether it is legally a derivative | |||
work. (Executables containing this object code plus portions of the | |||
Library will still fall under Section 6.) | |||
Otherwise, if the work is a derivative of the Library, you may | |||
distribute the object code for the work under the terms of Section 6. | |||
Any executables containing that work also fall under Section 6, | |||
whether or not they are linked directly with the Library itself. | |||
6. As an exception to the Sections above, you may also combine or | |||
link a "work that uses the Library" with the Library to produce a | |||
work containing portions of the Library, and distribute that work | |||
under terms of your choice, provided that the terms permit | |||
modification of the work for the customer's own use and reverse | |||
engineering for debugging such modifications. | |||
You must give prominent notice with each copy of the work that the | |||
Library is used in it and that the Library and its use are covered by | |||
this License. You must supply a copy of this License. If the work | |||
during execution displays copyright notices, you must include the | |||
copyright notice for the Library among them, as well as a reference | |||
directing the user to the copy of this License. Also, you must do one | |||
of these things: | |||
a) Accompany the work with the complete corresponding | |||
machine-readable source code for the Library including whatever | |||
changes were used in the work (which must be distributed under | |||
Sections 1 and 2 above); and, if the work is an executable linked | |||
with the Library, with the complete machine-readable "work that | |||
uses the Library", as object code and/or source code, so that the | |||
user can modify the Library and then relink to produce a modified | |||
executable containing the modified Library. (It is understood | |||
that the user who changes the contents of definitions files in the | |||
Library will not necessarily be able to recompile the application | |||
to use the modified definitions.) | |||
b) Use a suitable shared library mechanism for linking with the | |||
Library. A suitable mechanism is one that (1) uses at run time a | |||
copy of the library already present on the user's computer system, | |||
rather than copying library functions into the executable, and (2) | |||
will operate properly with a modified version of the library, if | |||
the user installs one, as long as the modified version is | |||
interface-compatible with the version that the work was made with. | |||
c) Accompany the work with a written offer, valid for at | |||
least three years, to give the same user the materials | |||
specified in Subsection 6a, above, for a charge no more | |||
than the cost of performing this distribution. | |||
d) If distribution of the work is made by offering access to copy | |||
from a designated place, offer equivalent access to copy the above | |||
specified materials from the same place. | |||
e) Verify that the user has already received a copy of these | |||
materials or that you have already sent this user a copy. | |||
For an executable, the required form of the "work that uses the | |||
Library" must include any data and utility programs needed for | |||
reproducing the executable from it. However, as a special exception, | |||
the materials to be distributed need not include anything that is | |||
normally distributed (in either source or binary form) with the major | |||
components (compiler, kernel, and so on) of the operating system on | |||
which the executable runs, unless that component itself accompanies | |||
the executable. | |||
It may happen that this requirement contradicts the license | |||
restrictions of other proprietary libraries that do not normally | |||
accompany the operating system. Such a contradiction means you cannot | |||
use both them and the Library together in an executable that you | |||
distribute. | |||
7. You may place library facilities that are a work based on the | |||
Library side-by-side in a single library together with other library | |||
facilities not covered by this License, and distribute such a combined | |||
library, provided that the separate distribution of the work based on | |||
the Library and of the other library facilities is otherwise | |||
permitted, and provided that you do these two things: | |||
a) Accompany the combined library with a copy of the same work | |||
based on the Library, uncombined with any other library | |||
facilities. This must be distributed under the terms of the | |||
Sections above. | |||
b) Give prominent notice with the combined library of the fact | |||
that part of it is a work based on the Library, and explaining | |||
where to find the accompanying uncombined form of the same work. | |||
8. You may not copy, modify, sublicense, link with, or distribute | |||
the Library except as expressly provided under this License. Any | |||
attempt otherwise to copy, modify, sublicense, link with, or | |||
distribute the Library is void, and will automatically terminate your | |||
rights under this License. However, parties who have received copies, | |||
or rights, from you under this License will not have their licenses | |||
terminated so long as such parties remain in full compliance. | |||
9. You are not required to accept this License, since you have not | |||
signed it. However, nothing else grants you permission to modify or | |||
distribute the Library or its derivative works. These actions are | |||
prohibited by law if you do not accept this License. Therefore, by | |||
modifying or distributing the Library (or any work based on the | |||
Library), you indicate your acceptance of this License to do so, and | |||
all its terms and conditions for copying, distributing or modifying | |||
the Library or works based on it. | |||
10. Each time you redistribute the Library (or any work based on the | |||
Library), the recipient automatically receives a license from the | |||
original licensor to copy, distribute, link with or modify the Library | |||
subject to these terms and conditions. You may not impose any further | |||
restrictions on the recipients' exercise of the rights granted herein. | |||
You are not responsible for enforcing compliance by third parties with | |||
this License. | |||
11. If, as a consequence of a court judgment or allegation of patent | |||
infringement or for any other reason (not limited to patent issues), | |||
conditions are imposed on you (whether by court order, agreement or | |||
otherwise) that contradict the conditions of this License, they do not | |||
excuse you from the conditions of this License. If you cannot | |||
distribute so as to satisfy simultaneously your obligations under this | |||
License and any other pertinent obligations, then as a consequence you | |||
may not distribute the Library at all. For example, if a patent | |||
license would not permit royalty-free redistribution of the Library by | |||
all those who receive copies directly or indirectly through you, then | |||
the only way you could satisfy both it and this License would be to | |||
refrain entirely from distribution of the Library. | |||
If any portion of this section is held invalid or unenforceable under any | |||
particular circumstance, the balance of the section is intended to apply, | |||
and the section as a whole is intended to apply in other circumstances. | |||
It is not the purpose of this section to induce you to infringe any | |||
patents or other property right claims or to contest validity of any | |||
such claims; this section has the sole purpose of protecting the | |||
integrity of the free software distribution system which is | |||
implemented by public license practices. Many people have made | |||
generous contributions to the wide range of software distributed | |||
through that system in reliance on consistent application of that | |||
system; it is up to the author/donor to decide if he or she is willing | |||
to distribute software through any other system and a licensee cannot | |||
impose that choice. | |||
This section is intended to make thoroughly clear what is believed to | |||
be a consequence of the rest of this License. | |||
12. If the distribution and/or use of the Library is restricted in | |||
certain countries either by patents or by copyrighted interfaces, the | |||
original copyright holder who places the Library under this License may add | |||
an explicit geographical distribution limitation excluding those countries, | |||
so that distribution is permitted only in or among countries not thus | |||
excluded. In such case, this License incorporates the limitation as if | |||
written in the body of this License. | |||
13. The Free Software Foundation may publish revised and/or new | |||
versions of the Lesser General Public License from time to time. | |||
Such new versions will be similar in spirit to the present version, | |||
but may differ in detail to address new problems or concerns. | |||
Each version is given a distinguishing version number. If the Library | |||
specifies a version number of this License which applies to it and | |||
"any later version", you have the option of following the terms and | |||
conditions either of that version or of any later version published by | |||
the Free Software Foundation. If the Library does not specify a | |||
license version number, you may choose any version ever published by | |||
the Free Software Foundation. | |||
14. If you wish to incorporate parts of the Library into other free | |||
programs whose distribution conditions are incompatible with these, | |||
write to the author to ask for permission. For software which is | |||
copyrighted by the Free Software Foundation, write to the Free | |||
Software Foundation; we sometimes make exceptions for this. Our | |||
decision will be guided by the two goals of preserving the free status | |||
of all derivatives of our free software and of promoting the sharing | |||
and reuse of software generally. | |||
NO WARRANTY | |||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO | |||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. | |||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR | |||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY | |||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE | |||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE | |||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME | |||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. | |||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN | |||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY | |||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU | |||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR | |||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE | |||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING | |||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A | |||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF | |||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH | |||
DAMAGES. | |||
END OF TERMS AND CONDITIONS | |||
@@ -0,0 +1,19 @@ | |||
### Building with LLVM JIT | |||
Install the LLVM libraries. I've used llvm-7 so far, see http://apt.llvm.org/ for LLVM repositories. | |||
``` | |||
sudo apt-get install llvm-7-dev llvm-7-tools | |||
``` | |||
Then run these commands to configure | |||
``` | |||
./autogen.sh && ./configure --enable-sdl --enable-qt --enable-llvm --prefix=$PWD/local | |||
``` | |||
And a clean build of course. | |||
``` | |||
make clean && make -j4 install | |||
``` |
@@ -0,0 +1,54 @@ | |||
ACLOCAL_AMFLAGS=-I m4 | |||
AM_CPPFLAGS=-DDATADIR_PATH='"${pkgdatadir}"' | |||
SUBDIRS=src | |||
PRESETSDIR=@srcdir@/presets | |||
EXTRA_DIST=README.md AUTHORS.txt presets fonts vendor $(PRESETSDIR) | |||
CLEANFILES=dist | |||
# stick apps in bin | |||
# bin_PROGRAMS = $(top_builddir)/bin | |||
# aka /usr/local/share/projectM | |||
pm_data_dir = $(pkgdatadir) | |||
pm_font_dir = $(pm_data_dir)/fonts | |||
# files to install | |||
pm_data__DATA = src/libprojectM/config.inp | |||
pm_font__DATA = fonts/Vera.ttf fonts/VeraMono.ttf | |||
# find and install all preset files | |||
install-data-local: | |||
find "$(PRESETSDIR)" -path "$(PRESETSDIR)/tests" -prune -o -type d -exec $(MKDIR_P) "$(DESTDIR)/$(pm_data_dir)/{}" \; | |||
find "$(PRESETSDIR)" -path "$(PRESETSDIR)/tests" -prune -o -type f -exec $(INSTALL_DATA) "{}" "$(DESTDIR)/$(pm_data_dir)/{}" \; | |||
# from https://stackoverflow.com/questions/30897170/ac-subst-does-not-expand-variable answer: https://stackoverflow.com/a/30960268 | |||
# ptomato https://stackoverflow.com/users/172999/ptomato | |||
src/libprojectM/config.inp: src/libprojectM/config.inp.in Makefile | |||
$(AM_V_GEN)rm -f $@ $@.tmp && \ | |||
$(SED) -e "s,%datadir%,$(datadir),"g $< >$@.tmp && \ | |||
chmod a-w $@.tmp && \ | |||
mv $@.tmp $@ | |||
macOS/Build/Products/Debug/presets: | |||
mkdir -p macOS/Build/Products/Debug | |||
ln -s $(PWD)/presets macOS/Build/Products/Debug/ | |||
build-mac: macOS/Build/Products/Debug/presets | |||
xcrun xcodebuild -scheme "projectM SDL" -configuration Debug -derivedDataPath macOS | |||
@echo "Products built in macOS/Build/Products/Debug" | |||
open macOS/Build/Products/Debug | |||
build-mac-release: | |||
xcrun xcodebuild -allowProvisioningUpdates -scheme "ProjectM Installer" -configuration Release archive -archivePath build/ProjectM.xcarchive | |||
# do a macOS build | |||
dist-mac: dist build-mac-release | |||
mac/notarize.sh | |||
rm -rf dist | |||
mkdir -p dist | |||
mv ProjectM.pkg dist/projectM-macOS.pkg | |||
mv projectM-*.tar.gz dist/ | |||
@echo "Success!\nBuilt plugin installer and SDL app installer in dist/" | |||
CLEANFILES+=src/libprojectM/config.inp |
@@ -0,0 +1,152 @@ | |||
[](https://travis-ci.org/projectM-visualizer/projectm) | |||
 | |||
## projectM - The most advanced open-source music visualizer | |||
**Experience psychedelic and mesmerizing visuals by transforming music into equations that render into a limitless array of user-contributed visualizations.** | |||
projectM is an open-source project that reimplements the esteemed [Winamp Milkdrop](https://en.wikipedia.org/wiki/MilkDrop) by Geiss in a more modern, cross-platform reusable library. | |||
Its purpose in life is to read an audio input and to produce mesmerizing visuals, detecting tempo, and rendering advanced equations into a limitless array of user-contributed visualizations. | |||
### Available For | |||
##### Windows | |||
* [Standalone](https://github.com/projectM-visualizer/projectm/releases) ([latest build](https://ci.appveyor.com/project/revmischa/projectm/build/artifacts)) - (Requires the latest [Visual C++ redistributable](https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads)) | |||
* [Steam](https://store.steampowered.com/app/1358800/projectM_Music_Visualizer/) | |||
* [Windows Store](https://www.microsoft.com/store/apps/9NDCVH0VCWJN) | |||
#### macOS | |||
* [Standalone](https://github.com/projectM-visualizer/projectm/releases) | |||
* [Steam](https://store.steampowered.com/app/1358800/projectM_Music_Visualizer/) | |||
* [Music.app Plugin](https://github.com/projectM-visualizer/projectm/releases/) | |||
* [Brew](https://formulae.brew.sh/formula/projectm) | |||
#### Linux | |||
* [Steam](https://store.steampowered.com/app/1358800/projectM_Music_Visualizer/) | |||
* Check your repository for a binary release. | |||
#### Android | |||
* [Google Play](https://play.google.com/store/apps/details?id=com.psperl.prjM) | |||
#### Xbox / Windows Phone | |||
* [Windows Store](https://www.microsoft.com/store/apps/9NDCVH0VCWJN) | |||
#### Other | |||
* [Source code](https://github.com/projectM-visualizer/projectm/) | |||
* [LV2 + VST2 audio plugin](https://github.com/DISTRHO/ProM/) | |||
* [Qt5](https://www.qt.io/)-based [PulseAudio](https://www.freedesktop.org/wiki/Software/PulseAudio/) and JACK desktop apps in [source code](https://github.com/projectM-visualizer/projectm/) | |||
* [ALSA, XMMS, Winamp, JACK](https://sourceforge.net/projects/projectm/files/) (source, unmaintained) | |||
### Discord chat | |||
[Chat with us on Discord.](https://discord.gg/tpEuywB) | |||
### Demo Video | |||
[](http://www.youtube.com/watch?v=2dSam8zwSFw "Demo") | |||
### Presets | |||
The preset files define the visualizations via pixel shaders and Milkdrop-style equations and parameters. Included with projectM are the bltc201, Milkdrop 1 and 2, projectM, tryptonaut and yin collections. You can grab these presets [here](http://spiegelmc.com/pub/projectm_presets.zip). | |||
You can also download an enormous 41,000 preset pack of presets [here](https://mischa.lol/projectM/presets_community.zip) (123MB zipped). | |||
### Also Featured In | |||
[ Kodi (formerly XBMC)](https://kodi.tv/) | |||
[ Helix](http://ghostfiregames.com/helixhome.html) | |||
[ Silverjuke (FOSS Jukebox)](https://www.silverjuke.net) | |||
[<img src="https://silentradiance.com/demos/projectM_vr/projectm_vr.png" width="200" > Silent Radiance Distance Disco](https://silentradiance.com) | |||
*** | |||
## Screenshots | |||
 | |||
 | |||
 | |||
 | |||
 | |||
 | |||
 | |||
 | |||
 | |||
*** | |||
## Architecture | |||
* [Article](https://lwn.net/Articles/750152/) | |||
# Building from source | |||
See [BUILDING.md](BUILDING.md) | |||
# Keyboard Controls: | |||
* Up: increase beat sensitivity (max 5) | |||
* Down: decrease beat sensitivity (min 0) | |||
* Y: toggle shuffle enabled | |||
* R: jump to random preset | |||
* N or P: next or previous preset (hard transition) | |||
* Shift-N or Shift-P: next or previous preset (soft transition) | |||
* L: lock current preset | |||
* H or F1: show help (if supported) | |||
* M: Open preset navigation menu (if supported) | |||
* F3: show preset (if supported) | |||
* F4: show stats (if supported) | |||
* F5: show FPS (if supported) | |||
#### Only ProjectM SDL: | |||
* Cmd/Ctrl-Q: *q*uit | |||
* Cmd/Ctrl-I: select next audio *i*nput device | |||
* Cmd/Ctrl-S: *s*tretch monitors | |||
* Cmd/Ctrl-M: change *m*onitor | |||
* Cmd/Ctrl-F: toggle *f*ull screen | |||
* Mouse Scroll Up / Down: next or previous preset (hard transition) | |||
* Return: search for preset (RETURN or ESCAPE to exit search) | |||
* Space: lock current preset | |||
# Using the library | |||
At its core projectM is a library, [libprojectM](src/libprojectM). This library is responsible for parsing presets, analyzing audio PCM data with beat detection and FFT, applying the preset to the audio feature data and rendering the resulting output with openGL. It can render to an OpenGL context or a texture. | |||
To look at a simple example way of using the library see the [libSDL2 sample code](src/projectM-sdl/projectM_SDL_main.cpp). | |||
There are many other applications that make use of libprojectM and that can be found in the [src](src/) directory. | |||
*** | |||
# Todo | |||
* Steal cool stuff from the recently-released Milkdrop source. | |||
* Finish [emscripten support](https://github.com/projectM-visualizer/projectm/pull/307) for building to wasm/webGL for the web. | |||
* Update the [various implementations using libprojectM](src). | |||
* Update downstream projects with new versions. | |||
*** | |||
## Help | |||
Report issues on [GitHub](https://github.com/projectM-visualizer/projectm/issues/new) | |||
[Chat with us on Discord.](https://discord.gg/tpEuywB). | |||
If you would like to help improve this project, either with documentation, code, porting, hardware or anything else please let us know! We gladly accept pull requests and issues. | |||
## Maintainers | |||
If you maintain packages of libprojectM, we are happy to work with you! Please note well: | |||
* The main focus of this project is libprojectM. It's a library that only really depends on OpenGL. The other applications are more like examples and demos. | |||
* Most of the applications (e.g. `src/projectM-*`) are likely outdated and of less utility than the core library. If you desire to use them or depend on them, please file an issue so we can help update them. | |||
* The "canonical" application for actually viewing the visualizations is now projectM-sdl, based on libSDL2 because it supports audio input and is completely cross-platform. | |||
* This is an open source project! If you don't like something, feel free to contribute improvements! | |||
* Yes, you are looking at the official version. This is not a fork. | |||
## Authors | |||
[Authors](https://github.com/projectM-visualizer/projectm/raw/master/AUTHORS.txt) | |||
## License | |||
[LGPL](https://github.com/projectM-visualizer/projectm/raw/master/LICENSE.txt) |
@@ -0,0 +1,9 @@ | |||
#!/usr/bin/env sh | |||
set -e # Drop-out from execution if error occurs | |||
printf 'Running autoreconf...' | |||
autoreconf --install | |||
printf '\nSuccess!\nNow please run: ./configure\n' |
@@ -0,0 +1,26 @@ | |||
include_guard() | |||
include(CheckCSourceCompiles) | |||
macro(check_enum_value_exists enum_value include variable) | |||
if(NOT DEFINED ${variable}) | |||
message(STATUS "Looking for enum value ${enum_value}") | |||
set(_CMAKE_REQUIRED_QUIET_tmp "${CMAKE_REQUIRED_QUIET}") | |||
set(CMAKE_REQUIRED_QUIET ON) | |||
check_c_source_compiles(" | |||
#include <${include}> | |||
int main() { | |||
int tmp = ${enum_value}; | |||
return 0; | |||
} | |||
" | |||
${variable} | |||
) | |||
if(${variable}) | |||
message(STATUS "Looking for enum value ${enum_value} - found") | |||
else() | |||
message(STATUS "Looking for enum value ${enum_value} - not found") | |||
endif() | |||
set(CMAKE_REQUIRED_QUIET "${_CMAKE_REQUIRED_QUIET_tmp}") | |||
endif() | |||
endmacro() |
@@ -0,0 +1,47 @@ | |||
include(CheckCXXCompilerFlag) | |||
include(CheckCXXSourceCompiles) | |||
macro(enable_cflags_if_supported) | |||
foreach(flag ${ARGN}) | |||
check_cxx_compiler_flag("${flag}" CXXFLAG_${flag}_SUPPORTED) | |||
if(CXXFLAG_${flag}_SUPPORTED) | |||
add_compile_options("${flag}") | |||
endif() | |||
endforeach() | |||
endmacro() | |||
macro(enable_linker_flags_if_supported) | |||
set(_old_CMAKE_REQUIRED_LINK_OPTIONS "${CMAKE_REQUIRED_LINK_OPTIONS}") | |||
foreach(flag ${ARGN}) | |||
set(CMAKE_REQUIRED_LINK_OPTIONS "${flag}") | |||
check_cxx_source_compiles("int main(){return 0;}" LDCFLAG_${flag}_SUPPORTED) | |||
if(LDCFLAG_${flag}_SUPPORTED) | |||
add_link_options(${flag}) | |||
else() | |||
set(CMAKE_REQUIRED_LINK_OPTIONS "LINKER:${flag}") | |||
check_cxx_source_compiles("int main(){return 0;}" LDCFLAG_LINKER_${flag}_SUPPORTED) | |||
if(LDFLAG_LINKER_${flag}_SUPPORTED) | |||
add_link_options(LINKER:${flag}) | |||
endif() | |||
endif() | |||
endforeach() | |||
set(CMAKE_REQUIRED_LINK_OPTIONS "${_old_CMAKE_REQUIRED_LINK_OPTIONS}") | |||
endmacro() | |||
macro(enable_target_linker_flags_if_supported target access) | |||
set(_old_CMAKE_REQUIRED_LINK_OPTIONS "${CMAKE_REQUIRED_LINK_OPTIONS}") | |||
foreach(flag ${ARGN}) | |||
set(CMAKE_REQUIRED_LINK_OPTIONS "${flag}") | |||
check_cxx_source_compiles("int main(){return 0;}" LDCFLAG_${flag}_SUPPORTED) | |||
if(LDCFLAG_${flag}_SUPPORTED) | |||
target_link_options(${target} ${access} ${flag}) | |||
else() | |||
set(CMAKE_REQUIRED_LINK_OPTIONS "LINKER:${flag}") | |||
check_cxx_source_compiles("int main(){return 0;}" LDCFLAG_LINKER_${flag}_SUPPORTED) | |||
if(LDFLAG_LINKER_${flag}_SUPPORTED) | |||
target_link_options(${target} ${access} LINKER:${flag}) | |||
endif() | |||
endif() | |||
endforeach() | |||
set(CMAKE_REQUIRED_LINK_OPTIONS "${_old_CMAKE_REQUIRED_LINK_OPTIONS}") | |||
endmacro() |
@@ -0,0 +1,20 @@ | |||
# The GLM library is header-only, so we only need to find the glm/glm.hpp header. | |||
find_path(GLM_INCLUDE_DIR | |||
glm/glm.hpp | |||
) | |||
find_file(GLM_INCLUDE_FILE | |||
glm/glm.hpp | |||
) | |||
include(FindPackageHandleStandardArgs) | |||
find_package_handle_standard_args(GLM DEFAULT_MSG GLM_INCLUDE_FILE GLM_INCLUDE_DIR) | |||
if(GLM_FOUND AND NOT TARGET GLM::GLM) | |||
add_library(GLM::GLM INTERFACE IMPORTED) | |||
set_target_properties(GLM::GLM PROPERTIES | |||
INTERFACE_INCLUDE_DIRECTORIES "${GLM_INCLUDE_DIR}" | |||
) | |||
endif() |
@@ -0,0 +1,33 @@ | |||
# First try to use PKG_CONFIG to find JACK. | |||
find_package(PkgConfig QUIET) | |||
if(PKG_CONFIG_FOUND) | |||
pkg_check_modules(JACK jack QUIET) | |||
endif() | |||
if(NOT JACK_INCLUDEDIR OR NOT JACK_LIBRARIES) | |||
find_path(JACK_INCLUDEDIR | |||
jack/jack.h | |||
) | |||
find_library(JACK_LIBRARIES | |||
jack | |||
) | |||
endif() | |||
include(FindPackageHandleStandardArgs) | |||
find_package_handle_standard_args(JACK | |||
REQUIRED_VARS JACK_LIBRARIES JACK_INCLUDEDIR | |||
VERSION_VAR JACK_VERSION | |||
) | |||
if(JACK_FOUND AND NOT TARGET JACK::JACK) | |||
add_library(JACK::JACK INTERFACE IMPORTED) | |||
set_target_properties(JACK::JACK PROPERTIES | |||
INTERFACE_LINK_LIBRARIES "${JACK_LIBRARIES}" | |||
INTERFACE_LINK_DIRECTORIES "${JACK_LIBRARY_DIRS}" | |||
INTERFACE_INCLUDE_DIRECTORIES "${JACK_INCLUDEDIR}" | |||
INTERFACE_COMPILE_OPTIONS "${JACK_CFLAGS}" | |||
) | |||
endif() |
@@ -0,0 +1,55 @@ | |||
# Find and use llvm-config to determine the proper library and include locations. | |||
find_program(LLVM_CONFIG_COMMAND | |||
NAMES llvm-config llvm-config.exe | |||
) | |||
if(LLVM_CONFIG_COMMAND) | |||
execute_process(COMMAND | |||
${LLVM_CONFIG_COMMAND} --version | |||
OUTPUT_VARIABLE LLVM_VERSION | |||
) | |||
string(STRIP "${LLVM_VERSION}" LLVM_VERSION) | |||
execute_process(COMMAND | |||
${LLVM_CONFIG_COMMAND} --includedir | |||
OUTPUT_VARIABLE LLVM_INCLUDE_DIR | |||
) | |||
string(STRIP "${LLVM_INCLUDE_DIR}" LLVM_INCLUDE_DIR) | |||
execute_process(COMMAND | |||
${LLVM_CONFIG_COMMAND} --libdir | |||
OUTPUT_VARIABLE LLVM_LIB_DIR | |||
) | |||
string(STRIP "${LLVM_LIB_DIR}" LLVM_LIB_DIR) | |||
execute_process(COMMAND | |||
${LLVM_CONFIG_COMMAND} --libs | |||
OUTPUT_VARIABLE LLVM_LIBRARIES | |||
) | |||
string(STRIP "${LLVM_LIBRARIES}" LLVM_LIBRARIES) | |||
execute_process(COMMAND | |||
${LLVM_CONFIG_COMMAND} --ldflags | |||
OUTPUT_VARIABLE LLVM_LDFLAGS | |||
) | |||
string(STRIP "${LLVM_LDFLAGS}" LLVM_LDFLAGS) | |||
endif() | |||
include(FindPackageHandleStandardArgs) | |||
find_package_handle_standard_args(LLVM | |||
REQUIRED_VARS LLVM_CONFIG_COMMAND LLVM_LIBRARIES LLVM_LIB_DIR LLVM_INCLUDE_DIR LLVM_LDFLAGS | |||
VERSION_VAR LLVM_VERSION | |||
) | |||
if(LLVM_FOUND AND NOT TARGET LLVM::LLVM) | |||
add_library(LLVM::LLVM INTERFACE IMPORTED) | |||
set_target_properties(LLVM::LLVM PROPERTIES | |||
INTERFACE_LINK_LIBRARIES "${LLVM_LIBRARIES}" | |||
INTERFACE_LINK_DIRECTORIES "${LLVM_LIB_DIR}" | |||
INTERFACE_INCLUDE_DIRECTORIES "${LLVM_INCLUDE_DIR}" | |||
INTERFACE_LINK_OPTIONS "${LLVM_LDFLAGS}" | |||
) | |||
endif() |
@@ -0,0 +1,44 @@ | |||
# First try to use PKG_CONFIG to find Pulseaudio. | |||
find_package(PkgConfig QUIET) | |||
if(PKG_CONFIG_FOUND) | |||
pkg_check_modules(PULSEAUDIO libpulse QUIET) | |||
endif() | |||
if(NOT PULSEAUDIO_INCLUDEDIR OR NOT PULSEAUDIO_LIBRARIES) | |||
find_path(PULSEAUDIO_INCLUDEDIR | |||
pulse/pulseaudio.h | |||
) | |||
find_library(PULSEAUDIO_LIBRARIES | |||
pulse | |||
) | |||
if(PULSEAUDIO_INCLUDEDIR AND EXISTS "${PULSEAUDIO_INCLUDEDIR}/pulse/version.h") | |||
file(STRINGS "${PULSEAUDIO_INCLUDEDIR}/pulse/version.h" pulseaudio_version_str | |||
REGEX "pa_get_headers_version\(\)" | |||
) | |||
if(pulseaudio_version_str AND "${pulseaudio_version_str}" MATCHES "\\(\"([0-9.]+)\"\\)") | |||
set(PULSEAUDIO_VERSION "${CMAKE_MATCH_1}") | |||
endif() | |||
endif() | |||
set(PULSEAUDIO_CFLAGS "-D_REENTRANT") | |||
endif() | |||
include(FindPackageHandleStandardArgs) | |||
find_package_handle_standard_args(Pulseaudio | |||
REQUIRED_VARS PULSEAUDIO_LIBRARIES PULSEAUDIO_INCLUDEDIR | |||
VERSION_VAR PULSEAUDIO_VERSION | |||
) | |||
if(Pulseaudio_FOUND AND NOT TARGET Pulseaudio::Pulseaudio) | |||
add_library(Pulseaudio::Pulseaudio INTERFACE IMPORTED) | |||
set_target_properties(Pulseaudio::Pulseaudio PROPERTIES | |||
INTERFACE_LINK_LIBRARIES "${PULSEAUDIO_LIBRARIES}" | |||
INTERFACE_LINK_DIRECTORIES "${PULSEAUDIO_LIBRARY_DIRS}" | |||
INTERFACE_INCLUDE_DIRECTORIES "${PULSEAUDIO_INCLUDEDIR}" | |||
INTERFACE_COMPILE_OPTIONS "${PULSEAUDIO_CFLAGS}" | |||
) | |||
endif() |
@@ -0,0 +1,42 @@ | |||
# First try to use PKG_CONFIG to find libvisual. | |||
find_package(PkgConfig QUIET) | |||
if(PKG_CONFIG_FOUND) | |||
pkg_check_modules(LIBVISUAL libvisual-0.4 QUIET) | |||
if(LIBVISUAL_INCLUDEDIR) | |||
# Retrieve the plug-in install directory | |||
pkg_get_variable(LIBVISUAL_PLUGINSBASEDIR libvisual-0.4 pluginsbasedir) | |||
endif() | |||
endif() | |||
if(NOT LIBVISUAL_INCLUDEDIR OR NOT LIBVISUAL_LIBRARIES) | |||
find_path(LIBVISUAL_INCLUDEDIR | |||
libvisual/libvisual.h | |||
PATH_SUFFIXES libvisual-0.4 | |||
) | |||
find_library(LIBVISUAL_LIBRARIES | |||
visual-0.4 | |||
) | |||
# Use the default path. | |||
set(LIBVISUAL_PLUGINSBASEDIR "lib/libvisual-0.4") | |||
endif() | |||
include(FindPackageHandleStandardArgs) | |||
find_package_handle_standard_args(libvisual | |||
REQUIRED_VARS LIBVISUAL_INCLUDEDIR LIBVISUAL_LIBRARIES | |||
VERSION_VAR LIBVISUAL_VERSION | |||
) | |||
if(LIBVISUAL_FOUND AND NOT TARGET libvisual::libvisual) | |||
add_library(libvisual::libvisual INTERFACE IMPORTED) | |||
set_target_properties(libvisual::libvisual PROPERTIES | |||
INTERFACE_LINK_LIBRARIES "${LIBVISUAL_LIBRARIES}" | |||
INTERFACE_LINK_DIRECTORIES "${LIBVISUAL_LIBRARY_DIRS}" | |||
INTERFACE_INCLUDE_DIRECTORIES "${LIBVISUAL_INCLUDEDIR}" | |||
INTERFACE_COMPILE_OPTIONS "${LIBVISUAL_CFLAGS}" | |||
) | |||
endif() |
@@ -0,0 +1,68 @@ | |||
# Helper script to add the SDL2 CMake target and version variable as introduced in SDL 2.0.12. | |||
# Also fixes a wrong include path provided by the SDL2 config script. | |||
# Proper CMake target support was added in SDL 2.0.12, create one | |||
# Need to search again to find the full path of libSDL2 | |||
if(NOT TARGET SDL2::SDL2) | |||
# Remove -lSDL2 as that is handled by CMake, note the space at the end so it does not replace e.g. -lSDL2main | |||
# This may require "libdir" being set (from above) | |||
string(REPLACE "-lSDL2 " "" SDL2_EXTRA_LINK_FLAGS " -lSDL2 ") | |||
string(STRIP "${SDL2_EXTRA_LINK_FLAGS}" SDL2_EXTRA_LINK_FLAGS) | |||
string(REPLACE "-lSDL2 " "" SDL2_EXTRA_LINK_FLAGS_STATIC " -Wl,--no-undefined -lm -ldl -lasound -lm -ldl -lpthread -lpulse-simple -lpulse -lX11 -lXext -lXcursor -lXinerama -lXi -lXrandr -lXss -lXxf86vm -lpthread -lrt ") | |||
string(STRIP "${SDL2_EXTRA_LINK_FLAGS_STATIC}" SDL2_EXTRA_LINK_FLAGS_STATIC) | |||
find_library(SDL2_LIBRARY SDL2) | |||
if(NOT SDL2_LIBRARY) | |||
message(FATAL_ERROR "Could not determine the location of the SDL2 library.") | |||
endif() | |||
add_library(SDL2::SDL2 SHARED IMPORTED) | |||
set_target_properties(SDL2::SDL2 PROPERTIES | |||
INTERFACE_INCLUDE_DIRECTORIES "${SDL2_INCLUDE_DIRS}" | |||
IMPORTED_LINK_INTERFACE_LANGUAGES "C" | |||
IMPORTED_LOCATION "${SDL2_LIBRARY}" | |||
INTERFACE_LINK_LIBRARIES "${SDL2_EXTRA_LINK_FLAGS}") | |||
find_library(SDL2MAIN_LIBRARY SDL2main) | |||
if(NOT SDL2MAIN_LIBRARY) | |||
message(FATAL_ERROR "Could not determine the location of the SDL2main library.") | |||
endif() | |||
add_library(SDL2::SDL2main STATIC IMPORTED) | |||
set_target_properties(SDL2::SDL2main PROPERTIES | |||
IMPORTED_LINK_INTERFACE_LANGUAGES "C" | |||
IMPORTED_LOCATION "${SDL2MAIN_LIBRARY}") | |||
# Retrieve the version from the SDL2_version.h header | |||
if(SDL2_INCLUDE_DIRS AND EXISTS "${SDL2_INCLUDE_DIRS}/SDL_version.h") | |||
file(STRINGS "${SDL2_INCLUDE_DIRS}/SDL_version.h" SDL_VERSION_MAJOR_LINE REGEX "^#define[ \t]+SDL_MAJOR_VERSION[ \t]+[0-9]+$") | |||
file(STRINGS "${SDL2_INCLUDE_DIRS}/SDL_version.h" SDL_VERSION_MINOR_LINE REGEX "^#define[ \t]+SDL_MINOR_VERSION[ \t]+[0-9]+$") | |||
file(STRINGS "${SDL2_INCLUDE_DIRS}/SDL_version.h" SDL_VERSION_PATCH_LINE REGEX "^#define[ \t]+SDL_PATCHLEVEL[ \t]+[0-9]+$") | |||
string(REGEX REPLACE "^#define[ \t]+SDL_MAJOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL_VERSION_MAJOR "${SDL_VERSION_MAJOR_LINE}") | |||
string(REGEX REPLACE "^#define[ \t]+SDL_MINOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL_VERSION_MINOR "${SDL_VERSION_MINOR_LINE}") | |||
string(REGEX REPLACE "^#define[ \t]+SDL_PATCHLEVEL[ \t]+([0-9]+)$" "\\1" SDL_VERSION_PATCH "${SDL_VERSION_PATCH_LINE}") | |||
set(SDL2_VERSION ${SDL_VERSION_MAJOR}.${SDL_VERSION_MINOR}.${SDL_VERSION_PATCH}) | |||
unset(SDL_VERSION_MAJOR_LINE) | |||
unset(SDL_VERSION_MINOR_LINE) | |||
unset(SDL_VERSION_PATCH_LINE) | |||
unset(SDL_VERSION_MAJOR) | |||
unset(SDL_VERSION_MINOR) | |||
unset(SDL_VERSION_PATCH) | |||
endif() | |||
endif() | |||
# Temporary fix to deal with wrong include dir set by SDL2's CMake configuration. | |||
get_target_property(_SDL2_INCLUDE_DIR SDL2::SDL2 INTERFACE_INCLUDE_DIRECTORIES) | |||
if(_SDL2_INCLUDE_DIR MATCHES "(.+)/SDL2\$") | |||
message(STATUS "SDL2 include dir contains \"SDL2\" subdir (SDL bug #4004) - fixing to \"${CMAKE_MATCH_1}\".") | |||
set_target_properties(SDL2::SDL2 PROPERTIES | |||
INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_MATCH_1}" | |||
) | |||
endif() | |||
if(SDL2_VERSION AND SDL2_VERSION VERSION_LESS "2.0.5") | |||
message(FATAL_ERROR "SDL2 libraries were found, but have version ${SDL2_VERSION}. At least version 2.0.5 is required.") | |||
endif() | |||
@@ -0,0 +1,73 @@ | |||
#pragma once | |||
/* Define to 1 if you have the `aligned_alloc' function. */ | |||
#cmakedefine01 HAVE_ALIGNED_ALLOC | |||
/* Define to 1 if you have the <dlfcn.h> header file. */ | |||
#cmakedefine01 HAVE_DLFCN_H | |||
/* Define to 1 if you have the <fts.h> header file. */ | |||
#cmakedefine01 HAVE_FTS_H | |||
/* Defined if a valid OpenGL implementation is found. */ | |||
#cmakedefine01 HAVE_GL | |||
/* Define to 1 if you have the <GLES/gl.h> header file. */ | |||
#cmakedefine01 HAVE_GLES_GL_H | |||
/* Define to 1 if you have the <GL/gl.h> header file. */ | |||
#cmakedefine01 HAVE_GL_GL_H | |||
/* Define to 1 if you have the <inttypes.h> header file. */ | |||
#cmakedefine01 HAVE_INTTYPES_H | |||
/* Define HAVE_LLVM */ | |||
#cmakedefine01 HAVE_LLVM | |||
/* Define to 1 if you have the <memory.h> header file. */ | |||
#cmakedefine01 HAVE_MEMORY_H | |||
/* Define to 1 if you have the <OpenGL/gl.h> header file. */ | |||
#cmakedefine01 HAVE_OPENGL_GL_H | |||
/* Define to 1 if you have the `posix_memalign' function. */ | |||
#cmakedefine01 HAVE_POSIX_MEMALIGN | |||
/* Have PTHREAD_PRIO_INHERIT. */ | |||
#cmakedefine01 HAVE_PTHREAD_PRIO_INHERIT | |||
/* Define to 1 if you have the <stdint.h> header file. */ | |||
#cmakedefine HAVE_STDINT_H | |||
/* Define to 1 if you have the <stdlib.h> header file. */ | |||
#cmakedefine HAVE_STDLIB_H | |||
/* Define to 1 if you have the <strings.h> header file. */ | |||
#cmakedefine HAVE_STRINGS_H | |||
/* Define to 1 if you have the <string.h> header file. */ | |||
#cmakedefine HAVE_STRING_H | |||
/* Define to 1 if you have the <sys/stat.h> header file. */ | |||
#cmakedefine HAVE_SYS_STAT_H | |||
/* Define to 1 if you have the <sys/types.h> header file. */ | |||
#cmakedefine HAVE_SYS_TYPES_H | |||
/* Define to 1 if you have the <unistd.h> header file. */ | |||
#cmakedefine HAVE_UNISTD_H | |||
/* Define to 1 if you have the <windows.h> header file. */ | |||
#cmakedefine HAVE_WINDOWS_H | |||
/* Define to 1 if you have the ANSI C header files. */ | |||
#cmakedefine STDC_HEADERS | |||
/* Define USE_GLES */ | |||
#cmakedefine01 USE_GLES | |||
/* Define USE_THREADS */ | |||
#cmakedefine01 USE_THREADS | |||
/* Version number of package */ | |||
#define VERSION "@PROJECT_VERSION@" |
@@ -0,0 +1,25 @@ | |||
#!/bin/bash | |||
if [ -z ${NDK+x} ]; then | |||
export NDK=${HOME}/Android/Sdk/ndk-bundle; | |||
fi | |||
export HOST_TAG=linux-x86_64 | |||
export TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/$HOST_TAG | |||
export TARGET=arm-linux-androideabi | |||
export AR=$TOOLCHAIN/bin/$TARGET-ar | |||
export AS=$TOOLCHAIN/bin/$TARGET-as | |||
export LD=$TOOLCHAIN/bin/$TARGET-ld | |||
export RANLIB=$TOOLCHAIN/bin/$TARGET-ranlib | |||
export STRIP=$TOOLCHAIN/bin/$TARGET-strip | |||
export CC=$TOOLCHAIN/bin/armv7a-linux-androideabi19-clang | |||
export CXX=$TOOLCHAIN/bin/armv7a-linux-androideabi19-clang++ | |||
export LIBS_NDK=$NDK/sources/third_party/vulkan/src/libs/ | |||
export CPPFLAGS="-march=armv7-a -I$LIBS_NDK -fPIC" | |||
export GL_LIBS="-lGLESv3 -lEGL" | |||
./configure --host arm-linux-androideabi \ | |||
--enable-gles --disable-static --disable-sdl --disable-qt \ | |||
--prefix=`realpath src/projectm-android/app/jniLibs` \ | |||
--libdir='${exec_prefix}/armeabi-v7a' \ | |||
--datarootdir=`realpath src/projectm-android/app/src/main/assets` |
@@ -0,0 +1,275 @@ | |||
AC_INIT([projectM], [3.1.13], [me@mish.dev], [projectM], [https://github.com/projectM-visualizer/projectm/]) | |||
AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects tar-pax]) | |||
AX_IS_RELEASE([git-directory]) | |||
AX_CHECK_ENABLE_DEBUG([no], [DEBUG]) | |||
m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) | |||
LT_INIT | |||
# Check if we should disable rpath. | |||
# | |||
# For advanced users: In certain configurations, the rpath attributes | |||
# added by libtool cause problems as rpath will be preferred over | |||
# LD_LIBRARY_PATH. This does not seem to be a problem with | |||
# clang. When using --disable-rpath you will likely need to set | |||
# LD_LIBRARY_PATH if you are using libraries in non-system locations. | |||
# YMMV. | |||
# | |||
DISABLE_RPATH | |||
AC_PROG_CXX | |||
AC_LANG(C++) | |||
AC_CONFIG_MACRO_DIRS([m4 m4/autoconf-archive]) | |||
dnl emscripten | |||
AC_ARG_ENABLE([emscripten], | |||
AS_HELP_STRING([--enable-emscripten], [Build for web with emscripten]), | |||
[], [enable_emscripten=no]) | |||
AS_IF([test "x$enable_emscripten" = "xyes" || test "x$EMSCRIPTEN" = "xyes"], [ | |||
dnl Set up emscripten | |||
m4_include([m4/emscripten.m4]) | |||
AC_DEFINE([EMSCRIPTEN], [1], [Define EMSCRIPTEN]) | |||
enable_threading=no | |||
enable_gles=yes | |||
enable_sdl=yes | |||
], [ | |||
dnl Running in a normal OS (not emscripten) | |||
AX_CHECK_GL | |||
# check OS if mac or linux | |||
AC_CANONICAL_HOST | |||
AC_MSG_CHECKING(Freedom) | |||
case $host_os in | |||
darwin*) | |||
# OSX needs CoreFoundation | |||
AC_MSG_RESULT(Apple hoarderware detected) | |||
LIBS="$LIBS -framework CoreFoundation" | |||
;; | |||
linux*) | |||
# limux needs dl | |||
AC_MSG_RESULT(GNU/LINUX detected) | |||
LIBS="$LIBS -ldl" | |||
;; | |||
*) | |||
AC_MSG_RESULT(Unknown) | |||
;; | |||
esac | |||
]) | |||
AC_CHECK_LIB(c, dlopen, LIBDL="", AC_CHECK_LIB(dl, dlopen, LIBDL="-ldl")) | |||
AC_CHECK_FUNCS_ONCE([aligned_alloc posix_memalign]) | |||
AC_CHECK_HEADERS_ONCE([fts.h]) | |||
AC_CONFIG_HEADERS([config.h]) | |||
AC_CONFIG_FILES([ | |||
Makefile | |||
src/Makefile | |||
src/libprojectM/Makefile | |||
src/libprojectM/Renderer/Makefile | |||
src/libprojectM/NativePresetFactory/Makefile | |||
src/libprojectM/MilkdropPresetFactory/Makefile | |||
src/libprojectM/libprojectM.pc | |||
src/NativePresets/Makefile | |||
src/projectM-sdl/Makefile | |||
src/projectM-emscripten/Makefile | |||
src/projectM-qt/Makefile | |||
src/projectM-pulseaudio/Makefile | |||
src/projectM-jack/Makefile | |||
src/projectM-test/Makefile | |||
]) | |||
# SDL | |||
AC_ARG_ENABLE([sdl], AS_HELP_STRING([--enable-sdl], [Build SDL2 application]), [], [enable_sdl=check]) | |||
AS_IF([test "$enable_sdl" != "no"], [ | |||
PKG_CHECK_MODULES([SDL], [sdl2], [ | |||
m4_include([m4/sdl2.m4]) | |||
SDL_VERSION="2.0.5" | |||
AS_IF([test "$TRAVIS"], [SDL_VERSION=2.0.2]) # travis has old SDL, we don't care | |||
AS_IF([test "$EMSCRIPTEN"], [SDL_VERSION=2.0.0]) # emscripten has old SDL, we don't care | |||
# Check for libSDL >= $SDL_VERSION | |||
AM_PATH_SDL2($SDL_VERSION, | |||
[enable_sdl=yes], | |||
[AS_IF([test "$enable_sdl" = "yes"], AC_MSG_ERROR([*** SDL version >= $SDL_VERSION not found!])); enable_sdl=no]) | |||
], | |||
[ | |||
# not found | |||
AS_IF([test "$enable_sdl" = "yes"], AC_MSG_ERROR([*** libsdl2 not found!])) | |||
enable_sdl=no | |||
]) | |||
]) | |||
# Threading | |||
AC_ARG_ENABLE([threading], | |||
AS_HELP_STRING([--enable-threading], [multhreading]), | |||
[], [enable_threading=yes]) | |||
AS_IF([test "x$enable_threading" = "xyes" && ! test "$EMSCRIPTEN"], [ | |||
m4_include([m4/autoconf-archive/ax_pthread.m4]) | |||
AX_PTHREAD([ | |||
AC_DEFINE([USE_THREADS], [1], [Define USE_THREADS]) | |||
LIBS="$LIBS $PTHREAD_LIBS $PTHREAD_CFLAGS" | |||
CFLAGS="$CFLAGS $PTHREAD_CFLAGS" | |||
CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS" | |||
echo "LIBS=$LIBS" | |||
], [ | |||
AC_MSG_ERROR([pthreads not found]) | |||
]) | |||
]) | |||
AC_ARG_ENABLE([gles], | |||
AS_HELP_STRING([--enable-gles], [OpenGL ES support]), | |||
[], [enable_gles=no]) | |||
AS_IF([test "x$enable_gles" = "xyes"], [ | |||
AC_DEFINE([USE_GLES], [1], [Define USE_GLES]) | |||
]) | |||
dnl LLVM | |||
dnl unfortuately AX_LLVM macro seems to be out of date, so we're going to rely on the user to make sure LLVM is installed correctly | |||
AC_ARG_ENABLE([llvm], | |||
AS_HELP_STRING([--enable-llvm],[Support for JIT using LLVM]), | |||
[], [enable_llvm=no]) | |||
AS_IF([test x"$enable_llvm" = "xyes"], [ | |||
AC_DEFINE([HAVE_LLVM], [1], [Define HAVE_LLVM]) | |||
CFLAGS="$CFLAGS -I$(llvm-config --includedir)" | |||
CXXFLAGS="$CXXFLAGS -I$(llvm-config --includedir)" | |||
LIBS="$LIBS $(llvm-config --libs)" | |||
LDFLAGS="$LDFLAGS $(llvm-config --ldflags)" | |||
]) | |||
dnl from https://stackoverflow.com/questions/30897170/ac-subst-does-not-expand-variable answer: https://stackoverflow.com/a/30960268 | |||
dnl ptomato https://stackoverflow.com/users/172999/ptomato | |||
AC_SUBST([PACKAGE]) | |||
AC_PROG_SED | |||
AC_CONFIG_FILES([src/libprojectM/config.inp.in]) | |||
AC_PREFIX_DEFAULT([/usr/local]) | |||
AC_PROG_MKDIR_P | |||
AS_IF([echo ${host} | grep -Fq android], [], | |||
[AX_CHECK_COMPILE_FLAG([-stdlib=libc++], [ | |||
CXXFLAGS="$CXXFLAGS -stdlib=libc++"]) | |||
]) | |||
AX_CHECK_COMPILE_FLAG([-std=c++14], [ | |||
CXXFLAGS="$CXXFLAGS -std=c++14"]) | |||
# Qt5 | |||
AC_ARG_ENABLE([qt], AS_HELP_STRING([--enable-qt], [Enable Qt: needed for pulseaudio and jack GUIs]), [], [enable_qt=check]) | |||
AS_IF([test "$enable_qt" != "no"], | |||
[ | |||
case $host_os in | |||
linux*) | |||
PATH="$PATH:`pkg-config --variable=host_bins Qt5Core`" | |||
;; | |||
esac | |||
AX_HAVE_QT # m4/qt.m4 | |||
AS_IF([test "$have_qt" = "yes"], [ | |||
# we have at least qt5 if $have_qt is true | |||
enable_qt=yes | |||
export QT_SELECT=qt5 | |||
# we depend on libQt5Gui and libQt5OpenGL | |||
# https://github.com/projectM-visualizer/projectm/issues/271 | |||
LIBS="$LIBS -lQt5Gui -lQt5OpenGL" | |||
], | |||
[AS_IF([test "$enable_qt" = "yes"], | |||
[AC_MSG_ERROR(["Qt5 not found"])], | |||
[enable_qt=no])] | |||
)]) | |||
# Pulseaudio | |||
AC_ARG_ENABLE([pulseaudio], AS_HELP_STRING([--enable-pulseaudio], [Build Pulseaudio]), [], [enable_pulseaudio=check]) | |||
AS_IF([test "$enable_pulseaudio" != "no"], | |||
[PKG_CHECK_MODULES([libpulse], | |||
[libpulse], | |||
[ | |||
# still need qt | |||
AS_IF([test "$enable_qt" = "yes"], | |||
[enable_pulseaudio=yes], | |||
[enable_pulseaudio="no (Qt required)"]) | |||
], | |||
[AS_IF([test "$enable_pulseaudio" = "yes"], | |||
[AC_MSG_ERROR([libpulse required, but not found.])], | |||
[enable_pulseaudio=no])])]) | |||
# Jack | |||
AC_ARG_ENABLE([jack], AS_HELP_STRING([--enable-jack], [Build Jack]), [], [enable_jack=check]) | |||
AS_IF([test "$enable_jack" != "no"], | |||
[PKG_CHECK_MODULES([jack], | |||
[jack], | |||
[ | |||
# still need qt | |||
AS_IF([test "$enable_qt" = "yes"], | |||
[enable_jack=yes], | |||
[enable_jack="no (Qt required)"]) | |||
], | |||
[AS_IF([test "$enable_jack" = "yes"], | |||
[AC_MSG_ERROR([jack required, but not found.])], | |||
[enable_jack=no])])]) | |||
AM_CONDITIONAL([ENABLE_SDL], [test "x$enable_sdl" = "xyes"]) | |||
AM_CONDITIONAL([ENABLE_QT], [test "x$enable_qt" = "xyes"]) | |||
AM_CONDITIONAL([ENABLE_JACK], [test "x$enable_jack" = "xyes"]) | |||
AM_CONDITIONAL([ENABLE_PULSEAUDIO], [test "x$enable_pulseaudio" = "xyes"]) | |||
AM_CONDITIONAL([ENABLE_EMSCRIPTEN], [test "x$enable_emscripten" = "xyes"]) | |||
my_CFLAGS="-Wall -Wchar-subscripts -Wformat-security -Wpointer-arith -Wshadow -Wsign-compare -Wtype-limits" | |||
#my_CFLAGS+="-fsanitize=address -fno-omit-frame-pointer " | |||
my_CFLAGS="${my_CFLAGS} -DDATADIR_PATH=\\\"\"\$(pkgdatadir)\\\"\"" | |||
my_CFLAGS="${my_CFLAGS} -I\"\$(top_srcdir)/vendor\"" # provides glm headers | |||
my_CFLAGS="${my_CFLAGS} -DGL_SILENCE_DEPRECATION" | |||
AC_SUBST([my_CFLAGS]) | |||
# glm (vendored, this should never fail; headers are in vendor/glm) | |||
AC_SUBST(CPPFLAGS, "$CPPFLAGS -I${srcdir}/vendor") | |||
AS_IF([test "x$enable_emscripten" != "xyes"], [ | |||
AC_CHECK_HEADER([glm/glm.hpp],, AC_MSG_ERROR(vendored libglm not found.)) | |||
]) | |||
AC_OUTPUT | |||
AC_MSG_RESULT([ | |||
projectM v$VERSION | |||
===== | |||
prefix: ${prefix} | |||
sysconfdir: ${sysconfdir} | |||
libdir: ${libdir} | |||
includedir: ${includedir} | |||
compiler: ${CC} | |||
cflags: ${CFLAGS} ${my_CFLAGS} | |||
cxxflags: ${CXXFLAGS} | |||
libs: ${LIBS} | |||
ldflags: ${LDFLAGS} | |||
- - - | |||
Applications: | |||
===== | |||
libprojectM: yes | |||
Threading: ${enable_threading} | |||
SDL: ${enable_sdl} | |||
Qt: ${enable_qt} | |||
Pulseaudio: ${enable_pulseaudio} | |||
Jack: ${enable_jack} | |||
OpenGLES: ${enable_gles} | |||
Emscripten: ${enable_emscripten} | |||
LLVM JIT: ${enable_llvm} | |||
]) |
@@ -0,0 +1,103 @@ | |||
# Tests for various platform features and generates a header with the appropriate defines, | |||
# similar to the one created by autotools. | |||
include(CheckSymbolExists) | |||
include(CheckCXXSymbolExists) | |||
include(CheckFunctionExists) | |||
include(CheckIncludeFileCXX) | |||
include(CheckEnumValueExists) | |||
include(CheckIncludeFiles) | |||
include(EnableCFlagsIfSupported) | |||
add_compile_definitions( | |||
$<$<CONFIG:DEBUG>:DEBUG> | |||
) | |||
if(NOT MSVC) | |||
enable_cflags_if_supported( | |||
-Wall | |||
-Wchar-subscripts | |||
-Wformat-security | |||
-Wpointer-arith | |||
-Wshadow | |||
-Wsign-compare | |||
-Wtype-limits | |||
-fopenmp | |||
) | |||
enable_linker_flags_if_supported( | |||
-fopenmp | |||
) | |||
else() | |||
enable_cflags_if_supported( | |||
/W4 | |||
/openmp | |||
) | |||
enable_linker_flags_if_supported( | |||
/openmp | |||
) | |||
endif() | |||
check_function_exists(aligned_alloc HAVE_ALIGNED_ALLOC) | |||
check_include_file_cxx("dlfcn.h" HAVE_DLFCN_H) | |||
check_include_file_cxx("fts.h" HAVE_FTS_H) | |||
check_include_file_cxx("GL/gl.h" HAVE_GL_GL_H) | |||
check_include_file_cxx("inttypes.h" HAVE_INTTYPES_H) | |||
check_include_file_cxx("memory.h" HAVE_MEMORY_H) | |||
check_function_exists(posix_memalign HAVE_POSIX_MEMALIGN) | |||
check_enum_value_exists("PTHREAD_PRIO_INHERIT" "pthread.h" HAVE_PTHREAD_PRIO_INHERIT) | |||
check_include_file_cxx("fts.h" HAVE_FTS_H) | |||
check_include_file_cxx("stdint.h" HAVE_STDINT_H) | |||
check_include_file_cxx("stdlib.h" HAVE_STDLIB_H) | |||
check_include_file_cxx("strings.h" HAVE_STRINGS_H) | |||
check_include_file_cxx("string.h" HAVE_STRING_H) | |||
check_include_file_cxx("sys/stat.h" HAVE_SYS_STAT_H) | |||
check_include_file_cxx("sys/types.h" HAVE_SYS_TYPES_H) | |||
check_include_file_cxx("unistd.h" HAVE_UNISTD_H) | |||
check_include_file_cxx("windows.h" HAVE_WINDOWS_H) | |||
set(_std_c_headers | |||
# C89/C90 | |||
assert.h | |||
ctype.h | |||
errno.h | |||
float.h | |||
limits.h | |||
locale.h | |||
math.h | |||
setjmp.h | |||
signal.h | |||
stdarg.h | |||
stddef.h | |||
stdio.h | |||
stdlib.h | |||
string.h | |||
time.h | |||
# C95/NA1 | |||
iso646.h | |||
wctype.h | |||
# C99 | |||
complex.h | |||
fenv.h | |||
inttypes.h | |||
stdbool.h | |||
stdint.h | |||
tgmath.h | |||
) | |||
check_include_files("${_std_c_headers}" STDC_HEADERS LANGUAGE C) | |||
unset(_std_c_headers) | |||
# Create global configuration header | |||
file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/include") | |||
configure_file(config.h.cmake.in "${CMAKE_BINARY_DIR}/include/config.h") | |||
include_directories("${CMAKE_BINARY_DIR}/include") | |||
add_compile_definitions(HAVE_CONFIG_H) | |||
# Force-include the file in all targets | |||
if(MSVC) | |||
add_definitions(/FI"config.h") | |||
else() | |||
# GCC or Clang | |||
add_definitions(-include config.h) | |||
endif() |
@@ -0,0 +1,71 @@ | |||
# =========================================================================== | |||
# https://www.gnu.org/software/autoconf-archive/ax_absolute_header.html | |||
# =========================================================================== | |||
# | |||
# SYNOPSIS | |||
# | |||
# AX_ABSOLUTE_HEADER(HEADER1 HEADER2 ...) | |||
# | |||
# DESCRIPTION | |||
# | |||
# Find the absolute name of a header file, assuming the header exists. If | |||
# the header were sys/inttypes.h, this macro would define | |||
# ABSOLUTE_SYS_INTTYPES_H to the `""' quoted absolute name of | |||
# sys/inttypes.h in config.h (e.g. `#define ABSOLUTE_SYS_INTTYPES_H | |||
# "///usr/include/sys/inttypes.h"'). The three "///" are to pacify Sun C | |||
# 5.8, which otherwise would say "warning: #include of /usr/include/... | |||
# may be non-portable". Use `""', not `<>', so that the /// cannot be | |||
# confused with a C99 comment. | |||
# | |||
# LICENSE | |||
# | |||
# Copyright (c) 2009 Derek Price | |||
# Copyright (c) 2009 Rhys Ulerich <rhys.ulerich@gmail.com> | |||
# | |||
# Copying and distribution of this file, with or without modification, are | |||
# permitted in any medium without royalty provided the copyright notice | |||
# and this notice are preserved. This file is offered as-is, without any | |||
# warranty. | |||
#serial 7 | |||
dnl Copyright (C) 2006, 2007 Free Software Foundation, Inc. | |||
dnl This file is free software; the Free Software Foundation | |||
dnl gives unlimited permission to copy and/or distribute it, | |||
dnl with or without modifications, as long as this notice is preserved. | |||
dnl From Derek Price. | |||
dnl Modified by Rhys Ulerich to use AC_CHECK_HEADERS instead of _ONCE | |||
AU_ALIAS([GL_TRILINOS_ABSOLUTE_HEADER], [AX_ABSOLUTE_HEADER]) | |||
AC_DEFUN([AX_ABSOLUTE_HEADER], | |||
[AC_LANG_PREPROC_REQUIRE()dnl | |||
AC_FOREACH([gl_HEADER_NAME], [$1], | |||
[AS_VAR_PUSHDEF([gl_absolute_header], | |||
[gl_cv_absolute_]m4_quote(m4_defn([gl_HEADER_NAME])))dnl | |||
AC_CACHE_CHECK([absolute name of <]m4_quote(m4_defn([gl_HEADER_NAME]))[>], | |||
m4_quote(m4_defn([gl_absolute_header])), | |||
[AS_VAR_PUSHDEF([ac_header_exists], | |||
[ac_cv_header_]m4_quote(m4_defn([gl_HEADER_NAME])))dnl | |||
AC_CHECK_HEADERS(m4_quote(m4_defn([gl_HEADER_NAME])))dnl | |||
if test AS_VAR_GET(ac_header_exists) = yes; then | |||
AC_LANG_CONFTEST([AC_LANG_SOURCE([[#include <]]m4_dquote(m4_defn([gl_HEADER_NAME]))[[>]])]) | |||
dnl eval is necessary to expand ac_cpp. | |||
dnl Ultrix and Pyramid sh refuse to redirect output of eval, so use subshell. | |||
AS_VAR_SET(gl_absolute_header, | |||
[`(eval "$ac_cpp conftest.$ac_ext") 2>&AS_MESSAGE_LOG_FD | | |||
sed -n '\#/]m4_quote(m4_defn([gl_HEADER_NAME]))[#{ | |||
s#.*"\(.*/]m4_quote(m4_defn([gl_HEADER_NAME]))[\)".*#\1# | |||
s#^/[^/]#//&# | |||
p | |||
q | |||
}'`]) | |||
fi | |||
AS_VAR_POPDEF([ac_header_exists])dnl | |||
])dnl | |||
AC_DEFINE_UNQUOTED(AS_TR_CPP([ABSOLUTE_]m4_quote(m4_defn([gl_HEADER_NAME]))), | |||
["AS_VAR_GET(gl_absolute_header)"], | |||
[Define this to an absolute name of <]m4_quote(m4_defn([gl_HEADER_NAME]))[>.]) | |||
AS_VAR_POPDEF([gl_absolute_header])dnl | |||
])dnl | |||
])# AX_ABSOLUTE_HEADER |
@@ -0,0 +1,32 @@ | |||
# =========================================================================== | |||
# https://www.gnu.org/software/autoconf-archive/ax_ac_append_to_file.html | |||
# =========================================================================== | |||
# | |||
# SYNOPSIS | |||
# | |||
# AX_AC_APPEND_TO_FILE([FILE],[DATA]) | |||
# | |||
# DESCRIPTION | |||
# | |||
# Appends the specified data to the specified Autoconf is run. If you want | |||
# to append to a file when configure is run use AX_APPEND_TO_FILE instead. | |||
# | |||
# LICENSE | |||
# | |||
# Copyright (c) 2009 Allan Caffee <allan.caffee@gmail.com> | |||
# | |||
# Copying and distribution of this file, with or without modification, are | |||
# permitted in any medium without royalty provided the copyright notice | |||
# and this notice are preserved. This file is offered as-is, without any | |||
# warranty. | |||
#serial 9 | |||
AC_DEFUN([AX_AC_APPEND_TO_FILE],[ | |||
AC_REQUIRE([AX_FILE_ESCAPES]) | |||
m4_esyscmd( | |||
AX_FILE_ESCAPES | |||
[ | |||
printf "$2" >> "$1" | |||
]) | |||
]) |
@@ -0,0 +1,32 @@ | |||
# =========================================================================== | |||
# https://www.gnu.org/software/autoconf-archive/ax_ac_print_to_file.html | |||
# =========================================================================== | |||
# | |||
# SYNOPSIS | |||
# | |||
# AX_AC_PRINT_TO_FILE([FILE],[DATA]) | |||
# | |||
# DESCRIPTION | |||
# | |||
# Writes the specified data to the specified file when Autoconf is run. If | |||
# you want to print to a file when configure is run use AX_PRINT_TO_FILE | |||
# instead. | |||
# | |||
# LICENSE | |||
# | |||
# Copyright (c) 2009 Allan Caffee <allan.caffee@gmail.com> | |||
# | |||
# Copying and distribution of this file, with or without modification, are | |||
# permitted in any medium without royalty provided the copyright notice | |||
# and this notice are preserved. This file is offered as-is, without any | |||
# warranty. | |||
#serial 9 | |||
AC_DEFUN([AX_AC_PRINT_TO_FILE],[ | |||
m4_esyscmd( | |||
AC_REQUIRE([AX_FILE_ESCAPES]) | |||
[ | |||
printf "$2" > "$1" | |||
]) | |||
]) |
@@ -0,0 +1,29 @@ | |||
# =========================================================================== | |||
# https://www.gnu.org/software/autoconf-archive/ax_add_am_macro.html | |||
# =========================================================================== | |||
# | |||
# SYNOPSIS | |||
# | |||
# AX_ADD_AM_MACRO([RULE]) | |||
# | |||
# DESCRIPTION | |||
# | |||
# Adds the specified rule to $AMINCLUDE. This macro will only work | |||
# properly with implementations of Make which allow include statements. | |||
# See also AX_ADD_AM_MACRO_STATIC. | |||
# | |||
# LICENSE | |||
# | |||
# Copyright (c) 2009 Tom Howard <tomhoward@users.sf.net> | |||
# | |||
# Copying and distribution of this file, with or without modification, are | |||
# permitted in any medium without royalty provided the copyright notice | |||
# and this notice are preserved. This file is offered as-is, without any | |||
# warranty. | |||
#serial 10 | |||
AC_DEFUN([AX_ADD_AM_MACRO],[ | |||
AC_REQUIRE([AX_AM_MACROS]) | |||
AX_APPEND_TO_FILE([$AMINCLUDE],[$1]) | |||
]) |
@@ -0,0 +1,28 @@ | |||
# =========================================================================== | |||
# https://www.gnu.org/software/autoconf-archive/ax_add_am_macro_static.html | |||
# =========================================================================== | |||
# | |||
# SYNOPSIS | |||
# | |||
# AX_ADD_AM_MACRO_STATIC([RULE]) | |||
# | |||
# DESCRIPTION | |||
# | |||
# Adds the specified rule to $AMINCLUDE. | |||
# | |||
# LICENSE | |||
# | |||
# Copyright (c) 2009 Tom Howard <tomhoward@users.sf.net> | |||
# Copyright (c) 2009 Allan Caffee <allan.caffee@gmail.com> | |||
# | |||
# Copying and distribution of this file, with or without modification, are | |||
# permitted in any medium without royalty provided the copyright notice | |||
# and this notice are preserved. This file is offered as-is, without any | |||
# warranty. | |||
#serial 8 | |||
AC_DEFUN([AX_ADD_AM_MACRO_STATIC],[ | |||
AC_REQUIRE([AX_AM_MACROS_STATIC]) | |||
AX_AC_APPEND_TO_FILE(AMINCLUDE_STATIC,[$1]) | |||
]) |
@@ -0,0 +1,50 @@ | |||
# ======================================================================================= | |||
# https://www.gnu.org/software/autoconf-archive/ax_add_am_trilinos_makefile_export.html | |||
# ======================================================================================= | |||
# | |||
# SYNOPSIS | |||
# | |||
# AX_ADD_AM_TRILINOS_MAKEFILE_EXPORT(EXPORT_SUFFIX [, ACTION-IF-NOT-FOUND]) | |||
# | |||
# DESCRIPTION | |||
# | |||
# Checks if a file named <Makefile.export.EXPORT_SUFFIX> appears in the | |||
# $TRILINOS_INCLUDE directory. If so, adds an include for it using the | |||
# AX_AM_MACROS framework. | |||
# | |||
# If ACTION-IF-NOT-FOUND is not provided, configure fails. | |||
# | |||
# LICENSE | |||
# | |||
# Copyright (c) 2009 Rhys Ulerich <rhys.ulerich@gmail.com> | |||
# | |||
# Copying and distribution of this file, with or without modification, are | |||
# permitted in any medium without royalty provided the copyright notice | |||
# and this notice are preserved. This file is offered as-is, without any | |||
# warranty. | |||
#serial 8 | |||
AC_DEFUN([AX_ADD_AM_TRILINOS_MAKEFILE_EXPORT],[ | |||
AC_REQUIRE([AX_TRILINOS_BASE]) | |||
AC_REQUIRE([AX_AM_MACROS]) | |||
AC_CACHE_CHECK( | |||
[for file ${TRILINOS_INCLUDE}/Makefile.export.$1], | |||
[ax_cv_add_am_trilinos_makefile_export_]translit($1,[. ],[_])[_exists], | |||
[[ax_cv_add_am_trilinos_makefile_export_]translit($1,[. ],[_])[_exists]=no | |||
test -f "${TRILINOS_INCLUDE}/Makefile.export.$1" && dnl | |||
[ax_cv_add_am_trilinos_makefile_export_]translit($1,[. ],[_])[_exists]=yes]) | |||
if test "${[ax_cv_add_am_trilinos_makefile_export_]translit($1,[. ],[_])[_exists]}" = "yes" | |||
then | |||
AX_ADD_AM_MACRO([ | |||
include ${TRILINOS_INCLUDE}/Makefile.export.$1 | |||
]) | |||
else | |||
ifelse([$2],,AC_MSG_ERROR([Could not find ${TRILINOS_INCLUDE}/Makefile.export.$1. Was Trilinos compiled with --enable-export-makefiles?]),[ | |||
AC_MSG_WARN([Could not find ${TRILINOS_INCLUDE}/Makefile.export.$1. Was Trilinos compiled with --enable-export-makefiles?]) | |||
$2]) | |||
fi | |||
]) |
@@ -0,0 +1,53 @@ | |||
# =========================================================================== | |||
# https://www.gnu.org/software/autoconf-archive/ax_add_fortify_source.html | |||
# =========================================================================== | |||
# | |||
# SYNOPSIS | |||
# | |||
# AX_ADD_FORTIFY_SOURCE | |||
# | |||
# DESCRIPTION | |||
# | |||
# Check whether -D_FORTIFY_SOURCE=2 can be added to CPPFLAGS without macro | |||
# redefinition warnings. Some distributions (such as Gentoo Linux) enable | |||
# _FORTIFY_SOURCE globally in their compilers, leading to unnecessary | |||
# warnings in the form of | |||
# | |||
# <command-line>:0:0: error: "_FORTIFY_SOURCE" redefined [-Werror] | |||
# <built-in>: note: this is the location of the previous definition | |||
# | |||
# which is a problem if -Werror is enabled. This macro checks whether | |||
# _FORTIFY_SOURCE is already defined, and if not, adds -D_FORTIFY_SOURCE=2 | |||
# to CPPFLAGS. | |||
# | |||
# LICENSE | |||
# | |||
# Copyright (c) 2017 David Seifert <soap@gentoo.org> | |||
# | |||
# Copying and distribution of this file, with or without modification, are | |||
# permitted in any medium without royalty provided the copyright notice | |||
# and this notice are preserved. This file is offered as-is, without any | |||
# warranty. | |||
#serial 2 | |||
AC_DEFUN([AX_ADD_FORTIFY_SOURCE],[ | |||
AC_MSG_CHECKING([whether to add -D_FORTIFY_SOURCE=2 to CPPFLAGS]) | |||
AC_LINK_IFELSE([ | |||
AC_LANG_SOURCE( | |||
[[ | |||
int main() { | |||
#ifndef _FORTIFY_SOURCE | |||
return 0; | |||
#else | |||
this_is_an_error; | |||
#endif | |||
} | |||
]] | |||
)], [ | |||
AC_MSG_RESULT([yes]) | |||
CPPFLAGS="$CPPFLAGS -D_FORTIFY_SOURCE=2" | |||
], [ | |||
AC_MSG_RESULT([no]) | |||
]) | |||
]) |
@@ -0,0 +1,49 @@ | |||
# ============================================================================== | |||
# https://www.gnu.org/software/autoconf-archive/ax_add_recursive_am_macro.html | |||
# ============================================================================== | |||
# | |||
# SYNOPSIS | |||
# | |||
# AX_ADD_RECURSIVE_AM_MACRO([TARGET],[RULE]) | |||
# | |||
# DESCRIPTION | |||
# | |||
# Adds the specified rule to $AMINCLUDE along with a TARGET-recursive rule | |||
# that will call TARGET for the current directory and TARGET-am | |||
# recursively for each subdirectory. See also | |||
# AX_ADD_RECURSIVE_AM_MACRO_STATIC. | |||
# | |||
# LICENSE | |||
# | |||
# Copyright (c) 2009 Tom Howard <tomhoward@users.sf.net> | |||
# | |||
# Copying and distribution of this file, with or without modification, are | |||
# permitted in any medium without royalty provided the copyright notice | |||
# and this notice are preserved. This file is offered as-is, without any | |||
# warranty. | |||
#serial 10 | |||
AC_DEFUN([AX_ADD_RECURSIVE_AM_MACRO],[ | |||
AX_ADD_AM_MACRO([ | |||
$1-recursive: | |||
@set fnord ${AX_DOLLAR}${AX_DOLLAR}MAKEFLAGS; amf=${AX_DOLLAR}${AX_DOLLAR}2; \\ | |||
dot_seen=no; \\ | |||
list='${AX_DOLLAR}(SUBDIRS)'; for subdir in ${AX_DOLLAR}${AX_DOLLAR}list; do \\ | |||
echo \"Making $1 in ${AX_DOLLAR}${AX_DOLLAR}subdir\"; \\ | |||
if test \"${AX_DOLLAR}${AX_DOLLAR}subdir\" = \".\"; then \\ | |||
dot_seen=yes; \\ | |||
local_target=\"$1-am\"; \\ | |||
else \\ | |||
local_target=\"$1\"; \\ | |||
fi; \\ | |||
(cd ${AX_DOLLAR}${AX_DOLLAR}subdir && ${AX_DOLLAR}(MAKE) ${AX_DOLLAR}(AM_MAKEFLAGS) ${AX_DOLLAR}${AX_DOLLAR}local_target) \\ | |||
|| case \"${AX_DOLLAR}${AX_DOLLAR}amf\" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \\ | |||
done; \\ | |||
if test \"${AX_DOLLAR}${AX_DOLLAR}dot_seen\" = \"no\"; then \\ | |||
${AX_DOLLAR}(MAKE) ${AX_DOLLAR}(AM_MAKEFLAGS) \"$1-am\" || exit 1; \\ | |||
fi; test -z \"${AX_DOLLAR}${AX_DOLLAR}fail\" | |||
$2 | |||
]) | |||
]) |
@@ -0,0 +1,49 @@ | |||
# ===================================================================================== | |||
# https://www.gnu.org/software/autoconf-archive/ax_add_recursive_am_macro_static.html | |||
# ===================================================================================== | |||
# | |||
# SYNOPSIS | |||
# | |||
# AX_ADD_RECURSIVE_AM_MACRO_STATIC([TARGET],[RULE]) | |||
# | |||
# DESCRIPTION | |||
# | |||
# Adds the specified rule to AMINCLUDE_STATIC along with a | |||
# TARGET-recursive rule that will call TARGET for the current directory | |||
# and TARGET-am recursively for each subdirectory. | |||
# | |||
# LICENSE | |||
# | |||
# Copyright (c) 2009 Tom Howard <tomhoward@users.sf.net> | |||
# Copyright (c) 2009 Allan Caffee <allan.caffee@gmail.com> | |||
# | |||
# Copying and distribution of this file, with or without modification, are | |||
# permitted in any medium without royalty provided the copyright notice | |||
# and this notice are preserved. This file is offered as-is, without any | |||
# warranty. | |||
#serial 8 | |||
AC_DEFUN([AX_ADD_RECURSIVE_AM_MACRO_STATIC],[ | |||
AX_ADD_AM_MACRO_STATIC([ | |||
$1-recursive: | |||
@set fnord ${AX_DOLLAR}${AX_DOLLAR}MAKEFLAGS; amf=${AX_DOLLAR}${AX_DOLLAR}2; \\ | |||
dot_seen=no; \\ | |||
list='${AX_DOLLAR}(SUBDIRS)'; for subdir in ${AX_DOLLAR}${AX_DOLLAR}list; do \\ | |||
echo \"Making $1 in ${AX_DOLLAR}${AX_DOLLAR}subdir\"; \\ | |||
if test \"${AX_DOLLAR}${AX_DOLLAR}subdir\" = \".\"; then \\ | |||
dot_seen=yes; \\ | |||
local_target=\"$1-am\"; \\ | |||
else \\ | |||
local_target=\"$1\"; \\ | |||
fi; \\ | |||
(cd ${AX_DOLLAR}${AX_DOLLAR}subdir && ${AX_DOLLAR}(MAKE) ${AX_DOLLAR}(AM_MAKEFLAGS) ${AX_DOLLAR}${AX_DOLLAR}local_target) \\ | |||
|| case \"${AX_DOLLAR}${AX_DOLLAR}amf\" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \\ | |||
done; \\ | |||
if test \"${AX_DOLLAR}${AX_DOLLAR}dot_seen\" = \"no\"; then \\ | |||
${AX_DOLLAR}(MAKE) ${AX_DOLLAR}(AM_MAKEFLAGS) \"$1-am\" || exit 1; \\ | |||
fi; test -z \"${AX_DOLLAR}${AX_DOLLAR}fail\" | |||
$2 | |||
]) | |||
]) |
@@ -0,0 +1,120 @@ | |||
# =========================================================================== | |||
# https://www.gnu.org/software/autoconf-archive/ax_afs.html | |||
# =========================================================================== | |||
# | |||
# SYNOPSIS | |||
# | |||
# AX_AFS | |||
# | |||
# DESCRIPTION | |||
# | |||
# This sets up the proper includes and libs needed for building programs | |||
# that link with AFS. It adds a --with-afsdir option that lets you specify | |||
# where the AFS includes and libs are (defaulting to /usr/afsws). | |||
# | |||
# It also adds the -I and -L options to CPPFLAGS and LDFLAGS | |||
# | |||
# It creates an AC_SUBST(AFSWS) that contains the directory being used. | |||
# | |||
# It checks for -lBSD, -lsocket and -lnsl since AFS needs those if they | |||
# exist. It also adds -R/usr/ucblib -L/usr/ucblib -lucb if on Solaris. | |||
# | |||
# It sets VICE_ETC_PATH to be the directory where /usr/vice/etc lives, | |||
# since AFS 3.4 uses a different define than AFS 3.5 does for that path. | |||
# | |||
# Finally, it defines AFS_int32 to be the in32 type needed. In older | |||
# versions of afs it was 'int32', and in newer versions it's 'afs_int32'. | |||
# | |||
# LICENSE | |||
# | |||
# Copyright (c) 2008 Scott Grosch <Scott.Grosch@intel.com> | |||
# | |||
# Copying and distribution of this file, with or without modification, are | |||
# permitted in any medium without royalty provided the copyright notice | |||
# and this notice are preserved. This file is offered as-is, without any | |||
# warranty. | |||
#serial 7 | |||
AU_ALIAS([SG_AFS], [AX_AFS]) | |||
AC_DEFUN([AX_AFS], | |||
[AC_ARG_WITH(afsdir, AS_HELP_STRING([--with-afsdir=DIR], | |||
[Directory holding AFS includes/libs]), | |||
ax_cv_with_afsdir=$withval) | |||
AC_CACHE_CHECK([for location of AFS directory], | |||
ax_cv_with_afsdir, ax_cv_with_afsdir=/usr/afsws) | |||
CPPFLAGS="-I${ax_cv_with_afsdir}/include $CPPFLAGS" | |||
LDFLAGS="-L${ax_cv_with_afsdir}/lib -L${ax_cv_with_afsdir}/lib/afs $LDFLAGS" | |||
dnl Once we specify a directory, we try to link a test program. If the link | |||
dnl works, we store the value of the directory in a cache variable. If not, | |||
dnl we put _FAILED_ in the cache value. In this way we don't try to link | |||
dnl the test program if our afsdir value was cached, as we know it works. | |||
AC_MAX_CHECKING([whether the specified AFS dir looks valid]) | |||
if test "x${ax_cv_afsdir_link_works:-set}" != "x$ax_cv_with_afsdir"; then | |||
save_LIBS="$LIBS" | |||
LIBS="$save_LIBS -lcmd" | |||
AC_TRY_LINK([#include <afs/cmd.h>], | |||
[cmd_CreateAlias((struct cmd_syndesc *)0, "foo")], | |||
ax_cv_afsdir_link_works=$ax_cv_with_afsdir, | |||
ax_cv_afsdir_link_works=_FAILED_) | |||
LIBS="$save_LIBS" | |||
wasCached="" | |||
else | |||
wasCached="(cached)" | |||
fi | |||
if test "x$ax_cv_afsdir_link_works" = "x$ax_cv_with_afsdir"; then | |||
AC_MAX_RESULT([${wasCached} yes]) | |||
else | |||
AC_MAX_RESULT([no]) | |||
AC_MAX_ERROR([Unable to link test program....bad AFS dir specified?]) | |||
fi | |||
dnl Much easier to use in XXX.in files | |||
AFSWS=$ax_cv_with_afsdir | |||
AC_SUBST(AFSWS) | |||
dnl Linking against AFS always needs these | |||
AC_CHECK_LIB(BSD, signal) | |||
AC_CHECK_LIB(socket, getservbyname) | |||
AC_CHECK_LIB(nsl, gethostbyname) | |||
dnl On Solaris is just always needs the -lucb library from the compatibility | |||
dnl area. I can't think of any other way to do this than just hardcode it. | |||
AC_CANONICAL_HOST | |||
case "$host" in | |||
*-*-solaris*) | |||
LDFLAGS="-L/usr/ucblib -R/usr/ucblib $LDFLAGS" | |||
LIBS="-lucb $LIBS" | |||
;; | |||
esac | |||
dnl And it always needs these libs added | |||
LIBS="$LIBS -lacl -lvolser -lvldb -lprot -lkauth -lauth -lrxkad -lubik ${ax_cv_with_afsdir}/lib/afs/vlib.a -ldir ${ax_cv_with_afsdir}/lib/afs/util.a -lsys -lafsint -lrx -lsys -ldes -lcom_err -llwp -lcmd -laudit" | |||
dnl This really should be AC_CHECK_LIB() but that always fails for some reason | |||
if test -f "${ax_cv_with_afsdir}/lib/afs/libaudit.a"; then | |||
LIBS="$LIBS -laudit" | |||
fi | |||
dnl If dirpath.h exists and has the value, use that. Otherwise don't | |||
AC_CHECK_HEADERS(afs/dirpath.h, | |||
[AC_DEFINE(VICE_ETC_PATH, AFSDIR_CLIENT_ETC_DIRPATH)], | |||
[AC_DEFINE(VICE_ETC_PATH, AFSCONF_CLIENTNAME)]) | |||
dnl Find out if we should use afs_int32 or int32. They changed the | |||
dnl type across AFS versions. | |||
AC_CACHE_CHECK([for AFS int32 type], ac_cv_type_int32, | |||
[AC_EGREP_CPP(dnl | |||
changequote(<<,>>)dnl | |||
<<(^|[^a-zA-Z_0-9])afs_int32[^a-zA-Z_0-9]>>dnl | |||
changequote([,]), [#include <afs/stds.h> | |||
], ac_cv_type_int32=afs_int32, ac_cv_type_int32=int32)]) | |||
AC_DEFINE_UNQUOTED(AFS_int32, $ac_cv_type_int32) | |||
AH_TEMPLATE([VICE_ETC_PATH], | |||
[Define this to be the define used in the AFS header for /usr/vice/etc]) | |||
AH_TEMPLATE([AFS_int32], [Define this to be the type AFS uses for int32]) | |||
])dnl |
@@ -0,0 +1,55 @@ | |||
# =========================================================================== | |||
# https://www.gnu.org/software/autoconf-archive/ax_am_jobserver.html | |||
# =========================================================================== | |||
# | |||
# SYNOPSIS | |||
# | |||
# AX_AM_JOBSERVER([default_value]) | |||
# | |||
# DESCRIPTION | |||
# | |||
# Enables the use of make's jobserver for the purpose of parallel building | |||
# by passing the -j option to make. | |||
# | |||
# The option --enable-jobserver is added to configure which can accept a | |||
# yes, no, or an integer. The integer is the number of separate jobs to | |||
# allow. If 'yes' is given, then the is assumed to be one more than the | |||
# number of CPUs (determined through AX_COUNT_CPUS). If the value of no is | |||
# given, then the jobserver is disabled. The default value is given by the | |||
# first argument of the macro, or 'yes' if the argument is omitted. | |||
# | |||
# This macro makes use of AX_AM_MACROS, so you must add the following line | |||
# | |||
# @INC_AMINCLUDE@ | |||
# | |||
# to your Makefile.am files. | |||
# | |||
# LICENSE | |||
# | |||
# Copyright (c) 2008 Michael Paul Bailey <jinxidoru@byu.net> | |||
# | |||
# Copying and distribution of this file, with or without modification, are | |||
# permitted in any medium without royalty provided the copyright notice | |||
# and this notice are preserved. This file is offered as-is, without any | |||
# warranty. | |||
#serial 8 | |||
AC_DEFUN([AX_AM_JOBSERVER], [ | |||
AC_REQUIRE([AX_COUNT_CPUS]) | |||
AC_REQUIRE([AX_AM_MACROS]) | |||
AC_ARG_ENABLE( jobserver, | |||
[ --enable-jobserver@<:@=no/yes/@%:@@:>@ default=m4_ifval([$1],[$1],[yes]) | |||
Enable up to @%:@ make jobs | |||
yes: enable one more than CPU count | |||
],, [enable_jobserver=m4_ifval([$1],[$1],[yes])]) | |||
if test "x$enable_jobserver" = "xyes"; then | |||
enable_jobserver=$CPU_COUNT | |||
((enable_jobserver++)) | |||
fi | |||
m4_pattern_allow(AM_MAKEFLAGS) | |||
if test "x$enable_jobserver" != "xno"; then | |||
AC_MSG_NOTICE([added jobserver support to make for $enable_jobserver jobs]) | |||
AX_ADD_AM_MACRO( AM_MAKEFLAGS += -j$enable_jobserver ) | |||
fi | |||
]) |
@@ -0,0 +1,44 @@ | |||
# =========================================================================== | |||
# https://www.gnu.org/software/autoconf-archive/ax_am_macros.html | |||
# =========================================================================== | |||
# | |||
# SYNOPSIS | |||
# | |||
# AX_AM_MACROS | |||
# | |||
# DESCRIPTION | |||
# | |||
# Adds support for macros that create Make rules. You must manually add | |||
# the following line | |||
# | |||
# @INC_AMINCLUDE@ | |||
# | |||
# to your Makefile.in (or Makefile.am if you use Automake) files. | |||
# | |||
# LICENSE | |||
# | |||
# Copyright (c) 2009 Tom Howard <tomhoward@users.sf.net> | |||
# | |||
# Copying and distribution of this file, with or without modification, are | |||
# permitted in any medium without royalty provided the copyright notice | |||
# and this notice are preserved. This file is offered as-is, without any | |||
# warranty. | |||
#serial 10 | |||
AC_DEFUN([AX_AM_MACROS], | |||
[ | |||
AC_MSG_NOTICE([adding automake macro support]) | |||
AMINCLUDE="aminclude.am" | |||
AC_SUBST(AMINCLUDE) | |||
AC_MSG_NOTICE([creating $AMINCLUDE]) | |||
AMINCLUDE_TIME=`date` | |||
AX_PRINT_TO_FILE([$AMINCLUDE],[[ | |||
# generated automatically by configure from AX_AUTOMAKE_MACROS | |||
# on $AMINCLUDE_TIME | |||
]]) | |||
INC_AMINCLUDE="include \$(top_builddir)/$AMINCLUDE" | |||
AC_SUBST(INC_AMINCLUDE) | |||
]) |
@@ -0,0 +1,38 @@ | |||
# =========================================================================== | |||
# https://www.gnu.org/software/autoconf-archive/ax_am_macros_static.html | |||
# =========================================================================== | |||
# | |||
# SYNOPSIS | |||
# | |||
# AX_AM_MACROS_STATIC | |||
# | |||
# DESCRIPTION | |||
# | |||
# Adds support for macros that create Automake rules. You must manually | |||
# add the following line | |||
# | |||
# include $(top_srcdir)/aminclude_static.am | |||
# | |||
# to your Makefile.am files. | |||
# | |||
# LICENSE | |||
# | |||
# Copyright (c) 2009 Tom Howard <tomhoward@users.sf.net> | |||
# Copyright (c) 2009 Allan Caffee <allan.caffee@gmail.com> | |||
# | |||
# Copying and distribution of this file, with or without modification, are | |||
# permitted in any medium without royalty provided the copyright notice | |||
# and this notice are preserved. This file is offered as-is, without any | |||
# warranty. | |||
#serial 10 | |||
AC_DEFUN([AMINCLUDE_STATIC],[aminclude_static.am]) | |||
AC_DEFUN([AX_AM_MACROS_STATIC], | |||
[ | |||
AX_AC_PRINT_TO_FILE(AMINCLUDE_STATIC,[ | |||
# ]AMINCLUDE_STATIC[ generated automatically by Autoconf | |||
# from AX_AM_MACROS_STATIC on ]m4_esyscmd([date])[ | |||
]) | |||
]) |
@@ -0,0 +1,155 @@ | |||
# =========================================================================== | |||
# https://www.gnu.org/software/autoconf-archive/ax_am_override_var.html | |||
# =========================================================================== | |||
# | |||
# SYNOPSIS | |||
# | |||
# AX_AM_OVERRIDE_VAR([varname1 varname ... ]) | |||
# AX_AM_OVERRIDE_FINALIZE | |||
# | |||
# DESCRIPTION | |||
# | |||
# This autoconf macro generalizes the approach given in | |||
# <http://lists.gnu.org/archive/html/automake/2005-09/msg00108.html> which | |||
# moves user specified values for variable 'varname' given at configure | |||
# time into the corresponding AM_${varname} variable and clears out | |||
# 'varname', allowing further manipulation by the configure script so that | |||
# target specific variables can be given specialized versions. 'varname | |||
# may still be specified on the make command line and will be appended as | |||
# usual. | |||
# | |||
# As an example usage, consider a project which might benefit from | |||
# different compiler flags for different components. Typically this is | |||
# done via target specific flags, e.g. | |||
# | |||
# libgtest_la_CXXFLAGS = \ | |||
# -I $(top_srcdir)/tests \ | |||
# -I $(top_builddir)/tests \ | |||
# $(GTEST_CXXFLAGS) | |||
# | |||
# automake will automatically append $(CXXFLAGS) -- provided by the user | |||
# -- to the build rule for libgtest_la. That might be problematic, as | |||
# CXXFLAGS may contain compiler options which are inappropriate for | |||
# libgtest_la. | |||
# | |||
# The approach laid out in the referenced mailing list message is to | |||
# supply a base value for a variable during _configure_ time, during which | |||
# it is possible to amend it for specific targets. The user may | |||
# subsequently specify a value for the variable during _build_ time, which | |||
# make will apply (via the standard automake rules) to all appropriate | |||
# targets. | |||
# | |||
# For example, | |||
# | |||
# AX_AM_OVERRIDE_VAR([CXXFLAGS]) | |||
# | |||
# will store the value of CXXFLAGS specified at configure time into the | |||
# AM_CXXFLAGS variable, AC_SUBST it, and clear CXXFLAGS. configure may | |||
# then create a target specific set of flags based upon AM_CXXFLAGS, e.g. | |||
# | |||
# # googletest uses variadic macros, which g++ -pedantic-errors | |||
# # is very unhappy about | |||
# AC_SUBST([GTEST_CXXFLAGS], | |||
# [`AS_ECHO_N(["$AM_CXXFLAGS"]) \ | |||
# | sed s/-pedantic-errors/-pedantic/` | |||
# ] | |||
# ) | |||
# | |||
# which would be used in a Makefile.am as above. Since CXXFLAGS is | |||
# cleared, the configure time value will not affect the build for | |||
# libgtest_la. | |||
# | |||
# Prior to _any other command_ which may set ${varname}, call | |||
# | |||
# AX_AM_OVERRIDE_VAR([varname]) | |||
# | |||
# This will preserve the value (if any) passed to configure in | |||
# AM_${varname} and AC_SUBST([AM_${varname}). You may pass a space | |||
# separated list of variable names, or may call AX_AM_OVERRIDE_VAR | |||
# multiple times for the same effect. | |||
# | |||
# If any subsequent configure commands set ${varname} and you wish to | |||
# capture the resultant value into AM_${varname} in the case where | |||
# ${varname} was _not_ provided at configure time, call | |||
# | |||
# AX_AM_OVERRIDE_FINALIZE | |||
# | |||
# after _all_ commands which might affect any of the variables specified | |||
# in calls to AX_AM_OVERRIDE_VAR. This need be done only once, but | |||
# repeated calls will not cause harm. | |||
# | |||
# There is a bit of trickery required to allow further manipulation of the | |||
# AM_${varname} in a Makefile.am file. If AM_CFLAGS is used as is in a | |||
# Makefile.am, e.g. | |||
# | |||
# libfoo_la_CFLAGS = $(AM_CFLAGS) | |||
# | |||
# then automake will emit code in Makefile.in which sets AM_CFLAGS from | |||
# the configure'd value. | |||
# | |||
# If however, AM_CFLAGS is manipulated (i.e. appended to), you will have | |||
# to explicitly arrange for the configure'd value to be substituted: | |||
# | |||
# AM_CFLAGS = @AM_CFLAGS@ | |||
# AM_CFLAGS += -lfoo | |||
# | |||
# or else automake will complain about using += before =. | |||
# | |||
# LICENSE | |||
# | |||
# Copyright (c) 2013 Smithsonian Astrophysical Observatory | |||
# Copyright (c) 2013 Diab Jerius <djerius@cfa.harvard.edu> | |||
# | |||
# Copying and distribution of this file, with or without modification, are | |||
# permitted in any medium without royalty provided the copyright notice | |||
# and this notice are preserved. This file is offered as-is, without any | |||
# warranty. | |||
#serial 2 | |||
AC_DEFUN([_AX_AM_OVERRIDE_INITIALIZE], | |||
[ | |||
m4_define([_mst_am_override_vars],[]) | |||
]) | |||
# _AX_AM_OVERRIDE_VAR(varname) | |||
AC_DEFUN([_AX_AM_OVERRIDE_VAR], | |||
[ | |||
m4_define([_mst_am_override_vars], m4_defn([_mst_am_override_vars]) $1 ) | |||
_mst_am_override_$1_set=false | |||
AS_IF( [test "${$1+set}" = set], | |||
[AC_SUBST([AM_$1],["$$1"]) | |||
$1= | |||
_mst_am_override_$1_set=: | |||
] | |||
) | |||
]) # _AX_AM_OVERRIDE_VAR | |||
# _AX_AM_OVERRIDE_FINALIZE(varname) | |||
AC_DEFUN([_AX_AM_OVERRIDE_FINALIZE], | |||
[ | |||
AS_IF([$_mst_am_override_$1_set = :], | |||
[], | |||
[AC_SUBST([AM_$1],["$$1"]) | |||
$1= | |||
_mst_am_override_$1_set= | |||
] | |||
) | |||
AC_SUBST($1) | |||
]) # _AX_AM_OVERRIDE_FINALIZE | |||
AC_DEFUN([AX_AM_OVERRIDE_VAR], | |||
[ | |||
AC_REQUIRE([_AX_AM_OVERRIDE_INITIALIZE]) | |||
m4_map_args_w([$1],[_AX_AM_OVERRIDE_VAR(],[)]) | |||
])# AX_OVERRIDE_VAR | |||
# AX_AM_OVERRIDE_FINALIZE | |||
AC_DEFUN([AX_AM_OVERRIDE_FINALIZE], | |||
[ | |||
AC_REQUIRE([_AX_AM_OVERRIDE_INITIALIZE]) | |||
m4_map_args_w(_mst_am_override_vars,[_AX_AM_OVERRIDE_FINALIZE(],[)]) | |||
]) # AX_AM_OVERRIDE_FINALIZE |
@@ -0,0 +1,67 @@ | |||
# ============================================================================ | |||
# https://www.gnu.org/software/autoconf-archive/ax_append_compile_flags.html | |||
# ============================================================================ | |||
# | |||
# SYNOPSIS | |||
# | |||
# AX_APPEND_COMPILE_FLAGS([FLAG1 FLAG2 ...], [FLAGS-VARIABLE], [EXTRA-FLAGS], [INPUT]) | |||
# | |||
# DESCRIPTION | |||
# | |||
# For every FLAG1, FLAG2 it is checked whether the compiler works with the | |||
# flag. If it does, the flag is added FLAGS-VARIABLE | |||
# | |||
# If FLAGS-VARIABLE is not specified, the current language's flags (e.g. | |||
# CFLAGS) is used. During the check the flag is always added to the | |||
# current language's flags. | |||
# | |||
# If EXTRA-FLAGS is defined, it is added to the current language's default | |||
# flags (e.g. CFLAGS) when the check is done. The check is thus made with | |||
# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to | |||
# force the compiler to issue an error when a bad flag is given. | |||
# | |||
# INPUT gives an alternative input source to AC_COMPILE_IFELSE. | |||
# | |||
# NOTE: This macro depends on the AX_APPEND_FLAG and | |||
# AX_CHECK_COMPILE_FLAG. Please keep this macro in sync with | |||
# AX_APPEND_LINK_FLAGS. | |||
# | |||
# LICENSE | |||
# | |||
# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com> | |||
# | |||
# This program is free software: you can redistribute it and/or modify it | |||
# under the terms of the GNU General Public License as published by the | |||
# Free Software Foundation, either version 3 of the License, or (at your | |||
# option) any later version. | |||
# | |||
# This program is distributed in the hope that it will be useful, but | |||
# WITHOUT ANY WARRANTY; without even the implied warranty of | |||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General | |||
# Public License for more details. | |||
# | |||
# You should have received a copy of the GNU General Public License along | |||
# with this program. If not, see <https://www.gnu.org/licenses/>. | |||
# | |||
# As a special exception, the respective Autoconf Macro's copyright owner | |||
# gives unlimited permission to copy, distribute and modify the configure | |||
# scripts that are the output of Autoconf when processing the Macro. You | |||
# need not follow the terms of the GNU General Public License when using | |||
# or distributing such scripts, even though portions of the text of the | |||
# Macro appear in them. The GNU General Public License (GPL) does govern | |||
# all other use of the material that constitutes the Autoconf Macro. | |||
# | |||
# This special exception to the GPL applies to versions of the Autoconf | |||
# Macro released by the Autoconf Archive. When you make and distribute a | |||
# modified version of the Autoconf Macro, you may extend this special | |||
# exception to the GPL to apply to your modified version as well. | |||
#serial 6 | |||
AC_DEFUN([AX_APPEND_COMPILE_FLAGS], | |||
[AX_REQUIRE_DEFINED([AX_CHECK_COMPILE_FLAG]) | |||
AX_REQUIRE_DEFINED([AX_APPEND_FLAG]) | |||
for flag in $1; do | |||
AX_CHECK_COMPILE_FLAG([$flag], [AX_APPEND_FLAG([$flag], [$2])], [], [$3], [$4]) | |||
done | |||
])dnl AX_APPEND_COMPILE_FLAGS |
@@ -0,0 +1,71 @@ | |||
# =========================================================================== | |||
# https://www.gnu.org/software/autoconf-archive/ax_append_flag.html | |||
# =========================================================================== | |||
# | |||
# SYNOPSIS | |||
# | |||
# AX_APPEND_FLAG(FLAG, [FLAGS-VARIABLE]) | |||
# | |||
# DESCRIPTION | |||
# | |||
# FLAG is appended to the FLAGS-VARIABLE shell variable, with a space | |||
# added in between. | |||
# | |||
# If FLAGS-VARIABLE is not specified, the current language's flags (e.g. | |||
# CFLAGS) is used. FLAGS-VARIABLE is not changed if it already contains | |||
# FLAG. If FLAGS-VARIABLE is unset in the shell, it is set to exactly | |||
# FLAG. | |||
# | |||
# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. | |||
# | |||
# LICENSE | |||
# | |||
# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de> | |||
# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com> | |||
# | |||
# This program is free software: you can redistribute it and/or modify it | |||
# under the terms of the GNU General Public License as published by the | |||
# Free Software Foundation, either version 3 of the License, or (at your | |||
# option) any later version. | |||
# | |||
# This program is distributed in the hope that it will be useful, but | |||
# WITHOUT ANY WARRANTY; without even the implied warranty of | |||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General | |||
# Public License for more details. | |||
# | |||
# You should have received a copy of the GNU General Public License along | |||
# with this program. If not, see <https://www.gnu.org/licenses/>. | |||
# | |||
# As a special exception, the respective Autoconf Macro's copyright owner | |||
# gives unlimited permission to copy, distribute and modify the configure | |||
# scripts that are the output of Autoconf when processing the Macro. You | |||
# need not follow the terms of the GNU General Public License when using | |||
# or distributing such scripts, even though portions of the text of the | |||
# Macro appear in them. The GNU General Public License (GPL) does govern | |||
# all other use of the material that constitutes the Autoconf Macro. | |||
# | |||
# This special exception to the GPL applies to versions of the Autoconf | |||
# Macro released by the Autoconf Archive. When you make and distribute a | |||
# modified version of the Autoconf Macro, you may extend this special | |||
# exception to the GPL to apply to your modified version as well. | |||
#serial 7 | |||
AC_DEFUN([AX_APPEND_FLAG], | |||
[dnl | |||
AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_SET_IF | |||
AS_VAR_PUSHDEF([FLAGS], [m4_default($2,_AC_LANG_PREFIX[FLAGS])]) | |||
AS_VAR_SET_IF(FLAGS,[ | |||
AS_CASE([" AS_VAR_GET(FLAGS) "], | |||
[*" $1 "*], [AC_RUN_LOG([: FLAGS already contains $1])], | |||
[ | |||
AS_VAR_APPEND(FLAGS,[" $1"]) | |||
AC_RUN_LOG([: FLAGS="$FLAGS"]) | |||
]) | |||
], | |||
[ | |||
AS_VAR_SET(FLAGS,[$1]) | |||
AC_RUN_LOG([: FLAGS="$FLAGS"]) | |||
]) | |||
AS_VAR_POPDEF([FLAGS])dnl | |||
])dnl AX_APPEND_FLAG |
@@ -0,0 +1,65 @@ | |||
# =========================================================================== | |||
# https://www.gnu.org/software/autoconf-archive/ax_append_link_flags.html | |||
# =========================================================================== | |||
# | |||
# SYNOPSIS | |||
# | |||
# AX_APPEND_LINK_FLAGS([FLAG1 FLAG2 ...], [FLAGS-VARIABLE], [EXTRA-FLAGS], [INPUT]) | |||
# | |||
# DESCRIPTION | |||
# | |||
# For every FLAG1, FLAG2 it is checked whether the linker works with the | |||
# flag. If it does, the flag is added FLAGS-VARIABLE | |||
# | |||
# If FLAGS-VARIABLE is not specified, the linker's flags (LDFLAGS) is | |||
# used. During the check the flag is always added to the linker's flags. | |||
# | |||
# If EXTRA-FLAGS is defined, it is added to the linker's default flags | |||
# when the check is done. The check is thus made with the flags: "LDFLAGS | |||
# EXTRA-FLAGS FLAG". This can for example be used to force the linker to | |||
# issue an error when a bad flag is given. | |||
# | |||
# INPUT gives an alternative input source to AC_COMPILE_IFELSE. | |||
# | |||
# NOTE: This macro depends on the AX_APPEND_FLAG and AX_CHECK_LINK_FLAG. | |||
# Please keep this macro in sync with AX_APPEND_COMPILE_FLAGS. | |||
# | |||
# LICENSE | |||
# | |||
# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com> | |||
# | |||
# This program is free software: you can redistribute it and/or modify it | |||
# under the terms of the GNU General Public License as published by the | |||
# Free Software Foundation, either version 3 of the License, or (at your | |||
# option) any later version. | |||
# | |||
# This program is distributed in the hope that it will be useful, but | |||
# WITHOUT ANY WARRANTY; without even the implied warranty of | |||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General | |||
# Public License for more details. | |||
# | |||
# You should have received a copy of the GNU General Public License along | |||
# with this program. If not, see <https://www.gnu.org/licenses/>. | |||
# | |||
# As a special exception, the respective Autoconf Macro's copyright owner | |||
# gives unlimited permission to copy, distribute and modify the configure | |||
# scripts that are the output of Autoconf when processing the Macro. You | |||
# need not follow the terms of the GNU General Public License when using | |||
# or distributing such scripts, even though portions of the text of the | |||
# Macro appear in them. The GNU General Public License (GPL) does govern | |||
# all other use of the material that constitutes the Autoconf Macro. | |||
# | |||
# This special exception to the GPL applies to versions of the Autoconf | |||
# Macro released by the Autoconf Archive. When you make and distribute a | |||
# modified version of the Autoconf Macro, you may extend this special | |||
# exception to the GPL to apply to your modified version as well. | |||
#serial 6 | |||
AC_DEFUN([AX_APPEND_LINK_FLAGS], | |||
[AX_REQUIRE_DEFINED([AX_CHECK_LINK_FLAG]) | |||
AX_REQUIRE_DEFINED([AX_APPEND_FLAG]) | |||
for flag in $1; do | |||
AX_CHECK_LINK_FLAG([$flag], [AX_APPEND_FLAG([$flag], [m4_default([$2], [LDFLAGS])])], [], [$3], [$4]) | |||
done | |||
])dnl AX_APPEND_LINK_FLAGS |
@@ -0,0 +1,27 @@ | |||
# =========================================================================== | |||
# https://www.gnu.org/software/autoconf-archive/ax_append_to_file.html | |||
# =========================================================================== | |||
# | |||
# SYNOPSIS | |||
# | |||
# AX_APPEND_TO_FILE([FILE],[DATA]) | |||
# | |||
# DESCRIPTION | |||
# | |||
# Appends the specified data to the specified file. | |||
# | |||
# LICENSE | |||
# | |||
# Copyright (c) 2008 Tom Howard <tomhoward@users.sf.net> | |||
# | |||
# Copying and distribution of this file, with or without modification, are | |||
# permitted in any medium without royalty provided the copyright notice | |||
# and this notice are preserved. This file is offered as-is, without any | |||
# warranty. | |||
#serial 8 | |||
AC_DEFUN([AX_APPEND_TO_FILE],[ | |||
AC_REQUIRE([AX_FILE_ESCAPES]) | |||
printf "$2" >> "$1" | |||
]) |
@@ -0,0 +1,185 @@ | |||
# =========================================================================== | |||
# https://www.gnu.org/software/autoconf-archive/ax_arg_with_path_style.html | |||
# =========================================================================== | |||
# | |||
# SYNOPSIS | |||
# | |||
# AX_ARG_WITH_PATH_STYLE | |||
# | |||
# DESCRIPTION | |||
# | |||
# _AC_DEFINE(PATH_STYLE) describing the filesys interface. The value is | |||
# numeric, where the basetype is encoded as 16 = dos/win, 32 = unix, 64 = | |||
# url/www, 0 = other | |||
# | |||
# some extra semantics are described in other bits of the value, | |||
# especially | |||
# | |||
# 1024 accepts "/" as a dir separator | |||
# 2048 accepts ";" as a path separator | |||
# 4096 accepts "," as a path separator | |||
# | |||
# the macro provides a configure' --with-path-style option that can be | |||
# used with descriptive arg names. If not explicitly given, the $target_os | |||
# will be checked to provide a sane default. Additional (lower) bits can | |||
# be used by the user for some additional magic, higher bits are reserved | |||
# for this macro. | |||
# | |||
# the mnemonic "strict" or "also" is used to instruct the code that | |||
# additional separators shall be accepted but converted to the separator | |||
# of the underlying pathstyle system. (or-512) | |||
# | |||
# example: --with-path-style=win,slash | |||
# to make it accept ";" as pathsep, and | |||
# both "/" and "\" as dirseps. | |||
# | |||
# LICENSE | |||
# | |||
# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de> | |||
# | |||
# This program is free software; you can redistribute it and/or modify it | |||
# under the terms of the GNU General Public License as published by the | |||
# Free Software Foundation; either version 3 of the License, or (at your | |||
# option) any later version. | |||
# | |||
# This program is distributed in the hope that it will be useful, but | |||
# WITHOUT ANY WARRANTY; without even the implied warranty of | |||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General | |||
# Public License for more details. | |||
# | |||
# You should have received a copy of the GNU General Public License along | |||
# with this program. If not, see <https://www.gnu.org/licenses/>. | |||
# | |||
# As a special exception, the respective Autoconf Macro's copyright owner | |||
# gives unlimited permission to copy, distribute and modify the configure | |||
# scripts that are the output of Autoconf when processing the Macro. You | |||
# need not follow the terms of the GNU General Public License when using | |||
# or distributing such scripts, even though portions of the text of the | |||
# Macro appear in them. The GNU General Public License (GPL) does govern | |||
# all other use of the material that constitutes the Autoconf Macro. | |||
# | |||
# This special exception to the GPL applies to versions of the Autoconf | |||
# Macro released by the Autoconf Archive. When you make and distribute a | |||
# modified version of the Autoconf Macro, you may extend this special | |||
# exception to the GPL to apply to your modified version as well. | |||
#serial 10 | |||
AU_ALIAS([AC_ARG_WITH_PATH_STYLE], [AX_ARG_WITH_PATH_STYLE]) | |||
AC_DEFUN([AX_ARG_WITH_PATH_STYLE], | |||
[ | |||
AC_ARG_WITH(path-style, | |||
[ --with-path-style=[dos,unix,url,also,slash,comma], | |||
[ac_with_path_style="$withval"], | |||
[dnl | |||
case "$target_os" in | |||
*djgpp | *mingw32* | *emx*) ac_with_path_style="dos" ;; | |||
*) case `eval echo $exec_prefix` in | |||
*:*) ac_with_path_style="url" ;; | |||
*) ac_with_path_style="posix" ;; | |||
esac | |||
;; | |||
esac | |||
]) | |||
ac_with_path_style__unx="0" | |||
ac_with_path_style__dos="0" | |||
ac_with_path_style__win="0" | |||
ac_with_path_style__mac="0" | |||
ac_with_path_style__def="0" | |||
ac_with_path_style__use="0" | |||
ac_with_path_style__slash="0" | |||
ac_with_path_style__semic="0" | |||
ac_with_path_style__comma="0" | |||
ac_with_path_style__level="0" | |||
case ",$ac_with_path_style," in | |||
*,unx,*|*,unix,*|*,bsd,*|*,posix,*) : | |||
ac_with_path_style__unx="32" ;; | |||
*) ac_with_path_style__unx="0" ;; | |||
esac | |||
case ",$ac_with_path_style," in | |||
*,dos,*|*,win,*|*,windows,*) : | |||
ac_with_path_style__dos="16" ;; | |||
*) ac_with_path_style__dos="0" ;; | |||
esac | |||
case ",$ac_with_path_style," in | |||
*,web,*|*,url,*|*,www,*) : | |||
ac_with_path_style__url="64" ;; | |||
*) ac_with_path_style__url="0" ;; | |||
esac | |||
case ",$ac_with_path_style," in | |||
*,mac,*|*,macintosh,*|*,apple,*) : | |||
ac_with_path_style__mac="128" ;; | |||
*) ac_with_path_style__mac="0" ;; | |||
esac | |||
case ",$ac_with_path_style," in | |||
*,def,*|*,define,*|*,special,*) : | |||
ac_with_path_style__def="256" ;; | |||
*) ac_with_path_style__def="0" ;; | |||
esac | |||
case ",$ac_with_path_style," in | |||
*,also,*|*,strict,*|*,accept,*|*,convert,*) : | |||
ac_with_path_style__use="512" ;; | |||
*) ac_with_path_style__use="0" ;; | |||
esac | |||
case ",$ac_with_path_style," in | |||
*,sl,*|*,slash,*|*,forwslash,*|*,slashsep,*) : | |||
ac_with_path_style__slash="1024" ;; | |||
*) ac_with_path_style__slash="0" ;; | |||
esac | |||
case ",$ac_with_path_style," in | |||
*,sc,*|*,semi,*|*,semisep,*|*,semicolon,*|*,semicolonsep,*) : | |||
ac_with_path_style__semic="2048" ;; | |||
*) ac_with_path_style__semic="0" ;; | |||
esac | |||
case ",$ac_with_path_style," in | |||
*,cm,*|*,comma,*|*,commasep,*) : | |||
ac_with_path_style__comma="4096" ;; | |||
*) ac_with_path_style__comma="0" ;; | |||
esac | |||
if test "$ac_with_path_style__unx" != "0" ; then | |||
ac_with_path_style__slash="1024" | |||
fi | |||
if test "$ac_with_path_style__dos" != "0" ; then | |||
ac_with_path_style__semic="2048" | |||
fi | |||
if test "$ac_with_path_style__url" != "0" ; then | |||
ac_with_path_style__slash="1024" | |||
ac_with_path_style__semic="2048" | |||
fi | |||
case ",$ac_with_path_style," in | |||
*,7,*|*,all,*|*,muchmore,*) | |||
ac_with_path_style__level="7" ;; | |||
*,6,*|*,extra,*|*,manymore,*) | |||
ac_with_path_style__level="6" ;; | |||
*,5,*|*,much,*) | |||
ac_with_path_style__level="5" ;; | |||
*,4,*|*,many,*) | |||
ac_with_path_style__level="4" ;; | |||
*,3,*|*,plus,*|*,somemore,*) | |||
ac_with_path_style__level="3" ;; | |||
*,2,*|*,more,*) | |||
ac_with_path_style__level="2" ;; | |||
*,1,*|*,some,*) | |||
ac_with_path_style__level="1" ;; | |||
*) | |||
ac_with_path_style__level="0" ;; | |||
esac | |||
PATH_STYLE=`expr \ | |||
$ac_with_path_style__unx '+' \ | |||
$ac_with_path_style__dos '+' \ | |||
$ac_with_path_style__win '+' \ | |||
$ac_with_path_style__mac '+' \ | |||
$ac_with_path_style__def '+' \ | |||
$ac_with_path_style__use '+' \ | |||
$ac_with_path_style__slash '+' \ | |||
$ac_with_path_style__semic '+' \ | |||
$ac_with_path_style__comma '+' \ | |||
$ac_with_path_style__level ` | |||
AC_DEFINE_UNQUOTED(PATH_STYLE,$PATH_STYLE, | |||
[ the OS pathstyle, 16=dos 32=unx 64=url 1024=slash 2048=semic 4096=comma ]) | |||
]) |
@@ -0,0 +1,57 @@ | |||
# =========================================================================== | |||
# https://www.gnu.org/software/autoconf-archive/ax_asm_inline.html | |||
# =========================================================================== | |||
# | |||
# SYNOPSIS | |||
# | |||
# AX_ASM_INLINE() | |||
# | |||
# DESCRIPTION | |||
# | |||
# Tests for C compiler support of inline assembly instructions. If inline | |||
# assembly is supported, this macro #defines ASM_INLINE to be the | |||
# appropriate keyword. | |||
# | |||
# LICENSE | |||
# | |||
# Copyright (c) 2008 Alan Woodland <ajw05@aber.ac.uk> | |||
# Copyright (c) 2009 Rhys Ulerich <rhys.ulerich@gmail.com> | |||
# Copyright (c) 2017 Reini Urban <rurban@cpan.org> | |||
# | |||
# Copying and distribution of this file, with or without modification, are | |||
# permitted in any medium without royalty provided the copyright notice | |||
# and this notice are preserved. This file is offered as-is, without any | |||
# warranty. | |||
#serial 4 | |||
AC_DEFUN([AX_ASM_INLINE], [ | |||
AC_LANG_PUSH([C]) | |||
AC_MSG_CHECKING(for inline assembly style) | |||
AC_CACHE_VAL(ac_cv_asm_inline, [ | |||
ax_asm_inline_keywords="__asm__ __asm none" | |||
for ax_asm_inline_keyword in $ax_asm_inline_keywords; do | |||
case $ax_asm_inline_keyword in | |||
none) ac_cv_asm_inline=none ; break ;; | |||
*) | |||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM( | |||
[#include <stdlib.h> | |||
static void | |||
foo(void) { | |||
] $ax_asm_inline_keyword [(""); | |||
exit(1); | |||
}], | |||
[])], | |||
[ac_cv_asm_inline=$ax_asm_inline_keyword ; break], | |||
ac_cv_asm_inline=none | |||
) | |||
esac | |||
done | |||
]) | |||
if test "$ac_cv_asm_inline" != "none"; then | |||
AC_DEFINE_UNQUOTED([ASM_INLINE], $ac_cv_asm_inline, [If the compiler supports inline assembly define it to that keyword here]) | |||
fi | |||
AC_MSG_RESULT($ac_cv_asm_inline) | |||
AC_LANG_POP([C]) | |||
]) |
@@ -0,0 +1,130 @@ | |||
# =========================================================================== | |||
# https://www.gnu.org/software/autoconf-archive/ax_at_check_pattern.html | |||
# =========================================================================== | |||
# | |||
# SYNOPSIS | |||
# | |||
# AX_AT_CHECK_PATTERN(COMMANDS, [STATUS], [STDOUT-RE], [STDERR-RE], [RUN-IF-FAIL], [RUN-IF-PASS]) | |||
# AX_AT_DIFF_PATTERN(PATTERN-FILE, TEST-FILE, [STATUS=0], [DIFFERENCES]) | |||
# | |||
# DESCRIPTION | |||
# | |||
# AX_AT_CHECK_PATTERN() executes a test similar to AT_CHECK(), except that | |||
# stdout and stderr are awk regular expressions (REs). | |||
# | |||
# NOTE: as autoconf uses [] for quoting, the use of [brackets] in the RE | |||
# arguments STDOUT-RE and STDERR-RE can be awkward and require careful | |||
# extra quoting, or quadrigraphs '@<:@' (for '[') and '@:>@' (for ']'). | |||
# | |||
# awk is invoked via $AWK, which defaults to "awk" if unset or empty. | |||
# | |||
# Implemented using AT_CHECK() with a custom value for $at_diff that | |||
# invokes diff with an awk post-processor. | |||
# | |||
# AX_AT_DIFF_PATTERN() checks that the PATTERN-FILE applies to TEST-FILE. | |||
# If there are differences, STATUS will be 1 and they should be | |||
# DIFFERENCES. | |||
# | |||
# LICENSE | |||
# | |||
# Copyright (c) 2013-2014 Luke Mewburn <luke@mewburn.net> | |||
# | |||
# Copying and distribution of this file, with or without modification, are | |||
# permitted in any medium without royalty provided the copyright notice | |||
# and this notice are preserved. This file is offered as-is, without any | |||
# warranty. | |||
#serial 2 | |||
m4_defun([_AX_AT_CHECK_PATTERN_PREPARE], [dnl | |||
dnl Can't use AC_PROG_AWK() in autotest. | |||
AS_VAR_IF([AWK], [], [AWK=awk]) | |||
AS_REQUIRE_SHELL_FN([ax_at_diff_pattern], | |||
[AS_FUNCTION_DESCRIBE([ax_at_diff_pattern], [PATTERN OUTPUT], | |||
[Diff PATTERN OUTPUT and elide change lines where the RE pattern matches])], | |||
[diff "$[]1" "$[]2" | $AWK ' | |||
BEGIN { exitval=0 } | |||
function mismatch() | |||
{ | |||
print mode | |||
for (i = 0; i < lc; i++) { | |||
print ll[[i]] | |||
} | |||
print "---" | |||
for (i = 0; i < rc; i++) { | |||
print rl[[i]] | |||
} | |||
mode="" | |||
exitval=1 | |||
} | |||
$[]1 ~ /^[[0-9]]+(,[[0-9]]+)?[[ad]][[0-9]]+(,[[0-9]]+)?$/ { | |||
mode="" | |||
exitval=1 | |||
next | |||
} | |||
$[]1 ~ /^[[0-9]]+(,[[0-9]]+)?[[c]][[0-9]]+(,[[0-9]]+)?$/ { | |||
mode=$[]1 | |||
lc=0 | |||
rc=0 | |||
next | |||
} | |||
mode == "" { | |||
print $[]0 | |||
next | |||
} | |||
$[]1 == "<" { | |||
ll[[lc]] = $[]0 | |||
lc = lc + 1 | |||
next | |||
} | |||
$[]1 == "---" { | |||
next | |||
} | |||
$[]1 == ">" { | |||
rl[[rc]] = $[]0 | |||
rc = rc + 1 | |||
if (rc > lc) { | |||
mismatch() | |||
next | |||
} | |||
pat = "^" substr(ll[[rc-1]], 2) "$" | |||
str = substr($[]0, 2) | |||
if (str !~ pat) { | |||
mismatch() | |||
} | |||
next | |||
} | |||
{ | |||
print "UNEXPECTED LINE: " $[]0 | |||
exit 10 | |||
} | |||
END { exit exitval } | |||
'])dnl ax_at_diff_pattern | |||
])dnl _AX_AT_CHECK_PATTERN_PREPARE | |||
m4_defun([AX_AT_CHECK_PATTERN], [dnl | |||
AS_REQUIRE([_AX_AT_CHECK_PATTERN_PREPARE]) | |||
_ax_at_check_pattern_prepare_original_at_diff="$at_diff" | |||
at_diff='ax_at_diff_pattern' | |||
AT_CHECK($1, $2, $3, $4, | |||
[at_diff="$_ax_at_check_pattern_prepare_original_at_diff";]$5, | |||
[at_diff="$_ax_at_check_pattern_prepare_original_at_diff";]$6) | |||
])dnl AX_AT_CHECK_PATTERN | |||
m4_defun([AX_AT_DIFF_PATTERN], [dnl | |||
AS_REQUIRE([_AX_AT_CHECK_PATTERN_PREPARE]) | |||
AT_CHECK([ax_at_diff_pattern $1 $2], [$3], [$4]) | |||
])dnl AX_AT_CHECK_PATTERN |
@@ -0,0 +1,63 @@ | |||
# ============================================================================ | |||
# https://www.gnu.org/software/autoconf-archive/ax_auto_include_headers.html | |||
# ============================================================================ | |||
# | |||
# SYNOPSIS | |||
# | |||
# AX_AUTO_INCLUDE_HEADERS(INCLUDE-FILE ...) | |||
# | |||
# DESCRIPTION | |||
# | |||
# Given a space-separated list of INCLUDE-FILEs, AX_AUTO_INCLUDE_HEADERS | |||
# will output a conditional #include for each INCLUDE-FILE. The following | |||
# example demonstrates how AX_AUTO_INCLUDE_HEADERS's might be used in a | |||
# configure.ac script: | |||
# | |||
# AH_BOTTOM([ | |||
# AX_AUTO_INCLUDE_HEADERS([sys/resource.h invent.h sys/sysinfo.h])dnl | |||
# ]) | |||
# | |||
# The preceding invocation instructs autoheader to put the following code | |||
# at the bottom of the config.h file: | |||
# | |||
# #ifdef HAVE_SYS_RESOURCE_H | |||
# # include <sys/resource.h> | |||
# #endif | |||
# #ifdef HAVE_INVENT_H | |||
# # include <invent.h> | |||
# #endif | |||
# #ifdef HAVE_SYS_SYSINFO_H | |||
# # include <sys/sysinfo.h> | |||
# #endif | |||
# | |||
# Note that AX_AUTO_INCLUDE_HEADERS merely outputs #ifdef/#include/#endif | |||
# blocks. The configure.ac script still needs to invoke AC_CHECK_HEADERS | |||
# to #define the various HAVE_*_H preprocessor macros. | |||
# | |||
# Here's an easy way to get from config.h a complete list of header files | |||
# who existence is tested by the configure script: | |||
# | |||
# cat config.h | perl -ane '/ HAVE_\S+_H / && do {$_=$F[$#F-1]; s/^HAVE_//; s/_H/.h/; s|_|/|g; tr/A-Z/a-z/; print "$_ "}' | |||
# | |||
# You can then manually edit the resulting list and incorporate it into | |||
# one or more calls to AX_AUTO_INCLUDE_HEADERS. | |||
# | |||
# LICENSE | |||
# | |||
# Copyright (c) 2008 Scott Pakin <pakin@uiuc.edu> | |||
# | |||
# Copying and distribution of this file, with or without modification, are | |||
# permitted in any medium without royalty provided the copyright notice | |||
# and this notice are preserved. This file is offered as-is, without any | |||
# warranty. | |||
#serial 9 | |||
AC_DEFUN([AX_AUTO_INCLUDE_HEADERS], [dnl | |||
AC_FOREACH([AX_Header], [$1], [dnl | |||
m4_pushdef([AX_IfDef], AS_TR_CPP(HAVE_[]AX_Header))dnl | |||
[#]ifdef AX_IfDef | |||
[#] include <AX_Header> | |||
[#]endif | |||
m4_popdef([AX_IfDef])dnl | |||
])]) |
@@ -0,0 +1,148 @@ | |||
# =========================================================================== | |||
# https://www.gnu.org/software/autoconf-archive/ax_berkeley_db.html | |||
# =========================================================================== | |||
# | |||
# SYNOPSIS | |||
# | |||
# AX_BERKELEY_DB([MINIMUM-VERSION [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) | |||
# | |||
# DESCRIPTION | |||
# | |||
# This macro tries to find Berkeley DB. It honors MINIMUM-VERSION if | |||
# given. | |||
# | |||
# If libdb is found, DB_HEADER and DB_LIBS variables are set and | |||
# ACTION-IF-FOUND shell code is executed if specified. DB_HEADER is set to | |||
# location of db.h header in quotes (e.g. "db3/db.h") and | |||
# AC_DEFINE_UNQUOTED is called on it, so that you can type | |||
# | |||
# #include DB_HEADER | |||
# | |||
# in your C/C++ code. DB_LIBS is set to linker flags needed to link | |||
# against the library (e.g. -ldb3.1) and AC_SUBST is called on it. | |||
# | |||
# when specified user-selected spot (via --with-libdb) also sets | |||
# | |||
# DB_CPPFLAGS to the include directives required | |||
# DB_LDFLAGS to the -L flags required | |||
# | |||
# LICENSE | |||
# | |||
# Copyright (c) 2008 Vaclav Slavik <vaclav.slavik@matfyz.cz> | |||
# Copyright (c) 2014 Kirill A. Korinskiy <catap@catap.ru> | |||
# | |||
# Copying and distribution of this file, with or without modification, are | |||
# permitted in any medium without royalty provided the copyright notice | |||
# and this notice are preserved. This file is offered as-is, without any | |||
# warranty. | |||
#serial 8 | |||
AC_DEFUN([AX_BERKELEY_DB], | |||
[ | |||
old_LIBS="$LIBS" | |||
old_LDFLAGS="$LDFLAGS" | |||
old_CFLAGS="$CFLAGS" | |||
libdbdir="" | |||
AC_ARG_WITH(libdb, | |||
AS_HELP_STRING([--with-libdb=DIR], | |||
[root of the Berkeley DB directory]), | |||
[ | |||
case "$withval" in | |||
"" | y | ye | yes | n | no) | |||
AC_MSG_ERROR([Invalid --with-libdb value]) | |||
;; | |||
*) libdbdir="$withval" | |||
;; | |||
esac | |||
], []) | |||
minversion=ifelse([$1], ,,$1) | |||
DB_HEADER="" | |||
DB_LIBS="" | |||
DB_LDFLAGS="" | |||
DB_CFLAGS="" | |||
if test -z $minversion ; then | |||
minvermajor=0 | |||
minverminor=0 | |||
minverpatch=0 | |||
AC_MSG_CHECKING([for Berkeley DB]) | |||
else | |||
minvermajor=`echo $minversion | cut -d. -f1` | |||
minverminor=`echo $minversion | cut -d. -f2` | |||
minverpatch=`echo $minversion | cut -d. -f3` | |||
minvermajor=${minvermajor:-0} | |||
minverminor=${minverminor:-0} | |||
minverpatch=${minverpatch:-0} | |||
AC_MSG_CHECKING([for Berkeley DB >= $minversion]) | |||
fi | |||
if test x$libdbdir != x""; then | |||
DB_CFLAGS="-I${libdbdir}/include" | |||
DB_LDFLAGS="-L${libdbdir}/lib" | |||
LDFLAGS="$DB_LDFLAGS $old_LDFLAGS" | |||
CFLAGS="$DB_CFLAGS $old_CPPFLAGS" | |||
fi | |||
for version in "" 5.0 4.9 4.8 4.7 4.6 4.5 4.4 4.3 4.2 4.1 4.0 3.6 3.5 3.4 3.3 3.2 3.1 ; do | |||
if test -z $version ; then | |||
db_lib="-ldb" | |||
try_headers="db.h" | |||
else | |||
db_lib="-ldb-$version" | |||
try_headers="db$version/db.h db`echo $version | sed -e 's,\..*,,g'`/db.h" | |||
fi | |||
LIBS="$old_LIBS $db_lib" | |||
for db_hdr in $try_headers ; do | |||
if test -z $DB_HEADER ; then | |||
AC_LINK_IFELSE( | |||
[AC_LANG_PROGRAM( | |||
[ | |||
#include <${db_hdr}> | |||
], | |||
[ | |||
#if !((DB_VERSION_MAJOR > (${minvermajor}) || \ | |||
(DB_VERSION_MAJOR == (${minvermajor}) && \ | |||
DB_VERSION_MINOR > (${minverminor})) || \ | |||
(DB_VERSION_MAJOR == (${minvermajor}) && \ | |||
DB_VERSION_MINOR == (${minverminor}) && \ | |||
DB_VERSION_PATCH >= (${minverpatch})))) | |||
#error "too old version" | |||
#endif | |||
DB *db; | |||
db_create(&db, NULL, 0); | |||
])], | |||
[ | |||
AC_MSG_RESULT([header $db_hdr, library $db_lib]) | |||
DB_HEADER="$db_hdr" | |||
DB_LIBS="$db_lib" | |||
]) | |||
fi | |||
done | |||
done | |||
LIBS="$old_LIBS" | |||
LDFLAGS="$old_LDFLAGS" | |||
CFLAGS="$old_CPPFLAGS" | |||
if test -z $DB_HEADER ; then | |||
AC_MSG_RESULT([not found]) | |||
DB_LDFLAGS="" | |||
DB_CFLAGS="" | |||
ifelse([$3], , :, [$3]) | |||
else | |||
AC_DEFINE_UNQUOTED(DB_HEADER, ["$DB_HEADER"], ["Berkeley DB Header File"]) | |||
AC_SUBST(DB_LIBS) | |||
AC_SUBST(DB_LDFLAGS) | |||
AC_SUBST(DB_CFLAGS) | |||
ifelse([$2], , :, [$2]) | |||
fi | |||
]) |
@@ -0,0 +1,152 @@ | |||
# =========================================================================== | |||
# https://www.gnu.org/software/autoconf-archive/ax_berkeley_db_cxx.html | |||
# =========================================================================== | |||
# | |||
# SYNOPSIS | |||
# | |||
# AX_BERKELEY_DB_CXX([MINIMUM-VERSION [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) | |||
# | |||
# DESCRIPTION | |||
# | |||
# This macro tries to find Berkeley DB C++ support. It honors | |||
# MINIMUM-VERSION if given. | |||
# | |||
# If libdb_cxx is found, DB_CXX_HEADER and DB_CXX_LIBS variables are set | |||
# and ACTION-IF-FOUND shell code is executed if specified. DB_CXX_HEADER | |||
# is set to location of db.h header in quotes (e.g. "db3/db_cxx.h") and | |||
# AC_DEFINE_UNQUOTED is called on it, so that you can type | |||
# | |||
# #include DB_CXX_HEADER | |||
# | |||
# in your C/C++ code. DB_CXX_LIBS is set to linker flags needed to link | |||
# against the library (e.g. -ldb3.1_cxx) and AC_SUBST is called on it. | |||
# | |||
# when specified user-selected spot (via --with-libdb) also sets | |||
# | |||
# DB_CXX_CPPFLAGS to the include directives required | |||
# DB_CXX_LDFLAGS to the -L flags required | |||
# | |||
# LICENSE | |||
# | |||
# Copyright (c) 2008 Vaclav Slavik <vaclav.slavik@matfyz.cz> | |||
# Copyright (c) 2011 Stephan Suerken <absurd@debian.org> | |||
# Copyright (c) 2014 Kirill A. Korinskiy <catap@catap.ru> | |||
# | |||
# Copying and distribution of this file, with or without modification, are | |||
# permitted in any medium without royalty provided the copyright notice | |||
# and this notice are preserved. This file is offered as-is, without any | |||
# warranty. | |||
#serial 6 | |||
AC_DEFUN([AX_BERKELEY_DB_CXX], | |||
[ | |||
AC_LANG_ASSERT(C++) | |||
old_LIBS="$LIBS" | |||
old_LDFLAGS="$LDFLAGS" | |||
old_CPPFLAGS="$CPPFLAGS" | |||
libdbdir="" | |||
AC_ARG_WITH(libdb, | |||
AS_HELP_STRING([--with-libdb=DIR], | |||
[root of the Berkeley DB directory]), | |||
[ | |||
case "$withval" in | |||
"" | y | ye | yes | n | no) | |||
AC_MSG_ERROR([Invalid --with-libdb value]) | |||
;; | |||
*) libdbdir="$withval" | |||
;; | |||
esac | |||
], []) | |||
minversion=ifelse([$1], ,,$1) | |||
DB_CXX_HEADER="" | |||
DB_CXX_LIBS="" | |||
DB_CXX_LDFLAGS="" | |||
DB_CXX_CPPFLAGS="" | |||
if test -z $minversion ; then | |||
minvermajor=0 | |||
minverminor=0 | |||
minverpatch=0 | |||
AC_MSG_CHECKING([for Berkeley DB (C++)]) | |||
else | |||
minvermajor=`echo $minversion | cut -d. -f1` | |||
minverminor=`echo $minversion | cut -d. -f2 -s` | |||
minverpatch=`echo $minversion | cut -d. -f3 -s` | |||
if test -z "$minvermajor"; then minvermajor=0; fi | |||
if test -z "$minverminor"; then minverminor=0; fi | |||
if test -z "$minverpatch"; then minverpatch=0; fi | |||
AC_MSG_CHECKING([for Berkeley DB (C++) >= $minvermajor.$minverminor.$minverpatch]) | |||
fi | |||
if test x$libdbdir != x""; then | |||
DB_CXX_CPPFLAGS="-I${libdbdir}/include" | |||
DB_CXX_LDFLAGS="-L${libdbdir}/lib" | |||
LDFLAGS="$DB_CXX_LDFLAGS $old_LDFLAGS" | |||
CPPFLAGS="$DB_CXX_CPPFLAGS $old_CPPFLAGS" | |||
fi | |||
for major in 4; do | |||
for minor in 0 1 2 3 4 5 6 7 8 9; do | |||
for version in "${major}.${minor}" "${major}${minor}"; do | |||
try_libs="-ldb_cxx-${version}%-ldb-${version} -ldb${version}_cxx%-ldb${version}" | |||
try_headers="db${major}.${minor}/db_cxx.h db${major}${minor}/db_cxx.h db${major}/db_cxx.h" | |||
for db_cxx_hdr in $try_headers ; do | |||
for db_cxx_lib in $try_libs; do | |||
db_cxx_lib="$libdbdir `echo "$db_cxx_lib" | sed 's/%/ /g'`" | |||
LIBS="$old_LIBS $db_cxx_lib" | |||
#echo "Trying <$db_cxx_lib> <$db_cxx_hdr>" | |||
if test -z $DB_CXX_HEADER ; then | |||
AC_LINK_IFELSE( | |||
[AC_LANG_PROGRAM( | |||
[ | |||
#include <${db_cxx_hdr}> | |||
], | |||
[ | |||
#if !((DB_VERSION_MAJOR > (${minvermajor}) || \ | |||
(DB_VERSION_MAJOR == (${minvermajor}) && \ | |||
DB_VERSION_MINOR > (${minverminor})) || \ | |||
(DB_VERSION_MAJOR == (${minvermajor}) && \ | |||
DB_VERSION_MINOR == (${minverminor}) && \ | |||
DB_VERSION_PATCH >= (${minverpatch})))) | |||
#error "too old version" | |||
#endif | |||
DB *db; | |||
db_create(&db, NULL, 0); | |||
])], | |||
[ | |||
AC_MSG_RESULT([header $db_cxx_hdr, library $db_cxx_lib]) | |||
DB_CXX_HEADER="$db_cxx_hdr" | |||
DB_CXX_LIBS="$db_cxx_lib" | |||
], | |||
) | |||
fi | |||
done | |||
done | |||
done | |||
done | |||
done | |||
LIBS="$old_LIBS" | |||
LDFLAGS="$old_LDFLAGS" | |||
CPPFLAGS="$old_CPPFLAGS" | |||
if test -z $DB_CXX_HEADER ; then | |||
AC_MSG_RESULT([not found]) | |||
DB_CXX_LDFLAGS="" | |||
DB_CXX_CPPFLAGS="" | |||
ifelse([$3], , :, [$3]) | |||
else | |||
AC_DEFINE_UNQUOTED(DB_CXX_HEADER, ["$DB_CXX_HEADER"], ["Berkeley DB C++ Header File"]) | |||
AC_SUBST(DB_CXX_LIBS) | |||
AC_SUBST(DB_CXX_LDFLAGS) | |||
AC_SUBST(DB_CXX_CPPFLAGS) | |||
ifelse([$2], , :, [$2]) | |||
fi | |||
]) |
@@ -0,0 +1,238 @@ | |||
# =========================================================================== | |||
# https://www.gnu.org/software/autoconf-archive/ax_blas.html | |||
# =========================================================================== | |||
# | |||
# SYNOPSIS | |||
# | |||
# AX_BLAS([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) | |||
# | |||
# DESCRIPTION | |||
# | |||
# This macro looks for a library that implements the BLAS linear-algebra | |||
# interface (see http://www.netlib.org/blas/). On success, it sets the | |||
# BLAS_LIBS output variable to hold the requisite library linkages. | |||
# | |||
# To link with BLAS, you should link with: | |||
# | |||
# $BLAS_LIBS $LIBS $FLIBS | |||
# | |||
# in that order. FLIBS is the output variable of the | |||
# AC_F77_LIBRARY_LDFLAGS macro (called if necessary by AX_BLAS), and is | |||
# sometimes necessary in order to link with F77 libraries. Users will also | |||
# need to use AC_F77_DUMMY_MAIN (see the autoconf manual), for the same | |||
# reason. | |||
# | |||
# Many libraries are searched for, from ATLAS to CXML to ESSL. The user | |||
# may also use --with-blas=<lib> in order to use some specific BLAS | |||
# library <lib>. In order to link successfully, however, be aware that you | |||
# will probably need to use the same Fortran compiler (which can be set | |||
# via the F77 env. var.) as was used to compile the BLAS library. | |||
# | |||
# ACTION-IF-FOUND is a list of shell commands to run if a BLAS library is | |||
# found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it is | |||
# not found. If ACTION-IF-FOUND is not specified, the default action will | |||
# define HAVE_BLAS. | |||
# | |||
# LICENSE | |||
# | |||
# Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu> | |||
# | |||
# This program is free software: you can redistribute it and/or modify it | |||
# under the terms of the GNU General Public License as published by the | |||
# Free Software Foundation, either version 3 of the License, or (at your | |||
# option) any later version. | |||
# | |||
# This program is distributed in the hope that it will be useful, but | |||
# WITHOUT ANY WARRANTY; without even the implied warranty of | |||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General | |||
# Public License for more details. | |||
# | |||
# You should have received a copy of the GNU General Public License along | |||
# with this program. If not, see <https://www.gnu.org/licenses/>. | |||
# | |||
# As a special exception, the respective Autoconf Macro's copyright owner | |||
# gives unlimited permission to copy, distribute and modify the configure | |||
# scripts that are the output of Autoconf when processing the Macro. You | |||
# need not follow the terms of the GNU General Public License when using | |||
# or distributing such scripts, even though portions of the text of the | |||
# Macro appear in them. The GNU General Public License (GPL) does govern | |||
# all other use of the material that constitutes the Autoconf Macro. | |||
# | |||
# This special exception to the GPL applies to versions of the Autoconf | |||
# Macro released by the Autoconf Archive. When you make and distribute a | |||
# modified version of the Autoconf Macro, you may extend this special | |||
# exception to the GPL to apply to your modified version as well. | |||
#serial 15 | |||
AU_ALIAS([ACX_BLAS], [AX_BLAS]) | |||
AC_DEFUN([AX_BLAS], [ | |||
AC_PREREQ(2.50) | |||
AC_REQUIRE([AC_F77_LIBRARY_LDFLAGS]) | |||
AC_REQUIRE([AC_CANONICAL_HOST]) | |||
ax_blas_ok=no | |||
AC_ARG_WITH(blas, | |||
[AS_HELP_STRING([--with-blas=<lib>], [use BLAS library <lib>])]) | |||
case $with_blas in | |||
yes | "") ;; | |||
no) ax_blas_ok=disable ;; | |||
-* | */* | *.a | *.so | *.so.* | *.o) BLAS_LIBS="$with_blas" ;; | |||
*) BLAS_LIBS="-l$with_blas" ;; | |||
esac | |||
# Get fortran linker names of BLAS functions to check for. | |||
AC_F77_FUNC(sgemm) | |||
AC_F77_FUNC(dgemm) | |||
ax_blas_save_LIBS="$LIBS" | |||
LIBS="$LIBS $FLIBS" | |||
# First, check BLAS_LIBS environment variable | |||
if test $ax_blas_ok = no; then | |||
if test "x$BLAS_LIBS" != x; then | |||
save_LIBS="$LIBS"; LIBS="$BLAS_LIBS $LIBS" | |||
AC_MSG_CHECKING([for $sgemm in $BLAS_LIBS]) | |||
AC_TRY_LINK_FUNC($sgemm, [ax_blas_ok=yes], [BLAS_LIBS=""]) | |||
AC_MSG_RESULT($ax_blas_ok) | |||
LIBS="$save_LIBS" | |||
fi | |||
fi | |||
# BLAS linked to by default? (happens on some supercomputers) | |||
if test $ax_blas_ok = no; then | |||
save_LIBS="$LIBS"; LIBS="$LIBS" | |||
AC_MSG_CHECKING([if $sgemm is being linked in already]) | |||
AC_TRY_LINK_FUNC($sgemm, [ax_blas_ok=yes]) | |||
AC_MSG_RESULT($ax_blas_ok) | |||
LIBS="$save_LIBS" | |||
fi | |||
# BLAS in OpenBLAS library? (http://xianyi.github.com/OpenBLAS/) | |||
if test $ax_blas_ok = no; then | |||
AC_CHECK_LIB(openblas, $sgemm, [ax_blas_ok=yes | |||
BLAS_LIBS="-lopenblas"]) | |||
fi | |||
# BLAS in ATLAS library? (http://math-atlas.sourceforge.net/) | |||
if test $ax_blas_ok = no; then | |||
AC_CHECK_LIB(atlas, ATL_xerbla, | |||
[AC_CHECK_LIB(f77blas, $sgemm, | |||
[AC_CHECK_LIB(cblas, cblas_dgemm, | |||
[ax_blas_ok=yes | |||
BLAS_LIBS="-lcblas -lf77blas -latlas"], | |||
[], [-lf77blas -latlas])], | |||
[], [-latlas])]) | |||
fi | |||
# BLAS in PhiPACK libraries? (requires generic BLAS lib, too) | |||
if test $ax_blas_ok = no; then | |||
AC_CHECK_LIB(blas, $sgemm, | |||
[AC_CHECK_LIB(dgemm, $dgemm, | |||
[AC_CHECK_LIB(sgemm, $sgemm, | |||
[ax_blas_ok=yes; BLAS_LIBS="-lsgemm -ldgemm -lblas"], | |||
[], [-lblas])], | |||
[], [-lblas])]) | |||
fi | |||
# BLAS in Intel MKL library? | |||
if test $ax_blas_ok = no; then | |||
# MKL for gfortran | |||
if test x"$ac_cv_fc_compiler_gnu" = xyes; then | |||
# 64 bit | |||
if test $host_cpu = x86_64; then | |||
AC_CHECK_LIB(mkl_gf_lp64, $sgemm, | |||
[ax_blas_ok=yes;BLAS_LIBS="-lmkl_gf_lp64 -lmkl_sequential -lmkl_core -lpthread"],, | |||
[-lmkl_gf_lp64 -lmkl_sequential -lmkl_core -lpthread]) | |||
# 32 bit | |||
elif test $host_cpu = i686; then | |||
AC_CHECK_LIB(mkl_gf, $sgemm, | |||
[ax_blas_ok=yes;BLAS_LIBS="-lmkl_gf -lmkl_sequential -lmkl_core -lpthread"],, | |||
[-lmkl_gf -lmkl_sequential -lmkl_core -lpthread]) | |||
fi | |||
# MKL for other compilers (Intel, PGI, ...?) | |||
else | |||
# 64-bit | |||
if test $host_cpu = x86_64; then | |||
AC_CHECK_LIB(mkl_intel_lp64, $sgemm, | |||
[ax_blas_ok=yes;BLAS_LIBS="-lmkl_intel_lp64 -lmkl_sequential -lmkl_core -lpthread"],, | |||
[-lmkl_intel_lp64 -lmkl_sequential -lmkl_core -lpthread]) | |||
# 32-bit | |||
elif test $host_cpu = i686; then | |||
AC_CHECK_LIB(mkl_intel, $sgemm, | |||
[ax_blas_ok=yes;BLAS_LIBS="-lmkl_intel -lmkl_sequential -lmkl_core -lpthread"],, | |||
[-lmkl_intel -lmkl_sequential -lmkl_core -lpthread]) | |||
fi | |||
fi | |||
fi | |||
# Old versions of MKL | |||
if test $ax_blas_ok = no; then | |||
AC_CHECK_LIB(mkl, $sgemm, [ax_blas_ok=yes;BLAS_LIBS="-lmkl -lguide -lpthread"],,[-lguide -lpthread]) | |||
fi | |||
# BLAS in Apple vecLib library? | |||
if test $ax_blas_ok = no; then | |||
save_LIBS="$LIBS"; LIBS="-framework vecLib $LIBS" | |||
AC_MSG_CHECKING([for $sgemm in -framework vecLib]) | |||
AC_TRY_LINK_FUNC($sgemm, [ax_blas_ok=yes;BLAS_LIBS="-framework vecLib"]) | |||
AC_MSG_RESULT($ax_blas_ok) | |||
LIBS="$save_LIBS" | |||
fi | |||
# BLAS in Alpha CXML library? | |||
if test $ax_blas_ok = no; then | |||
AC_CHECK_LIB(cxml, $sgemm, [ax_blas_ok=yes;BLAS_LIBS="-lcxml"]) | |||
fi | |||
# BLAS in Alpha DXML library? (now called CXML, see above) | |||
if test $ax_blas_ok = no; then | |||
AC_CHECK_LIB(dxml, $sgemm, [ax_blas_ok=yes;BLAS_LIBS="-ldxml"]) | |||
fi | |||
# BLAS in Sun Performance library? | |||
if test $ax_blas_ok = no; then | |||
if test "x$GCC" != xyes; then # only works with Sun CC | |||
AC_CHECK_LIB(sunmath, acosp, | |||
[AC_CHECK_LIB(sunperf, $sgemm, | |||
[BLAS_LIBS="-xlic_lib=sunperf -lsunmath" | |||
ax_blas_ok=yes],[],[-lsunmath])]) | |||
fi | |||
fi | |||
# BLAS in SCSL library? (SGI/Cray Scientific Library) | |||
if test $ax_blas_ok = no; then | |||
AC_CHECK_LIB(scs, $sgemm, [ax_blas_ok=yes; BLAS_LIBS="-lscs"]) | |||
fi | |||
# BLAS in SGIMATH library? | |||
if test $ax_blas_ok = no; then | |||
AC_CHECK_LIB(complib.sgimath, $sgemm, | |||
[ax_blas_ok=yes; BLAS_LIBS="-lcomplib.sgimath"]) | |||
fi | |||
# BLAS in IBM ESSL library? (requires generic BLAS lib, too) | |||
if test $ax_blas_ok = no; then | |||
AC_CHECK_LIB(blas, $sgemm, | |||
[AC_CHECK_LIB(essl, $sgemm, | |||
[ax_blas_ok=yes; BLAS_LIBS="-lessl -lblas"], | |||
[], [-lblas $FLIBS])]) | |||
fi | |||
# Generic BLAS library? | |||
if test $ax_blas_ok = no; then | |||
AC_CHECK_LIB(blas, $sgemm, [ax_blas_ok=yes; BLAS_LIBS="-lblas"]) | |||
fi | |||
AC_SUBST(BLAS_LIBS) | |||
LIBS="$ax_blas_save_LIBS" | |||
# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: | |||
if test x"$ax_blas_ok" = xyes; then | |||
ifelse([$1],,AC_DEFINE(HAVE_BLAS,1,[Define if you have a BLAS library.]),[$1]) | |||
: | |||
else | |||
ax_blas_ok=no | |||
$2 | |||
fi | |||
])dnl AX_BLAS |