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

Add libmicrohttpd/0.9.75 recipe #13564

Merged
merged 15 commits into from
Oct 20, 2022
Merged
9 changes: 9 additions & 0 deletions recipes/libmicrohttpd/all/conandata.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
sources:
"0.9.75":
url: "https://ftp.gnu.org/gnu/libmicrohttpd/libmicrohttpd-0.9.75.tar.gz"
sha256: "9278907a6f571b391aab9644fd646a5108ed97311ec66f6359cebbedb0a4e3bb"
patches:
"0.9.75":
- patch_file: "patches/0.9.75-0001-msbuild-RuntimeLibrary.patch"
patch_description: "Remove RuntimeLibrary from vcxproject + use conantoolchain.props"
patch_type: "conan"
189 changes: 189 additions & 0 deletions recipes/libmicrohttpd/all/conanfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
from conan import ConanFile, Version
from conan.tools.files import apply_conandata_patches, copy, export_conandata_patches, get, rm, rmdir
from conan.tools.microsoft import MSBuild, MSBuildToolchain, is_msvc, vs_layout
from conan.errors import ConanInvalidConfiguration
madebr marked this conversation as resolved.
Show resolved Hide resolved
from conans import AutoToolsBuildEnvironment
import functools
import os

required_conan_version = ">=1.52.0"


class LibmicrohttpdConan(ConanFile):
name = "libmicrohttpd"
description = "A small C library that is supposed to make it easy to run an HTTP server"
homepage = "https://www.gnu.org/software/libmicrohttpd/"
topics = ("libmicrohttpd", "httpd", "server", "service")
Copy link
Contributor

Choose a reason for hiding this comment

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

The package name doesn't need to be in topics.

Suggested change
topics = ("libmicrohttpd", "httpd", "server", "service")
topics = ("httpd", "server", "service")

license = "LGPL-2.1"
url = "https://github.com/conan-io/conan-center-index"
settings = "os", "arch", "compiler", "build_type"
options = {
"shared": [True, False],
"fPIC": [True, False],
"with_https": [True, False],
"with_error_messages": [True, False],
"with_postprocessor": [True, False],
"with_digest_authentification": [True, False],
"epoll": [True, False],
"with_zlib": [True, False],
}
default_options = {
"shared": False,
"fPIC": True,
"with_https": False, # FIXME: should be True, but gnutls is not yet available in cci
Copy link
Member

Choose a reason for hiding this comment

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

I started a PR for GNU TlS, need to resume it.

Copy link
Contributor Author

@madebr madebr Oct 18, 2022

Choose a reason for hiding this comment

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

I stopped when I failed to get it building for MSVC x years ago.
Would be nice if you get it working.

"with_error_messages": True,
"with_postprocessor": True,
"with_digest_authentification": True,
"epoll": True,
"with_zlib": True,
}
generators = "pkg_config"
Copy link
Contributor

Choose a reason for hiding this comment

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

PkgConfigDeps + generate() method?


@property
def _settings_build(self):
return getattr(self, "settings_build", self.settings)

def config_options(self):
if self.settings.os != "Linux":
del self.options.fPIC
del self.options.epoll
if is_msvc(self):
del self.options.with_https
del self.options.with_error_messages
del self.options.with_postprocessor
del self.options.with_digest_authentification
del self.options.with_zlib

def configure(self):
if self.options.shared:
del self.options.fPIC
madebr marked this conversation as resolved.
Show resolved Hide resolved
try:
del self.settings.compiler.libcxx
except Exception:
pass
try:
del self.settings.compiler.cppstd
except Exception:
pass

def validate(self):
if is_msvc(self):
if self.info.settings.arch not in ("x86", "x86_64"):
raise ConanInvalidConfiguration("Unsupported architecture (only x86 and x86_64 are supported)")
if self.info.settings.build_type not in ("Release", "Debug"):
raise ConanInvalidConfiguration("Unsupported build type (only Release and Debug are supported)")

