Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Adds conan support via a conan 2.0 recipe #1066

Closed
wants to merge 23 commits into from
Closed
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
e838136
First test of SCM conan 2.0
MikeRavenelle Sep 24, 2023
7277b21
Fixed requires
MikeRavenelle Jan 19, 2024
60d31d4
Added package info for libs
MikeRavenelle Jan 19, 2024
5947864
renamed libdpp to dpp
MikeRavenelle Jan 19, 2024
25943bb
Made CmakeLists work for both conan and non conan users
MikeRavenelle Jan 19, 2024
f7ee95b
Added documentation for using conan
MikeRavenelle Jan 19, 2024
c2c2854
Merge branch 'dev' into conan_support
MikeRavenelle Jan 19, 2024
3abef91
Changed how conan detected and changed how opus is checked
MikeRavenelle Jan 20, 2024
7e3a98b
Merge branch 'conan_support' of https://github.com/MikeRavenelle/DPP …
MikeRavenelle Jan 20, 2024
857c4fc
Added DPP_NO_CONAN to pipeline, moved conan cmake out of main library…
MikeRavenelle Jan 20, 2024
0c5cbf0
Reset ci.yml since github wont let me commit
MikeRavenelle Jan 20, 2024
84792c8
Fixed 1 error and tabbing
MikeRavenelle Jan 20, 2024
d5dd3f6
Added missing endif()
MikeRavenelle Jan 20, 2024
ffa9cd5
Added parent folder for commit instead of recipe folder and BUILD_VOI…
MikeRavenelle Jan 21, 2024
f4ecfc3
Fixed CMake variables for opus and libsodium
MikeRavenelle Jan 21, 2024
68560d6
Removed load from conan.tools.files and moved conan recipe into libra…
MikeRavenelle Jan 22, 2024
f37ce14
Updated the version number
MikeRavenelle Jan 25, 2024
ea84883
Remove docpage from branch so we can control docpage separately.
MikeRavenelle Jan 26, 2024
3b50591
Rearranged find_packages to top and removed include directories for O…
MikeRavenelle Jan 26, 2024
de0c141
Removed possibly uneeded windows flags and added exclusion for win32 …
MikeRavenelle Jan 28, 2024
2f02ae7
Added flags for tests and BUILD_SHARED_LIBS
MikeRavenelle Mar 29, 2024
4ea4362
Update library-conan/conanfile.py
braindigitalis Oct 23, 2024
6d1dbfa
Update library-conan/conanfile.py
braindigitalis Oct 23, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@ else()
message("-- INFO: Using VCPKG if detected")
endif()

if (DPP_NO_CONAN)
message("-- INFO: Explicitly disabling Conan as running inside the CI action.")
else()
message("-- INFO: Using Conan if detected")
endif()

if (WIN32 AND NOT MINGW AND BUILD_SHARED_LIBS)
message("-- INFO: Configuring .rc resource script")
configure_file("${DPP_ROOT_PATH}/src/dpp/dpp.rc.in" "${DPP_ROOT_PATH}/src/dpp/dpp.rc" NEWLINE_STYLE WIN32)
Expand Down Expand Up @@ -99,7 +105,11 @@ else()
enable_testing(${CMAKE_CURRENT_SOURCE_DIR})
endif()

add_subdirectory(library)
if(CONAN_EXPORTED AND NOT DPP_NO_CONAN)
add_subdirectory(library-conan)
else()
add_subdirectory(library)
endif()
endif()

if(DPP_USE_EXTERNAL_JSON)
Expand Down
315 changes: 315 additions & 0 deletions library-conan/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,315 @@
message("-- INFO: Conan detected... finding packages")
find_package(OpenSSL REQUIRED COMPONENTS SSL Crypto)
find_package(ZLIB REQUIRED)
find_package(libsodium REQUIRED)
find_package(Opus)
find_package(Threads REQUIRED)
find_package(Git QUIET)

Comment on lines +1 to +8

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand that using Conan might need some find_package() that maybe are not used when not using Conan because some other strategy like FetchContent is done, but why the big CMakeLists.txt and all the code below? In theory Conan can integrate quite cleanly, without requiring modifying CMakeLists code.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We wanted the CMakeLists.txt to be separate (see library-vcpkg), this is just something we do with VCPKG so we wanted the same format to follow.

Copy link
Contributor

