Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature merge from enhex fork #1

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
155 changes: 82 additions & 73 deletions cmake_project.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
-- Joel Linn
-- UndefinedVertex
-- Created: 2013/05/06
-- Copyright: (c) 2008-2020 Jason Perkins and the Premake project
-- Copyright: (c) 2008-2022 Jason Perkins and the Premake project
--

local p = premake
Expand All @@ -35,7 +35,7 @@ function m.files(prj)
local tr = project.getsourcetree(prj)
tree.traverse(tr, {
onleaf = function(node, depth)

_p(depth, '"%s"', path.getrelative(prj.workspace.location, node.abspath))

-- add generated files
Expand Down Expand Up @@ -110,118 +110,130 @@ function m.generate(prj)
-- output dir
_p(1,'set_target_properties("%s" PROPERTIES', prj.name)
_p(2, 'OUTPUT_NAME "%s"', cfg.buildtarget.basename)
_p(2, 'ARCHIVE_OUTPUT_DIRECTORY "%s"', path.getrelative(prj.workspace.location, cfg.buildtarget.directory))
_p(2, 'LIBRARY_OUTPUT_DIRECTORY "%s"', path.getrelative(prj.workspace.location, cfg.buildtarget.directory))
_p(2, 'RUNTIME_OUTPUT_DIRECTORY "%s"', path.getrelative(prj.workspace.location, cfg.buildtarget.directory))
local relBinDir = path.getrelative(prj.workspace.location, cfg.buildtarget.directory)
_p(2, 'ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/%s"', relBinDir)
_p(2, 'LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/%s"', relBinDir)
_p(2, 'RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/%s"', relBinDir)
_p(1,')')
_p('endif()')

-- include dirs

if #cfg.sysincludedirs > 0 then
_p('target_include_directories("%s" SYSTEM PRIVATE', prj.name)
_p(1, 'target_include_directories("%s" SYSTEM PRIVATE', prj.name)
for _, includedir in ipairs(cfg.sysincludedirs) do
_x(1, '$<$<CONFIG:%s>:%s>', cmake.cfgname(cfg), includedir)
_x(2, '%s', includedir)
end
_p(')')
_p(1, ')')
end
if #cfg.includedirs > 0 then
_p('target_include_directories("%s" PRIVATE', prj.name)
_p(1, 'target_include_directories("%s" PRIVATE', prj.name)
for _, includedir in ipairs(cfg.includedirs) do
_x(1, '$<$<CONFIG:%s>:%s>', cmake.cfgname(cfg), includedir)
_x(2, '%s', includedir)
end
_p(')')
_p(1, ')')
end

if #cfg.forceincludes > 0 then
_p('if (MSVC)')
_p(1, 'target_compile_options("%s" PRIVATE %s)', prj.name, table.implode(p.tools.msc.getforceincludes(cfg), "", "", " "))
_p('else()')
_p(1, 'target_compile_options("%s" PRIVATE %s)', prj.name, table.implode(p.tools.gcc.getforceincludes(cfg), "", "", " "))
_p('endif()')
_p(1, 'if (MSVC)')
_p(2, 'target_compile_options("%s" PRIVATE %s)', prj.name, table.implode(p.tools.msc.getforceincludes(cfg), "", "", " "))
_p(1, 'else()')
_p(2, 'target_compile_options("%s" PRIVATE %s)', prj.name, table.implode(p.tools.gcc.getforceincludes(cfg), "", "", " "))
_p(1, 'endif()')
end

-- defines
if #cfg.defines > 0 then
_p('target_compile_definitions("%s" PRIVATE', prj.name)
_p(1, 'target_compile_definitions("%s" PRIVATE', prj.name)
for _, define in ipairs(cfg.defines) do
_p(1, '$<$<CONFIG:%s>:%s>', cmake.cfgname(cfg), p.esc(define):gsub(' ', '\\ '))
_p(2, '%s', p.esc(define):gsub(' ', '\\ '))
end
_p(')')
_p(1, ')')
end

-- lib dirs
if #cfg.libdirs > 0 then
_p('target_link_directories("%s" PRIVATE', prj.name)
_p(1, 'target_link_directories("%s" PRIVATE', prj.name)
for _, libdir in ipairs(cfg.libdirs) do
_p(1, '$<$<CONFIG:%s>:%s>', cmake.cfgname(cfg), libdir)
_p(2, '%s', libdir)
end
_p(')')
_p(1, ')')
end

-- libs
local uselinkgroups = isclangorgcc and cfg.linkgroups == p.ON
if uselinkgroups or # config.getlinks(cfg, "dependencies", "object") > 0 or #config.getlinks(cfg, "system", "fullpath") > 0 then
_p('target_link_libraries("%s"', prj.name)
_p(1, 'target_link_libraries("%s"', prj.name)
-- Do not use toolset here as cmake needs to resolve dependency chains
if uselinkgroups then
_p(1, '-Wl,--start-group')
_p(2, '-Wl,--start-group')
end
for a, link in ipairs(config.getlinks(cfg, "dependencies", "object")) do
_p(1, '$<$<CONFIG:%s>:%s>', cmake.cfgname(cfg), link.project.name)
_p(2, '%s', link.project.name)
end
if uselinkgroups then
-- System libraries don't depend on the project
_p(1, '-Wl,--end-group')
_p(1, '-Wl,--start-group')
_p(2, '-Wl,--end-group')
_p(2, '-Wl,--start-group')
end
for _, link in ipairs(config.getlinks(cfg, "system", "fullpath")) do
_p(1, '$<$<CONFIG:%s>:%s>', cmake.cfgname(cfg), link)
_p(2, '%s', link)
end
if uselinkgroups then
_p(1, '-Wl,--end-group')
_p(2, '-Wl,--end-group')
end
_p(')')
_p(1, ')')
end

-- setting build options
all_build_options = ""
for _, option in ipairs(cfg.buildoptions) do
all_build_options = all_build_options .. option .. " "
end

if all_build_options ~= "" then
_p('if(CMAKE_BUILD_TYPE STREQUAL %s)', cmake.cfgname(cfg))
_p(1, 'set_target_properties("%s" PROPERTIES COMPILE_FLAGS %s)', prj.name, all_build_options)
_p('endif()')
if #cfg.buildoptions > 0 then
_p(1, 'set(_TARGET_COMPILE_FLAGS %s)', table.concat(cfg.buildoptions, ' '))
_p(1, 'string(REPLACE ";" " " _TARGET_COMPILE_FLAGS "${_TARGET_COMPILE_FLAGS}")')
_p(1, 'set_property(TARGET "%s" PROPERTY COMPILE_FLAGS ${_TARGET_COMPILE_FLAGS})', prj.name)
_p(1, 'unset(_TARGET_COMPILE_FLAGS)')
end

-- setting link options
all_link_options = ""
for _, option in ipairs(cfg.linkoptions) do
all_link_options = all_link_options .. option .. " "
if #cfg.linkoptions > 0 then
_p(1, 'set(_TARGET_LINK_FLAGS %s)', table.concat(cfg.linkoptions, ' '))
_p(1, 'string(REPLACE ";" " " _TARGET_LINK_FLAGS "${_TARGET_COMPILE_FLAGS}")')
_p(1, 'set_property(TARGET "%s" PROPERTY LINK_FLAGS ${_TARGET_LINK_FLAGS})', prj.name)
_p(1, 'unset(_TARGET_LINK_FLAGS)')
end

if all_link_options ~= "" then
_p('if(CMAKE_BUILD_TYPE STREQUAL %s)', cmake.cfgname(cfg))
_p(1, 'set_target_properties("%s" PROPERTIES LINK_FLAGS "%s")', prj.name, all_link_options)
_p('endif()')
end

if #toolset.getcflags(cfg) > 0 or #toolset.getcxxflags(cfg) > 0 then
_p('target_compile_options("%s" PRIVATE', prj.name)
_p(1, 'target_compile_options("%s" PRIVATE', prj.name)

for _, flag in ipairs(toolset.getcflags(cfg)) do
_p(1, '$<$<AND:$<CONFIG:%s>,$<COMPILE_LANGUAGE:C>>:%s>', cmake.cfgname(cfg), flag)
_p(2, '$<$<COMPILE_LANGUAGE:C>:%s>', flag)
end
for _, flag in ipairs(toolset.getcxxflags(cfg)) do
_p(1, '$<$<AND:$<CONFIG:%s>,$<COMPILE_LANGUAGE:CXX>>:%s>', cmake.cfgname(cfg), flag)
_p(2, '$<$<COMPILE_LANGUAGE:CXX>:%s>', flag)
end
_p(')')
_p(1, ')')
end

-- setting per fille build options
table.foreachi(prj._.files, function(node)
local fcfg = p.fileconfig.getconfig(node, cfg)
if fcfg then
toolset_flags = {}
if path.iscfile(fcfg.name) then
toolset_flags = toolset.getcflags(fcfg)
else
toolset_flags = toolset.getcxxflags(fcfg)
end
file_build_options = table.concat(table.join(toolset_flags, fcfg.buildoptions), " ")
if file_build_options ~= "" then
_p(1,
'set_source_files_properties("%s" PROPERTIES COMPILE_FLAGS "%s")',
path.getrelative(prj.workspace.location, fcfg.abspath),
file_build_options)
end
end
end)

-- C++ standard
-- only need to configure it specified
-- only need to configure if specified
if (cfg.cppdialect ~= nil and cfg.cppdialect ~= '') or cfg.cppdialect == 'Default' then
local standard = {}
standard["C++98"] = 98
Expand All @@ -239,15 +251,13 @@ function m.generate(prj)
local pic = iif(cfg.pic == 'On', 'True', 'False')
local lto = iif(cfg.flags.LinkTimeOptimization, 'True', 'False')

_p('if(CMAKE_BUILD_TYPE STREQUAL %s)', cmake.cfgname(cfg))
_p(1, 'set_target_properties("%s" PROPERTIES', prj.name)
_p(2, 'CXX_STANDARD %s', standard[cfg.cppdialect])
_p(2, 'CXX_STANDARD_REQUIRED YES')
_p(2, 'CXX_EXTENSIONS %s', extentions)
_p(2, 'POSITION_INDEPENDENT_CODE %s', pic)
_p(2, 'INTERPROCEDURAL_OPTIMIZATION %s', lto)
_p(1, ')')
_p('endif()')
end

-- precompiled headers
Expand Down Expand Up @@ -277,60 +287,58 @@ function m.generate(prj)
pch = project.getrelative(cfg.project, path.getabsolute(pch))
end

_p('if(CMAKE_BUILD_TYPE STREQUAL %s)', cmake.cfgname(cfg))
_p('target_precompile_headers("%s" PUBLIC %s)', prj.name, pch)
_p('endif()')
_p(1, 'target_precompile_headers("%s" PUBLIC %s)', prj.name, pch)
end

-- pre/post buildcommands
if cfg.prebuildmessage or #cfg.prebuildcommands > 0 then
-- add_custom_command PRE_BUILD runs just before generating the target
-- so instead, use add_custom_target to run it before any rule (as obj)
_p('add_custom_target(prebuild-%s', prj.name)
_p(1, 'add_custom_target(prebuild-%s', prj.name)
if cfg.prebuildmessage then
local command = os.translateCommandsAndPaths("{ECHO} " .. cfg.prebuildmessage, cfg.project.basedir, cfg.project.location)
_p(' COMMAND %s', command)
_p(2, 'COMMAND %s', command)
end
local commands = os.translateCommandsAndPaths(cfg.prebuildcommands, cfg.project.basedir, cfg.project.location)
for _, command in ipairs(commands) do
_p(' COMMAND %s', command)
_p(2, 'COMMAND %s', command)
end
_p(')')
_p('add_dependencies(%s prebuild-%s)', prj.name, prj.name)
_p(1, ')')
_p(1, 'add_dependencies(%s prebuild-%s)', prj.name, prj.name)
end

if cfg.postbuildmessage or #cfg.postbuildcommands > 0 then
_p('add_custom_command(TARGET %s POST_BUILD', prj.name)
_p(1, 'add_custom_command(TARGET %s POST_BUILD', prj.name)
if cfg.postbuildmessage then
local command = os.translateCommandsAndPaths("{ECHO} " .. cfg.postbuildmessage, cfg.project.basedir, cfg.project.location)
_p(' COMMAND %s', command)
_p(2, 'COMMAND %s', command)
end
local commands = os.translateCommandsAndPaths(cfg.postbuildcommands, cfg.project.basedir, cfg.project.location)
for _, command in ipairs(commands) do
_p(' COMMAND %s', command)
_p(2, 'COMMAND %s', command)
end
_p(')')
_p(1, ')')
end

-- custom command
local function addCustomCommand(fileconfig, filename)
if #fileconfig.buildcommands == 0 or #fileconfig.buildoutputs == 0 then
return
end
_p('add_custom_command(TARGET OUTPUT %s', table.implode(project.getrelative(cfg.project, fileconfig.buildoutputs),"",""," "))
_p(1, 'add_custom_command(TARGET OUTPUT %s', table.implode(project.getrelative(cfg.project, fileconfig.buildoutputs),"",""," "))
if fileconfig.buildmessage then
_p(' COMMAND %s', os.translateCommandsAndPaths('{ECHO} ' .. fileconfig.buildmessage, cfg.project.basedir, cfg.project.location))
_p(2, 'COMMAND %s', os.translateCommandsAndPaths('{ECHO} ' .. fileconfig.buildmessage, cfg.project.basedir, cfg.project.location))
end
for _, command in ipairs(fileconfig.buildcommands) do
_p(' COMMAND %s', os.translateCommandsAndPaths(command, cfg.project.basedir, cfg.project.location))
_p(2, 'COMMAND %s', os.translateCommandsAndPaths(command, cfg.project.basedir, cfg.project.location))
end
if filename ~= "" and #fileconfig.buildinputs ~= 0 then
filename = filename .. " "
end
if filename ~= "" or #fileconfig.buildinputs ~= 0 then
_p(' DEPENDS %s', filename .. table.implode(fileconfig.buildinputs,"",""," "))
_p(2, 'DEPENDS %s', filename .. table.implode(fileconfig.buildinputs,"",""," "))
end
_p(')')
_p(1, ')')
end
local tr = project.getsourcetree(cfg.project)
p.tree.traverse(tr, {
Expand All @@ -353,6 +361,7 @@ function m.generate(prj)
end
})
addCustomCommand(cfg, "")
_p('endif()')
end
-- restore
path.getDefaultSeparator = oldGetDefaultSeparator
Expand Down
4 changes: 2 additions & 2 deletions cmake_workspace.lua
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ function m.generate(wks)

-- Clear default flags
p.w('set(CMAKE_MSVC_RUNTIME_LIBRARY "")')
p.w('set(CMAKE_C_FLAGS "")')
p.w('set(CMAKE_CXX_FLAGS "")')
p.w('set(CMAKE_C_FLAGS "$ENV{CFLAGS}")')
p.w('set(CMAKE_CXX_FLAGS "$ENV{CXXFLAGS}")')
for _, cfg in pairs(cfgs) do
p.w('set(CMAKE_C_FLAGS_%s "")', string.upper(cfg))
p.w('set(CMAKE_CXX_FLAGS_%s "")', string.upper(cfg))
Expand Down