Repository: conan-io/conan
Pull request #15731 (2024-02-22 07:51:29)

Backport cppstd_flag from Conan 2.x
Related to the PR #15710, this PR backports the method available in Conan 2.x

In Conan 1.x we have [cppstd_flag](https://docs.conan.io/1/reference/tools.html#tools-cppstd-flag) available already, but it receives `settings` only is under `conans.tools`.

This change creates a wrapper to make it available under `conan.tools.build` and should pass `conanfile` instead.

Changelog: Feature: Promote cppstd_flag in the new conan.tools.build module.

Docs: https://github.com/conan-io/docs/pull/3602

- [x] Refer to the issue that supports this Pull Request.
- [x] If the issue has missing info, explain the purpose/use case/pain/need that covers this Pull Request.
- [x] I've read the [Contributing guide](https://github.com/conan-io/conan/blob/develop/.github/CONTRIBUTING.md).
- [x] I've followed the PEP8 style guides for Python code.
- [x] I've opened another PR in the Conan docs repo to the ``develop`` branch, documenting this one.



Patch:
diff --git a/conan/tools/build/__init__.py b/conan/tools/build/__init__.py
index 829886a8d..da2223ff1 100644
--- a/conan/tools/build/__init__.py
+++ b/conan/tools/build/__init__.py
@@ -3,3 +3,4 @@ from conan.tools.build.cross_building import cross_building, can_run
 from conan.tools.build.cppstd import check_min_cppstd, valid_min_cppstd, default_cppstd, \
     supported_cppstd
 from conan.tools.build.stdcpp_library import stdcpp_library
+from conan.tools.build.flags import cppstd_flag
diff --git a/conan/tools/build/flags.py b/conan/tools/build/flags.py
new file mode 100644
index 000000000..9cd9f0638
--- /dev/null
+++ b/conan/tools/build/flags.py
@@ -0,0 +1,16 @@
+from conan.tools._compilers import cppstd_flag as cppstd_flag_settings
+
+
+def cppstd_flag(conanfile):
+    """
+    Returns flags specific to the C++ standard based on the ``conanfile.settings.compiler``,
+    ``conanfile.settings.compiler.version`` and ``conanfile.settings.compiler.cppstd``.
+    It also considers when using GNU extension in ``settings.compiler.cppstd``, reflecting it in the
+    compiler flag. Currently, it supports GCC, Clang, AppleClang, MSVC, Intel, MCST-LCC.
+    In case there is no ``settings.compiler`` or ``settings.cppstd`` in the profile, the result will
+    be an **empty string**.
+    :param conanfile: The current recipe object. Always use ``self``.
+    :return: ``str`` with the standard C++ flag used by the compiler. e.g. "-std=c++11", "/std:c++latest"
+    """
+    settings = conanfile.settings
+    return cppstd_flag_settings(settings)


Test patch:
diff --git a/conans/test/unittests/client/build/cpp_std_flags_test.py b/conans/test/unittests/client/build/cpp_std_flags_test.py
index 1badf2c90..3c30e8371 100644
--- a/conans/test/unittests/client/build/cpp_std_flags_test.py
+++ b/conans/test/unittests/client/build/cpp_std_flags_test.py
@@ -1,9 +1,11 @@
 import unittest
 
 from conans.client.build.cppstd_flags import cppstd_default
-from conans.test.utils.mocks import MockSettings
+from conans.test.utils.mocks import MockSettings, ConanFileMock
 from conans.tools import cppstd_flag
 
+from conan.tools.build import cppstd_flag as cppstd_flag_conanfile
+
 
 def _make_cppstd_flag(compiler, compiler_version, cppstd=None, compiler_base=None):
     settings = MockSettings({"compiler": compiler,
@@ -399,3 +401,12 @@ class CompilerFlagsTest(unittest.TestCase):
         self.assertEqual(_make_cppstd_flag("mcst-lcc", "1.25", "14", "gcc"), "-std=c++14")
         self.assertEqual(_make_cppstd_flag("mcst-lcc", "1.25", "17", "gcc"), "-std=c++17")
         self.assertEqual(_make_cppstd_flag("mcst-lcc", "1.25", "20", "gcc"), "-std=c++2a")
+
+    def test_cppstd_flag_conanfile(self):
+        """The conan.tools.build.cppstd_flag should work when passing a ConanFile instance
+        """
+        conanfile = ConanFileMock()
+        conanfile.settings = MockSettings({"compiler": "gcc",
+                                          "compiler.version": "9",
+                                          "compiler.cppstd": "17"})
+        self.assertEqual(cppstd_flag_conanfile(conanfile), "-std=c++17")