@Jaskowicz1 Jaskowicz1 Apr 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should also be noted, our main CMakeLists.txt doesn't do everything hence why we have library/CMakeLists.txt, library-vcpkg/CMakeLists.txt, and now library-conan/CMakeLists.txt.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is a bit unexpected to me is that such a file wouldn't be way shorter, at least for Conan. Besides some potential minor differences in the dependencies (like the above commented possible find_package() vs FetchContent). So it shouldn't be necessary much different logic to build the project. There are full blocks of CMake code in library-conan/CMakeLists.txt that are completely unrelated to Conan, and also seem completely unrelated to dependencies too, basic definition of the library like globbing files, handling compiler flags, etc. So I would expect that this would be common CMakeLists.txt, and the specializations for vcpkg or Conan would be way more minimal.

Am I missing something here?

# Check for various C functions

check_cxx_symbol_exists(prctl "sys/prctl.h" HAVE_PRCTL)
check_cxx_symbol_exists(pthread_setname_np "pthread.h" HAVE_PTHREAD_SETNAME_NP)

# Go into more detail here and identify the valid signature of pthread_setname_np,
# because different systems have different forms of this function (ugh).
if (HAVE_PTHREAD_SETNAME_NP)
include(CheckCXXSourceCompiles)
check_cxx_source_compiles("
#include <thread>
int main() {
pthread_setname_np(\"ThreadName\");
return 0;
}" HAVE_SINGLE_PARAMETER_SETNAME_NP)
check_cxx_source_compiles("
#include <thread>
int main() {
pthread_setname_np(pthread_self(), \"ThreadName\");
return 0;
}" HAVE_TWO_PARAMETER_SETNAME_NP)
endif()

add_compile_definitions(DPP_OS=${CMAKE_SYSTEM_NAME})

if(${AVX_TYPE} STREQUAL "OFF")
include("${CMAKE_CURRENT_SOURCE_DIR}/../cmake/DetectArchitecture.cmake")
else()
message("-- AVX type overridden by configuration: ${AVX_TYPE}")
endif()
STRING(REPLACE "AVX" "" AVX_TYPE ${AVX_TYPE})
add_compile_definitions(AVX_TYPE=${AVX_TYPE})
add_compile_options(${AVX_FLAG})

if(WIN32 AND NOT MINGW)
if (NOT WINDOWS_32_BIT)
message("-- Setting Windows flags")
add_compile_definitions(_WINSOCK_DEPRECATED_NO_WARNINGS)
add_compile_definitions(WIN32_LEAN_AND_MEAN)
add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
add_compile_definitions(_CRT_NONSTDC_NO_DEPRECATE)
endif()
endif()

if (UNIX)
message("-- Checking for ability to update autogenerated files")
execute_process(
COMMAND which php
RESULT_VARIABLE HAS_PHP
OUTPUT_QUIET
)

if (${HAS_PHP} STREQUAL "0")
message("-- Checking for update to autogenerated files")
# target for rebuild of cluster::*_sync() functions
execute_process(
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/.."
COMMAND php buildtools/make_struct.php "\\Dpp\\Generator\\SyncGenerator"
)
set_source_files_properties( "${CMAKE_CURRENT_SOURCE_DIR}/../include/dpp/cluster_sync_calls.h" PROPERTIES GENERATED TRUE )
# target for unicode_emojis.h
execute_process(
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/.."
COMMAND php buildtools/emojis.php
)
set_source_files_properties( "${CMAKE_CURRENT_SOURCE_DIR}/../include/dpp/unicode_emojis.h" PROPERTIES GENERATED TRUE )
else()
message("-- Autogeneration is not available")
endif()
endif()

include("${CMAKE_CURRENT_SOURCE_DIR}/../cmake/colour.cmake")
if (BUILD_VOICE_SUPPORT)
if(Opus_FOUND AND libsodium_FOUND)
message("-- Found Opus ${Green}${Opus_VERSION}${ColourReset}")
add_compile_definitions(HAVE_VOICE)
message("-- Sodium ${Green}${libsodium_VERSION}${ColourReset}")
set(HAVE_VOICE 1)
endif()

if(HAVE_VOICE)
message("-- Detected ${Green}libsodium${ColourReset} and ${Green}libopus${ColourReset}. VOICE support will be ${Green}enabled${ColourReset}")
else(HAVE_VOICE)
message("-- Could not detect ${Green}libsodium${ColourReset} and/or ${Green}libopus${ColourReset}. VOICE support will be ${Red}disabled${ColourReset}")
endif(HAVE_VOICE)
else()
message("-- Voice support disabled by cmake option")
endif()

string(ASCII 27 Esc)

set(THREADS_PREFER_PTHREAD_FLAG ON)

if(NOT GIT_FOUND AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../.git")
message(FATAL_ERROR "You are using a git version of D++ but do not have git installed. Install git (not 'gh') and try again.")
endif()

if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../.git")
message("-- Building ${Green}git${ColourReset} version. ${Green}Be aware git versions may be unstable!${ColourReset}")
else()
message("-- Building ${Green}stable${ColourReset} version ${Green}${DPP_VERSION}${ColourReset}")
endif()

if(UNIX OR MSYS)
find_program(LDCONFIG_EXECUTABLE "ldconfig")
endif()

if(MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /sdl /DFD_SETSIZE=1024")
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj /Od /DEBUG /Zi")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /O2 /Oi /Oy /Gy")
endif()
if(NOT DPP_CLANG_CL)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP /Zc:preprocessor")
if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /GL")
endif()
endif()
string(REGEX REPLACE "/W[1|2|3|4]" "/W3" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-unused-private-field -Wno-psabi -Wempty-body -Wignored-qualifiers -Wimplicit-fallthrough -Wmissing-field-initializers -Wsign-compare -Wtype-limits -Wuninitialized -Wshift-negative-value -pthread")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Og")

if (NOT MINGW)
add_link_options("-rdynamic")
endif ()
endif()

set(modules_dir "../src")

file(GLOB subdirlist ${modules_dir}/dpp)

foreach (fullmodname ${subdirlist})
get_filename_component(modname ${fullmodname} NAME)
set (modsrc "")

file(GLOB modsrc "${modules_dir}/dpp/*.cpp" "${modules_dir}/dpp/events/*.cpp" "${modules_dir}/dpp/cluster/*.cpp" "${modules_dir}/dpp/*.rc")

if(BUILD_SHARED_LIBS)
add_library(${modname} SHARED ${modsrc})
else()
add_library(${modname} STATIC ${modsrc})
endif()
set_target_properties(${modname}
PROPERTIES
VERSION ${CMAKE_PROJECT_VERSION}
SOVERSION ${CMAKE_PROJECT_VERSION}
POSITION_INDEPENDENT_CODE true
)
target_include_directories(${modname} PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../include/dpp>
)

if (DPP_USE_PCH)
target_precompile_headers(${modname} PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}/../include/dpp/cluster.h"
"${CMAKE_CURRENT_SOURCE_DIR}/../include/dpp/json.h"
"${CMAKE_CURRENT_SOURCE_DIR}/../include/dpp/utility.h"
"${CMAKE_CURRENT_SOURCE_DIR}/../include/dpp/restresults.h"
)
endif()

if (WIN32 AND NOT MINGW)
target_link_libraries(${modname} PRIVATE openssl::openssl
libsodium::libsodium
Opus::opus
ZLIB::ZLIB)
else()
target_link_libraries(${modname} PRIVATE openssl::openssl ZLIB::ZLIB)
if (MINGW)
target_link_libraries(${modname} PUBLIC wsock32 ws2_32 crypt32)
endif ()
endif()

if (HAVE_VOICE)
target_link_libraries(${modname} PRIVATE libsodium::libsodium Opus::opus)
include_directories(${OPUS_INCLUDE_DIRS} ${sodium_INCLUDE_DIR})
endif()

endforeach()

target_compile_features(dpp PUBLIC cxx_std_17)
target_compile_features(dpp PRIVATE cxx_constexpr)
target_compile_features(dpp PRIVATE cxx_auto_type)
target_compile_features(dpp PRIVATE cxx_defaulted_functions)
target_compile_features(dpp PRIVATE cxx_deleted_functions)
target_compile_features(dpp PRIVATE cxx_final)
target_compile_features(dpp PRIVATE cxx_lambdas)
target_compile_features(dpp PRIVATE cxx_override)
target_compile_features(dpp PRIVATE cxx_thread_local)
target_compile_features(dpp PRIVATE cxx_variadic_templates)
target_compile_features(dpp PRIVATE cxx_attribute_deprecated)

if(HAVE_PRCTL)
target_compile_definitions(dpp PRIVATE HAVE_PRCTL)
endif()
if(HAVE_PTHREAD_SETNAME_NP)
target_compile_definitions(dpp PRIVATE HAVE_PTHREAD_SETNAME_NP)
endif()

if(DPP_CORO)
message("-- ${Yellow}Enabled experimental coroutine feature${ColourReset}")
set(CMAKE_CXX_STANDARD 20)
target_compile_features(dpp PUBLIC cxx_std_20)
if(WIN32 AND NOT MINGW AND NOT DPP_CLANG_CL)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /await:strict") # https://learn.microsoft.com/en-us/cpp/build/reference/await-enable-coroutine-support?view=msvc-170
else()
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 14.0.0) # clang >= 14 has native support
message("-- ${Yellow}Clang < 14 - attempting to detect if using libc++ or stdc++${ColourReset}")
check_cxx_source_compiles("
#include <iostream>

int a =
#ifdef __GLIBCXX__
1;
#else
fgsfds;
#endif

int main(int argc, char* argv[])
{
return 0;
}
" IS_GLIBCXX)
if(IS_GLIBCXX)
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 12.0.0)
message(FATAL_ERROR "${BoldRed}Clang with stdc++ and coroutines requires version 12.0.0 or above${ColourReset}")
endif()
message("-- ${Yellow}Detected stdc++ - enabling mock std::experimental namespace${ColourReset}")
target_compile_definitions(dpp PUBLIC "STDCORO_GLIBCXX_COMPAT")
else()
message("-- ${Yellow}Detected libc++ - using <experimental/coroutine>${ColourReset}")
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.0.0)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fcoroutines-ts")
endif()
endif()
message("-- ${Yellow}Note - coroutines in clang < 14 are experimental, upgrading is recommended${ColourReset}")
endif()
elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 10.0)
message(FATAL_ERROR "${BoldRed}Coroutines with g++ require version 10 or above${ColourReset}")
elseif(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 11.0)
message("-- ${Yellow}Note - coroutines in g++10 are experimental, upgrading to g++11 or above is recommended${ColourReset}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fcoroutines")
endif()
endif()
endif()
target_compile_definitions(dpp PUBLIC DPP_CORO)
execute_process(WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/.."
COMMAND php buildtools/make_struct.php "\\Dpp\\Generator\\CoroGenerator")
endif()

if (DPP_BUILD_TEST)
enable_testing(${CMAKE_CURRENT_SOURCE_DIR}/..)
file(GLOB testnamelist "${CMAKE_CURRENT_SOURCE_DIR}/../src/*")
foreach (fulltestname ${testnamelist})
get_filename_component(testname ${fulltestname} NAME)
if (NOT "${testname}" STREQUAL "dpp")
message("-- Configuring test: ${Green}${testname}${ColourReset} with source: ${modules_dir}/${testname}/*.cpp")
set (testsrc "")
file(GLOB testsrc "${modules_dir}/${testname}/*.cpp")
add_executable(${testname} ${testsrc})
if (DPP_CORO)
target_compile_features(${testname} PRIVATE cxx_std_20)
else()
target_compile_features(${testname} PRIVATE cxx_std_17)
endif()
if (MSVC)
target_compile_options(${testname} PRIVATE /utf-8)
endif()
target_link_libraries(${testname} PUBLIC ${modname})
endif()
endforeach()
add_test(
NAME unittest
COMMAND unittest
)
endif()

if(DPP_INSTALL)
if(NOT WIN32)
# Installation

include(GNUInstallDirs)
install(TARGETS dpp LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
message("Library install directory at ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}")
install(DIRECTORY ../include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
message("Include files install directory at ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}")
install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} -DRUN_LDCONFIG=${RUN_LDCONFIG} -DLDCONFIG_EXECUTABLE=${LDCONFIG_EXECUTABLE} -P ${CMAKE_CURRENT_SOURCE_DIR}/../cmake/PostInstall.cmake)")

configure_file("${CMAKE_CURRENT_SOURCE_DIR}/../dpp.pc.in" "${CMAKE_BINARY_DIR}/dpp.pc" @ONLY)
install(FILES "${CMAKE_BINARY_DIR}/dpp.pc" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
elseif(MINGW)
install(TARGETS dpp LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/lib)
install(DIRECTORY ../include/ DESTINATION ${CMAKE_INSTALL_PREFIX}/include)
endif()

# Setup information for packaging and distribution
include("${CMAKE_CURRENT_SOURCE_DIR}/../cmake/CPackSetup.cmake")

# CPack initialization for distribution
include(CPack)
endif()
Loading
Loading