def requirements(self):
if self.options.get_safe("with_zlib", False):
self.requires("zlib/1.2.13")
if self.options.get_safe("with_https", False):
raise ConanInvalidConfiguration("gnutls is not (yet) available in cci")

def build_requirements(self):
if self._settings_build.os == "Windows" and not is_msvc(self) and not self.conf.get("tools.microsoft.bash:path", default=False, check_type=str):
self.build_requires("msys2/cci.latest")
Copy link
Contributor

Choose a reason for hiding this comment

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

I think self.win_bash should be set to True here.

Suggested change
if self._settings_build.os == "Windows" and not is_msvc(self) and not self.conf.get("tools.microsoft.bash:path", default=False, check_type=str):
self.build_requires("msys2/cci.latest")
if self._settings_build.os == "Windows" and not is_msvc(self) :
self.win_bash = True
if not self.conf.get("tools.microsoft.bash:path", default=False, check_type=str):
self.tool_requires("msys2/cci.latest")


def source(self):
get(self, **self.conan_data["sources"][self.version],
destination=self.source_folder, strip_root=True)

def export_sources(self):
export_conandata_patches(self)

def layout(self):
if is_msvc(self):
vs_layout(self)
madebr marked this conversation as resolved.
Show resolved Hide resolved

def generate(self):
if is_msvc(self):
tc = MSBuildToolchain(self)
tc.configuration = self._msvc_configuration
tc.generate()

@property
def _msvc_configuration(self):
return f"{self.settings.build_type}-{'dll' if self.options.shared else 'static'}"

@property
def _msvc_sln_folder(self):
if self.settings.compiler == "Visual Studio":
if Version(self.settings.compiler.version) >= 16:
subdir = "VS-Any-Version"
else:
subdir = "VS2017"
else:
subdir = "VS-Any-Version"
return os.path.join("w32", subdir)

@property
def _msvc_arch(self):
return {
"x86": "Win32",
"x86_64": "x64",
}[str(self.settings.arch)]

def _patch_sources(self):
apply_conandata_patches(self)

@functools.lru_cache(1)
def _configure_autotools(self):
yes_no = lambda v: "yes" if v else "no"
autotools = AutoToolsBuildEnvironment(self, win_bash=self._settings_build.os == "Windows")
Copy link
Contributor

Choose a reason for hiding this comment

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

Is it possible to use AutotoolsToolchain?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, but I got bitten by 2 bugs: conan-io/conan#12193 and conan-io/conan#12338

autotools.libs = []
if self.settings.os == "Windows":
if self.options.with_zlib:
libdir = self.deps_cpp_info["zlib"].lib_paths[0]
autotools.link_flags.extend([os.path.join(libdir, lib).replace("\\", "/") for lib in os.listdir(libdir)])
autotools.configure(self.source_folder,[
f"--enable-shared={yes_no(self.options.shared)}",
f"--enable-static={yes_no(not self.options.shared)}",
f"--enable-https={yes_no(self.options.with_https)}",
f"--enable-messages={yes_no(self.options.with_error_messages)}",
f"--enable-postprocessor={yes_no(self.options.with_postprocessor)}",
f"--enable-dauth={yes_no(self.options.with_digest_authentification)}",
f"--enable-epoll={yes_no(self.options.get_safe('epoll'))}",
"--disable-doc",
"--disable-examples",
"--disable-curl",
])
return autotools

def build(self):
self._patch_sources()
if is_msvc(self):
msbuild = MSBuild(self)
msbuild.build_type = self._msvc_configuration
msbuild.build(sln=os.path.join(self._msvc_sln_folder, "libmicrohttpd.sln"), targets=["libmicrohttpd"])
else:
autotools = self._configure_autotools()
autotools.make()

