Giter Site home page Giter Site logo

Comments (9)

trivigy avatar trivigy commented on July 20, 2024 2

Here is an example of how the emsdk is later being used by a dependent package. I am compiling here protobuf to emscripten. One weird thing to note is that I have an additional conanfile.py for the actual standard protobuf. That is because of the need for the executable. Unfortunately in em-Protobuf I remove the compilation of the executable since this will compile stuff into web-assembly and cannot run on localhost. Basically I am just grabbing protoc from the standard Protobuf conanfile.

conanfile.py

from conans import ConanFile, tools, AutoToolsBuildEnvironment
from conans.tools import os_info, SystemPackageTool


class ProtobufConan(ConanFile):
    name = "em-Protobuf"
    version = "3.5.2"
    folder = "protobuf"
    url = "https://github.com/google/protobuf"
    description = "Protocol Buffers - Google's data interchange format"
    license = "https://github.com/google/protobuf/blob/master/LICENSE"
    requires = "Protobuf/3.5.2@syncaide/stable", "emsdk/1.37.35@syncaide/stable"
    settings = "os", "compiler", "build_type", "arch"
    exports_sources = ["emscripten.patch"]
    generators = "cmake"
    packages = [
        "autoconf",
        "automake",
        "libtool",
        "curl",
        "make",
        "g++",
        "unzip"
    ]

    def source(self):
        self.run("git clone https://github.com/google/protobuf.git")
        self.run("git checkout tags/v{}".format(self.version), cwd=self.folder)
        self.run("git apply ../emscripten.patch", cwd=self.folder)

    def configure(self):
        self.options["Protobuf"].bin_only = True

    def system_requirements(self):
        if os_info.is_linux:
            installer = SystemPackageTool()
            for pkg in self.packages:
                installer.install(pkg)

    def build(self):
        protoc = self.deps_cpp_info["Protobuf"].rootpath + '/bin/protoc'

        env = AutoToolsBuildEnvironment(self)
        with tools.environment_append(env.vars):
            self.run("./autogen.sh", cwd=self.folder)

            args = ['--disable-shared', '--with-protoc={}'.format(protoc)]
            self.run("emconfigure ./configure {}".format(' '.join(args)), cwd=self.folder)
            self.run("emmake make -j {}".format(tools.cpu_count()), cwd=self.folder)

    def package(self):
        self.copy("*.h", "include", "{}/src".format(self.folder))
        self.copy("*.proto", "include", "{}/src".format(self.folder))
        self.copy("*.a", "lib", "{}/src/.libs".format(self.folder), keep_path=False)

    def package_info(self):
        self.cpp_info.libs = ["protobuf", "protobuf-lite"]

from cmake-conan.

trivigy avatar trivigy commented on July 20, 2024 1

@memsharded package() is empty because emsdk comes with already compiled stuff and in effect nothing needs to be moved out of the build directory. The reason it is build and not source is because there are some minor manipulations to config files that needs to be done so by that point everything is copied to the build directory. Once it is there, some emsdk commands are ran ./emsdk {command} those actually configure variables inside of the emsdk itself so if you then move things into the package directory, those configured variables will fail. After all, they were linked to the build directory. So that leaves us with only exporting the environment variables through package_info().

No the generator cmake is not actually being used. I just forgot that stuff there. For now I am leaving this stuff here as a reference but if I find some free time on my hands I will gladly make a little "hello world". Alternatively if someone else would I am happy to answer any questions thrown my way.

from cmake-conan.

Trass3r avatar Trass3r commented on July 20, 2024 1

I think it doesn't make sense to provide something in cmake-conan for emscripten if conan itself doesn't provide so minimun tooling & docs for emscripten.

Looks like it's supported by conan now.

from cmake-conan.

jfaust-fy avatar jfaust-fy commented on July 20, 2024 1

This seems to work...

PROFILE "${CMAKE_CURRENT_SOURCE_DIR}/conan/emscripten.profile"
        ENV
            EMSDK="${EMSCRIPTEN_ROOT_PATH}/../../"
            EMSCRIPTEN="${EMSCRIPTEN_ROOT_PATH}"
            CONAN_CMAKE_TOOLCHAIN_FILE="${EMSCRIPTEN_ROOT_PATH}/cmake/Modules/Platform/Emscripten.cmake"
            PATH="$ENV{PATH}:${EMSCRIPTEN_ROOT_PATH}:${EMSCRIPTEN_ROOT_PATH}"
            CC="${EMSCRIPTEN_ROOT_PATH}/emcc"
            CXX="${EMSCRIPTEN_ROOT_PATH}/em++"
            RANLIB="${EMSCRIPTEN_ROOT_PATH}/ranlib"
            AR="${EMSCRIPTEN_ROOT_PATH}/ar"

