diff --git a/CMakeLists.txt b/CMakeLists.txt index ef150348..cd0d5921 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,49 +4,61 @@ cmake_minimum_required(VERSION 3.1 FATAL_ERROR) project(lemonbuddy CXX) +# Include local cmake modules set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/cmake/modules) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -Wall -Wno-unused-parameter -Wno-unused-local-typedefs") -set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG -O0 -g2") -set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3") +# Load cmake utility functions +include(cmake/utils.cmake) -set(CMAKE_C_STANDARD 11) -set(CMAKE_C_STANDARD_REQUIRED ON) -set(CMAKE_CXX_STANDARD 14) -set(CMAKE_CXX_STANDARD_REQUIRED ON) -SET(CMAKE_EXPORT_COMPILE_COMMANDS ON) +# Warn if using an unsupported compiler +if(NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL Clang) + message_colored(WARNING "Unsupported compiler!" 31) +endif() +# Set default build type if not specified if(NOT CMAKE_BUILD_TYPE) - message(STATUS "No build type specified; using Release") + message_colored(STATUS "No build type specified; using Release" 33) set(CMAKE_BUILD_TYPE "Release") endif() -include(cmake/utils.cmake) -include(cmake/clang-cpp-tools.cmake) +# Export compile commands used for custom targets +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) -# Figure out default option values {{{ +# Generic compiler flags +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic") +#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic-errors") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wextra") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror") +# Debug specific compiler flags +set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG") +set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -pedantic-errors") +set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Werror") +set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0") +set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g2") + +# Release specific compiler flags +set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O2") + +# Generic linker flags +set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lc++abi") + +# Project settings {{{ + +# Set default option values based on current environment find_package(ALSA QUIET) find_package(Libiw QUIET) find_package(LibMPDClient QUIET) -find_program(CCACHE_BINARY ccache) find_program(I3_BINARY i3) -find_package(CppUnit QUIET) -if(CPPUNIT_FOUND) - set(BUILD_TESTS ON) -endif() -if(CCACHE_BINARY) - set(CCACHE_FOUND ON) -endif() if(I3_BINARY) set(I3_FOUND ON) endif() -# }}} -# Project settings {{{ - -option(BUILD_TESTS "Build testsuite" ${BUILD_TESTS}) -option(ENABLE_CCACHE "Enable ccache support" ${CCACHE_FOUND}) +option(BUILD_TESTS "Build testsuite" OFF) +option(ENABLE_CCACHE "Enable ccache support" OFF) option(ENABLE_ALSA "Enable alsa support" ${ALSA_FOUND}) option(ENABLE_I3 "Enable i3 support" ${I3_FOUND}) option(ENABLE_MPD "Enable mpd support" ${LIBMPDCLIENT_FOUND}) @@ -76,69 +88,21 @@ set(SETTING_PATH_MEMORY_INFO "/proc/meminfo" CACHE STRING "Path to file containing memory info") if(ENABLE_CCACHE) - set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "ccache") - set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK "ccache") + require_binary(ccache) + set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${BINPATH_ccache}) + set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ${BINPATH_ccache}) endif() # }}} -# Locate dependencies {{{ - -set(THREADS_PREFER_PTHREAD_FLAG ON) -find_package(Boost REQUIRED) -find_package(Threads REQUIRED) -find_package(Freetype REQUIRED Freetype2) -find_package(PkgConfig) -find_package(X11 REQUIRED COMPONENTS Xft Xutil) -find_package(X11_XCB REQUIRED) - -pkg_check_modules(FONTCONFIG REQUIRED fontconfig) - -link_libraries(${X11_X11_LIB}) -link_libraries(${X11_Xft_LIB}) -link_libraries(${X11_XCB_LIB}) -link_libraries(${BOOST_LIBRARIES}) -link_libraries(${CMAKE_THREAD_LIBS_INIT}) -link_libraries(${X11_LIBRARIES}) -link_libraries(${FREETYPE_LIBRARIES}) -link_libraries(${FONTCONFIG_LIBRARIES}) -link_libraries() - -include_directories( - ${BOOST_INCLUDE_DIR} - ${FONTCONFIG_INCLUDE_DIRS} - ${PROJECT_SOURCE_DIR}/include - ${PROJECT_SOURCE_DIR}/lib/boost/include - ${PROJECT_SOURCE_DIR}/lib/fastdelegate/include) - -set(XCB_PROTOS xproto randr) -add_subdirectory(${PROJECT_SOURCE_DIR}/lib/xpp) -link_libraries(${XPP_LIBRARIES}) - -if(ENABLE_ALSA) - find_package(ALSA REQUIRED) - link_libraries(${ALSA_LIBRARY}) -endif() -if(ENABLE_MPD) - find_package(LibMPDClient REQUIRED) - link_libraries(${LIBMPDCLIENT_LIBRARIES}) -endif() -if(ENABLE_NETWORK) - find_package(Libiw REQUIRED) - link_libraries(${LIBIW_LIBRARY}) -endif() -if(ENABLE_I3) - add_subdirectory(${PROJECT_SOURCE_DIR}/lib/i3ipcpp EXCLUDE_FROM_ALL) - include_directories(${I3IPCPP_INCLUDE_DIRS}) - link_libraries(${I3IPCPP_LIBRARIES}) -endif() - -# }}} -# Build source tree {{{ +# Add subdirectories {{{ add_subdirectory(${PROJECT_SOURCE_DIR}/man) add_subdirectory(${PROJECT_SOURCE_DIR}/src ${PROJECT_BINARY_DIR}/bin) add_subdirectory(${PROJECT_SOURCE_DIR}/examples ${PROJECT_BINARY_DIR}/examples) + if(BUILD_TESTS) + add_subdirectory(${PROJECT_SOURCE_DIR}/tests ${PROJECT_BINARY_DIR}/tests) +else() add_subdirectory(${PROJECT_SOURCE_DIR}/tests ${PROJECT_BINARY_DIR}/tests EXCLUDE_FROM_ALL) endif() @@ -150,7 +114,6 @@ message(STATUS " Build type: ${CMAKE_BUILD_TYPE}") message(STATUS " Compiler C: ${CMAKE_C_COMPILER}") message(STATUS " Compiler C++: ${CMAKE_CXX_COMPILER}") message(STATUS " Compiler flags: ${CMAKE_CXX_FLAGS}") - if(CMAKE_BUILD_TYPE STREQUAL "Debug") message(STATUS " + debug flags:: ${CMAKE_CXX_FLAGS_DEBUG}") elseif(CMAKE_BUILD_TYPE STREQUAL "Release") @@ -161,14 +124,12 @@ elseif(CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo") message(STATUS " + relwithdebinfo flags:: ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") endif() message(STATUS "---------------------------") - message(STATUS " Build testsuite ${BUILD_TESTS}") message(STATUS " Enable ccache support ${ENABLE_CCACHE}") message(STATUS " Enable alsa support ${ENABLE_ALSA}") message(STATUS " Enable i3 support ${ENABLE_I3}") message(STATUS " Enable mpd support ${ENABLE_MPD}") message(STATUS " Enable network support ${ENABLE_NETWORK}") - if(DISABLE_MODULES) message(STATUS " Disable modules ON") endif() @@ -178,11 +139,11 @@ endif() if(DISABLE_DRAW) message(STATUS " Disable drawing ON") endif() - message(STATUS "---------------------------") # }}} -# Uninstall target {{{ + +# Custom target: uninstall {{{ configure_file( ${PROJECT_SOURCE_DIR}/cmake/uninstall.cmake.in @@ -193,3 +154,26 @@ add_custom_target(uninstall COMMAND ${CMAKE_COMMAND} -P ${PROJECT_BINARY_DIR}/cmake/uninstall.cmake) # }}} +# Custom target: clang-format {{{ + +find_program(CLANG_FORMAT "clang-format") + +if(CLANG_FORMAT) + file(GLOB_RECURSE HEADERS ${PROJECT_SOURCE_DIR}/include/*.hpp) + file(GLOB_RECURSE SOURCES ${PROJECT_SOURCE_DIR}/src/*.cpp) + + add_custom_target(clang-format COMMAND ${CLANG_FORMAT} + -i -style=file ${HEADERS} ${SOURCES}) +endif() + +find_program(CLANG_TIDY "clang-tidy") + +# }}} +# Custom target: clang-tidy {{{ + +if(CLANG_TIDY) + add_custom_target(clang-tidy COMMAND ${CLANG_TIDY} + -p ${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR}/src/main.cpp) +endif() + +# }}} diff --git a/README.md b/README.md index fa4a389d..4dbf3d3c 100644 --- a/README.md +++ b/README.md @@ -61,8 +61,7 @@ available for more people. ### Dependencies -A compiler with c++14 support. For example [`clang`](http://clang.llvm.org/get_started.html). - +- clang-3.4+ - cmake - boost - xcb-util-wm @@ -74,11 +73,10 @@ Optional dependencies for module support: - wireless_tools (required for `internal/network` support) - alsa-lib (required for `internal/volume` support) - libmpdclient (required for `internal/mpd` support) -- jsoncpp (required for `internal/i3` support) ~~~ sh -$ pacman -S cmake python2 boost xcb-util-wm libxft wireless_tools alsa-lib libmpdclient jsoncpp -$ apt-get install cmake cmake-data libboost-dev libfreetype6-dev libxcb1-dev libx11-xcb-dev libxcb-util0-dev libxcb-randr0-dev libxcb-ewmh-dev libxcb-icccm4-dev xcb-proto python-xcbgen i3-wm libiw-dev libasound2-dev libmpdclient-dev +$ pacman -S clang35 cmake python2 boost xcb-util-wm libxft wireless_tools alsa-lib libmpdclient +$ apt-get install clang-3.8 libc++-dev libc++abi-dev cmake cmake-data libboost-dev libfreetype6-dev libxcb1-dev libx11-xcb-dev libxcb-util0-dev libxcb-randr0-dev libxcb-ewmh-dev libxcb-icccm4-dev xcb-proto python-xcbgen i3-wm libiw-dev libasound2-dev libmpdclient-dev ~~~ @@ -90,7 +88,7 @@ Please [report any problems](https://github.com/jaagr/lemonbuddy/issues/new) you $ git clone --branch 2.0.1 --recursive https://github.com/jaagr/lemonbuddy $ mkdir lemonbuddy/build $ cd lemonbuddy/build - $ cmake -DCMAKE_BUILD_TYPE=Release .. + $ cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE=Release .. $ sudo make install ~~~ diff --git a/cmake/clang-cpp-tools.cmake b/cmake/clang-cpp-tools.cmake deleted file mode 100644 index 74f4010b..00000000 --- a/cmake/clang-cpp-tools.cmake +++ /dev/null @@ -1,22 +0,0 @@ -# -# Additional targets to perform clang-format/clang-tidy -# - -file(GLOB_RECURSE header_files ${PROJECT_SOURCE_DIR}/include/*.hpp) -file(GLOB_RECURSE source_files ${PROJECT_SOURCE_DIR}/src/*.cpp) - -# Add clang-format target if executable is found -# -------------------------------------------------- -find_program(CLANG_FORMAT "clang-format") -if(CLANG_FORMAT) - add_custom_target(clang-format COMMAND ${CLANG_FORMAT} - -i -style=file ${header_files} ${source_files}) -endif() - -# Add clang-tidy target if executable is found -# -------------------------------------------------- -find_program(CLANG_TIDY "clang-tidy") -if(CLANG_TIDY) - add_custom_target(clang-tidy COMMAND ${CLANG_TIDY} - -p ${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR}/src/main.cpp) -endif() diff --git a/cmake/utils.cmake b/cmake/utils.cmake index f5a6298e..8cad7fd3 100644 --- a/cmake/utils.cmake +++ b/cmake/utils.cmake @@ -9,6 +9,16 @@ function(message_colored message_level text color) message(${message_level} "${esc}[${color}m${text}${esc}[0m") endfunction() +# }}} +# require_binary : Locates binary by name and exports its path to BINPATH_${name} {{{ + +function(require_binary binary_name) + find_program(BINPATH_${binary_name} ${binary_name}) + if(NOT BINPATH_${binary_name}) + message_colored(FATAL_ERROR "Failed to locate ${binary_name} binary" 31) + endif() +endfunction() + # }}} # make_executable : Builds an executable target {{{ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8232b466..bca5b83e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,36 +1,122 @@ # # Create library and executable # -set(library_name lemonlib) -set(executable_name lemonbuddy) -file(GLOB_RECURSE headers RELATIVE ${PROJECT_SOURCE_DIR}/include *.h[p]*) -file(GLOB_RECURSE sources RELATIVE ${PROJECT_SOURCE_DIR}/src *.c[p]*) -list(REMOVE_ITEM sources main.cpp) +set(BINARY_NAME ${PROJECT_NAME}) +set(LIBRARY_NAME lib${PROJECT_NAME}) -include_directories(${CMAKE_CURRENT_BINARY_DIR}) - -make_library(${library_name} STATIC - HEADER_INSTALL_DIR - lemonbuddy - HEADERS - ${headers} - SOURCES - ${sources}) - -make_executable(${executable_name} - SOURCES main.cpp - TARGET_DEPENDS ${library_name}_static) - -target_compile_definitions(lemonbuddy PUBLIC - ${X11_XCB_DEFINITIONS} - ${XCB_DEFINITIONS}) +file(GLOB_RECURSE HEADERS RELATIVE ${PROJECT_SOURCE_DIR}/include *.h[p]*) +file(GLOB_RECURSE SOURCES RELATIVE ${PROJECT_SOURCE_DIR}/src *.c[p]*) +list(REMOVE_ITEM SOURCES main.cpp) configure_file( ${PROJECT_SOURCE_DIR}/include/config.hpp.cmake ${CMAKE_SOURCE_DIR}/include/config.hpp ESCAPE_QUOTES @ONLY) -set(app_binary ${PROJECT_SOURCE_DIR}/bin/${executable_name} PARENT_SCOPE) -set(app_libraries ${XPP_LIBRARIES} PARENT_SCOPE) -set(app_include_dirs ${PROJECT_SOURCE_DIR}/include PARENT_SCOPE) +# Target: main library {{{ + +make_library(${LIBRARY_NAME} STATIC + HEADER_INSTALL_DIR + ${PROJECT_NAME} + HEADERS + ${HEADERS} + SOURCES + ${SOURCES}) + +target_include_directories(${LIBRARY_NAME}_static PUBLIC ${CMAKE_CURRENT_BINARY_DIR}) + +# }}} +# Target: main executable {{{ + +make_executable(${BINARY_NAME} + SOURCES main.cpp + TARGET_DEPENDS ${LIBRARY_NAME}_static) + +# }}} + +# Link dependencies {{{ + +set(THREADS_PREFER_PTHREAD_FLAG ON) + +find_package(Boost REQUIRED) +find_package(Threads REQUIRED) +find_package(Freetype REQUIRED Freetype2) +find_package(X11 REQUIRED COMPONENTS Xft Xutil) +find_package(X11_XCB REQUIRED) + +find_package(PkgConfig) +pkg_check_modules(FONTCONFIG REQUIRED fontconfig) + +target_link_libraries(${LIBRARY_NAME}_static PUBLIC ${BOOST_LIBRARIES}) +target_link_libraries(${LIBRARY_NAME}_static PUBLIC ${CMAKE_THREAD_LIBS_INIT}) +target_link_libraries(${LIBRARY_NAME}_static PUBLIC Threads::Threads) +target_link_libraries(${LIBRARY_NAME}_static PUBLIC ${X11_LIBRARIES}) +target_link_libraries(${LIBRARY_NAME}_static PUBLIC ${X11_X11_LIB}) +target_link_libraries(${LIBRARY_NAME}_static PUBLIC ${X11_XCB_LIB}) +target_link_libraries(${LIBRARY_NAME}_static PUBLIC ${X11_Xft_LIB}) +target_link_libraries(${LIBRARY_NAME}_static PUBLIC ${FREETYPE_LIBRARIES}) +target_link_libraries(${LIBRARY_NAME}_static PUBLIC ${FONTCONFIG_LIBRARIES}) + +target_include_directories(${LIBRARY_NAME}_static PUBLIC ${BOOST_INCLUDE_DIR}) +target_include_directories(${LIBRARY_NAME}_static PUBLIC ${FONTCONFIG_INCLUDE_DIRS}) +target_include_directories(${LIBRARY_NAME}_static PUBLIC ${PROJECT_SOURCE_DIR}/include) +target_include_directories(${LIBRARY_NAME}_static PUBLIC ${PROJECT_SOURCE_DIR}/lib/boost/include) + +target_compile_definitions(${BINARY_NAME} PUBLIC + ${X11_XCB_DEFINITIONS} + ${XCB_DEFINITIONS}) + +# xpp library +set(XCB_PROTOS xproto randr) +add_subdirectory(${PROJECT_SOURCE_DIR}/lib/xpp ${PROJECT_BINARY_DIR}/lib/xpp) + +target_link_libraries(${LIBRARY_NAME}_static PUBLIC ${XPP_LIBRARIES}) + +# }}} + +# Optional dependency: alsalib {{{ + +if(ENABLE_ALSA) + find_package(ALSA REQUIRED) + target_link_libraries(${LIBRARY_NAME}_static PUBLIC ${ALSA_LIBRARY}) +endif() + +# }}} +# Optional dependency: libmpdclient {{{ + +if(ENABLE_MPD) + find_package(LibMPDClient REQUIRED) + target_link_libraries(${LIBRARY_NAME}_static PUBLIC ${LIBMPDCLIENT_LIBRARIES}) +endif() + +# }}} +# Optional dependency: libiw {{{ + +if(ENABLE_NETWORK) + find_package(Libiw REQUIRED) + target_link_libraries(${LIBRARY_NAME}_static PUBLIC ${LIBIW_LIBRARY}) +endif() + +# }}} +# Optional dependency: i3ipcpp {{{ + +if(ENABLE_I3) + add_subdirectory(${PROJECT_SOURCE_DIR}/lib/i3ipcpp ${PROJECT_BINARY_DIR}/lib/i3ipcpp) + target_include_directories(${LIBRARY_NAME}_static PUBLIC ${I3IPCPP_INCLUDE_DIRS}) + target_link_libraries(${LIBRARY_NAME}_static PUBLIC ${I3IPCPP_LIBRARIES}) +endif() + +# }}} + +# Export target details {{{ + +set(APP_BINARY ${PROJECT_SOURCE_DIR}/bin/${BINARY_NAME} PARENT_SCOPE) +set(APP_LIBRARIES ${LIBRARY_NAME}_static ${XPP_LIBRARY} PARENT_SCOPE) +set(APP_INCLUDE_DIRS + ${PROJECT_SOURCE_DIR}/include + ${PROJECT_SOURCE_DIR}/lib/boost/include + ${XPP_INCLUDE_DIRS} + PARENT_SCOPE) + +# }}}