Failing to load font in SFML - c

Problem description
I'm trying to write some text to the screen, but it feels like no matter what I do i always get:
Failed to load font "../assets/Font.ttf" (failed to create the font face)
A very simple example of the code.
#include<SFML/Graphics.hpp>
int main()
{
sf::Font font;
font.loadFromFile("../assets/Font.ttf");
sf::RenderWindow window(sf::VideoMode(800, 600), "SFML works!");
sf::Text text("Hello World", font, 50);
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
window.draw(text);
window.display();
window.clear();
}
return 0;
}
I'm building using Cmake and I expect that the problem lies in my CMakeLists files. I have one main and a sub-directory like: (Also very simple)
#Main
cmake_minimum_required(VERSION 3.0)
project(Sorting_Visualization)
add_subdirectory(src)
# Sub Directory
add_executable(${PROJECT_NAME} main.cpp)
find_package(SFML 2.5 COMPONENTS graphics audio REQUIRED)
target_link_libraries(${PROJECT_NAME} sfml-graphics sfml-audio)
File structure:
.
├── assets
│   └── Font.ttf
├── CMakeLists.txt
└── src
├── CMakeLists.txt
└── main.cpp
What I've tried
I read that similar problems occurred when people using Visual Studio linked release libs to their debug builds. There was suggested to link with ex. sfml-graphics-d for debug libs. However this doesn't seem to work for me and using dpkg libsfml-dev I don't see any files matching sfml-graphics-d. Should I maybe install these in some way?. Or is that some Visual Studio specific issue?
Further I think I was missing the Freetype dependecy at the time of installing SFML however running ldd on my sfml-graphics.so file it seem that freetype is found.
libfreetype.so.6 => /lib/x86_64-linux-gnu/libfreetype.so.6 (0x00007f26fdca0000)
Lastly I was thinking that maybe the font I'm using is simply not compatible. But surely any true type font should be possible to use. Here is a link the font.
To summarize
I think I've read nearly everything there is online and I'm still completely stumped. The only thing left is my linking in Cmake which I found no clear resources on and I'm pretty new to working with libs. Some guidence would be greatly appreciated on this : )

Solution
I solved the problem and it was apparently the order in which I was finding the packages and linking them. I also have to always make all
This is working!
set(SOURCES main.cpp)
add_executable(${PROJECT_NAME} ${SOURCES})
find_package(SFML 2.5 COMPONENTS REQUIRED audio graphics )
target_link_libraries(${PROJECT_NAME} sfml-audio sfml-graphics)

Related

How do I make my project modular with CMake?

