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")
}
Related
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
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 implement premake to my first solution, all projects build fine except my googleTest project in Visual Studio 19 when I enter the test properties there is an additional property - "Referenced Packages" where Google Test is included. How to reference Google Test package in premake? My premake file looks like this
workspace "MyLib"
configurations {"Debug", "Release"}
outputdir = "%{cfg.buildcfg}-%{cfg.system}-%{cfg.architecture}"
project "MyLibTest"
location "MyLibTest"
kind "ConsoleApp"
language "C++"
targetdir("bin/" .. outputdir .. "/%{prj.name}")
objdir("obj/" .. outputdir .. "/%{prj.name}")
pchheader "pch.h"
pchsource "pch.cpp"
includedirs {"MyLib"}
links {"MyLib"}
files{"%{prj.name}/**.h", "%{prj.name}/**.cpp"}
cppdialect "C++17"
systemversion "latest"
Okay I got it, you can add packages by typing
nuget{"package:version"}
I recently watched this video and decided to include a premake build step in my project. However, after seemingly implementing the code in my .lua file identically (apart from the names), premake doesn't generate the bin and bin-int directories. The strange thing is that the .sln, .vcxproj and .vcxproj.filters files are all generated.
my premake5.lua file:
workspace "OpenGE"
architecture "x64"
startproject "Sandbox"
configurations
{
"Debug",
"Release",
"Dist"
}
outputdir = "%{cfg.buildcfg}-%{cfg.system}-%{cfg.architecture}"
project "OpenGE"
location "OpenGE"
kind "SharedLib"
language "C++"
targetdir ("bin/" .. outputdir .. "/%{prj.name}")
objdir ("bin-int/" .. outputdir .. "/%{prj.name}")
files
{
"%{prj.name}/src/**.h",
"%{prj.name}/src/**.cpp"
}
filter "system:windows"
cppdialect "C++17"
staticruntime "On"
systemversion "latest"
defines
{
"GE_DLL_BUILD"
}
postbuildcommands
{
"{COPY} %{cfg.buildtarget.relpath} ../bin/" .. outputdir .. "/Sandbox"
}
filter "configurations:Debug"
defines "GE_DEBUG"
runtime "Debug"
symbols "On"
filter "configurations:Release"
defines "GE_RELEASE"
runtime "Release"
optimize "On"
filter "configurations:Dist"
defines "GE_DIST"
runtime "Release"
optimize "On"
project "Sandbox"
location "Sandbox"
kind "ConsoleApp"
language "C++"
targetdir ("bin/" .. outputdir .. "/%{prj.name}")
objdir ("bin-int/" .. outputdir .. "/%{prj.name}")
files
{
"%{prj.name}/src/**.h",
"%{prj.name}/src/**.cpp"
}
includedirs
{
"OpenGE/src"
}
links
{
"OpenGE"
}
filter "system:windows"
cppdialect "C++17"
staticruntime "On"
systemversion "latest"
filter "configurations:Debug"
defines "GE_DEBUG"
runtime "Debug"
symbols "On"
filter "configurations:Release"
defines "GE_RELEASE"
runtime "Release"
optimize "On"
filter "configurations:Dist"
defines "GE_DIST"
runtime "Release"
optimize "On"
The output on the command line by running premake looks fine:
C:\Users\bonnl\source\repos\OpenGE>call dependencies\premake\premake5 vs2019
Building configurations...
Running action 'vs2019'...
Done (92ms).
C:\Users\bonnl\source\repos\OpenGE>PAUSE
Press any key to continue . . .
If any additional code or information is needed, I'd be glad to add it.
Turns out I thought that premake will build my project as well as generate the solution and project files. I have since built the project and it works like a charm
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.