GithubHelp home page GithubHelp logo

cmrc's People

Contributors

claudiofantacci avatar danblae avatar drdanz avatar jorgen avatar marcizhu avatar moritz-h avatar pospelove avatar quacke-rsa avatar richardhozak avatar thomasgt avatar vector-of-bool avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cmrc's Issues

Specify include directories as system includes

When using strict compiler warnings with clang, the header cmrc.hpp emits conversion warnings.
When building a project using cmrc, such a warning should not appear to the user, so I woud propose to specify the include directory as a system include to silence warnings:

target_include_directories(cmrc-base SYSTEM INTERFACE $<BUILD_INTERFACE:${CMRC_INCLUDE_DIR}>)

Failing to compile with GLSL shaders

Hi!

I am currently trying to use this tool to compile shader into our shared library, but I get the following error during compile:

make[3]: *** No rule to make target '../src/shaders/debug_fragment.glsl', needed by '__cmrc_foo-shaders/intermediate/debug_fragment.glsl.cpp'. Stop.

I am using the following function to include the files:
cmrc_add_resource_library(foo-shaders ALIAS shaders::rc NAMESPACE shaders WHENCE src/shaders ...)

How do I embed my file into an executable and how do I retrieve my resources from it?

Hi, I hope you are doing well.

What I don't understand is how it's possible to embed arbitrary files into my executable. Would you mind explaining that to me? Of course I followed the exact method that was in the README.md file. However, the size of my executable didn't change no matter how large my resources were.

There is my project structure:

-CMakeLists.txt
-CMakeRC.cmake
-resources/
Photo.jpg

My configuration for CMake:

cmake_minimum_required(VERSION 3.10)


project(AddResource)#========== Global Configurations 
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_VERBOSE_MAKEFILE ON)set(CMAKE_CXX_EXTENSIONS OFF)
include(CMakeRC.cmake)



cmrc_add_resource_library(    app1-resources
ALIAS app1::rc    NAMESPACE app1    resources/archive.zip    resources/photo.jpg )
add_executable(MyExe code.cpp)
target_link_libraries(MyExe app1::rc)

My code is:

#include <stdio.h>
#include <cmrc/cmrc.hpp>

CMRC_DECLARE(app1);

int main()

{

    getchar();

    return 0;

}

clangd-lsp does not recognize header files

First of all, to use Clangd's LSP feature, I set set(CMAKE_EXPORT_COMPILE_COMMANDS ON) in CMakeLists.txt. This makes the compile commands to be written to the compile_commands.json file, which helps the language server understand the project structure.

However, using cmrc_add_resource_library() in CMakeLists.txt causes some header files to not recognize other header files. For example, the project structure is as follows

│  CMakeLists.txt
│  CMakeRC.cmake
├─build
├─include1
│      header1.h
├─include2
│      header2.h
├─resources
│      kitty.png
└─src
        main.cpp

in this case, if header1.h imports header2.h, LSP says it could not find the file. (However, it will compile and build normally!)

std::string_view API on file

Please provide one.

My current workaround is: std::string_view data(file.begin(), file.end() - file.begin());

Adding ouputs of other targets as the inputs to a resource libary target

Right now it seems that cmrc only supports adding files from the sourcetree.
I have an application where I have to add some build outputs to the resource library, but there seems to be a configure time check for the existence of the file. The actual conversion of the file is performed at build time, so I can ensure that the target generating the file is executed before and the file is present.

As a workaround I've added a file(TOUCH ...) command before the cmrc calls. This works but looks a bit funny.

Is there a better way to do this right now? Is it a valid usecase?
Possible improvements to cmrc in this regard:

  • remove the check (probably not good for the majority of users)
  • move the check to build-time
  • add a flag to skip the test
  • add a new command variant which accepts a target as a dependency and does not perform the test for build artifacts.

I'd be happy to contribute a PR but I wanted to make sure that this isn't already supported or going into the wrong direction.

My usecase is to compile a webasembly client in a cmake ExternalProject_add call and then add the .wasm/.html files as resources to the server component which will serve them next to the api endpoint.

linking cmrc with a shared library

Linker error when I try to link with cmrc generated library with a SHARED library.