when configuring with:

cmake -DCMAKE_TOOLCHAIN_FILE=$EMSCRIPTEN_ROOT_PATH/cmake/Modules/Platform/Emscripten.cmake

from cmake-conan.

trivigy avatar trivigy commented on July 20, 2024

p.s. I am aware of this: conan-io/conan#1565

This is more of a question with regards to the conan-cmake extension.

from cmake-conan.

memsharded avatar memsharded commented on July 20, 2024

Hi!

I think it doesn't make sense to provide something in cmake-conan for emscripten if conan itself doesn't provide so minimun tooling & docs for emscripten. As we are not experienced in emscripten, we were waiting for emscripten users contributions and feedback (cc @mikea).
What do you think? could you provide some help so conan provides some emscripten support? Of course we can adapt cmake-conan in parallel to use that. Thanks!

from cmake-conan.

trivigy avatar trivigy commented on July 20, 2024

@memsharded I actually came up with a work around that turned out to really work well for me. Basically the trick is that I let cmake load conan regularly first and execute any cmake dependencies. The dependencies themselves have to be obviously rewritten a bit to rely on the emsdk (which is also made into a conanfile.py) Once that is done, switch the toolchain configs to the emsdk (which was just downloaded and compiled by conan) and let everything else be done with the new toolchain from there.

Sorry for spamming all of the file content here. But here is my example:

CmakeLists.txt

cmake_minimum_required(VERSION 3.9.3)

if (NOT DEFINED CMAKE_TOOLCHAIN_FILE)
    set(CMAKE_TOOLCHAIN_FILE ${CMAKE_SOURCE_DIR}/cmake/toolchain.cmake)
    include(${CMAKE_SOURCE_DIR}/cmake/toolchain.cmake)
endif ()

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/")
if (NOT EXISTS "${CMAKE_BINARY_DIR}/conan.cmake")
    message(STATUS "Downloading conan.cmake from https://github.com/conan-io/cmake-conan")
    file(DOWNLOAD
        "https://raw.githubusercontent.com/conan-io/cmake-conan/v0.8/conan.cmake"
        "${CMAKE_BINARY_DIR}/conan.cmake"
        EXPECTED_MD5 58bc519cadc890b5c33235defadc1176)
endif ()
include(${CMAKE_BINARY_DIR}/conan.cmake)

project(agent VERSION 0.0.2)
conan_cmake_run(
    CONANFILE conanfile.txt
    BASIC_SETUP CMAKE_TARGETS
    BUILD missing
)

set(CMAKE_TOOLCHAIN_FILE ${CONAN_USER_EMSDK_emscripten_root}/cmake/Modules/Platform/Emscripten.cmake)
set(CMAKE_C_COMPILER "")
set(CMAKE_CXX_COMPILER "")
set(CMAKE_AR "")
set(CMAKE_RANLIB "")

include(${CONAN_USER_EMSDK_emscripten_root}/cmake/Modules/Platform/Emscripten.cmake)

set(CMAKE_CXX_FLAGS "-s WASM=1 --bind --shell-file ${CMAKE_CURRENT_SOURCE_DIR}/src/shell.html")
set(CMAKE_CXX_FLAGS_DEBUG "-s DEMANGLE_SUPPORT=1")
set(CMAKE_CXX_FLAGS_RELEASE "-O2")

