def build(self): with tools.chdir(self.ZIP_FOLDER_NAME): if not tools.OSInfo().is_windows: env_build = AutoToolsBuildEnvironment(self) if self.settings.arch == "x86" or self.settings.arch == "x86_64": env_build.flags.append('-mstackrealign') env_build.fpic = True if self.settings.os == "Macos": old_str = '-install_name $libdir/$SHAREDLIBM' new_str = '-install_name $SHAREDLIBM' tools.replace_in_file("./configure", old_str, new_str) # Zlib configure doesnt allow this parameters (in 1.2.8) env_build.configure("./", build=False, host=False, target=False) env_build.make() else: files.mkdir("_build") with tools.chdir("_build"): cmake = CMake(self) cmake.configure(build_dir=".") cmake.build(build_dir=".")
def migrate_plugins_to_hooks(client_cache): plugins_path = os.path.join(client_cache.conan_folder, "plugins") if os.path.exists(plugins_path) and not os.path.exists( client_cache.hooks_path): os.rename(plugins_path, client_cache.hooks_path) conf_path = client_cache.conan_conf_path replace_in_file(conf_path, "[plugins]", "[hooks]", strict=False)
def no_output_test(self): client = TestClient() client.run("new Test/1.0 --sources") cmakelists_path = os.path.join(client.current_folder, "src", "CMakeLists.txt") # Test output works as expected client.run("install .") # No need to do a full create, the build --configure is good client.run("build . --configure") self.assertIn("Conan: Using cmake global configuration", client.out) self.assertIn("Conan: Adjusting default RPATHs Conan policies", client.out) self.assertIn("Conan: Adjusting language standard", client.out) # Silence output replace_in_file(cmakelists_path, "conan_basic_setup()", "set(CONAN_CMAKE_SILENT_OUTPUT True)\nconan_basic_setup()", output=client.out) client.run("build . --configure") self.assertNotIn("Conan: Using cmake global configuration", client.out) self.assertNotIn("Conan: Adjusting default RPATHs Conan policies", client.out) self.assertNotIn("Conan: Adjusting language standard", client.out) # Use TARGETS replace_in_file(cmakelists_path, "conan_basic_setup()", "conan_basic_setup(TARGETS)", output=client.out) client.run("build . --configure") self.assertNotIn("Conan: Using cmake targets configuration", client.out) self.assertNotIn("Conan: Adjusting default RPATHs Conan policies", client.out) self.assertNotIn("Conan: Adjusting language standard", client.out)
def add_to_conan_file(after, add_lines, spaces_to_indent): indent = '\n' + (' ' * spaces_to_indent) replace = indent.join([after] + add_lines) replace_in_file(os.path.join(client.current_folder, "conanfile.py"), after, replace, output=client.out)
def test_transitive_multi(client): # TODO: Make a full linking example, with correct header transitivity # Save conanfile and example conanfile = textwrap.dedent(""" [requires] libb/0.1 [generators] CMakeDeps CMakeToolchain """) example_cpp = gen_function_cpp(name="main", includes=["libb", "liba"], preprocessor=["MYVARliba", "MYVARlibb"]) client.save({"conanfile.txt": conanfile, "CMakeLists.txt": gen_cmakelists(appname="example", appsources=["example.cpp"], find_package=["libb"]), "example.cpp": example_cpp}, clean_first=True) with client.chdir("build"): for bt in ("Debug", "Release"): client.run("install .. user/channel -s build_type={}".format(bt)) # Test that we are using find_dependency with the NO_MODULE option # to skip finding first possible FindBye somewhere assert "find_dependency(${_DEPENDENCY} REQUIRED NO_MODULE)" \ in client.load("libb-config.cmake") if platform.system() == "Windows": client.run_command('cmake .. -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake') client.run_command('cmake --build . --config Debug') client.run_command('cmake --build . --config Release') client.run_command('Debug\\example.exe') assert "main: Debug!" in client.out assert "MYVARliba: Debug" in client.out assert "MYVARlibb: Debug" in client.out client.run_command('Release\\example.exe') assert "main: Release!" in client.out assert "MYVARliba: Release" in client.out assert "MYVARlibb: Release" in client.out else: # The TOOLCHAIN IS MESSING WITH THE BUILD TYPE and then ignores the -D so I remove it replace_in_file(os.path.join(client.current_folder, "conan_toolchain.cmake"), "CMAKE_BUILD_TYPE", "DONT_MESS_WITH_BUILD_TYPE") for bt in ("Debug", "Release"): client.run_command('cmake .. -DCMAKE_BUILD_TYPE={} ' '-DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake'.format(bt)) client.run_command('cmake --build . --clean-first') client.run_command('./example') assert "main: {}!".format(bt) in client.out assert "MYVARliba: {}".format(bt) in client.out assert "MYVARlibb: {}".format(bt) in client.out
def prepare_for_package(the_client): the_client.save({"src/header.h": "contents"}, clean_first=True) the_client.run("new lib/1.0 -s") # don't need build method tools.replace_in_file(os.path.join(client.current_folder, "conanfile.py"), "def build", "def skip_build", output=the_client.out) the_client.run("install . --install-folder build") mkdir(os.path.join(client.current_folder, "build2"))
def build(self): shutil.move("CMakeLists.txt", f"{self.zip_folder_name}/CMakeLists.txt") with chdir(self.zip_folder_name): replace_in_file("bzip2.c", "sys\\stat.h", "sys/stat.h") os.mkdir("_build") with chdir("_build"): cmake = CMake(self) if self.options.fPIC: cmake.definitions["FPIC"] = "ON" cmake.configure(build_dir=".", source_dir="..") cmake.build(build_dir=".")
def default_including_another_profile_test(self): p1 = "include(p2)\n[env]\nA_VAR=1" p2 = "include(default)\n[env]\nA_VAR=2" self.client.client_cache.conan_config # Create the default conf self.client.client_cache.default_profile # Create default profile save(os.path.join(self.client.client_cache.profiles_path, "p1"), p1) save(os.path.join(self.client.client_cache.profiles_path, "p2"), p2) # Change default profile to p1 => p2 => default tools.replace_in_file(self.client.client_cache.conan_conf_path, "default_profile = default", "default_profile = p1") self.client.save({CONANFILE: conanfile_scope_env}) self.client.run("create . user/testing") self._assert_env_variable_printed("A_VAR", "1")
def test_cmake_toolchain_runtime_types_cmake_older_than_3_15(): client = TestClient(path_with_spaces=False) # Setting an older cmake_minimum_required in the CMakeLists fails, will link # against the default debug runtime (MDd->MSVCRTD), not against MTd->LIBCMTD client.run("new hello/0.1 --template=cmake_lib") replace_in_file(os.path.join(client.current_folder, "CMakeLists.txt"), 'cmake_minimum_required(VERSION 3.15)', 'cmake_minimum_required(VERSION 3.1)' , output=client.out) client.run("install . -s compiler.runtime=MTd -s build_type=Debug") client.run("build .") vcvars = vcvars_command(version="15", architecture="x64") lib = os.path.join(client.current_folder, "build", "Debug", "hello.lib") dumpbind_cmd = '{} && dumpbin /directives "{}"'.format(vcvars, lib) client.run_command(dumpbind_cmd) assert "LIBCMTD" in client.out
def build_local_different_folders_test(self): # Real build, needed to ensure that the generator is put in the correct place and # cmake finds it, using an install_folder different from build_folder client = TestClient() client.run("new lib/1.0") client.run("source . --source-folder src") # Patch the CMakeLists to include the generator file from a different folder install_dir = os.path.join(client.current_folder, "install_x86_64") tools.replace_in_file(os.path.join(client.current_folder, "src", "hello", "CMakeLists.txt"), "${CMAKE_BINARY_DIR}/conanbuildinfo.cmake", '"%s/conanbuildinfo.cmake"' % install_dir, output=client.out) client.run("install . --install-folder install_x86_64 -s arch=x86_64") client.run("build . --build-folder build_x86_64 --install-folder '%s' " "--source-folder src" % install_dir) self.assertTrue(os.path.exists(os.path.join(client.current_folder, "build_x86_64", "lib")))
def cpp_info_name_test(self): client = TestClient() client.run("new hello/1.0 -s") replace_in_file( os.path.join(client.current_folder, "conanfile.py"), 'self.cpp_info.libs = ["hello"]', 'self.cpp_info.libs = ["hello"]\n self.cpp_info.name = "MYHELLO"', output=client.out) client.run("create .") client.run("new hello2/1.0 -s") replace_in_file( os.path.join(client.current_folder, "conanfile.py"), 'self.cpp_info.libs = ["hello"]', 'self.cpp_info.libs = ["hello"]\n self.cpp_info.name = "MYHELLO2"', output=client.out) replace_in_file( os.path.join(client.current_folder, "conanfile.py"), 'exports_sources = "src/*"', 'exports_sources = "src/*"\n requires = "hello/1.0"', output=client.out) client.run("create .") cmakelists = """ project(consumer) cmake_minimum_required(VERSION 3.1) find_package(MYHELLO2) get_target_property(tmp MYHELLO2::MYHELLO2 INTERFACE_LINK_LIBRARIES) message("Target libs (hello2): ${tmp}") get_target_property(tmp MYHELLO::MYHELLO INTERFACE_LINK_LIBRARIES) message("Target libs (hello): ${tmp}") """ conanfile = """ from conans import ConanFile, CMake class Conan(ConanFile): requires = "hello2/1.0" generators = "cmake_find_package" def build(self): cmake = CMake(self) cmake.configure() """ client.save({"conanfile.py": conanfile, "CMakeLists.txt": cmakelists}) client.run("install .") client.run("build .") self.assertIn('Found MYHELLO2: 1.0 (found version "1.0")', client.out) self.assertIn('Found MYHELLO: 1.0 (found version "1.0")', client.out) self.assertIn( "Target libs (hello2): " "CONAN_LIB::MYHELLO2_hello;MYHELLO::MYHELLO;" "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,SHARED_LIBRARY>:>;" "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,MODULE_LIBRARY>:>;" "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:>", client.out) self.assertIn( "Target libs (hello): CONAN_LIB::MYHELLO_hello;;" "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,SHARED_LIBRARY>:>;" "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,MODULE_LIBRARY>:>;" "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:>", client.out)
def cpp_info_name_test(self): client = TestClient() client.run("new hello/1.0 -s") replace_in_file( os.path.join(client.current_folder, "conanfile.py"), 'self.cpp_info.libs = ["hello"]', 'self.cpp_info.libs = ["hello"]\n self.cpp_info.name = "MYHELLO"', output=client.out) client.run("create .") client.run("new hello2/1.0 -s") replace_in_file( os.path.join(client.current_folder, "conanfile.py"), 'self.cpp_info.libs = ["hello"]', 'self.cpp_info.libs = ["hello"]\n self.cpp_info.name = "MYHELLO2"', output=client.out) replace_in_file( os.path.join(client.current_folder, "conanfile.py"), 'exports_sources = "src/*"', 'exports_sources = "src/*"\n requires = "hello/1.0"', output=client.out) client.run("create .") cmakelists = """ project(consumer) cmake_minimum_required(VERSION 3.1) find_package(MYHELLO2) get_target_property(tmp MYHELLO2::MYHELLO2 INTERFACE_LINK_LIBRARIES) message("Target libs: ${tmp}") """ conanfile = """ from conans import ConanFile, CMake class Conan(ConanFile): settings = "build_type" requires = "hello2/1.0" generators = "cmake_find_package_multi" def build(self): cmake = CMake(self) cmake.configure() """ client.save({"conanfile.py": conanfile, "CMakeLists.txt": cmakelists}) client.run("install .") client.run("build .") self.assertIn( "Target libs: $<$<CONFIG:Release>:CONAN_LIB::MYHELLO2_hello_RELEASE;>;" "$<$<CONFIG:RelWithDebInfo>:;>;" "$<$<CONFIG:MinSizeRel>:;>;" "$<$<CONFIG:Debug>:;>;$" "<$<CONFIG:Release>:CONAN_LIB::MYHELLO_hello_RELEASE;>;" "$<$<CONFIG:RelWithDebInfo>:;>;" "$<$<CONFIG:MinSizeRel>:;>;" "$<$<CONFIG:Debug>:;>", client.out)
def complete_creation_reuse_test(self): client = TestClient(path_with_spaces=False) client.run("new myhello/1.0.0 --sources") conanfile_path = os.path.join(client.current_folder, "conanfile.py") replace_in_file(conanfile_path, "{\"shared\": [True, False]}", "{\"shared\": [True, False], \"fPIC\": [True, False]}", output=client.out) replace_in_file(conanfile_path, "{\"shared\": False}", "{\"shared\": False, \"fPIC\": True}", output=client.out) client.run("create . danimtb/testing") hellowrapper_include = """ #pragma once void hellowrapper(); """ hellowrapper_impl = """ #include "hello.h" #include "hellowrapper.h" void hellowrapper(){ hello(); } """ makefile = """ include conanbuildinfo.mak #---------------------------------------- # Make variables for a sample App #---------------------------------------- INCLUDE_DIRS = \ ./include CXX_SRCS = \ src/hellowrapper.cpp CXX_OBJ_FILES = \ hellowrapper.o STATIC_LIB_FILENAME = \ libhellowrapper.a SHARED_LIB_FILENAME = \ libhellowrapper.so CXXFLAGS += \ -fPIC #---------------------------------------- # Prepare flags from variables #---------------------------------------- CFLAGS += $(CONAN_CFLAGS) CXXFLAGS += $(CONAN_CXXFLAGS) CPPFLAGS += $(addprefix -I, $(INCLUDE_DIRS) $(CONAN_INCLUDE_DIRS)) CPPFLAGS += $(addprefix -D, $(CONAN_DEFINES)) LDFLAGS += $(addprefix -L, $(CONAN_LIB_DIRS)) LDLIBS += $(addprefix -l, $(CONAN_LIBS)) SHAREDLINKFLAGS += $(CONAN_SHAREDLINKFLAGS) #---------------------------------------- # Make Commands #---------------------------------------- COMPILE_CXX_COMMAND ?= \ g++ -c $(CPPFLAGS) $(CXXFLAGS) $< -o $@ CREATE_SHARED_LIB_COMMAND ?= \ g++ -shared $(CXX_OBJ_FILES) \ $(CXXFLAGS) $(LDFLAGS) $(LDLIBS) $(SHAREDLINKFLAGS) \ -o $(SHARED_LIB_FILENAME) CREATE_STATIC_LIB_COMMAND ?= \ ar rcs $(STATIC_LIB_FILENAME) $(CXX_OBJ_FILES) #---------------------------------------- # Make Rules #---------------------------------------- .PHONY : static shared static : $(STATIC_LIB_FILENAME) shared : $(SHARED_LIB_FILENAME) $(SHARED_LIB_FILENAME) : $(CXX_OBJ_FILES) $(CREATE_SHARED_LIB_COMMAND) $(STATIC_LIB_FILENAME) : $(CXX_OBJ_FILES) $(CREATE_STATIC_LIB_COMMAND) $(CXX_OBJ_FILES) : $(CXX_SRCS) $(COMPILE_CXX_COMMAND) """ conanfile = """ from conans import ConanFile class HelloWrapper(ConanFile): name = "hellowrapper" version = "1.0" settings = "os", "compiler", "build_type", "arch" requires = "myhello/1.0.0@danimtb/testing" generators = "make" exports_sources = "include/hellowrapper.h", "src/hellowrapper.cpp", "Makefile" options = {"shared": [True, False]} default_options = {"shared": False} def build(self): make_command = "make shared" if self.options.shared else "make static" self.run(make_command) def package(self): self.copy("*.h", dst="include", src="include") self.copy("*.so", dst="lib", keep_path=False) self.copy("*.a", dst="lib", keep_path=False) def package_info(self): self.cpp_info.libs = ["hellowrapper"] """ client.save( { "include/hellowrapper.h": hellowrapper_include, "src/hellowrapper.cpp": hellowrapper_impl, "Makefile": makefile, "conanfile.py": conanfile }, clean_first=True) client.run("create . danimtb/testing") # Test also shared client.run("create . danimtb/testing -o hellowrapper:shared=True") main = """ #include "hellowrapper.h" int main() { hellowrapper(); return 0; } """ makefile = """ include conanbuildinfo.mak #---------------------------------------- # Make variables for a sample App #---------------------------------------- CXX_SRCS = \ src/main.cpp CXX_OBJ_FILES = \ main.o EXE_FILENAME = \ main CXXFLAGS += \ -fPIC EXELINKFLAGS += \ -fPIE #---------------------------------------- # Prepare flags from variables #---------------------------------------- CFLAGS += $(CONAN_CFLAGS) CXXFLAGS += $(CONAN_CXXFLAGS) CPPFLAGS += $(addprefix -I, $(CONAN_INCLUDE_DIRS)) CPPFLAGS += $(addprefix -D, $(CONAN_DEFINES)) LDFLAGS += $(addprefix -L, $(CONAN_LIB_DIRS)) LDLIBS += $(addprefix -l, $(CONAN_LIBS)) EXELINKFLAGS += $(CONAN_EXELINKFLAGS) #---------------------------------------- # Make Commands #---------------------------------------- COMPILE_CXX_COMMAND ?= \ g++ -c $(CPPFLAGS) $(CXXFLAGS) $< -o $@ CREATE_EXE_COMMAND ?= \ g++ $(CXX_OBJ_FILES) \ $(CXXFLAGS) $(LDFLAGS) $(LDLIBS) $(EXELINKFLAGS) \ -o $(EXE_FILENAME) #---------------------------------------- # Make Rules #---------------------------------------- .PHONY : exe exe : $(EXE_FILENAME) $(EXE_FILENAME) : $(CXX_OBJ_FILES) $(CREATE_EXE_COMMAND) $(CXX_OBJ_FILES) : $(CXX_SRCS) $(COMPILE_CXX_COMMAND) """ conanfile_txt = """ [requires] hellowrapper/1.0@danimtb/testing [generators] make """ client.save( { "src/main.cpp": main, "Makefile": makefile, "conanfile.txt": conanfile_txt }, clean_first=True) client.run("install .") client.run_command("make exe") client.run_command("./main") self.assertIn("Hello World Release!", client.out) # Test it also builds with shared lib client.run("install . -o hellowrapper:shared=True") client.run_command("rm main main.o") client.run_command("make exe") client.run_command("ldd main") self.assertIn("libhellowrapper.so", client.out)
def test_complete_multi_conf_build(self): client = TestClient() def files(name, depend=None): includes = ('#include "hello%s.h"' % depend) if depend else "" calls = ('hello%s();' % depend) if depend else "" deps = ('"Hello%s/0.1@lasote/stable"' % depend) if depend else "None" return { "conanfile.py": conanfile_build.format(deps=deps, name=name), "src/hello%s.h" % name: hello_h.format(name=name), "src/hello.cpp": hello_cpp.format(name=name, includes=includes, calls=calls), "src/CMakeLists.txt": cmake_multi.format(name=name) } client.save(files("C"), path=os.path.join(client.current_folder, "C")) client.save(files("B", "C"), path=os.path.join(client.current_folder, "B")) a = files("A", "B") a["src/CMakeLists.txt"] += ("add_executable(app main.cpp)\n" "target_link_libraries(app helloA)\n") a["src/main.cpp"] = main_cpp client.save(a, path=os.path.join(client.current_folder, "A")) project = dedent(""" editables: HelloB/0.1@lasote/stable: path: B HelloC/0.1@lasote/stable: path: C HelloA/0.1@lasote/stable: path: A layout: layout workspace_generator: cmake root: HelloA/0.1@lasote/stable """) layout = dedent(""" [build_folder] build [source_folder] src [includedirs] src [libdirs] build/{{settings.build_type}} """) metacmake = dedent(""" cmake_minimum_required(VERSION 3.3) project(MyProject CXX) include(${CMAKE_BINARY_DIR}/conanworkspace.cmake) conan_workspace_subdirectories() """) client.save({ "conanws.yml": project, "layout": layout, "CMakeLists.txt": metacmake }) build = os.path.join(client.current_folder, "build") with client.chdir("build"): client.run("workspace install ../conanws.yml") client.run("workspace install ../conanws.yml -s build_type=Debug") generator = "Visual Studio 15 Win64" with client.chdir(build): client.run_command('cmake .. -G "%s" -DCMAKE_BUILD_TYPE=Release' % generator) client.run_command('cmake --build . --config Release') cmd_release = os.path.normpath("./A/build/Release/app") cmd_debug = os.path.normpath("./A/build/Debug/app") client.run_command(cmd_release) self.assertIn("Hello World C Release!", client.out) self.assertIn("Hello World B Release!", client.out) self.assertIn("Hello World A Release!", client.out) tools.replace_in_file(os.path.join(client.current_folder, "C/src/hello.cpp"), "Hello World", "Bye Moon", output=client.out) with client.chdir(build): client.run_command('cmake --build . --config Release') client.run_command(cmd_release) self.assertIn("Bye Moon C Release!", client.out) self.assertIn("Hello World B Release!", client.out) self.assertIn("Hello World A Release!", client.out) tools.replace_in_file(os.path.join(client.current_folder, "B/src/hello.cpp"), "Hello World", "Bye Moon", output=client.out) with client.chdir(build): client.run_command('cmake --build . --config Release') client.run_command(cmd_release) self.assertIn("Bye Moon C Release!", client.out) self.assertIn("Bye Moon B Release!", client.out) self.assertIn("Hello World A Release!", client.out) self.assertNotIn("Debug", client.out) client.run_command('cmake .. -G "%s" -DCMAKE_BUILD_TYPE=Debug' % generator, cwd=build) # CMake configure will find the Release libraries, as we are in cmake-multi mode # Need to reset the output after that client.run_command('cmake --build . --config Debug', cwd=build) client.run_command(cmd_debug) self.assertIn("Bye Moon C Debug!", client.out) self.assertIn("Bye Moon B Debug!", client.out) self.assertIn("Hello World A Debug!", client.out) tools.replace_in_file(os.path.join(client.current_folder, "C/src/hello.cpp"), "Bye Moon", "Hello World", output=client.out) client.run_command('cmake --build . --config Debug', cwd=build) client.run_command(cmd_debug) self.assertIn("Hello World C Debug!", client.out) self.assertIn("Bye Moon B Debug!", client.out) self.assertIn("Hello World A Debug!", client.out) self.assertNotIn("Release", client.out)
def install_profile_settings_test(self): files = cpp_hello_conan_files("Hello0", "0.1", build=False) # Create a profile and use it profile_settings = OrderedDict([("compiler", "Visual Studio"), ("compiler.version", "12"), ("compiler.runtime", "MD"), ("arch", "x86")]) create_profile(self.client.cache.profiles_path, "vs_12_86", settings=profile_settings, package_settings={}) self.client.cache.default_profile # Creates default tools.replace_in_file(self.client.cache.default_profile_path, "compiler.libcxx", "#compiler.libcxx", strict=False, output=TestBufferConanOutput()) self.client.save(files) self.client.run("export . lasote/stable") self.client.run("install . --build missing -pr vs_12_86") info = load(os.path.join(self.client.current_folder, "conaninfo.txt")) for setting, value in profile_settings.items(): self.assertIn("%s=%s" % (setting, value), info) # Try to override some settings in install command self.client.run( "install . --build missing -pr vs_12_86 -s compiler.version=14") info = load(os.path.join(self.client.current_folder, "conaninfo.txt")) for setting, value in profile_settings.items(): if setting != "compiler.version": self.assertIn("%s=%s" % (setting, value), info) else: self.assertIn("compiler.version=14", info) # Use package settings in profile tmp_settings = OrderedDict() tmp_settings["compiler"] = "gcc" tmp_settings["compiler.libcxx"] = "libstdc++11" tmp_settings["compiler.version"] = "4.8" package_settings = {"Hello0": tmp_settings} create_profile(self.client.cache.profiles_path, "vs_12_86_Hello0_gcc", settings=profile_settings, package_settings=package_settings) # Try to override some settings in install command self.client.run( "install . --build missing -pr vs_12_86_Hello0_gcc -s compiler.version=14" ) info = load(os.path.join(self.client.current_folder, "conaninfo.txt")) self.assertIn("compiler=gcc", info) self.assertIn("compiler.libcxx=libstdc++11", info) # If other package is specified compiler is not modified package_settings = {"NoExistsRecipe": tmp_settings} create_profile(self.client.cache.profiles_path, "vs_12_86_Hello0_gcc", settings=profile_settings, package_settings=package_settings) # Try to override some settings in install command self.client.run( "install . --build missing -pr vs_12_86_Hello0_gcc -s compiler.version=14" ) info = load(os.path.join(self.client.current_folder, "conaninfo.txt")) self.assertIn("compiler=Visual Studio", info) self.assertNotIn("compiler.libcxx", info) # Mix command line package settings with profile package_settings = {"Hello0": tmp_settings} create_profile(self.client.cache.profiles_path, "vs_12_86_Hello0_gcc", settings=profile_settings, package_settings=package_settings) # Try to override some settings in install command self.client.run( "install . --build missing -pr vs_12_86_Hello0_gcc" " -s compiler.version=14 -s Hello0:compiler.libcxx=libstdc++") info = load(os.path.join(self.client.current_folder, "conaninfo.txt")) self.assertIn("compiler=gcc", info) self.assertNotIn("compiler.libcxx=libstdc++11", info) self.assertIn("compiler.libcxx=libstdc++", info)
def build_vs_project_test(self): conan_build_vs = """ from conans import ConanFile, MSBuild class HelloConan(ConanFile): name = "Hello" version = "1.2.1" exports = "*" settings = "os", "build_type", "arch", "compiler", "cppstd" def build(self): msbuild = MSBuild(self) msbuild.build("MyProject.sln") def package(self): self.copy(pattern="*.exe") """ client = TestClient() # Test cpp standard stuff files = get_vs_project_files(std="cpp17_2015") files[CONANFILE] = conan_build_vs client.save(files) error = client.run( 'create . Hello/1.2.1@lasote/stable -s cppstd=11 -s ' 'compiler="Visual Studio" -s compiler.version=14', ignore_error=True) self.assertTrue(error) client.run('create . Hello/1.2.1@lasote/stable -s cppstd=17 ' '-s compiler="Visual Studio" -s compiler.version=14') self.assertIn("Copied 1 '.exe' file: MyProject.exe", client.user_io.out) files = get_vs_project_files() files[CONANFILE] = conan_build_vs # Try to not update the project client.client_cache._conan_config = None # Invalidate cached config tools.replace_in_file(client.client_cache.conan_conf_path, "[general]", "[general]\nskip_vs_projects_upgrade = True") client.save(files, clean_first=True) client.run("create . Hello/1.2.1@lasote/stable --build") self.assertNotIn("devenv", client.user_io.out) self.assertIn("Skipped sln project upgrade", client.user_io.out) # Try with x86_64 client.save(files) client.run("export . lasote/stable") client.run("install Hello/1.2.1@lasote/stable --build -s arch=x86_64") self.assertIn("Release|x64", client.user_io.out) self.assertIn("Copied 1 '.exe' file: MyProject.exe", client.user_io.out) # Try with x86 client.save(files, clean_first=True) client.run("export . lasote/stable") client.run("install Hello/1.2.1@lasote/stable --build -s arch=x86") self.assertIn("Release|x86", client.user_io.out) self.assertIn("Copied 1 '.exe' file: MyProject.exe", client.user_io.out) # Try with x86 debug client.save(files, clean_first=True) client.run("export . lasote/stable") client.run( "install Hello/1.2.1@lasote/stable --build -s arch=x86 -s build_type=Debug" ) self.assertIn("Debug|x86", client.user_io.out) self.assertIn("Copied 1 '.exe' file: MyProject.exe", client.user_io.out)
def __init__(self, base_folder=None, current_folder=None, servers=None, users=None, client_version=CLIENT_VERSION, min_server_compatible_version=MIN_SERVER_COMPATIBLE_VERSION, requester_class=None, runner=None, path_with_spaces=True, block_v2=None, revisions=None): """ storage_folder: Local storage path current_folder: Current execution folder servers: dict of {remote_name: TestServer} logins is a list of (user, password) for auto input in order if required==> [("lasote", "mypass"), ("other", "otherpass")] """ self.block_v2 = block_v2 or get_env("CONAN_API_V2_BLOCKED", True) if self.block_v2: self.revisions = False else: self.revisions = revisions or get_env( "CONAN_CLIENT_REVISIONS_ENABLED", False) self.block_v2 = False self.all_output = "" # For debugging purpose, append all the run outputs self.users = users or { "default": [(TESTING_REMOTE_PRIVATE_USER, TESTING_REMOTE_PRIVATE_PASS)] } self.client_version = Version(str(client_version)) self.min_server_compatible_version = Version( str(min_server_compatible_version)) self.base_folder = base_folder or temp_folder(path_with_spaces) # Define storage_folder, if not, it will be read from conf file & pointed to real user home self.storage_folder = os.path.join(self.base_folder, ".conan", "data") self.client_cache = ClientCache(self.base_folder, self.storage_folder, TestBufferConanOutput()) self.requester_class = requester_class self.conan_runner = runner if self.revisions: # Generate base file self.client_cache.conan_config replace_in_file(os.path.join(self.client_cache.conan_conf_path), "revisions_enabled = False", "revisions_enabled = True", strict=False) # Invalidate the cached config self.client_cache.invalidate() if servers and len(servers) > 1 and not isinstance( servers, OrderedDict): raise Exception( """Testing framework error: Servers should be an OrderedDict. e.g: servers = OrderedDict() servers["r1"] = server servers["r2"] = TestServer() """) self.servers = servers or {} if servers is not False: # Do not mess with registry remotes self.update_servers() self.init_dynamic_vars() logger.debug("Client storage = %s" % self.storage_folder) self.current_folder = current_folder or temp_folder(path_with_spaces)
def build_vs_project_test(self): conan_build_vs = """ from conans import ConanFile, MSBuild class HelloConan(ConanFile): name = "Hello" version = "1.2.1" exports = "*" settings = "os", "build_type", "arch", "compiler", "cppstd" def build(self): msbuild = MSBuild(self) msbuild.build("MyProject.sln") def package(self): self.copy(pattern="*.exe") """ client = TestClient() # Test cpp standard stuff files = get_vs_project_files(std="cpp17_2015") files[CONANFILE] = conan_build_vs client.save(files) client.run( 'create . Hello/1.2.1@lasote/stable -s cppstd=11 -s ' 'compiler="Visual Studio" -s compiler.version=14', assert_error=True) client.run('create . Hello/1.2.1@lasote/stable -s cppstd=17 ' '-s compiler="Visual Studio" -s compiler.version=14') self.assertIn("Copied 1 '.exe' file: MyProject.exe", client.user_io.out) files = get_vs_project_files() files[CONANFILE] = conan_build_vs # Try to not update the project client.client_cache._conan_config = None # Invalidate cached config tools.replace_in_file(client.client_cache.conan_conf_path, "[general]", "[general]\nskip_vs_projects_upgrade = True") client.save(files, clean_first=True) client.run("create . Hello/1.2.1@lasote/stable --build") self.assertNotIn("devenv", client.user_io.out) self.assertIn("Skipped sln project upgrade", client.user_io.out) # Try with x86_64 client.save(files) client.run("export . lasote/stable") client.run("install Hello/1.2.1@lasote/stable --build -s arch=x86_64") self.assertIn("Release|x64", client.user_io.out) self.assertIn("Copied 1 '.exe' file: MyProject.exe", client.user_io.out) # Try with x86 client.save(files, clean_first=True) client.run("export . lasote/stable") client.run("install Hello/1.2.1@lasote/stable --build -s arch=x86") self.assertIn("Release|x86", client.user_io.out) self.assertIn("Copied 1 '.exe' file: MyProject.exe", client.user_io.out) # Try with x86 debug client.save(files, clean_first=True) client.run("export . lasote/stable") client.run( "install Hello/1.2.1@lasote/stable --build -s arch=x86 -s build_type=Debug" ) self.assertIn("Debug|x86", client.user_io.out) self.assertIn("Copied 1 '.exe' file: MyProject.exe", client.user_io.out) # Try with a custom property file name files[CONANFILE] = conan_build_vs.replace( 'msbuild.build("MyProject.sln")', 'msbuild.build("MyProject.sln", ' 'property_file_name="myprops.props")') client.save(files, clean_first=True) client.run( "create . Hello/1.2.1@lasote/stable --build -s arch=x86 -s build_type=Debug" ) self.assertIn("Debug|x86", client.user_io.out) self.assertIn("Copied 1 '.exe' file: MyProject.exe", client.user_io.out) full_ref = "Hello/1.2.1@lasote/stable:b786e9ece960c3a76378ca4d5b0d0e922f4cedc1" pref = PackageReference.loads(full_ref) build_folder = client.client_cache.build(pref) self.assertTrue( os.path.exists(os.path.join(build_folder, "myprops.props")))
def install_profile_settings_test(self): files = cpp_hello_conan_files("Hello0", "0.1", build=False) # Create a profile and use it profile_settings = OrderedDict([("compiler", "Visual Studio"), ("compiler.version", "12"), ("compiler.runtime", "MD"), ("arch", "x86")]) create_profile(self.client.client_cache.profiles_path, "vs_12_86", settings=profile_settings, package_settings={}) self.client.client_cache.default_profile # Creates default tools.replace_in_file(self.client.client_cache.default_profile_path, "compiler.libcxx", "#compiler.libcxx", strict=False) self.client.save(files) self.client.run("export . lasote/stable") self.client.run("install . --build missing -pr vs_12_86") info = load(os.path.join(self.client.current_folder, "conaninfo.txt")) for setting, value in profile_settings.items(): self.assertIn("%s=%s" % (setting, value), info) # Try to override some settings in install command self.client.run("install . --build missing -pr vs_12_86 -s compiler.version=14") info = load(os.path.join(self.client.current_folder, "conaninfo.txt")) for setting, value in profile_settings.items(): if setting != "compiler.version": self.assertIn("%s=%s" % (setting, value), info) else: self.assertIn("compiler.version=14", info) # Use package settings in profile tmp_settings = OrderedDict() tmp_settings["compiler"] = "gcc" tmp_settings["compiler.libcxx"] = "libstdc++11" tmp_settings["compiler.version"] = "4.8" package_settings = {"Hello0": tmp_settings} create_profile(self.client.client_cache.profiles_path, "vs_12_86_Hello0_gcc", settings=profile_settings, package_settings=package_settings) # Try to override some settings in install command self.client.run("install . --build missing -pr vs_12_86_Hello0_gcc -s compiler.version=14") info = load(os.path.join(self.client.current_folder, "conaninfo.txt")) self.assertIn("compiler=gcc", info) self.assertIn("compiler.libcxx=libstdc++11", info) # If other package is specified compiler is not modified package_settings = {"NoExistsRecipe": tmp_settings} create_profile(self.client.client_cache.profiles_path, "vs_12_86_Hello0_gcc", settings=profile_settings, package_settings=package_settings) # Try to override some settings in install command self.client.run("install . --build missing -pr vs_12_86_Hello0_gcc -s compiler.version=14") info = load(os.path.join(self.client.current_folder, "conaninfo.txt")) self.assertIn("compiler=Visual Studio", info) self.assertNotIn("compiler.libcxx", info) # Mix command line package settings with profile package_settings = {"Hello0": tmp_settings} create_profile(self.client.client_cache.profiles_path, "vs_12_86_Hello0_gcc", settings=profile_settings, package_settings=package_settings) # Try to override some settings in install command self.client.run("install . --build missing -pr vs_12_86_Hello0_gcc" " -s compiler.version=14 -s Hello0:compiler.libcxx=libstdc++") info = load(os.path.join(self.client.current_folder, "conaninfo.txt")) self.assertIn("compiler=gcc", info) self.assertNotIn("compiler.libcxx=libstdc++11", info) self.assertIn("compiler.libcxx=libstdc++", info)
def cpp_info_filename_test(self): client = TestClient() client.run("new hello/1.0 -s") indent = '\n ' replace_in_file( os.path.join(client.current_folder, "conanfile.py"), search='self.cpp_info.libs = ["hello"]', replace=indent.join([ 'self.cpp_info.name = "MYHELLO"', 'self.cpp_info.filenames["cmake_find_package"] = "hello_1"', 'self.cpp_info.components["1"].names["cmake_find_package"] = "HELLO1"', 'self.cpp_info.components["1"].libs = [ "hello" ]' ]), output=client.out) client.run("create .") client.run("new hello2/1.0 -s") replace_in_file(os.path.join(client.current_folder, "src/CMakeLists.txt"), search='add_library(hello hello.cpp)', replace='add_library(hello2 hello.cpp)', output=client.out) replace_in_file( os.path.join(client.current_folder, "conanfile.py"), search='self.cpp_info.libs = ["hello"]', replace=indent.join([ 'self.cpp_info.name = "MYHELLO2"', 'self.cpp_info.filenames["cmake_find_package"] = "hello_2"', 'self.cpp_info.components["2"].names["cmake_find_package"] = "HELLO2"', 'self.cpp_info.components["2"].libs = [ "hello2" ]', 'self.cpp_info.components["2"].requires = [ "hello::1"]', ]), output=client.out) replace_in_file( os.path.join(client.current_folder, "conanfile.py"), search='exports_sources = "src/*"', replace='exports_sources = "src/*"\n requires = "hello/1.0"', output=client.out) client.run("create .") cmakelists = textwrap.dedent(""" set(CMAKE_CXX_COMPILER_WORKS 1) project(consumer CXX) cmake_minimum_required(VERSION 3.1) find_package(hello_2) get_target_property(tmp MYHELLO2::HELLO2 INTERFACE_LINK_LIBRARIES) message("Target libs (hello2): ${tmp}") get_target_property(tmp MYHELLO::HELLO1 INTERFACE_LINK_LIBRARIES) message("Target libs (hello): ${tmp}") """) conanfile = textwrap.dedent(""" from conans import ConanFile, CMake class Conan(ConanFile): requires = "hello2/1.0" generators = "cmake_find_package" def build(self): cmake = CMake(self) cmake.configure() """) client.save({"conanfile.py": conanfile, "CMakeLists.txt": cmakelists}) client.run("install .") client.run("build .") self.assertIn('Found hello_2: 1.0 (found version "1.0")', client.out) self.assertIn('Found hello_1: 1.0 (found version "1.0")', client.out) self.assertIn( "Target libs (hello2): " "CONAN_LIB::MYHELLO2_HELLO2_hello2;MYHELLO::HELLO1;" "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,SHARED_LIBRARY>:>;" "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,MODULE_LIBRARY>:>;" "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:>", client.out) self.assertIn( "Target libs (hello): CONAN_LIB::MYHELLO_HELLO1_hello;" "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,SHARED_LIBRARY>:>;" "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,MODULE_LIBRARY>:>;" "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:>", client.out)
def cmake_outsource_build_test(self, targets): client = TestClient() def files(name, depend=None): includes = ('#include "hello%s.h"' % depend) if depend else "" calls = ('hello%s();' % depend) if depend else "" deps = ('"Hello%s/0.1@lasote/stable"' % depend) if depend else "None" dep = "CONAN_PKG::Hello%s" % depend if depend else "" used_cmake = cmake_targets.format(dep=dep, name=name) if targets else cmake.format(name=name) return {"conanfile.py": conanfile_build.format(deps=deps, name=name), "src/hello%s.h" % name: hello_h.format(name=name), "src/hello.cpp": hello_cpp.format(name=name, includes=includes, calls=calls), "src/CMakeLists.txt": used_cmake} client.save(files("C"), path=os.path.join(client.current_folder, "C")) client.save(files("B", "C"), path=os.path.join(client.current_folder, "B")) a = files("A", "B") a["src/CMakeLists.txt"] += "add_executable(app main.cpp)\ntarget_link_libraries(app helloA)\n" a["src/main.cpp"] = main_cpp client.save(a, path=os.path.join(client.current_folder, "A")) project = """HelloB: folder: B includedirs: src cmakedir: src HelloC: folder: C includedirs: src cmakedir: src HelloA: folder: A cmakedir: src root: HelloA generator: cmake name: MyProject """ client.save({WORKSPACE_FILE: project}) client.run("install . -if=build") generator = "Visual Studio 15 Win64" if platform.system() == "Windows" else "Unix Makefiles" base_folder = os.path.join(client.current_folder, "build") client.runner('cmake .. -G "%s" -DCMAKE_BUILD_TYPE=Release' % generator, cwd=base_folder) client.runner('cmake --build . --config Release', cwd=base_folder) if platform.system() == "Windows": cmd_release = r".\build\A\Release\app" cmd_debug = r".\build\A\Debug\app" else: cmd_release = "./build/A/app" cmd_debug = "./build/A/app" client.runner(cmd_release, cwd=client.current_folder) self.assertIn("Hello World C Release!", client.out) self.assertIn("Hello World B Release!", client.out) self.assertIn("Hello World A Release!", client.out) TIME_DELAY = 1 time.sleep(TIME_DELAY) tools.replace_in_file(os.path.join(client.current_folder, "C/src/hello.cpp"), "Hello World", "Bye Moon", output=client.out) tools.replace_in_file(os.path.join(client.current_folder, "B/src/hello.cpp"), "Hello World", "Bye Moon", output=client.out) time.sleep(TIME_DELAY) client.runner('cmake --build . --config Release', cwd=base_folder) time.sleep(TIME_DELAY) client.runner(cmd_release, cwd=client.current_folder) self.assertIn("Bye Moon C Release!", client.out) self.assertIn("Bye Moon B Release!", client.out) self.assertIn("Hello World A Release!", client.out) time.sleep(TIME_DELAY) # Try to avoid windows errors in CI (The directory is not empty) shutil.rmtree(os.path.join(client.current_folder, "build")) client.run("install . -if=build -s build_type=Debug") client.runner('cmake .. -G "%s" -DCMAKE_BUILD_TYPE=Debug' % generator, cwd=base_folder) time.sleep(TIME_DELAY) client.runner('cmake --build . --config Debug', cwd=base_folder) time.sleep(TIME_DELAY) client.runner(cmd_debug, cwd=client.current_folder) self.assertIn("Bye Moon C Debug!", client.out) self.assertIn("Bye Moon B Debug!", client.out) self.assertIn("Hello World A Debug!", client.out) tools.replace_in_file(os.path.join(client.current_folder, "B/src/hello.cpp"), "Bye Moon", "Bye! Mars", output=client.out) time.sleep(TIME_DELAY) client.runner('cmake --build . --config Debug', cwd=base_folder) time.sleep(TIME_DELAY) client.runner(cmd_debug, cwd=client.current_folder) self.assertIn("Bye Moon C Debug!", client.out) self.assertIn("Bye! Mars B Debug!", client.out) self.assertIn("Hello World A Debug!", client.out)