First of all, I don't know what I should call it, module, component, or library are all fitting for me, but gave all mixed results trying to figure this out.
Problem
I am working on a project in C, where the amount of files grew quite large, so I wanted to split it up a bit, both for ordering and make it look less cluttered.
I want a file structure that looks something like this:
root
├modules
│├module_foo
││├include
│││├module_foo_a.h
││││...
│││└module_foo_z.h
││├private_include
│││├a.h
││││...
│││└z.h
││├source
│││├module_foo_a.c
││││...
│││└module_foo_z.c
││└module_foo.h
│└module_bar
│ ├include
│ │├module_bar_a.h
│ ││...
│ │└module_bar_z.h
│ ├private_include
│ │├a.h
│ ││...
│ │└z.h
│ ├source
│ │├module_bar_a.c
│ ││...
│ │└module_bar_z.c
│ └module_bar.h
├main.c
├main.h
└CMakeLists.txt
Clarification
The goal of this would be that the private_include folders would be inaccessible by other modules and main, and the different modules would need to work (fairly) independent. Modules can include other modules, but this would need to be defined explicitly.
I also would like the CMake to be easy to modify, ideally only a single/couple line(s) to change for the modules used.
Pre research
As mentioned above, I have searched already, but the CMake documentation isn't meant for the people who just want to do some C coding.
When I searched for modules, almost all results were about the C++ modules and how to integrate them into CMake.
Components mostly gave results about the COMPONENTS keyword.
Library had the most results, however it still requires me to use #include "modules/module_foo/include/module_foo_a.h" from main, or #include "../../module_bar/include/module_bar_a.h" from module foo. The goal would be to have in both instances #include "module_foo_a.h".
Subdirectory isn't what I am looking for I believe, because that still makes it part of the root project. This is not what I want.
For the modules I currently have
project(foo)
add_library(${PROJECT_NAME} STATIC source/module_foo_a.c include/module_foo_a.h)
include_directories(private_include include)
link_libraries(bar)
target_include_directories(${PROJECT_NAME} INTERFACE include)
target_link_libraries(${PROJECT_NAME} PRIVATE bar)
I have included the header files in the add_library because one source I found said it helped with IDE's.
I don't remember why I made the target_include_directories interface, or the target_link_libraries private.
For my main CMake I have
project(foobar)
include_directories(include)
add_executable(${PROJECT_NAME} source/main.c)
target_link_libraries(${PROJECT_NAME} foo bar)
I believe I need to include bar again because of the private link in the module.
I don't even know if what I am searching for is actually possible, but I would really like to work with it this way, or close to this.
edit
Before I tried to add modules the folder structure looked something like this:
root
├include
│├foo_a.h
││...
│├foo_z.h
│├bar_a.h
││...
│├bar_z.h
│└main.h
└source
├foo_a.c
│...
├foo_z.c
├bar_a.c
│...
├bar_z.c
└main.c
This got very cluttered very quickly, hence why I want to change to modules.
As stated in my comment, the part that I have put above is what I have now. This does not make the modules easy to work with, as they don't provide short include names, both from outside the modules (main) and other modules (bar).
The little bits that I understand from CMake is that the functions have a 'normal' variant and a 'target' variant.
'Normal' is just for the current project, and 'target' is meant to also allow other CMakes to use those specified files/folders. This should however not work for the private_include folders, as they are only to be known to the module itself.
If I understand it correctly, including private_include in the 'target' variant would make it possible that you would do #include "a.h" or #include "private_include/a.h" in main, which is not what I want.

Load a resource file at runtime

Suppose I have this architecture:
.
├── Cargo.lock
├── Cargo.toml
├── src/
│ ├── main.rs
├── rsc/
│ ├── file.xml
I want to load file.xml to fill some tables at each run. To do so I could write:
use std::fs::File;
use std::path::Path;
fn open<P: AsRef<Path>>(path: P) {
let _ = File::open(path).unwrap();
println!("file opened");
}
fn main() {
open("../rsc/file.xml");
}
But the relative path won't work if I don't run the program from src.
I could do the following:
fn main() {
include_str!("../rsc/file.xml");
}
But this will be done at compile time meaning that changing file.xml means recompiling the program so it's completely unsafe in terms of maintainability.
The other option I can see is giving the rsc path as an argument to my program but I find it a bit cumbersome since this is not an optional argument, I really need to know where my rsc directory is and I know my crate will have this architecture.
Is there something I can't see?
I saw this post: How to avoid hard-coded values in Rust
But my question is summarized in this part:
If you are deploying a binary, you may have to supply a path to where your application should find its resources.
And there's no other precision about it.
You can find the path to your binary using std::env::current_exe(). You can use this to find the directory that the binary is in, and then use that to load some resource relative to this directory.
For instance if your resources were in a directory 'rsrc' which was in the same directory as your binary:
let mut rsrc_dir = std::env::current_exe()
.expect("Can't find path to executable");
// Directory containing binary
rsrc_dir.pop();
// Subdir relative to binary
rsrc_dir.push("rsrc");
This would only be useful if your binary is installed with its resource files in some fixed location relative to the binary. Keep in mind that most users will not be cloning your crate from github and running it that way - typical methods for installation would include:
installing it with cargo install
using some OS specific package manager
perhaps downloading a tar or zip file and decompressing it
It seems that cargo install does not currently handle installing associated resource files (although there is an open bug for that).

How to create a library with CMakeLists.txt and include it in another program?

