diff --git a/recipes/azure-storage-cpp/all/CMakeLists.txt b/recipes/azure-storage-cpp/all/CMakeLists.txt index 82ba25e8c2576..3d130cd5365bf 100644 --- a/recipes/azure-storage-cpp/all/CMakeLists.txt +++ b/recipes/azure-storage-cpp/all/CMakeLists.txt @@ -1,7 +1,16 @@ -cmake_minimum_required(VERSION 2.8.12) +cmake_minimum_required(VERSION 3.15) project(cmake_wrapper) -include(conanbuildinfo.cmake) -conan_basic_setup() +find_package(cpprestsdk REQUIRED) +find_package(OpenSSL REQUIRED) +find_package(LibXml2 REQUIRED) +find_package(UUID QUIET) -add_subdirectory("source_subfolder/Microsoft.WindowsAzure.Storage") +add_subdirectory(src/Microsoft.WindowsAzure.Storage) + +target_link_libraries(azurestorage + cpprestsdk::cpprestsdk + OpenSSL::SSL + LibXml2::LibXml2 + $ +) diff --git a/recipes/azure-storage-cpp/all/conandata.yml b/recipes/azure-storage-cpp/all/conandata.yml index ccef8ba8c5bd6..5ce9572d0f722 100644 --- a/recipes/azure-storage-cpp/all/conandata.yml +++ b/recipes/azure-storage-cpp/all/conandata.yml @@ -4,5 +4,7 @@ sources: sha256: "446a821d115949f6511b7eb01e6a0e4f014b17bfeba0f3dc33a51750a9d5eca5" patches: "7.5.0": - - base_path: source_subfolder - patch_file: patches/0001-cmake-fixes.patch + - patch_file: "patches/fix-cpp17-incompatibility.patch" + patch_description: "Fix a minor C++17 incompatibility in util.cpp" + patch_type: "portability" + patch_source: "https://patch-diff.githubusercontent.com/raw/Azure/azure-storage-cpp/pull/366" diff --git a/recipes/azure-storage-cpp/all/conanfile.py b/recipes/azure-storage-cpp/all/conanfile.py index 92f05a255ac83..abe044bfc3367 100644 --- a/recipes/azure-storage-cpp/all/conanfile.py +++ b/recipes/azure-storage-cpp/all/conanfile.py @@ -1,19 +1,27 @@ -from conans import ConanFile, CMake, tools -from conans.errors import ConanInvalidConfiguration import os -required_conan_version = ">=1.33.0" +from conan import ConanFile +from conan.errors import ConanInvalidConfiguration +from conan.tools.apple import is_apple_os +from conan.tools.build import check_min_cppstd, valid_min_cppstd +from conan.tools.cmake import CMake, CMakeDeps, CMakeToolchain, cmake_layout +from conan.tools.files import copy, get, replace_in_file, export_conandata_patches, apply_conandata_patches +from conan.tools.microsoft import check_min_vs, is_msvc_static_runtime, is_msvc +from conan.tools.scm import Version + +required_conan_version = ">=1.53.0" + class AzureStorageCppConan(ConanFile): name = "azure-storage-cpp" + description = "Microsoft Azure Storage Client Library for C++" license = "Apache-2.0" url = "https://github.com/conan-io/conan-center-index" homepage = "https://github.com/Azure/azure-storage-cpp" - description = "Microsoft Azure Storage Client Library for C++" topics = ("azure", "cpp", "cross-platform", "microsoft", "cloud") - settings = "os", "compiler", "build_type", "arch" - generators = "cmake", "cmake_find_package" - exports_sources = ["CMakeLists.txt", "patches/**"] + + package_type = "library" + settings = "os", "arch", "compiler", "build_type" options = { "shared": [True, False], "fPIC": [True, False], @@ -22,16 +30,6 @@ class AzureStorageCppConan(ConanFile): "shared": False, "fPIC": True, } - short_paths = True - _cmake = None - - @property - def _source_subfolder(self): - return "source_subfolder" - - @property - def _build_subfolder(self): - return "build_subfolder" @property def _minimum_cpp_standard(self): @@ -40,41 +38,16 @@ def _minimum_cpp_standard(self): @property def _minimum_compiler_version(self): return { - "gcc": "5", + "gcc": "6", "Visual Studio": "14", + "msvc": "190", "clang": "3.4", "apple-clang": "5.1", } - def requirements(self): - self.requires("cpprestsdk/2.10.18") - if self.settings.os != "Windows": - self.requires("boost/1.76.0") - self.requires("libxml2/2.9.10") - self.requires("util-linux-libuuid/2.39") - if self.settings.os == "Macos": - self.requires("libgettext/0.20.1") - - def source(self): - tools.get(**self.conan_data["sources"][self.version], - destination=self._source_subfolder, strip_root=True) - - def _configure_cmake(self): - if self._cmake: - return self._cmake - self._cmake = CMake(self) - - self._cmake.definitions["CMAKE_FIND_FRAMEWORK"] = "LAST" - self._cmake.definitions["BUILD_TESTS"] = False - self._cmake.definitions["BUILD_SAMPLES"] = False - if not self.settings.compiler.cppstd: - self._cmake.definitions["CMAKE_CXX_STANDARD"] = self._minimum_cpp_standard - - if self.settings.os == "Macos": - self._cmake.definitions["GETTEXT_LIB_DIR"] = self.deps_cpp_info["libgettext"].lib_paths[0] - - self._cmake.configure(build_folder=self._build_subfolder) - return self._cmake + def export_sources(self): + copy(self, "CMakeLists.txt", src=self.recipe_folder, dst=self.export_sources_folder) + export_conandata_patches(self) def config_options(self): if self.settings.os == "Windows": @@ -82,42 +55,100 @@ def config_options(self): def configure(self): if self.options.shared: - del self.options.fPIC + self.options.rm_safe("fPIC") + + def layout(self): + cmake_layout(self, src_folder="src") + + def requirements(self): + self.requires("cpprestsdk/2.10.19", transitive_headers=True, transitive_libs=True) + self.requires("libxml2/[>=2.12.5 <3]", transitive_headers=True, transitive_libs=True) + if self.settings.os != "Windows": + # Boost.Asio is used in a public header here: + # https://github.com/Azure/azure-storage-cpp/blob/v7.5.0/Microsoft.WindowsAzure.Storage/includes/wascore/timer_handler.h#L27 + self.requires("boost/1.83.0", transitive_headers=True, transitive_libs=True) + self.requires("util-linux-libuuid/2.39.2", transitive_headers=True, transitive_libs=True) + self.requires("openssl/[>=1.1 <4]") + if is_apple_os(self): + self.requires("libgettext/0.22") def validate(self): if self.settings.compiler.cppstd: - tools.check_min_cppstd(self, self._minimum_cpp_standard) + check_min_cppstd(self, self._minimum_cpp_standard) min_version = self._minimum_compiler_version.get(str(self.settings.compiler)) if not min_version: - self.output.warn("{} recipe lacks information about the {} compiler support.".format( - self.name, self.settings.compiler)) + self.output.warning( + f"{self.name} recipe lacks information about the {self.settings.compiler} compiler support." + ) else: - if tools.Version(self.settings.compiler.version) < min_version: - raise ConanInvalidConfiguration("{} requires C++{} support. The current compiler {} {} does not support it.".format( - self.name, self._minimum_cpp_standard, self.settings.compiler, self.settings.compiler.version)) + if Version(self.settings.compiler.version) < min_version: + raise ConanInvalidConfiguration( + f"{self.name} requires C++{self._minimum_cpp_standard} support. The current compiler" + f" {self.settings.compiler} {self.settings.compiler.version} does not support it." + ) # FIXME: Visual Studio 2015 & 2017 are supported but CI of CCI lacks several Win SDK components # https://github.com/conan-io/conan-center-index/issues/4195 - if self.settings.compiler == "Visual Studio" and tools.Version(self.settings.compiler.version) < "16": + if not check_min_vs(self, 192, raise_invalid=False): raise ConanInvalidConfiguration("Visual Studio < 2019 not yet supported in this recipe") - if self.settings.compiler == "Visual Studio" and self.options.shared and "MT" in self.settings.compiler.runtime: + if self.options.shared and is_msvc_static_runtime(self): raise ConanInvalidConfiguration("Visual Studio build for shared library with MT runtime is not supported") + def source(self): + get(self, **self.conan_data["sources"][self.version], strip_root=True) + + def generate(self): + tc = CMakeToolchain(self) + tc.variables["CMAKE_FIND_FRAMEWORK"] = "LAST" + tc.variables["BUILD_TESTS"] = False + tc.variables["BUILD_SAMPLES"] = False + if is_apple_os(self): + tc.variables["GETTEXT_LIB_DIR"] = self.dependencies["libgettext"].cpp_info.libdir + if not valid_min_cppstd(self, self._minimum_cpp_standard): + tc.variables["CMAKE_CXX_STANDARD"] = self._minimum_cpp_standard + # Allow non-cache_variables to be used + tc.cache_variables["CMAKE_POLICY_DEFAULT_CMP0077"] = "NEW" + # Relocatable shared libs on macOS + tc.cache_variables["CMAKE_POLICY_DEFAULT_CMP0042"] = "NEW" + tc.generate() + + deps = CMakeDeps(self) + deps.set_property("util-linux-libuuid", "cmake_file_name", "UUID") + deps.generate() + + def _patch_sources(self): + apply_conandata_patches(self) + cmakelists_path = os.path.join(self.source_folder, "Microsoft.WindowsAzure.Storage", "CMakeLists.txt") + # Do not force C++11 and libc++ + replace_in_file(self, cmakelists_path, "-std=c++11", "") + replace_in_file(self, cmakelists_path, "-stdlib=libc++", "") + # Let Conan handle the Boost defines + replace_in_file(self, cmakelists_path, "add_definitions(-DBOOST_LOG_DYN_LINK)", "") + def build(self): - for patch in self.conan_data.get("patches", {}).get(self.version, []): - tools.patch(**patch) - cmake = self._configure_cmake() + self._patch_sources() + cmake = CMake(self) + cmake.configure(build_script_folder=self.source_path.parent) cmake.build() def package(self): - self.copy("LICENSE.txt", dst="licenses", src=self._source_subfolder) - cmake = self._configure_cmake() + copy(self, "LICENSE.txt", + dst=os.path.join(self.package_folder, "licenses"), + src=self.source_folder) + cmake = CMake(self) cmake.install() def package_info(self): - - self.cpp_info.libs = tools.collect_libs(self) if self.settings.os == "Windows": + # https://github.com/Azure/azure-storage-cpp/blob/v7.5.0/Microsoft.WindowsAzure.Storage/src/CMakeLists.txt#L100 + self.cpp_info.libs = ["wastorage"] + # https://github.com/Azure/azure-storage-cpp/blob/v7.5.0/Microsoft.WindowsAzure.Storage/src/CMakeLists.txt#L90 self.cpp_info.system_libs = ["ws2_32", "rpcrt4", "xmllite", "bcrypt"] - if not self.options.shared: - self.cpp_info.defines = ["_NO_WASTORAGE_API"] + if is_msvc(self): + # https://github.com/Azure/azure-storage-cpp/blob/v7.5.0/Microsoft.WindowsAzure.Storage/CMakeLists.txt#L116-L120 + if self.options.shared: + self.cpp_info.defines = ["WASTORAGE_DLL", "_USRDLL"] + else: + self.cpp_info.defines = ["_NO_WASTORAGE_API"] + else: + self.cpp_info.libs = ["azurestorage"] diff --git a/recipes/azure-storage-cpp/all/patches/0001-cmake-fixes.patch b/recipes/azure-storage-cpp/all/patches/0001-cmake-fixes.patch deleted file mode 100644 index c775329eb84fe..0000000000000 --- a/recipes/azure-storage-cpp/all/patches/0001-cmake-fixes.patch +++ /dev/null @@ -1,72 +0,0 @@ -diff --git a/Microsoft.WindowsAzure.Storage/CMakeLists.txt b/Microsoft.WindowsAzure.Storage/CMakeLists.txt -index ac9e65d..f5988f6 100644 ---- a/Microsoft.WindowsAzure.Storage/CMakeLists.txt -+++ b/Microsoft.WindowsAzure.Storage/CMakeLists.txt -@@ -46,9 +46,9 @@ if(UNIX) - find_package(OpenSSL 1.0.0 REQUIRED) - - -- find_package(UUID REQUIRED) -- find_package(Casablanca REQUIRED) -- find_package(LibXML2 REQUIRED) -+ find_package(libuuid REQUIRED) -+ find_package(cpprestsdk REQUIRED) -+ find_package(LibXml2 REQUIRED) - - if(BUILD_TESTS) - find_package(UnitTest++ REQUIRED) -@@ -57,7 +57,7 @@ if(UNIX) - - elseif(WIN32) - message("-- Setting WIN32 options") -- find_package(Casablanca REQUIRED) -+ find_package(cpprestsdk REQUIRED) - add_definitions(-DUNICODE -D_UNICODE -D_WIN32) - else() - message("-- Unsupported Build Platform.") -@@ -85,13 +85,10 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "GNU") - - set(LD_FLAGS "${LD_FLAGS} -Wl,-z,defs") - -- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fno-strict-aliasing") -+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-strict-aliasing") - - set(STRICT_CXX_FLAGS ${WARNINGS} "-Werror -pedantic") - -- if (BUILD_SHARED_LIBS) -- add_definitions(-DBOOST_LOG_DYN_LINK) -- endif() - add_definitions(-D_TURN_OFF_PLATFORM_STRING) - elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang") - message("-- Setting clang options") -@@ -100,14 +97,11 @@ elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang") - set(OSX_SUPPRESSIONS "-Wno-overloaded-virtual -Wno-sign-conversion -Wno-deprecated -Wno-unknown-pragmas -Wno-reorder -Wno-char-subscripts -Wno-switch -Wno-unused-parameter -Wno-unused-variable -Wno-deprecated -Wno-unused-value -Wno-unknown-warning-option -Wno-return-type-c-linkage -Wno-unused-function -Wno-sign-compare -Wno-shorten-64-to-32 -Wno-reorder -Wno-unused-local-typedefs") - set(WARNINGS "${WARNINGS} ${OSX_SUPPRESSIONS}") - -- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++ -Wno-return-type-c-linkage -Wno-unneeded-internal-declaration") -+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-return-type-c-linkage -Wno-unneeded-internal-declaration") - set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++") - set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++11") - -- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fno-strict-aliasing") -- if (BUILD_SHARED_LIBS) -- add_definitions(-DBOOST_LOG_DYN_LINK) -- endif() -+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-strict-aliasing") - add_definitions(-D_TURN_OFF_PLATFORM_STRING) - elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") - message("-- Setting MSVC options") -@@ -142,11 +136,11 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/Binaries) - set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/Binaries) - - set(AZURESTORAGE_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/includes) --set(AZURESTORAGE_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/includes ${CASABLANCA_INCLUDE_DIR} ${Boost_INCLUDE_DIRS} ${OPENSSL_INCLUDE_DIRS} ${UUID_INCLUDE_DIRS} ${LibXML2_INCLUDE_DIR}) -+set(AZURESTORAGE_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/includes ${cpprestsdk_INCLUDE_DIR} ${Boost_INCLUDE_DIRS} ${OpenSSL_INCLUDE_DIRS} ${libuuid_INCLUDE_DIRS} ${LibXml2_INCLUDE_DIR}) - - - set(AZURESTORAGE_LIBRARY azurestorage) --set(AZURESTORAGE_LIBRARIES ${AZURESTORAGE_LIBRARY} ${CASABLANCA_LIBRARY} ${Boost_LIBRARIES} ${Boost_FRAMEWORK} ${OPENSSL_LIBRARIES} ${UUID_LIBRARIES} ${LibXML2_LIBRARY} ${CMAKE_THREAD_LIBS_INIT}) -+set(AZURESTORAGE_LIBRARIES ${AZURESTORAGE_LIBRARY} ${cpprestsdk_LIBRARIES} ${Boost_LIBRARIES} ${OpenSSL_LIBRARIES} ${libuuid_LIBRARIES} ${LibXml2_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) - - # Set version numbers centralized - set (AZURESTORAGE_VERSION_MAJOR 7) diff --git a/recipes/azure-storage-cpp/all/patches/fix-cpp17-incompatibility.patch b/recipes/azure-storage-cpp/all/patches/fix-cpp17-incompatibility.patch new file mode 100644 index 0000000000000..23af9f8243be8 --- /dev/null +++ b/recipes/azure-storage-cpp/all/patches/fix-cpp17-incompatibility.patch @@ -0,0 +1,51 @@ +From b81d6349d3f6c05741978bab9b07372150c85137 Mon Sep 17 00:00:00 2001 +From: Adam Mensel +Date: Mon, 31 Aug 2020 19:44:24 -0600 +Subject: [PATCH 1/2] Use lambdas instead of std::fun_ptr, to get free C++17 + compatibility. + +--- + Microsoft.WindowsAzure.Storage/src/util.cpp | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/Microsoft.WindowsAzure.Storage/src/util.cpp b/Microsoft.WindowsAzure.Storage/src/util.cpp +index cf0a3116..2d0d540c 100644 +--- a/Microsoft.WindowsAzure.Storage/src/util.cpp ++++ b/Microsoft.WindowsAzure.Storage/src/util.cpp +@@ -334,8 +334,8 @@ namespace azure { namespace storage { namespace core { + + utility::string_t str_trim_starting_trailing_whitespaces(const utility::string_t& str) + { +- auto non_space_begin = std::find_if(str.begin(), str.end(), std::not1(std::ptr_fun(isspace))); +- auto non_space_end = std::find_if(str.rbegin(), str.rend(), std::not1(std::ptr_fun(isspace))).base(); ++ auto non_space_begin = std::find_if(str.begin(), str.end(), [](char c) { return !std::isspace(c); }); ++ auto non_space_end = std::find_if(str.rbegin(), str.rend(), [](char c) { return !std::isspace(c); }).base(); + return utility::string_t(non_space_begin, non_space_end); + } + + +From b71db982b9f7065494c950c558f7e30b89026a89 Mon Sep 17 00:00:00 2001 +From: Adam Mensel +Date: Mon, 31 Aug 2020 23:02:29 -0600 +Subject: [PATCH 2/2] Keep the exact same logic as before, but still using a + lambda instead of std::fun_ptr. + +--- + Microsoft.WindowsAzure.Storage/src/util.cpp | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/Microsoft.WindowsAzure.Storage/src/util.cpp b/Microsoft.WindowsAzure.Storage/src/util.cpp +index 2d0d540c..c2a3d7d4 100644 +--- a/Microsoft.WindowsAzure.Storage/src/util.cpp ++++ b/Microsoft.WindowsAzure.Storage/src/util.cpp +@@ -334,8 +334,8 @@ namespace azure { namespace storage { namespace core { + + utility::string_t str_trim_starting_trailing_whitespaces(const utility::string_t& str) + { +- auto non_space_begin = std::find_if(str.begin(), str.end(), [](char c) { return !std::isspace(c); }); +- auto non_space_end = std::find_if(str.rbegin(), str.rend(), [](char c) { return !std::isspace(c); }).base(); ++ auto non_space_begin = std::find_if(str.begin(), str.end(), [](int c) { return !isspace(c); }); ++ auto non_space_end = std::find_if(str.rbegin(), str.rend(), [](int c) { return !isspace(c); }).base(); + return utility::string_t(non_space_begin, non_space_end); + } + diff --git a/recipes/azure-storage-cpp/all/test_package/CMakeLists.txt b/recipes/azure-storage-cpp/all/test_package/CMakeLists.txt index 1c789ba4ceba1..b3dc1a61ac7d2 100644 --- a/recipes/azure-storage-cpp/all/test_package/CMakeLists.txt +++ b/recipes/azure-storage-cpp/all/test_package/CMakeLists.txt @@ -1,12 +1,8 @@ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.15) project(PackageTest CXX) -set(CMAKE_CXX_STANDARD 11) - -include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) -conan_basic_setup() - find_package(azure-storage-cpp REQUIRED CONFIG) add_executable(example example.cpp) target_link_libraries(example azure-storage-cpp::azure-storage-cpp) +target_compile_features(example PRIVATE cxx_std_11) diff --git a/recipes/azure-storage-cpp/all/test_package/conanfile.py b/recipes/azure-storage-cpp/all/test_package/conanfile.py index 33fb4c0ecc216..8d52b7021efe1 100644 --- a/recipes/azure-storage-cpp/all/test_package/conanfile.py +++ b/recipes/azure-storage-cpp/all/test_package/conanfile.py @@ -1,11 +1,19 @@ +from conan import ConanFile +from conan.tools.build import can_run +from conan.tools.cmake import cmake_layout, CMake import os -from conans import ConanFile, CMake, tools +class TestPackageConan(ConanFile): + settings = "os", "arch", "compiler", "build_type" + generators = "CMakeDeps", "CMakeToolchain", "VirtualRunEnv" + test_type = "explicit" -class AwsSdkCppTestConan(ConanFile): - settings = "os", "compiler", "build_type", "arch" - generators = "cmake", "cmake_find_package_multi" + def requirements(self): + self.requires(self.tested_reference_str) + + def layout(self): + cmake_layout(self) def build(self): cmake = CMake(self) @@ -13,6 +21,6 @@ def build(self): cmake.build() def test(self): - if not tools.cross_building(self): - bin_path = os.path.join("bin", "example") - self.run(bin_path, run_environment=True) + if can_run(self): + bin_path = os.path.join(self.cpp.build.bindir, "example") + self.run(bin_path, env="conanrun") diff --git a/recipes/azure-storage-cpp/all/test_v1_package/CMakeLists.txt b/recipes/azure-storage-cpp/all/test_v1_package/CMakeLists.txt new file mode 100644 index 0000000000000..91630d79f4abb --- /dev/null +++ b/recipes/azure-storage-cpp/all/test_v1_package/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 3.15) +project(test_package) + +include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) +conan_basic_setup(TARGETS) + +add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../test_package/ + ${CMAKE_CURRENT_BINARY_DIR}/test_package/) diff --git a/recipes/azure-storage-cpp/all/test_v1_package/conanfile.py b/recipes/azure-storage-cpp/all/test_v1_package/conanfile.py new file mode 100644 index 0000000000000..33fb4c0ecc216 --- /dev/null +++ b/recipes/azure-storage-cpp/all/test_v1_package/conanfile.py @@ -0,0 +1,18 @@ +import os + +from conans import ConanFile, CMake, tools + + +class AwsSdkCppTestConan(ConanFile): + settings = "os", "compiler", "build_type", "arch" + 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", "example") + self.run(bin_path, run_environment=True)