Recently I've changed from CMake to Premake (v5.0.0-alpha8) and I'm not quite sure how to achieve the the following in Premake.
I want to include some dependencies so in CMake I can do something like this:
target_link_libraries(${PROJECT_NAME}
${YALLA_ABS_PLATFORM}
${YALLA_LIBRARY})
The above will add the paths of these libraries (dir) to "Additional Include Directories" in the compiler and it will also add an entry (lib) to "Additional Dependencies" in the linker so I don't need to do anything special beyond calling target_link_libraries
.
So I expected that when I'm doing something like this in Premake:
links {
YALLA_LIBRARY
}
I'd get the same result but I don't.
I also tried to use the libdirs
but it doesn't really work, I mean I can't see the library directory and its subdirectories passed to the compiler as "Additional Include Directories" (/I) or Yalla.Library.lib passed to the the linker as "Additional Dependencies".
Here is the directory structure I use:
.
|-- src
| |-- launcher
| |-- library
| | `-- utils
| `-- platform
| |-- abstract
| `-- win32
`-- tests
`-- platform
`-- win32
The library dir is defined in Premake as follow:
project(YALLA_LIBRARY)
kind "SharedLib"
files {
"utils/string-converter.hpp",
"utils/string-converter.cpp",
"defines.hpp"
}
The platform dir is defined in Premake as follow:
project(YALLA_PLATFORM)
kind "SharedLib"
includedirs "abstract"
links {
YALLA_LIBRARY
}
if os.get() == "windows" then
include "win32"
else
return -- OS NOT SUPPORTED
end
The win32 dir is defined in Premake as follow:
files {
"event-loop.cpp",
"win32-exception.cpp",
"win32-exception.hpp",
"win32-window.cpp",
"win32-window.hpp",
"window.cpp"
}
And finally at the root dir I have the following Premake file:
PROJECT_NAME = "Yalla"
-- Sets global constants that represents the projects' names
YALLA_LAUNCHER = PROJECT_NAME .. ".Launcher"
YALLA_LIBRARY = PROJECT_NAME .. ".Library"
YALLA_ABS_PLATFORM = PROJECT_NAME .. ".AbstractPlatform"
YALLA_PLATFORM = PROJECT_NAME .. ".Platform"
workspace(PROJECT_NAME)
configurations { "Release", "Debug" }
flags { "Unicode" }
startproject ( YALLA_LAUNCHER )
location ( "../lua_build" )
include "src/launcher"
include "src/library"
include "src/platform"
I'm probably misunderstanding how Premake works due to lack of experience with it.
I solved it by creating a new global function and named it includedeps
.
function includedeps(workspace, ...)
local workspace = premake.global.getWorkspace(workspace)
local args = { ... }
local args_count = select("#", ...)
local func = select(args_count, ...)
if type(func) == "function" then
args_count = args_count - 1
args = table.remove(args, args_count)
else
func = nil
end
for i = 1, args_count do
local projectName = select(i, ...)
local project = premake.workspace.findproject(workspace, projectName)
if project then
local topIncludeDir, dirs = path.getdirectory(project.script)
if func then
dirs = func(topIncludeDir)
else
dirs = os.matchdirs(topIncludeDir .. "/**")
table.insert(dirs, topIncludeDir)
end
includedirs(dirs)
if premake.project.iscpp(project) then
libdirs(dirs)
end
links(args)
else
error(string.format("project '%s' does not exist.", projectName), 3)
end
end
end
Usage:
includedeps(PROJECT_NAME, YALLA_LIBRARY)
or
includedeps(PROJECT_NAME, YALLA_PLATFORM, function(topIncludeDir)
return { path.join(topIncludeDir, "win32") }
end)
Update:
For this to work properly you need to make sure that when you include
the dependencies they are included by their dependency order and not by the order of the directory structure.
So for example if I have the following dependency graph launcher --> platform --> library
then I'll have to include
them in the following order.
include "src/library"
include "src/platform"
include "src/launcher"
As opposed to the directory structure that in my case is as follow:
src/launcher
src/library
src/platform
If you will include them by their directory structure it will fail and tell you that "The project 'Yalla.Platform' does not exist."