/usr/bin/ld: thelibx-resources.a(lib.cpp.o): relocation R_X86_64_PC32 against symbol `_ZN4cmrc6detail9directoryD1Ev' can not be used when making a shared object; recompile with -fPIC

I want the shared library to be statically linked with the cmrc_add_resource_library generated target thelibx-resources.

add_library(thelibx SHARED ${THE_LIBX_SOURCES})
target_link_libraries(thelibx ${Boost_PROGRAM_OPTIONS_LIBRARY} thelibx-resources)

If I remove that SHARED then everything works fine.

#include <cmrc/cmrc.hpp> never finds the include file

CMakeLists.txt:

include(CMakeRC.cmake)

cmrc_add_resource_library(my_files data/foo.bin)

add_executable(
    MyApp
    main.cpp
)
target_link_libraries(
    MyApp
    PRIVATE
    my_files 
    ...
)

However for some reason #include <cmrc/cmrc.hpp> always says the include file cannot be found. When I look at the compiler command, I don't see the include path anywhere (there's no -I<...>/cmrc anywhere).

Any idea what might be going on?

CMake version 3.23.

Can you provide an install target on top level CMakelists.txt

Hello and well done on your excellent and hard work. I find this cmake module very usefull and I want to install it system-wide on my Gentoo with an ebuild. Perphaps pimp the ebuild into the Portage tree.

But the ebuild failed in install phase with this:

OUTPUT(tests/whence elf64-x86-64)
/usr/lib/gcc/x86_64-pc-linux-gnu/10.1.0/../../../../x86_64-pc-linux-gnu/bin/ld: total time in link: 0.143828
>>> Source compiled.
>>> Test phase [not enabled]: dev-cpp/cmrc-2.0.1

>>> Install dev-cpp/cmrc-2.0.1 into /mnt/Volume_3/Gentoo/temp/portage/dev-cpp/cmrc-2.0.1/image
>>> Working in BUILD_DIR: "/mnt/Volume_3/Gentoo/temp/portage/dev-cpp/cmrc-2.0.1/work/cmrc-2.0.1_build"
ninja: error: unknown target 'install'
 * ERROR: dev-cpp/cmrc-2.0.1::testing failed (install phase):
 *   died running ninja install
 * 
 * Call stack:
 *     ebuild.sh, line  125:  Called src_install
 *   environment, line 2183:  Called cmake-utils_src_install
 *   environment, line  974:  Called die
 * The specific snippet of code:
 *       DESTDIR="${D}" ${CMAKE_MAKEFILE_GENERATOR} install "$@" || die "died running ${CMAKE_MAKEFILE_GENERATOR} install";
 * 

So, could you provide an install target for the module and/or the examples?
Thank you very much.

Failure to compile long strings on MSVC

Building the current repository with Visual Studio 2017 fails:

$ mkdir build
$ cd build
$ cmake "Visual Studio 15 2017 Win64" ..
$ cmake --build .

Gives:

Microsoft (R) Build Engine version 15.7.177.53362 for .NET Framework
Copyright (C) Microsoft Corporation. All rights reserved.

Build started 18/05/2018 9:02:30 AM.
Project "C:\work\cmrc\build\ALL_BUILD.vcxproj" on node 1 (default targets).
Project "C:\work\cmrc\build\ALL_BUILD.vcxproj" (1) is building "C:\work\cmrc\build\ZERO_CHECK.vcxproj" (2) on node 1 (d
efault targets).
PrepareForBuild:
  Creating directory "x64\Debug\ZERO_CHECK\".
  Creating directory "x64\Debug\ZERO_CHECK\ZERO_CHECK.tlog\".
InitializeBuildStatus:
  Creating "x64\Debug\ZERO_CHECK\ZERO_CHECK.tlog\unsuccessfulbuild" because "AlwaysCreate" was specified.
CustomBuild:
  Checking Build System
  CMake does not need to re-run because C:/work/cmrc/build/CMakeFiles/generate.stamp is up-to-date.
FinalizeBuildStatus:
  Deleting file "x64\Debug\ZERO_CHECK\ZERO_CHECK.tlog\unsuccessfulbuild".
  Touching "x64\Debug\ZERO_CHECK\ZERO_CHECK.tlog\ZERO_CHECK.lastbuildstate".
Done Building Project "C:\work\cmrc\build\ZERO_CHECK.vcxproj" (default targets).

Project "C:\work\cmrc\build\ALL_BUILD.vcxproj" (1) is building "C:\work\cmrc\build\flower.vcxproj" (3) on node 1 (defau
lt targets).
Project "C:\work\cmrc\build\flower.vcxproj" (3) is building "C:\work\cmrc\build\hello.vcxproj" (4) on node 1 (default t
argets).
PrepareForBuild:
  Creating directory "hello.dir\Debug\".
  Creating directory "C:\work\cmrc\build\Debug\".
  Creating directory "hello.dir\Debug\hello.tlog\".
InitializeBuildStatus:
  Creating "hello.dir\Debug\hello.tlog\unsuccessfulbuild" because "AlwaysCreate" was specified.
ComputeCustomBuildOutput:
  Creating directory "C:\work\cmrc\build\hello\intermediate\".
CustomBuild:
  Generating hello resource loader
  Generating intermediate file for C:/work/cmrc/hello.txt
  Generating intermediate file for C:/work/cmrc/flower.jpg
  Building Custom Rule C:/work/cmrc/CMakeLists.txt
  CMake does not need to re-run because C:/work/cmrc/build/CMakeFiles/generate.stamp is up-to-date.
ClCompile:
  C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.14.26428\bin\HostX86\x64\CL.exe /c /IC
  :\work\cmrc\build\_cmrc\include /Zi /nologo /W3 /WX- /diagnostics:classic /Od /Ob0 /D WIN32 /D _WINDOWS /D "CMAKE_INT
  DIR=\"Debug\"" /D _MBCS /Gm- /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Zc:inline /GR /Fo"hello.dir\D
  ebug\\" /Fd"hello.dir\Debug\hello.pdb" /Gd /TP /FC /errorReport:queue C:\work\cmrc\build\hello\lib.cpp C:\work\cmrc\b
  uild\hello\intermediate\hello.txt.cpp C:\work\cmrc\build\hello\intermediate\flower.jpg.cpp
  lib.cpp
  hello.txt.cpp
  flower.jpg.cpp
c:\work\cmrc\build\hello\intermediate\flower.jpg.cpp(1): error C2026: string too big, trailing characters truncated [C:
\work\cmrc\build\hello.vcxproj]
  Generating Code...
Done Building Project "C:\work\cmrc\build\hello.vcxproj" (default targets) -- FAILED.

Done Building Project "C:\work\cmrc\build\flower.vcxproj" (default targets) -- FAILED.

Done Building Project "C:\work\cmrc\build\ALL_BUILD.vcxproj" (default targets) -- FAILED.


Build FAILED.

"C:\work\cmrc\build\ALL_BUILD.vcxproj" (default target) (1) ->
"C:\work\cmrc\build\flower.vcxproj" (default target) (3) ->
"C:\work\cmrc\build\hello.vcxproj" (default target) (4) ->
(ClCompile target) ->
  c:\work\cmrc\build\hello\intermediate\flower.jpg.cpp(1): error C2026: string too big, trailing characters truncated [
C:\work\cmrc\build\hello.vcxproj]

    0 Warning(s)
    1 Error(s)

Time Elapsed 00:00:04.11

We can fix this by reverting back to an array of chars in the intermediate representation rather than using a string literal.

[Wishlist] Allow nested namespaces

On most compilers (gcc, clang) you can actually have a nested namespace. This bit me, because MSVC doesn't let you do that by default. Maybe there's a way that a nested namespace can be detected and expanded in the generated code.

To reproduce, simply try following the instructions with

cmrc_add_resource_library(foo-resources ALIAS foo::rc NAMESPACE foo::bar  ...)

And then keep going. In the generated lib.cpp file you'll see

namespace foo::bar {

....which I think is legal C++17. I'm surprised that my gcc didn't choke (it was set to C++14), but MSVC for sure didn't like it. If this can be autoexpanded to

namespace foo { namespace bar {

(and then again on the closing braces), this will work just fine.

Constexpr

Would it be possible/worthwhile to have a version of this library that provides the file data in a constexpr context instead of hiding the data in a cpp file?

This library feels dangerously close to a std::embed equivalent/workaround, and having access to some file contents from a constexpr context would be very handy.

CMP0058: Ninja requires custom command byproducts to be explicit.

Running this with the Ninja generator results in the following warning:

[cmake] CMake Warning (dev):
[cmake]   Policy CMP0058 is not set: Ninja requires custom command byproducts to be
[cmake]   explicit.  Run "cmake --help-policy CMP0058" for policy details.  Use the
[cmake]   cmake_policy command to set the policy and suppress this warning.
[cmake] 
[cmake]   This project specifies custom command DEPENDS on files in the build tree
[cmake]   that are not specified as the OUTPUT or BYPRODUCTS of any
[cmake]   add_custom_command or add_custom_target:
[cmake] 
[cmake]    _cmrc/include/cmrc/cmrc.hpp
[cmake] 
[cmake]   For compatibility with versions of CMake that did not have the BYPRODUCTS
[cmake]   option, CMake is generating phony rules for such files to convince 'ninja'
[cmake]   to build.
[cmake] 
[cmake]   Project authors should add the missing BYPRODUCTS or OUTPUT options to the
[cmake]   custom commands that produce these files.
[cmake] This warning is for project developers.  Use -Wno-dev to suppress it.

Making the cmrc-generated resource libraries install-friendly

Hi,

When using CMakeRC in a project, one has to add all of the resource libraries to the export target. Like this:

cmrc_add_resource_library(foo-resources ALIAS foo::rc NAMESPACE foo data/test.txt)
target_link_libraries(sample_project PRIVATE foo::rc)
install(TARGETS sample_project foo-resources ... EXPORT sample_projectTargets ...)

foo-resources is of course a STATIC library, but it requires the cmrc::base as an INTERFACE dependency here:

target_link_libraries(${name} PUBLIC cmrc::base)

Thus, CMake complains that cmrc-base is not in any export target. According to this, this, and this, the most simple fix would be to change that line to:

target_link_libraries(${name} PUBLIC "$<BUILD_INTERFACE:cmrc-base>")

What do you think? Is it a viable fix or it breaks something elsewhere?

MSVC doesn't compile directory, since it contains a deque of itself

Currently, directory contains a std::deque<directory> _dirs. This std::deque is instantiated with the incomplete type directory.

class directory {
    std::deque<directory> _dirs;

As far as I can tell, this isn't allowed by the standard, and MSVC rejects it.

The cppreference entry on std::deque seems to imply that it doesn't allow incomplete types, especially when juxtaposed with std::vector. It's not just cppreference, n4659 does the same:

[vector]:

An incomplete type T may be used when instantiating vector if the allocator satisfies the allocator completeness requirements. T shall be complete before any member of the resulting specialization of vector is referenced.

[deque] has no such mention.

Undefined reference to get_filesystem()

I seem to have an issue with linking a library that uses cmrc. For example I have a file called foo.cpp in my src dir which has code that calls cmrc::resource_name::filesystem(). When I build this library I have no issues but when I link this library to its respective test file I have linkage issues where there is an error of undefined reference to cmrc::resource_name::filesystem().

Call "cmrc_add_resources" in sub directory

Hi, thanks for nice work. I am having trouble with a setup like this. Use "cmrc_add_resource_library" at top level source directory and "add_subdirectory" some sub directory. Each sub directory with a "cmrc_add_resources" command for resource files in that sub directory.
CMake always complain about that it can not find source file (intermediate cpp file) at configuring (cmake) step.
CMake Error at cmake/CMakeRC.cmake:498 (add_library):
Cannot find source file:
/home/nvidia/DeepStream/release/__cmrc_vinbigdata_deepstream-resources/intermediate/rc.jpg.cpp

I'd love to here your ideas or minimal example supporting such case.

Generate `OBJECT` library instead of `STATIC`

When installing a STATIC library that includes files using cmrc_add_resource_library, it is necessary to export and install the library generated by CMakeRC as well. This shouldn't be necessary.
An option would be to generate an OBJECT library instead of a STATIC library, and to use it with target_sources and target_include_directories instead of linking it with target_link_libraries

empty resources in android project

I'm currently writing a C++ app for android and accessing assets from native code is far from trivial in Android.
On my search for alternatives I stumbled upon your resource compiler. It looks fantastic and would solve a lot of problems for me. However when I try to access resources it just returns null pointers as iterators.
Have a look at the following:
Inside CMakeLists.txt:

cmrc_add_resource_library(shaderFiles src/main/assets/shader/standard.fs src/main/assets/shader/standard.vs)

Inside C++:

CMRC_INIT(shaderFiles);
auto stdVertexShader = cmrc::open("src/main/assets/shader/standard.vs");
auto stdFragShader = cmrc::open("src/main/assets/shader/standard.fs");
LOGI("%d", stdVertexShader.end()-stdVertexShader.begin()); // prints "0"
LOGI("%d", (int)stdVertexShader.begin()); // prints "0"

The code compiles without errors and prints two zeros when executed. However the vertex shader file definitely contains data.
In order to get behind this I added the following line to the cmake script:

function(_cmrc_generate_intermediate_cpp libname symbol outfile infile)
    message(STATUS "infile: ${infile}")  # <--
    add_custom_command(

This prints "infile: /home/<...>/ProjectPath/app/src/main/assets/shader/standard.vs" (and respectively "*.fs") which are the valid paths to my files I want to include. (Tested using "cat")
The table entries in "/home/<...>/ProjectPath/app/shaderFiles/lib_.cpp" are the following:

// Table entry for src/main/assets/shader/standard.fs
table.emplace("src/main/assets/shader/standard.fs", resource{res_chars::f_be11_src_main_assets_shader_standard_fs_begin, res_chars::f_be11_src_main_assets_shader_standard_fs_end});
// Table entry for src/main/assets/shader/standard.vs
table.emplace("src/main/assets/shader/standard.vs", resource{res_chars::f_6947_src_main_assets_shader_standard_vs_begin, res_chars::f_6947_src_main_assets_shader_standard_vs_end});

So I'm using the correct keys and the script uses the correct file paths. What could have gone wrong? How can I further investigate this problem? I'm not exactly a CMake expert...

Build failed(Error C1060) with big resource files.

I have a few resource files around 155 MB.
In the building process, the following error occurred:
(I used msvc tool set.)

~~~resourceFileName.cpp(1): fatal error C1060: compiler is out of heap space

(And overloads memory and disk. My computer almost died...)

How to solve this problem?

Using CMakeRC file objects with std::istream

I am trying to pass a cmrc resource file to a function that takes a std::istream object as input. In order to do that, I create a std::streambuf object from the cmrc data, which I can then pass to std::istream. There are two issues I've encountered:

  • streambuf uses char*, whereas cmrc's begin() and end() return const char*. This isn't such a big deal, as I've found a few workarounds.
  • The real issue is that istream::seekg seeks way past the end of the data. You can see this happen in the example below, which I created from the 'simple' test. The data_size value is enormous!

Is there some way to make this work? I could probably create a string from the data and then pass it to a std:istringstream, but I am trying to avoid the copy, as my data files could be very large. This is all rather new territory for me, so I wouldn't be surprised if I just overlooked something obvious.

include <cmrc/cmrc.hpp>

#include <cstddef>
#include <iostream>
#include <streambuf>

CMRC_DECLARE(simple);

struct membuf : std::streambuf {
    membuf(char *begin, char *end) { this->setg(begin, begin, end); }
};

int main() {
    auto fs = cmrc::simple::get_filesystem();
    auto data = fs.open("hello.txt");
    // Instead of const_cast, Krzysztof Tomaszewski at The Art of Code provides 
    // a solution to use const char* with streambuf.
    // https://artofcode.wordpress.com/2010/12/12/deriving-from-stdstreambuf/
    // However, I wanted to keep things simple for this example.
    membuf data_buf(const_cast<char*>(data.begin()),
                    const_cast<char*>(data.end()));
    std::istream data_stream(&data_buf);
    data_stream.seekg(0, data_stream.end);
    size_t data_size = data_stream.tellg();
    std::cout << data_size << '\n'; // This prints 18446744073709551615 on my computer.
}

Split C++ source from CMake files

Is it possible to split the C++ source embedded in the CMake file into its own files? It would make following the project much easier.

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.