AcademySoftwareFoundation / rez

An integrated package configuration, build and deployment system for software
https://rez.readthedocs.io
Apache License 2.0
937 stars 331 forks source link

How are people building and releasing packages on Windows? #431

Open KelSolaar opened 7 years ago

KelSolaar commented 7 years ago

Hi,

Given #348, and other related issues, I wanted to know if there is a canonical way to build and release packages on Windows. I have been creating a lot of them manually but I would like to proof the system and reach a point where I can build and release them using rez-build and rez-release.

Cheers,

Thomas

instinct-vfx commented 7 years ago

My current setup for things require builds is using bez and calling cmake from there. This also gives me a bit more flexibility for things that need to go into the call of cmake itself (e.g. platform target and alike).

I always wanted to go in there and look into doing proper cmake support on windows including required support for platform target overrides and other things, just never really found the time. Willing to join forces though if other people are interested.

KelSolaar commented 7 years ago

@instinct-vfx : Thanks, that is quite useful, I have just given a spin at bez with the hello_world example. I have it semi working, I will need to massage the rezbuild.py file. Which VCS are you using, git?

instinct-vfx commented 7 years ago

Yes we are using git. This is on of our (slightly stripped) rezbuild.py files:

def build(source_path, build_path, install_path, targets):
    # Generate visual studio project files
    subprocess.call(["cmake", "-G", "Visual Studio 14 2015 Win64", "-T", "v100", ".."], cwd=os.path.join(source_path, "build_cmake"))

    ## Build solution and install into source_dir   
    subprocess.call(["cmake", "--build", ".", "--config", "Release"],
        cwd=os.path.join(source_path, "build_cmake"))    

    if "install" not in (targets or []):
        return

    # Copy files to repository when installing
    shutil.copytree(os.path.join(source_path, "bootstrap"), os.path.join(install_path, "bootstrap"))
    shutil.copytree(os.path.join(source_path, "plugins", "Release"), os.path.join(install_path, "plugins"))
KelSolaar commented 7 years ago

Thanks!

How do you pick which compiler to use (x86, x64, etc...)? I made cmake and vs_buildtools packages and I can pick the compiler doing something like that: rez-env cmake vs_buildtools -- vcvars64.bat.

That being said even though cmake finds cl once invoked manually there is still the issue as per #348 where cl is not found when invoking rez-build.

KelSolaar commented 7 years ago

I will double check tomorrow but it seems like cmake actually manages to find the compiler this way.

instinct-vfx commented 7 years ago

Yes it should. At least it does for me. I have a setup with "dummy" packages for different MSVC versions that can be used to actually build different variants for different tool chains (an example use case would be python extensions that need to be build using different compilers for different host applications (e.g. Nuke/Max/Standard python).

KelSolaar commented 7 years ago

Confirming that it does, not really sure why but it works. In the light of that answer from @nerdvegas, I might actually drop bez: https://groups.google.com/forum/#!topic/rez-config/qyj0EG-hMYQ

instinct-vfx commented 7 years ago

I will also look into that. Working (as in also on windows) integration with cmake would also be nice though. I MAY be in the position to assign a bit of our resources to rez in a month or two. Might be on the list.

KelSolaar commented 7 years ago

I'm considering using fabric in package.build_command to replace bez. I have used it in the past to provision Vagrant VMs and it might a good fit for that type of tasks.

nerdvegas commented 7 years ago

RE fabric: It's been the plan for ages to add remote host builds to rez directly, and in fact fabric was on the cards as a way of doing that. But I couldn't say when that feature would be available.

RE bez: Here is some helpful code to turn your existing rezbuild.py files into a custom build_command:

  1. Add to your package.py:

build_command = "python {root}/rezbuild.py {install}"

  1. In your existing rezbuild.py, add the following code:

if name == 'main': build(source_path=os.environ['REZ_BUILD_SOURCE_PATH'], build_path=os.environ['REZ_BUILD_PATH'], install_path=os.environ['REZ_BUILD_INSTALL_PATH'], targets=sys.argv[1:])

That's all it should take! A

On Fri, Jun 2, 2017 at 8:07 AM, Thomas Mansencal notifications@github.com wrote:

I'm considering using fabric http://www.fabfile.org/ in package.build_command to replace bez. I have used it in the past to provision Vagrant VMs and it might a good fit for that type of tasks.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/nerdvegas/rez/issues/431#issuecomment-305634450, or mute the thread https://github.com/notifications/unsubscribe-auth/ABjqSrDFgmV5EDV81mfeHPk6H4d-QAQoks5r_zY6gaJpZM4Npzo4 .

KelSolaar commented 7 years ago

It looks like that {install} does not get expanded, neither by rez-build or rez-release, {root} is fine though. I'm on latest Rez release.

KelSolaar commented 7 years ago

Which is consistent with what this line does :)

https://github.com/nerdvegas/rez/blob/master/src/rezplugins/build_system/custom.py#L115

KelSolaar commented 7 years ago

So with the tiny above patch, I can run fabric fine. Here is a minimalist example:

in package.py:

build_command = (
    'fab build_package '
    '--set=package_name={0},'
    'package_source_path={{root}},'
    'package_build_path={{root}}/build,'
    'package_install_path={{install}}'.format(name))

and in fabfile.py:

# -*- coding: utf-8 -*-

import os
from fabric.api import lcd, env, local
from fabric.operations import put

from **** import copy_paths

PACKAGE_NAME = env['package_name']

SOURCE_DIRECTORY = env['package_source_path']
BUILD_DIRECTORY = env['package_build_path']
INSTALL_DIRECTORY = env['package_install_path']

DOCUMENTATION_DIRECTORY = os.path.join(
    BUILD_DIRECTORY, PACKAGE_NAME, 'utilities')

def build_package():
    copy_paths(
        [PACKAGE_NAME],
        SOURCE_DIRECTORY,
        BUILD_DIRECTORY,
        remove_existing=True)
    build_documentation()
    install_package()

def build_documentation():
    with lcd(DOCUMENTATION_DIRECTORY):
        local('bash ./build_sphinx_documentation.sh -ram')

def install_package():
    if not INSTALL_DIRECTORY:
        return

    copy_paths(
        [PACKAGE_NAME],
        BUILD_DIRECTORY,
        INSTALL_DIRECTORY,
        remove_existing=True)