set(CMAKE_EXECUTABLE_SUFFIX ".html")
file(GLOB_RECURSE SOURCE_FILES src/*.cpp)

... {more stuff comes later}

Most important is to notice a few things. The first one is that I am originally loading a toolchain.cmake that is designed for standard gcc compiler. But later, after emsdk conanfile.py was actually compiled and configured by conan, I am resetting the toolchain to the one provided by the emscripten tool. It will reset all of the variables to the right stuff. Important I am using here version 1.37.35 of emscripten. I had issues with the latest one 1.37.36 because I think something was messed up with their toolchain file.
The second important piece is that I am resetting executable_suffix to html. Without this, emsdk freaks out and cannot compile properly at the end.

/cmake/toolchain.cmake

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

conanfile.py for emsdk

from conans import ConanFile
from conans.tools import download, untargz, replace_in_file, os_info, SystemPackageTool
from pathlib import Path
import os


class EmsdkConan(ConanFile):
    name = "emsdk"
    version = "1.37.35"
    folder = "emsdk-portable"
    url = "https://github.com/kripken/emscripten"
    description = "Emscripten SDK"
    license = "https://github.com/kripken/emscripten/blob/incoming/LICENSE"
    settings = "os", "compiler", "build_type", "arch"
    generators = "cmake"

    def source(self):
        zip_name = "emsdk-portable.tar.gz"
        download("https://s3.amazonaws.com/mozilla-games/emscripten/releases/emsdk-portable.tar.gz", zip_name)
        untargz(zip_name)
        os.unlink(zip_name)

    def build(self):
        version = "latest"
        if self.version != "latest":
            version = "sdk-{}-64bit".format(self.version)

        self.run("rm -rf {}".format(str(Path.home() / ".emscripten")))
        self.run("./emsdk install {}".format(version), cwd=self.folder)
        self.run("./emsdk activate {}".format(version), cwd=self.folder)
        self.run("./emsdk construct_env", cwd=self.folder)

        replace_in_file(
            "{}/{}/emscripten/{}/cmake/Modules/Platform/Emscripten.cmake".format(self.build_folder, self.folder, self.version),
            'set(CMAKE_AR "${EMSCRIPTEN_ROOT_PATH}/emar${EMCC_SUFFIX}" CACHE FILEPATH "Emscripten ar")',
            'set(CMAKE_AR "${EMSCRIPTEN_ROOT_PATH}/emar${EMCC_SUFFIX}")'
        )

        replace_in_file(
            "{}/{}/emscripten/{}/cmake/Modules/Platform/Emscripten.cmake".format(self.build_folder, self.folder, self.version),
            'set(CMAKE_RANLIB "${EMSCRIPTEN_ROOT_PATH}/emranlib${EMCC_SUFFIX}" CACHE FILEPATH "Emscripten ranlib")',
            'set(CMAKE_RANLIB "${EMSCRIPTEN_ROOT_PATH}/emranlib${EMCC_SUFFIX}")'
        )

    def package(self):
        pass

    def system_requirements(self):
        if os_info.is_linux:
            installer = SystemPackageTool()
            for pkg in ["build-essential", "cmake", "python2.7", "nodejs", "default-jre"]:
                installer.install(pkg)

    def package_info(self):
        cwd = Path(self.package_folder)
        root = Path(*cwd.parts[:-2]) / "build" / cwd.parts[-1]
        folder = "{}/{}".format(root, self.folder)
        emscripten_folder = "{}/emscripten/{}".format(folder, self.version)

        self.user_info.emscripten_root = emscripten_folder
        self.env_info.path.append("{}".format(folder))
        self.env_info.path.append("{}/clang/e{}_64bit".format(folder, self.version))
        self.env_info.path.append("{}/node/8.9.1_64bit/bin".format(folder))
        self.env_info.path.append(emscripten_folder)
        self.env_info.emsdk = "{}".format(folder)
        self.env_info.em_config = str(Path.home() / ".emscripten")
        self.env_info.binaryen_root = "{}/clang/e{}_64bit/binarye".format(folder, self.version)
        self.env_info.emscripten = emscripten_folder

I am not really sure if I did a great job explaining how I got it to work but if someone stumbles on this because they were trying to do this, feel free to tag me and I'll give more details.

from cmake-conan.

memsharded avatar memsharded commented on July 20, 2024

Hi @trivigy

Thanks very much for providing this info. It might be useful for other people.

Let me point out some possible things to consider by users reading this:

  • Path is python 3 only (pathlib), if you are running python 2, you might need to adapt it.
  • The defined settings = "os", "compiler", .... might be redundant, maybe it is not necessary to have a different Emscripten package for different compiler combinations.
  • Is the generator cmake really being used?
  • Why package() is empty? Is it not creating a real package and intended to be always built locally?

What I'd like to learn myself is how to use emscripten with conan. So a simple "hello world" library conan package that is compiled with ems, then uploaded, then re-used in a different conan package project and how the final application is run.

from cmake-conan.

jfaust-fy avatar jfaust-fy commented on July 20, 2024

Emscripten is supported, and mostly works with with cmake-conan if you add Emscripten to the list of supported platforms in cmake.conan.

However, the main issue I'm running into is that cmake needs the toolchain specified on the command line, so we can't use the emscripten toolchain as part of [build_requires] as recommended by https://docs.conan.io/en/latest/integrations/cross_platform/emscripten.html.

Any ideas here? I guess I can use an external emscripten and setup all the env variables in conan_cmake_run...

from cmake-conan.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.