conan icon indicating copy to clipboard operation
conan copied to clipboard

[bug] Conan 1.59 compilation stage for test_package fails (missing type) whereas it succeeds in conan2

Open MartyMcFlyInTheSky opened this issue 1 year ago • 5 comments

Environment details

  • Operating System+version: Ubuntu 22.04
  • Compiler+version: Ubuntu clang version 15.0.7
  • Conan version 1.59.0 / 2.0.17
  • Python version: Python 3.10.13 ( in both cases)

Steps to reproduce

I was testing my conanfile.py for upload to conancenter. The library I'm packaging has an include "utility.hpp" which contains the following statement

#ifdef __has_include
  #if __has_include(<source_location>)
    #include <source_location>

namespace lf::detail {
using source_location = std::source_location;
}  // namespace lf::detail

Now here's the strange thing: When I execute the following using conan2 it works:

conan create all/conanfile.py -pr:b=cpp20 -pr:h=cpp20

However, when I use conan 1.5 with the exact same command, it can't build the testpackage, complaining that:

/home//.conan/data//2.1.1///package/5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9/include/-2.1.1//detail/utility.hpp:37:30: error: no type named 'source_location' in namespace 'std' using source_location = std::source_location;

Rest assured that the cpp20 profile is also the exact same (I copied it):

[settings]
arch=x86_64
build_type=Release
compiler=clang
compiler.cppstd=20
compiler.libcxx=libc++
compiler.version=15
os=Linux

[conf]
tools.build:compiler_executables={"cpp": "/usr/bin/clang++-15", "c": "/usr/bin/clang-15"}

[buildenv]
CMAKE_EXPORT_COMPILE_COMMANDS=ON

so the only difference seems to be the conan version involved. Now why would it compile in conan2 but not in conan 1.5?

Logs

No response

MartyMcFlyInTheSky avatar Feb 10 '24 07:02 MartyMcFlyInTheSky

Hi @MartyMcFlyInTheSky

Thanks for your question.

The way the profile and the compiler.cppstd=20 affects the compilation depends a lot on the build system integrations like CMakeToolchain, and how it is used in the recipe, and also what is in the CMakeLists.txt or in the build scripts.

To understand better why it is not working it would be necessary to know the recipe and the build scripts, if you can please share them, so we can reproduce the issue, that would help.

memsharded avatar Feb 11 '24 20:02 memsharded

Not a problem. Here's the recipe:

conanfile.py

from conan import ConanFile
from conan.tools.cmake import CMakeToolchain, CMake, cmake_layout, CMakeDeps
from conan.errors import ConanInvalidConfiguration
from conan.tools.build import check_min_cppstd
from conan.tools.files import apply_conandata_patches, copy, export_conandata_patches, get
from conan.tools.scm import Version
import os

required_conan_version = ">=1.52.0"

class PackageConan(ConanFile):
    name = "somelib"
    version = "2.1.1" 
    description = "My description."
    license = "MPL-2.0"
    author = "Some Guy"
    url = "https://github.com/conan-io/conan-center-index"
    homepage = "https://github.com/SomeGuy/somelib"
    topics = ("libstuff")
    package_type = "header-library"
    settings = "os", "arch", "compiler", "build_type"
    
    no_copy_source = True

    @property
    def _min_cppstd(self):
        return 20

    @property
    def _compilers_minimum_version(self):
        return {
            "apple-clang": "12.0.0",
            "clang": "10",
            "gcc": "10",
            "msvc": "19.29",
            "Visual Studio": "16.10",
        }

    def layout(self):
        cmake_layout(self)

    def build_requirements(self):
        self.tool_requires("cmake/3.28.1")
        if (not self.conf.get("tools.build:skip_test", default=True, check_type=bool)):
            self.test_requires("catch2/3.5.1")

    def package_id(self):
        self.info.clear()

    def validate(self):
        if self.settings.compiler.get_safe("cppstd"):
            check_min_cppstd(self, self._min_cppstd)
        minimum_version = self._compilers_minimum_version.get(str(self.settings.compiler), False)
        if minimum_version and Version(self.settings.compiler.version) < minimum_version:
            raise ConanInvalidConfiguration(
                f"{self.ref} requires C++{self._min_cppstd}, which your compiler does not support."
            )

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

    def generate(self):
        deps = CMakeDeps(self)
        deps.generate()
        tc = CMakeToolchain(self)
        tc.cache_variables["CPM_USE_LOCAL_PACKAGES"] = True
        if (not self.conf.get("tools.build:skip_test", default=True, check_type=bool)):
            tc.cache_variables["somelib_DEVELOPER_MODE"] = True
            tc.cache_variables["BUILD_TESTING"] = True
        tc.generate()

    def build(self):
        cmake = CMake(self)
        cmake.configure()
        cmake.build()
        if (not self.conf.get("tools.build:skip_test", default=True, check_type=bool)):
            cmake.test()

    def package(self):
        cmake = CMake(self)
        cmake.install()

    def package_info(self):
        self.cpp_info.includedirs = ["include/somelib-2.1.1"]
        self.cpp_info.bindirs = []
        self.cpp_info.libdirs = []
        self.cpp_info.set_property("cmake_file_name", "somelib")
        self.cpp_info.set_property("cmake_target_name", "somelib::somelib")

        if self.settings.os in ["Linux", "FreeBSD"]:
            self.cpp_info.system_libs.extend(["pthread"])

