mirror of
https://github.com/LMMS/lmms.git
synced 2026-03-03 13:46:19 -05:00
CMake: Build lmms shared library instead of object library
Resolves some inexplicable linking errors on Windows. Saves us from working around incomplete CMake support of object libraries.
This commit is contained in:
@@ -388,7 +388,7 @@ IF(WANT_JACK)
|
||||
IF(JACK_FOUND)
|
||||
IF(WANT_WEAKJACK)
|
||||
SET(LMMS_HAVE_WEAKJACK TRUE)
|
||||
SET(WEAKJACK_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/src/3rdparty/weakjack/weakjack)
|
||||
SET(WEAKJACK_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/src/3rdparty/weakjack/weakjack")
|
||||
SET(STATUS_JACK "OK (weak linking enabled)")
|
||||
# use dlsym instead
|
||||
SET(JACK_LIBRARIES ${CMAKE_DL_LIBS})
|
||||
|
||||
@@ -10,6 +10,5 @@ SET(CMAKE_AUTOMOC ON)
|
||||
ADD_EXECUTABLE(benchmarks
|
||||
EXCLUDE_FROM_ALL
|
||||
benchmark.cpp
|
||||
$<TARGET_OBJECTS:lmmsobjs>
|
||||
)
|
||||
TARGET_LINK_LIBRARIES(benchmarks ${QT_LIBRARIES} ${LMMS_REQUIRED_LIBS})
|
||||
TARGET_LINK_LIBRARIES(benchmarks lmmslib)
|
||||
|
||||
@@ -108,7 +108,7 @@ chmod +x "${APPDIR}usr/bin/lmms"
|
||||
unset LD_LIBRARY_PATH
|
||||
|
||||
# Ensure linuxdeployqt can find shared objects
|
||||
export LD_LIBRARY_PATH="${APPDIR}"usr/lib/lmms/:"${APPDIR}"usr/lib/lmms/optional:"$LD_LIBRARY_PATH"
|
||||
export LD_LIBRARY_PATH="${APPDIR}"usr/lib/:"${APPDIR}"usr/lib/lmms/:"${APPDIR}"usr/lib/lmms/optional:"$LD_LIBRARY_PATH"
|
||||
|
||||
# Move executables so linuxdeployqt can find them
|
||||
ZYNLIB="${APPDIR}usr/lib/lmms/RemoteZynAddSubFx"
|
||||
|
||||
@@ -60,7 +60,7 @@ FUNCTION(BUILD_PLUGIN PLUGIN_NAME)
|
||||
|
||||
ADD_LIBRARY(${PLUGIN_NAME} ${PLUGIN_LINK} ${PLUGIN_SOURCES} ${plugin_MOC_out} ${RCC_OUT})
|
||||
|
||||
TARGET_LINK_LIBRARIES(${PLUGIN_NAME} Qt5::Widgets Qt5::Xml lmms)
|
||||
TARGET_LINK_LIBRARIES(${PLUGIN_NAME} Qt5::Widgets Qt5::Xml lmmslib)
|
||||
|
||||
INSTALL(TARGETS ${PLUGIN_NAME}
|
||||
LIBRARY DESTINATION "${PLUGIN_DESTINATION}"
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#include "Track.h"
|
||||
|
||||
|
||||
class AutomationTrack : public Track
|
||||
class LMMS_EXPORT AutomationTrack : public Track
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
@@ -31,13 +31,14 @@
|
||||
#include <QtCore/QMap>
|
||||
#include <QStaticText>
|
||||
|
||||
#include "lmms_export.h"
|
||||
#include "Track.h"
|
||||
|
||||
class TrackLabelButton;
|
||||
class TrackContainer;
|
||||
|
||||
|
||||
class BBTCO : public TrackContentObject
|
||||
class LMMS_EXPORT BBTCO : public TrackContentObject
|
||||
{
|
||||
public:
|
||||
BBTCO( Track * _track );
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#ifndef MAINAPPLICATION_H
|
||||
#define MAINAPPLICATION_H
|
||||
|
||||
#include "lmms_export.h"
|
||||
#include "lmmsconfig.h"
|
||||
|
||||
#include <QApplication>
|
||||
@@ -35,7 +36,7 @@
|
||||
#endif
|
||||
|
||||
#if defined(LMMS_BUILD_WIN32)
|
||||
class MainApplication : public QApplication, public QAbstractNativeEventFilter
|
||||
class LMMS_EXPORT MainApplication : public QApplication, public QAbstractNativeEventFilter
|
||||
#else
|
||||
class MainApplication : public QApplication
|
||||
#endif
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
#ifndef MAIN_WINDOW_H
|
||||
#define MAIN_WINDOW_H
|
||||
|
||||
#include "lmms_export.h"
|
||||
|
||||
#include <QtCore/QBasicTimer>
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtCore/QList>
|
||||
@@ -43,7 +45,7 @@ class PluginView;
|
||||
class ToolButton;
|
||||
|
||||
|
||||
class MainWindow : public QMainWindow
|
||||
class LMMS_EXPORT MainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
@@ -61,7 +63,7 @@ public:
|
||||
void addSpacingToToolBar( int _size );
|
||||
|
||||
// wrap the widget with a window decoration and add it to the workspace
|
||||
LMMS_EXPORT SubWindow* addWindowedWidget(QWidget *w, Qt::WindowFlags windowFlags=0);
|
||||
SubWindow* addWindowedWidget(QWidget *w, Qt::WindowFlags windowFlags=0);
|
||||
|
||||
|
||||
///
|
||||
|
||||
@@ -54,7 +54,7 @@ static MemoryManager::MmCounter _mm_counter;
|
||||
static thread_local MemoryManager::MmCounter _mm_thread_counter;
|
||||
|
||||
template<typename T>
|
||||
class MmAllocator
|
||||
class LMMS_EXPORT MmAllocator
|
||||
{
|
||||
public:
|
||||
MmAllocator() = default;
|
||||
|
||||
@@ -14,10 +14,11 @@
|
||||
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include "lmms_export.h"
|
||||
|
||||
class _MemoryPool_Private;
|
||||
class LMMS_EXPORT _MemoryPool_Private;
|
||||
|
||||
class _MemoryPool_Base
|
||||
class LMMS_EXPORT _MemoryPool_Base
|
||||
{
|
||||
public:
|
||||
_MemoryPool_Base(size_t size, size_t nmemb);
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#define MIX_HELPERS_H
|
||||
|
||||
#include "lmms_basics.h"
|
||||
#include "lmms_export.h"
|
||||
|
||||
class ValueBuffer;
|
||||
namespace MixHelpers
|
||||
@@ -35,7 +36,7 @@ bool isSilent( const sampleFrame* src, int frames );
|
||||
|
||||
bool useNaNHandler();
|
||||
|
||||
void setNaNHandler( bool use );
|
||||
LMMS_EXPORT void setNaNHandler( bool use );
|
||||
|
||||
void clear(sampleFrame * src, int frames);
|
||||
#ifndef LMMS_DISABLE_SURROUND
|
||||
|
||||
@@ -27,10 +27,11 @@
|
||||
|
||||
#include <QFile>
|
||||
|
||||
#include "lmms_export.h"
|
||||
#include "lmms_basics.h"
|
||||
#include "MicroTimer.h"
|
||||
|
||||
class MixerProfiler
|
||||
class LMMS_EXPORT MixerProfiler
|
||||
{
|
||||
public:
|
||||
MixerProfiler();
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
#ifndef MODELVISITOR_H
|
||||
#define MODELVISITOR_H
|
||||
|
||||
#include "lmms_export.h"
|
||||
|
||||
class AutomatableModel;
|
||||
class BoolModel;
|
||||
class IntModel;
|
||||
@@ -32,7 +34,7 @@ class FloatModel;
|
||||
class ComboBoxModel;
|
||||
class TempoSyncKnobModel;
|
||||
|
||||
class ModelVisitor
|
||||
class LMMS_EXPORT ModelVisitor
|
||||
{
|
||||
template<class ParentType = AutomatableModel, class ModelType>
|
||||
void up(ModelType& m) { visit(static_cast<ParentType&>(m)); }
|
||||
@@ -46,7 +48,7 @@ public:
|
||||
virtual ~ModelVisitor();
|
||||
};
|
||||
|
||||
class ConstModelVisitor
|
||||
class LMMS_EXPORT ConstModelVisitor
|
||||
{
|
||||
template<class ParentType = AutomatableModel, class ModelType>
|
||||
void up(const ModelType& m) {
|
||||
|
||||
@@ -28,12 +28,13 @@
|
||||
#define PROJECT_VERSION_H
|
||||
|
||||
#include <QtCore/QString>
|
||||
#include "lmms_export.h"
|
||||
|
||||
/*! \brief Version number parsing and comparison
|
||||
*
|
||||
* Parses and compares version information. i.e. "1.0.3" < "1.0.10"
|
||||
*/
|
||||
class ProjectVersion
|
||||
class LMMS_EXPORT ProjectVersion
|
||||
{
|
||||
public:
|
||||
enum CompareType { Major, Minor, Release, Stage, Build };
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
#include "OutputSettings.h"
|
||||
|
||||
|
||||
class RenderManager : public QObject
|
||||
class LMMS_EXPORT RenderManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
@@ -50,4 +50,4 @@ IF(NOT LMMS_BUILD_APPLE AND NOT LMMS_BUILD_OPENBSD)
|
||||
SET_TARGET_PROPERTIES(veal PROPERTIES LINK_FLAGS "${LINK_FLAGS} -shared -Wl,-no-undefined")
|
||||
ENDIF()
|
||||
|
||||
TARGET_LINK_LIBRARIES(veal lmms)
|
||||
TARGET_LINK_LIBRARIES(veal lmmslib)
|
||||
|
||||
5
src/3rdparty/rpmalloc/CMakeLists.txt
vendored
5
src/3rdparty/rpmalloc/CMakeLists.txt
vendored
@@ -7,7 +7,10 @@ target_include_directories(rpmalloc PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rpmalloc/rpmalloc
|
||||
)
|
||||
|
||||
set_property(TARGET rpmalloc PROPERTY C_STANDARD 11)
|
||||
set_target_properties(rpmalloc PROPERTIES
|
||||
C_STANDARD 11
|
||||
POSITION_INDEPENDENT_CODE ON
|
||||
)
|
||||
|
||||
IF(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
|
||||
target_compile_options(rpmalloc
|
||||
|
||||
@@ -21,14 +21,6 @@ ADD_SUBDIRECTORY(gui)
|
||||
ADD_SUBDIRECTORY(tracks)
|
||||
|
||||
QT5_WRAP_UI(LMMS_UI_OUT ${LMMS_UIS})
|
||||
INCLUDE_DIRECTORIES(
|
||||
"${CMAKE_CURRENT_BINARY_DIR}"
|
||||
"${CMAKE_BINARY_DIR}"
|
||||
"${CMAKE_BINARY_DIR}/include"
|
||||
"${CMAKE_SOURCE_DIR}"
|
||||
"${CMAKE_SOURCE_DIR}/include"
|
||||
"${RINGBUFFER_DIR}/include"
|
||||
)
|
||||
|
||||
IF(WIN32 AND MSVC)
|
||||
SET(WINRC "${CMAKE_BINARY_DIR}/lmms.rc")
|
||||
@@ -49,49 +41,6 @@ ADD_GEN_QRC(LMMS_RCC_OUT lmms.qrc
|
||||
"${CONTRIBUTORS}"
|
||||
)
|
||||
|
||||
# Paths relative to lmms executable
|
||||
FILE(RELATIVE_PATH LIB_DIR_RELATIVE "/${BIN_DIR}" "/${LIB_DIR}")
|
||||
FILE(RELATIVE_PATH PLUGIN_DIR_RELATIVE "/${BIN_DIR}" "/${PLUGIN_DIR}")
|
||||
ADD_DEFINITIONS(-DLIB_DIR="${LIB_DIR_RELATIVE}" -DPLUGIN_DIR="${PLUGIN_DIR_RELATIVE}" ${PULSEAUDIO_DEFINITIONS} ${PORTAUDIO_DEFINITIONS})
|
||||
INCLUDE_DIRECTORIES(
|
||||
${JACK_INCLUDE_DIRS}
|
||||
${SAMPLERATE_INCLUDE_DIRS}
|
||||
${SNDFILE_INCLUDE_DIRS}
|
||||
${SNDIO_INCLUDE_DIRS}
|
||||
${FFTW3F_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
IF(NOT ("${SDL2_INCLUDE_DIR}" STREQUAL ""))
|
||||
INCLUDE_DIRECTORIES("${SDL2_INCLUDE_DIR}")
|
||||
ELSEIF(NOT ("${SDL_INCLUDE_DIR}" STREQUAL ""))
|
||||
INCLUDE_DIRECTORIES("${SDL_INCLUDE_DIR}")
|
||||
ENDIF()
|
||||
|
||||
IF(LMMS_HAVE_WEAKJACK)
|
||||
LIST(APPEND LMMS_SRCS "${WEAKJACK_INCLUDE_DIRS}/weak_libjack.c")
|
||||
LIST(APPEND LMMS_INCLUDES "${WEAKJACK_INCLUDE_DIRS}/weak_libjack.h")
|
||||
INCLUDE_DIRECTORIES("${WEAKJACK_INCLUDE_DIRS}")
|
||||
ADD_DEFINITIONS(-DUSE_WEAK_JACK=1 -DNO_JACK_METADATA=1)
|
||||
ENDIF()
|
||||
|
||||
IF(NOT ("${PORTAUDIO_INCLUDE_DIR}" STREQUAL ""))
|
||||
INCLUDE_DIRECTORIES("${PORTAUDIO_INCLUDE_DIR}")
|
||||
ENDIF()
|
||||
|
||||
IF(NOT ("${PULSEAUDIO_INCLUDE_DIR}" STREQUAL ""))
|
||||
INCLUDE_DIRECTORIES("${PULSEAUDIO_INCLUDE_DIR}")
|
||||
ENDIF()
|
||||
|
||||
IF(NOT ("${OGGVORBIS_INCLUDE_DIR}" STREQUAL ""))
|
||||
INCLUDE_DIRECTORIES("${OGGVORBIS_INCLUDE_DIR}")
|
||||
ENDIF()
|
||||
|
||||
IF(NOT ("${LAME_INCLUDE_DIRS}" STREQUAL ""))
|
||||
INCLUDE_DIRECTORIES("${LAME_INCLUDE_DIRS}")
|
||||
ENDIF()
|
||||
|
||||
LIST(APPEND LMMS_SRCS "${RINGBUFFER_DIR}/src/lib/ringbuffer.cpp")
|
||||
|
||||
# Use libraries in non-standard directories (e.g., another version of Qt)
|
||||
IF(LMMS_BUILD_LINUX)
|
||||
LINK_LIBRARIES(-Wl,--enable-new-dtags)
|
||||
@@ -99,35 +48,60 @@ IF(LMMS_BUILD_LINUX)
|
||||
ENDIF()
|
||||
SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
|
||||
|
||||
ADD_LIBRARY(lmmsobjs OBJECT
|
||||
ADD_LIBRARY(lmmslib SHARED
|
||||
${LMMS_SRCS}
|
||||
${LMMS_INCLUDES}
|
||||
${LMMS_UI_OUT}
|
||||
${LMMS_RCC_OUT}
|
||||
${RINGBUFFER_DIR}/src/lib/ringbuffer.cpp
|
||||
$<$<BOOL:${LMMS_HAVE_WEAKJACK}>:
|
||||
${WEAKJACK_INCLUDE_DIR}/weak_libjack.c
|
||||
${WEAKJACK_INCLUDE_DIR}/weak_libjack.h
|
||||
>
|
||||
)
|
||||
|
||||
GENERATE_EXPORT_HEADER(lmmsobjs
|
||||
GENERATE_EXPORT_HEADER(lmmslib
|
||||
BASE_NAME lmms
|
||||
)
|
||||
|
||||
ADD_EXECUTABLE(lmms
|
||||
core/main.cpp
|
||||
$<TARGET_OBJECTS:lmmsobjs>
|
||||
"${WINRC}"
|
||||
)
|
||||
TARGET_INCLUDE_DIRECTORIES(lmms
|
||||
PUBLIC ${CMAKE_CURRENT_BINARY_DIR}
|
||||
|
||||
TARGET_INCLUDE_DIRECTORIES(lmmslib PUBLIC
|
||||
"${CMAKE_CURRENT_BINARY_DIR}"
|
||||
"${CMAKE_BINARY_DIR}"
|
||||
"${CMAKE_BINARY_DIR}/include"
|
||||
"${CMAKE_SOURCE_DIR}"
|
||||
"${CMAKE_SOURCE_DIR}/include"
|
||||
"${RINGBUFFER_DIR}/include"
|
||||
${JACK_INCLUDE_DIRS}
|
||||
${SAMPLERATE_INCLUDE_DIRS}
|
||||
${SNDFILE_INCLUDE_DIRS}
|
||||
${SNDIO_INCLUDE_DIRS}
|
||||
${FFTW3F_INCLUDE_DIRS}
|
||||
${SDL2_INCLUDE_DIR}
|
||||
${SDL_INCLUDE_DIR}
|
||||
${PORTAUDIO_INCLUDE_DIR}
|
||||
${PULSEAUDIO_INCLUDE_DIR}
|
||||
${OGGVORBIS_INCLUDE_DIR}
|
||||
${LAME_INCLUDE_DIRS}
|
||||
${WEAKJACK_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
# CMake doesn't define target_EXPORTS for OBJECT libraries.
|
||||
# See the documentation of DEFINE_SYMBOL for details.
|
||||
# Also add LMMS_STATIC_DEFINE for targets linking against it.
|
||||
TARGET_COMPILE_DEFINITIONS(lmmsobjs
|
||||
PRIVATE -Dlmmsobjs_EXPORTS $<TARGET_PROPERTY:lmms,COMPILE_DEFINITIONS>
|
||||
INTERFACE -DLMMS_STATIC_DEFINE
|
||||
)
|
||||
TARGET_COMPILE_DEFINITIONS(lmms
|
||||
PRIVATE $<TARGET_PROPERTY:lmmsobjs,INTERFACE_COMPILE_DEFINITIONS>
|
||||
|
||||
# Paths relative to lmms executable
|
||||
FILE(RELATIVE_PATH LIB_DIR_RELATIVE "/${BIN_DIR}" "/${LIB_DIR}")
|
||||
FILE(RELATIVE_PATH PLUGIN_DIR_RELATIVE "/${BIN_DIR}" "/${PLUGIN_DIR}")
|
||||
TARGET_COMPILE_DEFINITIONS(lmmslib
|
||||
PRIVATE
|
||||
LIB_DIR="${LIB_DIR_RELATIVE}"
|
||||
PLUGIN_DIR="${PLUGIN_DIR_RELATIVE}"
|
||||
PUBLIC
|
||||
${PULSEAUDIO_DEFINITIONS}
|
||||
${PORTAUDIO_DEFINITIONS}
|
||||
$<$<BOOL:${LMMS_HAVE_WEAKJACK}>:USE_WEAK_JACK=1 NO_JACK_METADATA=1>
|
||||
)
|
||||
|
||||
# Set Visual Studio startup project to lmms
|
||||
@@ -154,7 +128,7 @@ IF(LMMS_BUILD_HAIKU)
|
||||
SET(EXTRA_LIBRARIES "-lnetwork")
|
||||
ENDIF()
|
||||
|
||||
SET(LMMS_REQUIRED_LIBS ${LMMS_REQUIRED_LIBS}
|
||||
TARGET_LINK_LIBRARIES(lmmslib
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
${QT_LIBRARIES}
|
||||
${ASOUND_LIBRARY}
|
||||
@@ -173,36 +147,9 @@ SET(LMMS_REQUIRED_LIBS ${LMMS_REQUIRED_LIBS}
|
||||
rpmalloc
|
||||
cds
|
||||
)
|
||||
TARGET_LINK_LIBRARIES(lmms lmmslib)
|
||||
|
||||
# Expose required libs for tests binary
|
||||
SET(LMMS_REQUIRED_LIBS ${LMMS_REQUIRED_LIBS} PARENT_SCOPE)
|
||||
|
||||
TARGET_LINK_LIBRARIES(lmms
|
||||
${LMMS_REQUIRED_LIBS}
|
||||
)
|
||||
|
||||
FOREACH(LIB ${LMMS_REQUIRED_LIBS})
|
||||
IF(TARGET ${LIB})
|
||||
GET_TARGET_PROPERTY(INCLUDE_DIRS ${LIB} INTERFACE_INCLUDE_DIRECTORIES)
|
||||
IF(INCLUDE_DIRS)
|
||||
TARGET_INCLUDE_DIRECTORIES(lmmsobjs PRIVATE ${INCLUDE_DIRS})
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
ENDFOREACH()
|
||||
|
||||
SET_TARGET_PROPERTIES(lmms PROPERTIES
|
||||
ENABLE_EXPORTS ON
|
||||
)
|
||||
|
||||
IF(LMMS_BUILD_WIN32)
|
||||
IF(LMMS_BUILD_MSYS)
|
||||
# ENABLE_EXPORTS property has no effect in some MSYS2 configurations.
|
||||
# Add the linker flag manually to create liblmms.dll.a import library
|
||||
SET_PROPERTY(TARGET lmms
|
||||
APPEND_STRING PROPERTY LINK_FLAGS " -Wl,--out-implib,liblmms.dll.a"
|
||||
)
|
||||
ENDIF()
|
||||
ELSE()
|
||||
IF(NOT LMMS_BUILD_WIN32)
|
||||
if(CMAKE_INSTALL_MANDIR)
|
||||
SET(INSTALL_MANDIR ${CMAKE_INSTALL_MANDIR})
|
||||
ELSE(CMAKE_INSTALL_MANDIR)
|
||||
@@ -213,4 +160,7 @@ ELSE()
|
||||
PERMISSIONS OWNER_READ GROUP_READ WORLD_READ)
|
||||
ENDIF()
|
||||
|
||||
INSTALL(TARGETS lmms RUNTIME DESTINATION "${BIN_DIR}")
|
||||
INSTALL(TARGETS lmms lmmslib
|
||||
RUNTIME DESTINATION "${BIN_DIR}"
|
||||
LIBRARY DESTINATION "${LIB_DIR}"
|
||||
)
|
||||
|
||||
@@ -14,7 +14,6 @@ ADD_EXECUTABLE(tests
|
||||
EXCLUDE_FROM_ALL
|
||||
main.cpp
|
||||
QTestSuite
|
||||
$<TARGET_OBJECTS:lmmsobjs>
|
||||
|
||||
src/core/AutomatableModelTest.cpp
|
||||
src/core/ProjectVersionTest.cpp
|
||||
@@ -23,8 +22,4 @@ ADD_EXECUTABLE(tests
|
||||
|
||||
src/tracks/AutomationTrackTest.cpp
|
||||
)
|
||||
TARGET_COMPILE_DEFINITIONS(tests
|
||||
PRIVATE $<TARGET_PROPERTY:lmmsobjs,INTERFACE_COMPILE_DEFINITIONS>
|
||||
)
|
||||
TARGET_LINK_LIBRARIES(tests ${QT_LIBRARIES} Qt5::Test)
|
||||
TARGET_LINK_LIBRARIES(tests ${LMMS_REQUIRED_LIBS})
|
||||
TARGET_LINK_LIBRARIES(tests lmmslib Qt5::Test)
|
||||
|
||||
Reference in New Issue
Block a user