Comments (9)
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.
@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.
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.
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.
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.
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.
@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.
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.
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)
- [question] Invalid: 'settings.compiler.runtime' value not defined HOT 21
- Different formatting of msvc runtime value conan_provider.cmake
- Installing only certain packages HOT 8
- [develop2] Question: How stable is the current state HOT 2
- tools.build:compiler_executables breaks build with Autotools and Xcode HOT 3
- [develop2] detect_compiler() detects invalid 'settings.compiler.version' for apple-clang
- [develop2] Can conan_provider.cmake work with add_subdirectory HOT 6
- find_program working when building from command line, but not when using the CLion Conan plugin HOT 11
- [bug] generated settings.yml missing Macos.version "14.2", causes build failures HOT 10
- [develop2, BUG] Unknown arguments specified in conan_provider.cmake:519 HOT 2
- Unable to cross compile openssl/3.x.x on develop2 HOT 6
- Using "build-scripts" package via tool_requires() not working HOT 2
- [develop2] CMAKE_CONFIGURATION_TYPES with custom build types not getting dependencies added properly HOT 3
- ERROR: Invalid setting '6' is not a valid 'settings.compiler.version' value HOT 2
- 【conan install】conan_provider.cmake downloads packages from source because detect_host_profile generates compiler.cppstd=xx in the cmake-build-release/conan_host_profile file with the detect_host_profile method HOT 5
- cmake bootstrapping fails if not on PATH HOT 3
- Not working with conan editable mode HOT 5
- Update readme with more details HOT 1
- MSVC version update HOT 6
- [question] Using layout and -of together Conan 2 HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from cmake-conan.