def package(self):
copy(self, "COPYING", os.path.join(self.build_folder), os.path.join(self.package_folder, "licenses"))
if is_msvc(self):
copy(self, "*.lib", os.path.join(self.build_folder, self._msvc_sln_folder, "Output", self._msvc_arch), os.path.join(self.package_folder, "lib"))
copy(self, "*.dll", os.path.join(self.build_folder, self._msvc_sln_folder, "Output", self._msvc_arch), os.path.join(self.package_folder, "bin"))
copy(self, "*.h", os.path.join(self.build_folder, self._msvc_sln_folder, "Output", self._msvc_arch), os.path.join(self.package_folder, "include"))
else:
autotools = self._configure_autotools()
autotools.install()

rm(self, "*.la", os.path.join(self.package_folder, "lib"))
rmdir(self, os.path.join(self.package_folder, "lib", "pkgconfig"))

def package_info(self):
self.cpp_info.set_property("pkg_config_name", "libmicrohttps")
libname = "microhttpd"
if is_msvc(self):
libname = "libmicrohttpd"
if self.options.shared:
libname += "-dll"
if self.settings.build_type == "Debug":
libname += "_d"
self.cpp_info.libs = [libname]
if self.settings.os in ("FreeBSD", "Linux"):
self.cpp_info.system_libs = ["pthread"]
elif self.settings.os == "Windows":
if self.options.shared:
self.cpp_info.defines.append("MHD_W32DLL")
self.cpp_info.system_libs = ["ws2_32"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
--- w32/common/common-build-settings.vcxproj
+++ w32/common/common-build-settings.vcxproj
@@ -5,7 +5,7 @@
Only 0 and 1 are used currently -->
<TargetOSLevel Condition="$(PlatformToolset.EndsWith('_xp'))">0</TargetOSLevel>
<TargetOSLevel Condition="! $(PlatformToolset.EndsWith('_xp'))">1</TargetOSLevel>
- </PropertyGroup>
+ </PropertyGroup><Import Project="../../conan/conantoolchain.props" />
<PropertyGroup>
<IncludePath>$(SolutionDir);$(MhdW32Common);$(MhdSrc)include;$(IncludePath)</IncludePath>
</PropertyGroup>
--- w32/common/libmicrohttpd-build-settings.vcxproj
+++ w32/common/libmicrohttpd-build-settings.vcxproj
@@ -31,8 +31,8 @@
<ItemDefinitionGroup Condition="'$(ConfigurationType)'=='StaticLibrary'">
<ClCompile>
<PreprocessorDefinitions>_LIB;MHD_W32LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <RuntimeLibrary Condition="'$(UseDebugLibraries)'=='true'">MultiThreadedDebug</RuntimeLibrary>
- <RuntimeLibrary Condition="'$(UseDebugLibraries)'!='true'">MultiThreaded</RuntimeLibrary>
+ <!--<RuntimeLibrary Condition="'$(UseDebugLibraries)'=='true'">MultiThreadedDebug</RuntimeLibrary>
+ <RuntimeLibrary Condition="'$(UseDebugLibraries)'!='true'">MultiThreaded</RuntimeLibrary>-->
</ClCompile>
<Lib>
<AdditionalDependencies>Ws2_32.lib</AdditionalDependencies>
@@ -45,8 +45,8 @@
<ItemDefinitionGroup Condition="'$(ConfigurationType)'=='DynamicLibrary'">
<ClCompile>
<PreprocessorDefinitions>_USRDLL;MHD_W32DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <RuntimeLibrary Condition="'$(UseDebugLibraries)'=='true'">MultiThreadedDebugDLL</RuntimeLibrary>
- <RuntimeLibrary Condition="'$(UseDebugLibraries)'!='true'">MultiThreadedDLL</RuntimeLibrary>
+ <!--<RuntimeLibrary Condition="'$(UseDebugLibraries)'=='true'">MultiThreadedDebugDLL</RuntimeLibrary>
+ <RuntimeLibrary Condition="'$(UseDebugLibraries)'!='true'">MultiThreadedDLL</RuntimeLibrary>-->
</ClCompile>
<Link>
<AdditionalDependencies>Ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
7 changes: 7 additions & 0 deletions recipes/libmicrohttpd/all/test_package/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
cmake_minimum_required(VERSION 3.1)
project(test_package LANGUAGES C)

find_package(libmicrohttpd REQUIRED CONFIG)

add_executable(${PROJECT_NAME} test_package.c)
target_link_libraries(${PROJECT_NAME} PRIVATE libmicrohttpd::libmicrohttpd)
30 changes: 30 additions & 0 deletions recipes/libmicrohttpd/all/test_package/conanfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
from conan import ConanFile
from conan.tools.build import can_run
from conan.tools.cmake import CMake, CMakeToolchain, cmake_layout
import os


class TestPackageConan(ConanFile):
settings = "os", "arch", "compiler", "build_type"
generators = "CMakeDeps", "VirtualRunEnv"
test_type = "explicit"

def layout(self):
cmake_layout(self)

def requirements(self):
self.requires(self.tested_reference_str)

def generate(self):
tc = CMakeToolchain(self)
tc.generate()

def build(self):
cmake = CMake(self)
cmake.configure()
cmake.build()

def test(self):
if can_run(self):
bin_path = os.path.join(self.cpp.build.bindirs[0], "test_package")
self.run(bin_path, env="conanrun")
74 changes: 74 additions & 0 deletions recipes/libmicrohttpd/all/test_package/test_package.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#include <microhttpd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#define PORT 8888
#define PAGE \
"<html>" \
"<head>" \
"<title>libmicrohttpd demo</title>" \
"</head>" \
"<body>" \
"libmicrohttpd demo" \
"</body>" \
"</html>"

static enum MHD_Result ahc_echo(void * cls,
struct MHD_Connection *connection,
const char *url,
const char *method,
const char *version,
const char *upload_data,
long unsigned int *upload_data_size,
void **con_cls) {
struct MHD_Response *response;
int ret;

if (strcmp(method, "GET") != 0) {
/**
* unexpected method
*/
return MHD_NO;
}
if (*con_cls == NULL) {
/**
* The first time only the headers are valid,
* do not respond in the first round.
* But accept the connection.
*/
*con_cls = connection;
return MHD_YES;
}
if (*upload_data_size != 0) {
/**
* upload data in a GET!?
*/
return MHD_NO;
}
response = MHD_create_response_from_buffer(strlen(PAGE), (void*)PAGE, MHD_RESPMEM_PERSISTENT);
ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
MHD_destroy_response(response);
return ret;
}

int main(int argc, char *argv[]) {
struct MHD_Daemon *daemon;

// Don't open a port and do not block so CI isn't interrupted.
#if 0
daemon = MHD_start_daemon(MHD_USE_INTERNAL_POLLING_THREAD,
PORT, NULL, NULL,
&ahc_echo, NULL, MHD_OPTION_END);
if (daemon == NULL) {
return 1;
}

(void)getchar();
#else
daemon = NULL;
#endif

MHD_stop_daemon(daemon);
return 0;
}
10 changes: 10 additions & 0 deletions recipes/libmicrohttpd/all/test_v1_package/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
cmake_minimum_required(VERSION 3.1)
project(test_package LANGUAGES C)

include("${CMAKE_BINARY_DIR}/conanbuildinfo.cmake")
conan_basic_setup(TARGETS)

find_package(libmicrohttpd REQUIRED CONFIG)

add_executable(${PROJECT_NAME} ../test_package/test_package.c)
target_link_libraries(${PROJECT_NAME} PRIVATE libmicrohttpd::libmicrohttpd)
17 changes: 17 additions & 0 deletions recipes/libmicrohttpd/all/test_v1_package/conanfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from conans import ConanFile, CMake, tools
import os


class TestPackageConan(ConanFile):
settings = "os", "arch", "compiler", "build_type"
generators = "cmake", "cmake_find_package_multi"

def build(self):
cmake = CMake(self)
cmake.configure()
cmake.build()

def test(self):
if not tools.cross_building(self):
bin_path = os.path.join("bin", "test_package")
self.run(bin_path, run_environment=True)
3 changes: 3 additions & 0 deletions recipes/libmicrohttpd/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
versions:
"0.9.75":
folder: all