Hey i follow tutorial about imGUI but i have a problem with libraries binding.
Here`s a reference to tutorial: https://youtu.be/U1BnzWX194Q?t=1419 .
This is how my premake5.lua file looks like
-- Include conan gennerate script
include("conanbuildinfo.premake.lua")
-- Main Workspace
workspace "GameOfLife"
-- Import conan gennerate config
conan_basic_setup()
-- Project
project "GOL"
kind "ConsoleApp"
language "C++"
targetdir "bin/%{cfg.buildcfg}"
objdir "bin/%{cfg.buildcfg}/obj/"
location "src"
debugdir "app"
linkoptions { conan_exelinkflags }
files { "**.hpp", "**.cpp" }
filter "configurations:Debug"
defines { "DEBUG" }
symbols "On"
filter "configurations:Release"
defines { "NDEBUG" }
optimize "On"
and conanfile.txt
[requires]
imgui/1.89.1
glfw/3.3.8
glad/0.1.36
[generators]
premake
[options]
*:shared=True
[imports]
bin,*.dll -> ./app
I looked in internet but i cant find any reference about it.
I managed to add binding
I created bindings folder
To premake5.lua i added this folder
liked this:
includedirs { "./bindings" }
In conanfile.txt i added imports like:
[imports]
./res/bindings, imgui_impl_glfw.h -> ./bindings
./res/bindings, imgui_impl_opengl3.h -> ./bindings
./res/bindings, imgui_impl_opengl3_loader.h -> ./bindings
I dont know it is good aproach but vs code see those bindings
Edit: So far it work with shared and static options
Related
I've been searching for a solution to this problem for a long time to no avail.
I am trying to compile this simple program:
#include <iostream>
#include <Magick++.h>
#include <Magick++/Image.h>
using namespace std;
using namespace Magick;
int main(int argc,char **argv) {
InitializeMagick("D:\\Programming\\CPPProjects\\NoteScripts\\Dependencies\\magick\\include");
Image image;
// image.read("arch");
// image.write("test.png");
}
Upon building, I get the following error:
CMakeFiles\main.dir/objects.a(main.cpp.obj):main.cpp:(.text+0x1c): undefined reference to `Magick::InitializeMagick(char const*)'
CMakeFiles\main.dir/objects.a(main.cpp.obj):main.cpp:(.text+0x28): undefined reference to `Magick::Image::Image()'
CMakeFiles\main.dir/objects.a(main.cpp.obj):main.cpp:(.text+0x34): undefined reference to `Magick::Image::~Image()'
collect2.exe: error: ld returned 1 exit status
From what I can tell, this is a linker error but I have no idea where I am going wrong with linking the libs needed.
I installed ImageMagick on Windows 10 from the ImageMagick downloads page with this installer: ImageMagick-7.1.0-50-Q16-HDRI-x64-dll.exe
I then copied the lib files from the lib folder under the installation directory into my project and then copied the include folder under the installtion directory into my project.
Here is what the project hierarchy looks like (Source Directory is NoteScripts):
My CMakeLists.txt consists of:
cmake_minimum_required(VERSION 3.10)
set( CMAKE_CXX_COMPILER "C:/Program Files/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/bin/g++.exe")
set( CMAKE_C_COMPILER "C:/Program Files/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/bin/gcc.exe" )
# set the project name
project("Notes")
include_directories(D:/Programming/CPPProjects/NoteScripts/Dependencies/magick/include)
# add the executable
add_executable(main main.cpp)
target_link_libraries(main D:/Programming/CPPProjects/NoteScripts/Dependencies/magick/lib/CORE_RL_Magick++_.lib)
target_link_libraries(main D:/Programming/CPPProjects/NoteScripts/Dependencies/magick/lib/CORE_RL_MagickCore_.lib)
target_link_libraries(main D:/Programming/CPPProjects/NoteScripts/Dependencies/magick/lib/CORE_RL_MagickWand_.lib)
If I comment out lines 9 and 10 where InitializeMagick() is called and where Image image is declared, the program compiles without error. I'm also aware that the order of the static libs listed out matters but trying out multiple combinations has resulted in the same error. I have also verfied the dependency order by sifting through the original source code and the reference path is Magick++ -> MagickCore -> MagickWand.
I am relatively new to the process of adding external dependencies to my C++ projects so this is unfamiliar territory (coming from languages with clean package managers). Any help as to how to fix this issue is greatly appreciated!
The typical (and easiest) way of handling dependencies in CMake is using its find_package command:
find_package(ImageMagick REQUIRED COMPONENTS MagickCore MagickWand Magick++)
// ...
target_link_libraries(main ${ImageMagick_LIBRARIES})
This method is available for ImageMagick with your CMake version. I'm not familiar with CMake on Windows, but find_package by default searches a number of standard (system) locations for the package's files. Since you have a custom setup, it should also be possible to specify a nonstandard search prefix to the command. Additionally, you could download external dependencies in a portable way with the FetchContent commands.
First of all, it is a pain to setup this thing if you are a newbie like me.
Now to the steps to dynamically link imagemagick libs with your C app:
go to https://github.com/ImageMagick/ImageMagick-Windows and follow the instructions there (Install Visual Studio dependencies - Clone the dependencies - Build configure.exe- Build ImageMagick)
in the step Build configure.exe, when running configure.exe, keep the default option selected when asked about the output library type (keep it set to dynamic)
in the Build ImageMagick step, when you open VisualDynamicMT.sln in visual studio, before you start the build, select all the solutions in the project, and right-click -> properties -> General -> C Language Standard -> choose Default (Legacy MSVC). After that, click on the top-most solution that contains all the other 196 solutions, and build it. watch the console for errors, I didn't get any errors with the configuration above.
After the latter step, go the VisualMagick folder (created from steps before), and you will see lib folder and bin folder. You're done, your dlls are in bin and your .lib file are in bin folder. Note that these files will be corresponding to build or release environments depending on what you selected in visual studio at the build step.
How do you use imagemagick now in your project regardless if you have imagemagick app installed on your pc or not? Lets create a new project in vscode, call it demo.
Create this project structure:
inside src you will put your C code.
inside deps create ImageMagick/lib and ImageMagick/bin and ImageMagick/include
inside ImageMagick/include place the same include files you said you got in your question.
inside ImageMagick/lib place the .lib files you got from above
inside ImageMagick/bin place the .dll files you got from above
now add this to your CMakeLists.txt:
cmake_minimum_required(VERSION 3.23)
project(demo-app C)
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
file(GLOB SOURCE_FILES src/*.c)
add_executable(demo ${SOURCE_FILES})
include_directories(src)
# ImageMagick
if(WIN32)
add_definitions( -DMAGICKCORE_QUANTUM_DEPTH=16 )
add_definitions( -DMAGICKCORE_HDRI_ENABLE=0 )
include_directories(deps/ImageMagick/include)
target_link_directories(demo PRIVATE deps/ImageMagick/lib)
file(GLOB IMAGEMAGICK_LIBS deps/ImageMagick/lib/*.lib)
target_link_libraries(demo
"${IMAGEMAGICK_LIBS}"
)
add_custom_command(TARGET demo POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory
"${PROJECT_SOURCE_DIR}/deps/ImageMagick/bin"
$<TARGET_FILE_DIR:demo>)
endif()
(The add_custom_command will copy the dlls to your executables path after every build)
Now write some magick code in you src directory.
ctrl + shift + A -> CMake select kit -> choose the Visual Studio community 2022 release -amd64 or change to what fits you if it doesn't work
ctrl + shift + A -> CMake Clean Rebuild
ctrl + shift + A -> CMake run without debugging
Im creating a really simple graphics framework as a learning project and thought I would try to better organize it and make it reusable, a separate project I could just include in any future project I might start. Im building it as a static library using premake for build configuration and it builds just fine. However, when I try to include any header file from my own library in an external project the compiler throws an error saying the include file couldn't be located (for example, if I try to include my "Window.hpp" in a external "Game" project, it throws "Cannot open include file: 'GLFW/glfw3.h').
Should I add an include for this libraries in all projects that might use my own library?
I thought it wouldn't be the case as in other graphics libraries it doesn't seem to be a thing, like in SFML or in the Hazel game engine made by youtuber TheCherno (pointed him out as Im building my projects based on the same design he was using in the beginning of the development of Hazel).
The solution directories are laid out as follows:
GraphicsLibrary
- Bin // For binaries
- Bin-int // For intermediates
- Cryon // Actual library
- Dependencies // Stores all libraries used by Cryon, like GLFW and Glad. The binaries are
// built in the solution "Bin" folder
- Include
- Source
- premake5.lua
- Game // The project I use to test the functionality of my library
- Source
- Main.cpp // File where Im including Cryon's headers for testing
- premake5.lua
- Dependencies.lua // Just to store the dependencies in arrays for easier access for the
// underlying projects
- premake5.lua // Actual premake file for the solution that includes the other projects
Here are the premake5.lua files I use to build the projects
Solution:
include "Dependencies.lua"
workspace "GraphicsLibrary"
architecture "x86_64"
startproject "Game"
configurations
{
"Debug",
"Release"
}
flags
{
"MultiProcessorCompile"
}
outputdir = "%{cfg.buildcfg}-%{cfg.system}-%{cfg.architecture}"
group "Dependencies"
include "Cryon/Dependencies/GLFW"
include "Cryon/Dependencies/GLAD"
group ""
include "Cryon"
include "Game"
Library:
project "Cryon"
kind "StaticLib"
language "c++"
cppdialect "c++17"
staticruntime "on"
targetdir ("%{wks.location}/Bin/" .. outputdir .. "/%{prj.name}")
objdir ("%{wks.location}/Bin-int/" .. outputdir .. "/%{prj.name}")
pchheader "CryonPCH.hpp"
pchsource "Source/CryonPCH.cpp"
files
{
"Include/**.hpp",
"Source/**.cpp"
}
defines
{
"_CRT_SECURE_NO_WARNINGS",
"GLFW_INCLUDE_NONE"
}
includedirs
{
"Include",
"%{IncludeDirs.GLFW}", -- This get evaluated to "%{wks.location}/Cryon/Dependencies/GLFW"
"%{IncludeDirs.GLAD}", -- All the others are similar
"%{IncludeDirs.glm}",
"%{IncludeDirs.spdlog}",
}
links
{
"GLFW",
"Glad",
"opengl32.lib"
}
filter "system:windows"
systemversion "latest"
defines {"CRYON_SYSTEM_WINDOWS"}
filter "configurations:Debug"
defines "CRYON_DEBUG"
runtime "Debug"
symbols "on"
filter "configurations:Release"
defines "CRYON_RELEASE"
runtime "Release"
optimize "on"
External game project:
project "Game"
kind "ConsoleApp"
language "c++"
cppdialect "c++17"
staticruntime "off"
targetdir ("%{wks.location}/Bin/" .. outputdir .. "/%{prj.name}")
objdir ("%{wks.location}/Bin-int/" .. outputdir .. "/%{prj.name}")
files
{
"Source/**.hpp",
"Source/**.cpp"
}
includedirs
{
"%{wks.location}/Cryon/Include",
"%{IncludeDirs.spdlog}"
}
links
{
"Cryon"
}
filter "system:windows"
systemversion "latest"
filter "configurations:Debug"
runtime "Debug"
symbols "on"
filter "configurations:Release"
runtime "Release"
optimize "on"
postbuildcommands
{
("{COPYDIR} Assets %{cfg.targetdir}/Assets")
}
I'm new to conan/premake, I've made a conanlist and a premake which is suppose to set my project.
But when I execute my project in release mode, I receive QT6Widgets.dll is missing and QT6Core.dll is missing. I don't know how to fix that. Here is my conanfile
[requires]
glfw/3.3#bincrafters/stable
qt/6.0.1#bincrafters/stable
boost/1.75.0
[generators]
premake
and this is the premake I've made
include "build/conanbuildinfo.premake.lua"
workspace "TileEditor"
conan_basic_setup()
configurations
{
"Debug",
"Release",
"Dist"
}
outputdir = "%{cfg.buildcfg}-%{cfg.system}-%{cfg.architecture}"
project "TileEditor"
location "TileEditor"
kind "WindowedApp"
language "C++"
targetdir ("bin/" .. outputdir .. "/%{prj.name}")
objdir ("bin-obj/" .. outputdir .. "/%{prj.name}")
linkoptions { conan_exelinkflags }
files
{
"**.h", "**.cpp"
}
filter "configurations:Debug"
defines { "DEBUG" }
symbols "On"
filter "configurations:Release"
defines { "NDEBUG" }
optimize "On"
Dynamic Link Libraries or DLL for short, is not linked to your application at compile time. The library type that gets liked at compile time are static libraries (.lib files).
By default when you try executing an application, the system will check if the required DLL is in the working directory (in the directory which the application is placed). If not found, it'll check in the default system directory. If that fails too, an error will be popped.
So to resolve your issue, copy the QT6Widgets.dll and QT6Core.dll files from your Qt installation directory, and place them in your application's working directory.
I'm trying to organize the targets in my subproject (in this case poco), but I've come to find that properties can't be modified for ALIAS targets. I want the targets in my external project to be in their own folder, instead of sprawled out everywhere in the project tree (say the visual studio generator). Is there an easier way to add projects with my own properties?
So instead of:
- CMakePredefinedTargets
- ALL_BUILD
- INSTALL
- ...
- MyTargets
- SomeLibrary
- SomeExe
- CppUnit
- Crypto
- Data
- ...
I want:
- CMakePredefinedTargets
- ALL_BUILD
- INSTALL
- ...
- MyTargets
- SomeLibrary
- SomeExe
- Poco
- CppUnit
- Crypto
- Data
- ...
My attempt:
function(add_subdirectory_with_folder folder_name)
function(add_library name type)
_add_library(${ARGV})
set_target_properties(${name}
PROPERTIES
FOLDER "${folder_name}"
)
endfunction()
add_subdirectory(${ARGN})
endfunction()
# External Libs
add_subdirectory_with_folder("Poco" libs/poco)
Example target from the poco library:
add_library( "${LIBNAME}" ${LIB_MODE} ${SRCS} )
add_library( "${POCO_LIBNAME}" ALIAS "${LIBNAME}")
set_target_properties( "${LIBNAME}"
PROPERTIES
VERSION ${SHARED_LIBRARY_VERSION} SOVERSION ${SHARED_LIBRARY_VERSION}
OUTPUT_NAME ${POCO_LIBNAME}
DEFINE_SYMBOL JSON_EXPORTS
)
My goal is to make it so I don't have to fork and maintain my own versions of libraries that I want to use just for quality of life tweaks. Is there a different method I can use to organize the project tree for IDEs? I know externalproject_add exists, but I do not think this has the facilities I am looking for. I will be adding other projects in the future in the form of git-submodules, but depending on if there is an easier method for this I'll explore other avenues.
EDIT:
To clarify, I'm already using a separate CMakeLists.txt for each module of my own project, plus a top level CMakeLists.txt which ties them all together, as well as collecting external libraries that my targets rely on. I want to modify the targets of external libraries without having to fork and maintain them myself just so I have nice folder structures in visual studio, xcode, or others. Linux obviously doesn't matter as much since most editing tools are folder based already.
I've given your example a try and here are my two variants:
Using the BUILDSYSTEM_TARGETS and SUBDIRECTORIES directory properties to evaluate a list of target names in the directory that "does not include any Imported Targets or Alias Targets":
cmake_minimum_required(VERSION 3.7)
project(AliasFolderSub)
set_property(GLOBAL PROPERTY USE_FOLDERS TRUE)
function(get_all_targets _result _dir)
get_property(_subdirs DIRECTORY "${_dir}" PROPERTY SUBDIRECTORIES)
foreach(_subdir IN LISTS _subdirs)
get_all_targets(${_result} "${_subdir}")
endforeach()
get_property(_sub_targets DIRECTORY "${_dir}" PROPERTY BUILDSYSTEM_TARGETS)
set(${_result} ${${_result}} ${_sub_targets} PARENT_SCOPE)
endfunction()
function(add_subdirectory_with_folder _folder_name _folder)
add_subdirectory(${_folder} ${ARGN})
get_all_targets(_targets "${_folder}")
foreach(_target IN LISTS _targets)
set_target_properties(
${_target}
PROPERTIES FOLDER "${_folder_name}"
)
endforeach()
endfunction()
# External Libs
add_subdirectory_with_folder("Poco" libs/poco)
By transforming the FOLDER target property into something that is inherited from a directory property of the same name. This can be done using define_property() to redefine the FOLDER property as INHERITED:
With the INHERITED option the get_property() command will chain up to the next higher scope when the requested property is not set in the scope given to the command. DIRECTORY scope chains to GLOBAL. TARGET, SOURCE, and TEST chain to DIRECTORY.
cmake_minimum_required(VERSION 2.6)
project(AliasFolderSub)
set_property(GLOBAL PROPERTY USE_FOLDERS TRUE)
define_property(
TARGET
PROPERTY FOLDER
INHERITED
BRIEF_DOCS "Set the folder name."
FULL_DOCS "Use to organize targets in an IDE."
)
function(add_subdirectory_with_folder _folder_name _folder)
add_subdirectory(${_folder} ${ARGN})
set_property(DIRECTORY "${_folder}" PROPERTY FOLDER "${_folder_name}")
endfunction()
# External Libs
add_subdirectory_with_folder("Poco" libs/poco)
𝓝𝓸𝓽𝓮: Using define_property() to redefine an existing property's scope is an undocumented behavior of CMake.
References
Directory properties and subdirectories
"make dist" equivalent in CMake
How to set Visual Studio Filters for nested sub directory using cmake
https://github.com/andry81/tacklelib
https://github.com/andry81/tacklelib/blob/trunk/cmake/tacklelib/Project.cmake
cmake_minimum_required(VERSION 3.14)
# enable project folders
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
## cmake builtin search paths and includes
LIST(APPEND CMAKE_MODULE_PATH "${TACKLELIB_CMAKE_ROOT}")
include(tacklelib/Project)
include(tacklelib/EnableTargetsExtension)
project(MyApp)
set(MYLIB_ROOT ...)
# somewhere at the end ...
## project folders
tkl_set_target_folder(CMAKE_CURRENT_LIST_DIR . * . UTILITY . util)
tkl_set_target_folder(CMAKE_CURRENT_LIST_DIR . * "tests" EXECUTABLE . exe)
tkl_set_target_folder(CMAKE_CURRENT_LIST_DIR . * . "SHARED_LIBRARY;STATIC_LIBRARY" . lib)
tkl_set_target_folder(MYLIB_ROOT * * . UTILITY . _3dparty/utility/mylib/util)
tkl_set_target_folder(MYLIB_ROOT * * "tests" EXECUTABLE . _3dparty/utility/mylib/exe)
tkl_set_target_folder(MYLIB_ROOT * * . "SHARED_LIBRARY;STATIC_LIBRARY" . _3dparty/utility/mylib/lib)
tkl_set_target_folder(MYLIB_ROOT * "tests" . * . _3dparty/utility/mylib/tests)
CMake command line:
cmake.exe -G "..." "-DTACKLELIB_CMAKE_ROOT=.../_externals/tacklelib/cmake" ...
Project directory structure:
...
_externals/
_out/
include/
src/
CMakeLists.txt
_out - directory with cmake cache and output
Solution layout:
_3dparty
utility
mylib
lib
mylib
CMakePredefinedTargets
ALL_BUILD
INSTALL
ZERO_CHECK
exe
myapp
util
bundle
I have a QBS Project which is a collection of subprojects, including static libraries, shared libraries, and a Qt GUI applications. The Qt GUI application has been giving me issue in that the linking stage fails, throwing several "/usr/bin/ld: cannot find {library}: File format not recognized" errors for libraries that are built earlier in the project chain. It does not do this for all libraries though, including libraries with near identical .qbs files as those which do throw this error.
Oddly enough, if I build the application on it's own, that is to say I run qbs from within the application's project directory rather than at the top level, it builds fine (assuming the dependent libraries all exist within their install directories). The main difference I see is that when building the full project, the cpp.libraryPaths for the application are ignored for all products in the project and the application attempts to link against the lib files produced in the build directory, while when building the application on it's own the cpp.libraryPaths are used as intended, and the files in the install directory are linked against successfully.
I have no idea why the lib files in the install directory can be linked against while files in the build directory throw errors. What could be causing the linking to fail in the first place? Additionally, how can I fix my project configuration so that I can build everything by calling qbs at the top level. Am I perhaps going about this in the wrong manner?
Here is the command I use to start the build:
qbs qbs.installRoot:. release
And a visual representation of the issue:
Poject <-- calling qbs here throws errors at linking application
|- LibraryOne
|- LibraryTwo
|- Application <-- calling qbs here works if libraries already built
And here is a very simplified reproduction of the relevent qbs files
-- SubOne.qbs and SubTwo --
// These are identical excluding the files
StaticLibrary {
name: // "One" or "Two"
files: [/*Files...*/]
Depends {
name: "Qt"
submodules: [/*core, etc...*/]
}
Depends { name: "cpp" }
// cpp depends and properties
Group {
fileTagsFilter: product.type
qbs.installDir: "lib"
qbs.install: true
}
}
-- App.qbs --
QtGuiApplication {
name: "App"
files: [/*Files...*/]
Depends { name: "One" } // I comment out these depends when building the Application on it's own
Depends { name: "Two" }
Depends { name: "cpp" }
cpp.includePaths: ["../One/include","..Two/include"]
cpp.libraryPaths: ["../lib"] // <-- Ignored during full project build
cpp.staticLibraries: ["One","Two"]
Group {
fileTagsFilter: product.type
qbs.installDir: "bin"
qbs.install: true
}
}
Never run qbs from a subdirectory. You should always run it on the top-level project file. In your root directory you should have a file like this:
// project.qbs
import qbs
Project {
// order doesn't matter here
references: [
"LibraryOne/SubOne.qbs",
"LibraryTwo/SubTwo.qbs",
"Application/App.qbs"
]
}
Secondly, you should not set the cpp.libraryPaths and cpp.staticLibraries in your application, as the Depends items which you have in your application, will already handle this (never comment them out).
Your cpp.includePaths properties should also not be set in the application, instead they should go into an Export item in each of your respective static libraries, like so:
StaticLibrary {
...
Export {
Depends { name: "cpp" }
cpp.includePaths: [product.sourceDirectory + "/include"]
}
...
}
Then run qbs -f project.qbs and everything should be built correctly.