And the build script.

Top level CMakeLists.txt:

cmake_minimum_required(VERSION 3.14)

include(cmake/prelude.cmake)

project(
  somelib
  VERSION 2.1.1
  DESCRIPTION "Some library."
  HOMEPAGE_URL "https://github.com/SomeGuy/somelib"
  LANGUAGES CXX
)

include(cmake/project-is-top-level.cmake)
include(cmake/variables.cmake)

# ---- Dependencies ----
find_package(Threads REQUIRED)

# ---- Declare library ----
add_library(somelib_somelib INTERFACE)
add_library(somelib::somelib ALIAS somelib_somelib)

target_link_libraries(somelib_somelib INTERFACE Threads::Threads)

set_property(
  TARGET somelib_somelib PROPERTY
  EXPORT_NAME somelib
)

set(CMAKE_INSTALL_INCLUDEDIR "include/somelib-${PROJECT_VERSION}" CACHE PATH "")

target_include_directories(
  somelib_somelib ${warning_guard}
  INTERFACE
  "$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>"
  "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
)

target_compile_features(somelib_somelib INTERFACE cxx_std_20)

# ---- Install rules ----
if(NOT CMAKE_SKIP_INSTALL_RULES)
  include(cmake/install-rules.cmake)
endif()

# ---- Developer mode ----
if(NOT somelib_DEVELOPER_MODE)
  return()
elseif(NOT PROJECT_IS_TOP_LEVEL)
  message(
    AUTHOR_WARNING
    "Developer mode is intended for developers of somelib"
  )
endif()

include(cmake/dev-mode.cmake)

MartyMcFlyInTheSky avatar Feb 12 '24 05:02 MartyMcFlyInTheSky

have you tried moving row compiler.version=15 before row compiler.cppstd=20 in profile?

Nekto89 avatar Feb 12 '24 11:02 Nekto89

Hi @MartyMcFlyInTheSky

I just tried libfork with your conanfile.py provided and GCC-11 instead, and it's working fine for Conan 1.59, 1.63, and 2.x. I had no problems with anything. Have you tried to compile it with GCC just in case? I could not reproduce the issue either in Linux or macOS.

UPDATED: I modified my profile to simulate something like yours:

[settings]
arch=x86_64
build_type=Release
compiler=gcc
compiler.cppstd=20
compiler.libcxx=libstdc++
compiler.version=11
os=Linux

[conf]
tools.build:compiler_executables={"cpp": "/usr/bin/g++", "c": "/usr/bin/gcc"}

[buildenv]
CMAKE_EXPORT_COMPILE_COMMANDS=ON

franramirez688 avatar Feb 13 '24 10:02 franramirez688

@Nekto89 Thanks for the tipp, tried it, but still the same error

@franramirez688 Tried that as well, also no success. I'll try to reproduce this on my windows in wsl, maybe I can further encircle the problem that way. Strange though that it worked for you?

Update: I also couldn't reproduce the problem on wsl ubuntu. Everything works also for conan 1.59 there. Somehow it seems I have messed up some settings I guess.

MartyMcFlyInTheSky avatar Feb 17 '24 15:02 MartyMcFlyInTheSky