I'm new to C/C++ development and I'm struggling with CMakeLists.txt in CLion IDE.
I can't create a library (static or shared) that I can #include in another program.
I have this kind of structure :
src/
|
|---> utilities/
| |---> CMakeLists.txt
| |---> utilties.h
| |
| |---> file_utilities/
| | |---> file_utilities.h
| | |---> file_utilities.c
| ...
|
|---> my_app
|---> CMakeLists.txt
|---> main.c
I have generated a libutilities.so and a libutilities.a. In my main.c file, it works if I do a #include "../utilities/utilities.h" or #include "../utilities/file_utilities/file_utilities.h".
Worse, if I create another project, with another program and link my libutilities.so, the link seems to work, but still can't include my headers.
I've tried many configuration, many options in CMakeLists.txt but it has never worked until now.
Here is the CMakeLists.txt that I use for my library. I'm quite sure the problem is in this file.
cmake_minimum_required(VERSION 3.7)
project(utilities VERSION 1.0.0)
set(CMAKE_CXX_STANDARD 11)
link_libraries(pthread)
link_libraries(ssl)
link_libraries(crypto)
find_package(CURL REQUIRED)
include_directories(${CURL_INCLUDE_DIRS})
file(GLOB_RECURSE SOURCES RELATIVES "*.c")
file(GLOB_RECURSE HEADERS RELATIVES "*.h")
add_library(${PROJECT_NAME} SHARED ${SOURCES} ${HEADERS})
set_target_properties(${PROJECT_NAME} PROPERTIES
PUBLIC_HEADER "${HEADERS}"
ARCHIVE_OUTPUT_DIRECTORY "lib"
LIBRARY_OUTPUT_DIRECTORY "lib"
OUTPUT_NAME ${PROJECT_NAME})
target_include_directories(${PROJECT_NAME} PUBLIC .)
target_link_libraries(${PROJECT_NAME} ${CURL_LIBRARIES})
include(GNUInstallDirs)
install(TARGETS ${PROJECT_NAME}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME})
I'd like to have something more like #include <utilities/utilties.h> as it's a library. But I can't make it works.
In the example I provided, the library is a simple "utils" library, but I have to create more that I'll have to deliver and be integrated in another program than mine.
I highly suggest reading this article, in which a fictional library target is created, starting from project structure to installing/exporting. From my understanding, the author has exactly the same goal as you do. The article has cleared up a lot of things for me when I started out. I also recomend the project structure laid out within.
Project structure:
libjsonutils
├── CMakeLists.txt
├── include
│ └── jsonutils
│ └── json_utils.h
├── src
│ ├── file_utils.h
│ └── json_utils.cpp
└── test
├── CMakeLists.txt
└── src
└── test_main.cpp
Specifically, you will want to take a look at Targets and Properties, where generator expressions are used to differentiate between the include dir at build time, and when installed:
target_include_directories(JSONUtils
PUBLIC
$<INSTALL_INTERFACE:include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/src
)
The install process and exporting/importing of targets is explained a little later in This is how you do CMake. What the author wants to do is be able to use the library in other cmake projects (e.g. a target called "example"), simply by doing the following:
find_package(JSONUtils 1.0 REQUIRED)
target_link_libraries(example JSONUtils::JSONUtils)
In order to make this work, you will need to install and export the library. The author encourages this for installation:
include(GNUInstallDirs)
install(TARGETS JSONUtils
EXPORT jsonutils-export
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
And this for exporting:
install(EXPORT jsonutils-targets
FILE
JSONUtilsTargets.cmake
NAMESPACE
JSONUtils::
DESTINATION
${CMAKE_INSTALL_LIBDIR}/cmake/JSONUtils
)
The export will place a file named findJsonUtils.cmake in the given destination. This file will be what you need to import the library in other projects by using the find_package mechanism.
All code samples in this post taken from Pablo Arias' linked article.
Your CMakeLists.txt is inside utilities try to use this.
src/utilities/CMakeLists.txt:
target_include_directories(${PROJECT_NAME}
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/..>
)
For the app you should have something like:
src/my_app/CMakeLists.txt:
target_link_libraries(${PROJECT_NAME} PRIVATE utilities)
and you should have simple
src/CMakeLists.txt:
add_subdirectory(utilities)
add_subdirectory(my_app)

In waf, how do I define a dependency on a generated header from another subdir

I am trying to get waf to generate header files generated by a task chain and pick up on them automatically using the c preprocessor's scan function.
Here is an example project. Some files get generated in the project's gen directory, to be used in the project's `prog' directory.
The layout:
├── gen
│   ├── test.txt
│   └── wscript
├── prog
│   ├── main.c
│   └── wscript
├── waf
└── wscript
The generation of the .h file happens through a task chain declared in the top-level file:
top = '.'
def configure(cfg):
cfg.load('compiler_c')
def build(bld):
from waflib import TaskGen
TaskGen.declare_chain(name = 'int',
rule = 'cat ${SRC} > ${TGT}',
ext_in = '.txt', ext_out = '.int')
TaskGen.declare_chain(name = 'inttoh',
rule = 'cat ${SRC} > ${TGT}',
ext_in = '.int', ext_out = '.h')
bld.recurse(['prog', 'gen'])
In gen, all we need is to define build as bld(source = 'test.txt', target='test.h').
In prog, we build a program and only set the include path, don't mention test.h directly (main.c includes test.h):
def build(bld):
includes = [ bld.path.parent.find_dir('gen').get_bld().abspath() ]
bld.program(source = 'main.c', target = 'prog', includes = includes)
When I run waf at the top level, everything works as expected. When I run it from the prog directory though, it never triggers the creation of test.h. I was under the impression that the c preprocessor from scan shouldn't run until all nodes are created, but it seems if I run from the prog directory, waf doesn't know about these generated headers, even though they are defined as targets in the other directory's wscript file.
[edit: This makes some amount of sense I just realized - when running from top level it will schedule building the headers, and then dependencies will resolve fine. Waf does not seem to have a list of items that "could be built, if needed"]
There are some workarounds, such as using name and adding a use = ... directive in the C file wscript. Is there a way. though, to make it work automatically? It seems waf should have all the information it needs to make it work automatically.
(tested with waf 1.7.8 and 2.0.8)
When you launch waf in a subdirectory, it only posts the task generator defined in the subtree. This is to allow partial builds. waf know of your dependencies scanning includes in your C files, but as includes can be system includes, that does not trigger anything. To trigger a task generator in another part of your tree, the best thing to do is use =, in my opinion that's the best way. You can also go for using:
bld.program(source = ["main.c", "../gen/test.h"], ...)
but I find it less modular.

vim doesn't appear to find .clang_complete

In trying to setup auto completion for C using clang complete in vim, and so far, when I'm inside a .c file, I kind of get auto completion when I hit ctrl+x,u. However it only displays some symbols.
None of the functions that's in the included headers appear in the auto complete popup box. It appears that only typedefs are showing?
The project structure is very simple:
$ tree -ap
.
├── [-rwxrw-r--] .clang_complete
├── [-rwxrw-r--] makefile
└── [drwxrw-r--] src
└── [-rwxrw-r--] FlightControl.c
1 directory, 3 files
I tried creating the .clang_complete file inside the project folder, that contains the following:
-I/.../Libraries/xpSDK/CHeaders/XPLM
I double checked the path to the XPLM headers, and it is correct.
Any ideas whats wrong?
During completion libclang tries to do its best by ignoring errors to present a user with the longest list of matches. I guess that you don't have XPLM_API macro defined. As it is used to declare every function in headers, you won't see any functions in completion list. Looking at defines in XPLMDefs.h I think that libclang gets Platform not defined! error (maybe even several times).
It should work if you define your platform for completion, I did this by adding -DLIN to .clang_complete file and completion works now.
So it doesn't seem to be an issue of vim or clang_complete, though it'd be nice to have a warning in such case.

Resources