Skip to content

Commit

Permalink
update conan new modern templates (#9516)
Browse files Browse the repository at this point in the history
* update conan new modern templates

* use CMake.install()

* fix broken test
  • Loading branch information
memsharded committed Sep 1, 2021
1 parent aae78ea commit 313552e
Show file tree
Hide file tree
Showing 10 changed files with 223 additions and 43 deletions.
208 changes: 185 additions & 23 deletions conans/assets/templates/new_v2_cmake.py
@@ -1,5 +1,6 @@
conanfile_sources_v2 = """from conans import ConanFile
from conan.tools.cmake import CMakeToolchain, CMake
from conan.tools.layout import cmake_layout
class {package_name}Conan(ConanFile):
Expand All @@ -26,9 +27,7 @@ def config_options(self):
del self.options.fPIC
def layout(self):
self.folders.source = "src"
self.folders.build = "build/{{}}".format(self.settings.build_type)
self.folders.generators = "build/generators"
cmake_layout(self)
def generate(self):
tc = CMakeToolchain(self)
Expand All @@ -40,12 +39,8 @@ def build(self):
cmake.build()
def package(self):
self.copy("*.h", dst="include")
self.copy("*.lib", dst="lib", keep_path=False)
self.copy("*.dll", dst="bin", keep_path=False)
self.copy("*.dylib*", dst="lib", keep_path=False)
self.copy("*.so", dst="lib", keep_path=False)
self.copy("*.a", dst="lib", keep_path=False)
cmake = CMake(self)
cmake.install()
def package_info(self):
self.cpp_info.libs = ["{name}"]
Expand All @@ -56,10 +51,13 @@ def package_info(self):
from conans import ConanFile, tools
from conan.tools.cmake import CMake
from conan.tools.layout import cmake_layout
class {package_name}TestConan(ConanFile):
settings = "os", "compiler", "build_type", "arch"
# VirtualBuildEnv and VirtualRunEnv can be avoided if "tools.env.virtualenv:auto_use" is defined
# (it will be defined in Conan 2.0)
generators = "CMakeDeps", "CMakeToolchain", "VirtualBuildEnv", "VirtualRunEnv"
apply_env = False
Expand All @@ -68,22 +66,19 @@ def build(self):
cmake.configure()
cmake.build()
def layout(self):
cmake_layout(self)
def test(self):
if not tools.cross_building(self):
self.run(os.path.sep.join([".", "bin", "example"]), env="conanrunenv")
cmd = os.path.join(self.cpp.build.bindirs[0], "example")
self.run(cmd, env="conanrunenv")
"""


test_cmake_v2 = """cmake_minimum_required(VERSION 3.15)
project(PackageTest CXX)
# TODO: Remove this when layouts are available
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${{CMAKE_CURRENT_BINARY_DIR}}/bin)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${{CMAKE_RUNTIME_OUTPUT_DIRECTORY}})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO ${{CMAKE_RUNTIME_OUTPUT_DIRECTORY}})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL ${{CMAKE_RUNTIME_OUTPUT_DIRECTORY}})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${{CMAKE_RUNTIME_OUTPUT_DIRECTORY}})
find_package({name} CONFIG REQUIRED)
add_executable(example example.cpp)
Expand All @@ -95,6 +90,14 @@ def test(self):
project({name} CXX)
add_library({name} {name}.cpp)
set_target_properties({name} PROPERTIES PUBLIC_HEADER "{name}.h")
install(TARGETS {name} DESTINATION "."
PUBLIC_HEADER DESTINATION include
RUNTIME DESTINATION bin
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
)
"""


Expand All @@ -110,14 +113,91 @@ def test(self):
"""


source_cpp = """#include <iostream>
source_cpp = r"""#include <iostream>
#include "{name}.h"
void {name}(){{
#ifdef NDEBUG
std::cout << "{name}/{version}: Hello World Release!" <<std::endl;
std::cout << "{name}/{version}: Hello World Release!\n";
#else
std::cout << "{name}/{version}: Hello World Debug!" <<std::endl;
std::cout << "{name}/{version}: Hello World Debug!\n";
#endif
// ARCHITECTURES
#ifdef _M_X64
std::cout << " {name}/{version}: _M_X64 defined\n";
#endif
#ifdef _M_IX86
std::cout << " {name}/{version}: _M_IX86 defined\n";
#endif
#if __i386__
std::cout << " {name}/{version}: __i386__ defined\n";
#endif
#if __x86_64__
std::cout << " {name}/{version}: __x86_64__ defined\n";
#endif
// Libstdc++
#if defined _GLIBCXX_USE_CXX11_ABI
std::cout << " {name}/{version}: _GLIBCXX_USE_CXX11_ABI "<< _GLIBCXX_USE_CXX11_ABI << "\n";
#endif
// COMPILER VERSIONS
#if _MSC_VER
std::cout << " {name}/{version}: _MSC_VER" << _MSC_VER<< "\n";
#endif
#if _MSVC_LANG
std::cout << " {name}/{version}: _MSVC_LANG" << _MSVC_LANG<< "\n";
#endif
#if __cplusplus
std::cout << " {name}/{version}: __cplusplus" << __cplusplus<< "\n";
#endif
#if __INTEL_COMPILER
std::cout << " {name}/{version}: __INTEL_COMPILER" << __INTEL_COMPILER<< "\n";
#endif
#if __GNUC__
std::cout << " {name}/{version}: __GNUC__" << __GNUC__<< "\n";
#endif
#if __GNUC_MINOR__
std::cout << " {name}/{version}: __GNUC_MINOR__" << __GNUC_MINOR__<< "\n";
#endif
#if __clang_major__
std::cout << " {name}/{version}: __clang_major__" << __clang_major__<< "\n";
#endif
#if __clang_minor__
std::cout << " {name}/{version}: __clang_minor__" << __clang_minor__<< "\n";
#endif
#if __apple_build_version__
std::cout << " {name}/{version}: __apple_build_version__" << __apple_build_version__<< "\n";
#endif
// SUBSYSTEMS
#if __MSYS__
std::cout << " {name}/{version}: __MSYS__" << __MSYS__<< "\n";
#endif
#if __MINGW32__
std::cout << " {name}/{version}: __MINGW32__" << __MINGW32__<< "\n";
#endif
#if __MINGW64__
std::cout << " {name}/{version}: __MINGW64__" << __MINGW64__<< "\n";
#endif
#if __CYGWIN__
std::cout << " {name}/{version}: __CYGWIN__" << __CYGWIN__<< "\n";
#endif
}}
"""
Expand All @@ -131,7 +211,7 @@ def test(self):
"""


def get_files(name, version, package_name="Pkg"):
def get_cmake_lib_files(name, version, package_name="Pkg"):
files = {"conanfile.py": conanfile_sources_v2.format(name=name, version=version,
package_name=package_name),
"src/{}.cpp".format(name): source_cpp.format(name=name, version=version),
Expand All @@ -140,6 +220,88 @@ def get_files(name, version, package_name="Pkg"):
"test_package/conanfile.py": test_conanfile_v2.format(name=name,
version=version,
package_name=package_name),
"test_package/example.cpp": test_main.format(name=name),
"test_package/CMakeLists.txt": test_cmake_v2.format(name=name)}
"test_package/src/example.cpp": test_main.format(name=name),
"test_package/src/CMakeLists.txt": test_cmake_v2.format(name=name)}
return files


conanfile_exe = """from conans import ConanFile
from conan.tools.cmake import CMakeToolchain, CMake
from conan.tools.layout import cmake_layout
class {package_name}Conan(ConanFile):
name = "{name}"
version = "{version}"
# Optional metadata
license = "<Put the package license here>"
author = "<Put your name here> <And your email here>"
url = "<Package recipe repository url here, for issues about the package>"
description = "<Description of {package_name} here>"
topics = ("<Put some tag here>", "<here>", "<and here>")
# Binary configuration
settings = "os", "compiler", "build_type", "arch"
# Sources are located in the same place as this recipe, copy them to the recipe
exports_sources = "src/*"
def layout(self):
cmake_layout(self)
def generate(self):
tc = CMakeToolchain(self)
tc.generate()
def build(self):
cmake = CMake(self)
cmake.configure()
cmake.build()
def package(self):
cmake = CMake(self)
cmake.install()
"""

cmake_exe_v2 = """cmake_minimum_required(VERSION 3.15)
project({name} CXX)
add_executable({name} {name}.cpp main.cpp)
install(TARGETS {name} DESTINATION "."
RUNTIME DESTINATION bin
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
)
"""

test_conanfile_exe_v2 = """import os
from conans import ConanFile, tools
class {package_name}TestConan(ConanFile):
settings = "os", "compiler", "build_type", "arch"
# VirtualRunEnv can be avoided if "tools.env.virtualenv:auto_use" is defined
# (it will be defined in Conan 2.0)
generators = "VirtualRunEnv"
apply_env = False
def test(self):
if not tools.cross_building(self):
self.run("{name}", env="conanrunenv")
"""


def get_cmake_exe_files(name, version, package_name="Pkg"):
files = {"conanfile.py": conanfile_exe.format(name=name, version=version,
package_name=package_name),
"src/{}.cpp".format(name): source_cpp.format(name=name, version=version),
"src/{}.h".format(name): source_h.format(name=name, version=version),
"src/main.cpp": test_main.format(name=name),
"src/CMakeLists.txt": cmake_exe_v2.format(name=name, version=version),
"test_package/conanfile.py": test_conanfile_exe_v2.format(name=name,
version=version,
package_name=package_name)
}
return files
9 changes: 6 additions & 3 deletions conans/client/cmd/new.py
Expand Up @@ -387,9 +387,12 @@ def cmd_new(ref, header=False, pure_c=False, test=False, exports_sources=False,
package_name=package_name,
defines=defines)
files = {"conanfile.py": replaced}
elif template == "v2_cmake":
from conans.assets.templates.new_v2_cmake import get_files
files = get_files(name, version, package_name)
elif template == "cmake_lib":
from conans.assets.templates.new_v2_cmake import get_cmake_lib_files
files = get_cmake_lib_files(name, version, package_name)
elif template == "cmake_exe":
from conans.assets.templates.new_v2_cmake import get_cmake_exe_files
files = get_cmake_exe_files(name, version, package_name)
else:
if not os.path.isabs(template):
template = os.path.join(cache.cache_folder, "templates", "command/new", template)
Expand Down
2 changes: 1 addition & 1 deletion conans/test/functional/command/test_command_test.py
Expand Up @@ -12,7 +12,7 @@ class ConanTestTest(unittest.TestCase):
@pytest.mark.tool_cmake
def test_conan_test(self):
client = TestClient()
client.run("new hello/0.1 -m=v2_cmake")
client.run("new hello/0.1 -m=cmake_lib")

client.run("create . lasote/stable -tf=None")
time.sleep(1) # Try to avoid windows errors in CI (Cannot change permissions)
Expand Down
Expand Up @@ -23,7 +23,7 @@ def test_m1(op_system):

client = TestClient(path_with_spaces=False)
client.save({"m1": profile}, clean_first=True)
client.run("new hello/0.1 --template=v2_cmake")
client.run("new hello/0.1 --template=cmake_lib")
client.run("create . --profile:build=default --profile:host=m1 -tf None")

main = gen_function_cpp(name="main", includes=["hello"], calls=["hello"])
Expand Down
23 changes: 19 additions & 4 deletions conans/test/functional/toolchains/cmake/test_v2_cmake_template.py
@@ -1,16 +1,31 @@
from conans.test.utils.tools import TestClient


def test_v2_cmake_template():
def test_cmake_lib_template():
client = TestClient(path_with_spaces=False)
client.run("new hello/0.1 --template=v2_cmake")
client.run("new hello/0.1 --template=cmake_lib")
# Local flow works
client.run("install . -if=install")
client.run("build . -if=install")

# Create works
client.run("create .")
assert "Hello World Release!" in client.out
assert "hello/0.1: Hello World Release!" in client.out

client.run("create . -s build_type=Debug")
assert "Hello World Debug!" in client.out
assert "hello/0.1: Hello World Debug!" in client.out


def test_cmake_exe_template():
client = TestClient(path_with_spaces=False)
client.run("new greet/0.1 --template=cmake_exe")
# Local flow works
client.run("install . -if=install")
client.run("build . -if=install")

# Create works
client.run("create .")
assert "greet/0.1: Hello World Release!" in client.out

client.run("create . -s build_type=Debug")
assert "greet/0.1: Hello World Debug!" in client.out
2 changes: 1 addition & 1 deletion conans/test/functional/toolchains/env/test_complete.py
Expand Up @@ -67,7 +67,7 @@ def build(self):

def test_complete():
client = TestClient()
client.run("new myopenssl/1.0 -m=v2_cmake")
client.run("new myopenssl/1.0 -m=cmake_lib")
client.run("create . -o myopenssl:shared=True")
client.run("create . -o myopenssl:shared=True -s build_type=Debug")

Expand Down
4 changes: 2 additions & 2 deletions conans/test/functional/toolchains/gnu/autotools/test_basic.py
Expand Up @@ -18,7 +18,7 @@
@pytest.mark.tool_autotools()
def test_autotools():
client = TestClient(path_with_spaces=False)
client.run("new hello/0.1 --template=v2_cmake")
client.run("new hello/0.1 --template=cmake_lib")
client.run("create .")

main = gen_function_cpp(name="main", includes=["hello"], calls=["hello"])
Expand Down Expand Up @@ -62,7 +62,7 @@ def build_windows_subsystem(profile, make_program):
"""
# FIXME: cygwin in CI (my local machine works) seems broken for path with spaces
client = TestClient(path_with_spaces=False)
client.run("new hello/0.1 --template=v2_cmake")
client.run("new hello/0.1 --template=cmake_lib")
# TODO: Test Windows subsystems in CMake, at least msys is broken
os.rename(os.path.join(client.current_folder, "test_package"),
os.path.join(client.current_folder, "test_package2"))
Expand Down
Expand Up @@ -35,7 +35,7 @@ def test_ios():

client = TestClient(path_with_spaces=False)
client.save({"m1": profile}, clean_first=True)
client.run("new hello/0.1 --template=v2_cmake")
client.run("new hello/0.1 --template=cmake_lib")
client.run("create . --profile:build=default --profile:host=m1 -tf None")

main = gen_function_cpp(name="main", includes=["hello"], calls=["hello"])
Expand Down
Expand Up @@ -460,7 +460,7 @@ def check_toolchain_win(self, compiler, version, runtime, cppstd):
# Build the profile according to the settings provided
settings = " ".join('-s %s="%s"' % (k, v) for k, v in settings if v)

client.run("new hello/0.1 -m=v2_cmake")
client.run("new hello/0.1 -m=cmake_lib")
client.run("create . hello/0.1@ %s" % (settings, ))

# Prepare the actual consumer package
Expand Down

0 comments on commit 313552e

Please sign in to comment.