From 3f460626d8d530ee8fb16f68b4e7e8c3c9b870dd Mon Sep 17 00:00:00 2001 From: Joel Linn Date: Sun, 17 Jul 2022 13:50:32 +0200 Subject: [PATCH 1/5] Support multiple (quoted) compile/link options --- cmake_project.lua | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/cmake_project.lua b/cmake_project.lua index 0bf1510..b92d902 100755 --- a/cmake_project.lua +++ b/cmake_project.lua @@ -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 @@ -185,29 +185,25 @@ function m.generate(prj) 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 + if #cfg.buildoptions > 0 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(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)') _p('endif()') end -- setting link options - all_link_options = "" - for _, option in ipairs(cfg.linkoptions) do - all_link_options = all_link_options .. option .. " " - end - - if all_link_options ~= "" then + if #cfg.linkoptions > 0 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(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)') _p('endif()') end - + if #toolset.getcflags(cfg) > 0 or #toolset.getcxxflags(cfg) > 0 then _p('target_compile_options("%s" PRIVATE', prj.name) From f379a0c52eb0e0ff7da49d1d1326425cb3e77bf0 Mon Sep 17 00:00:00 2001 From: Joel Linn Date: Sun, 17 Jul 2022 15:07:10 +0200 Subject: [PATCH 2/5] Honor C(XX)FLAGS environment variables - CMAKE_C(XX)FLAGS already contains them but also contains other flags added by cmake depending on the target. So add them manually. --- cmake_workspace.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake_workspace.lua b/cmake_workspace.lua index 3f65121..b1640f9 100644 --- a/cmake_workspace.lua +++ b/cmake_workspace.lua @@ -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)) From 1cf6f63ab210d87e53adf91f55ab6112e31d7289 Mon Sep 17 00:00:00 2001 From: Joel Linn Date: Sun, 17 Jul 2022 15:11:45 +0200 Subject: [PATCH 3/5] Replace filters by one common block --- cmake_project.lua | 98 ++++++++++++++++++++++------------------------- 1 file changed, 45 insertions(+), 53 deletions(-) diff --git a/cmake_project.lua b/cmake_project.lua index b92d902..2f88b9f 100755 --- a/cmake_project.lua +++ b/cmake_project.lua @@ -114,106 +114,101 @@ function m.generate(prj) _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)) _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, '$<$:%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, '$<$:%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, '$<$:%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, '$<$:%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, '$<$:%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, '$<$:%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 if #cfg.buildoptions > 0 then - _p('if(CMAKE_BUILD_TYPE STREQUAL %s)', cmake.cfgname(cfg)) _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)') - _p('endif()') end -- setting link options if #cfg.linkoptions > 0 then - _p('if(CMAKE_BUILD_TYPE STREQUAL %s)', cmake.cfgname(cfg)) _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)') - _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, '$<$,$>:%s>', cmake.cfgname(cfg), flag) + _p(2, '$<$:%s>', flag) end for _, flag in ipairs(toolset.getcxxflags(cfg)) do - _p(1, '$<$,$>:%s>', cmake.cfgname(cfg), flag) + _p(2, '$<$:%s>', flag) end - _p(')') + _p(1, ')') end -- C++ standard @@ -235,7 +230,6 @@ 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') @@ -243,7 +237,6 @@ function m.generate(prj) _p(2, 'POSITION_INDEPENDENT_CODE %s', pic) _p(2, 'INTERPROCEDURAL_OPTIMIZATION %s', lto) _p(1, ')') - _p('endif()') end -- precompiled headers @@ -273,39 +266,37 @@ 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 @@ -313,20 +304,20 @@ function m.generate(prj) 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, { @@ -349,6 +340,7 @@ function m.generate(prj) end }) addCustomCommand(cfg, "") + _p('endif()') end -- restore path.getDefaultSeparator = oldGetDefaultSeparator From 2032f33c91d1d273cddc4c78e0b39cb4d13d3ecb Mon Sep 17 00:00:00 2001 From: Joel Linn Date: Wed, 15 Sep 2021 12:15:02 +0200 Subject: [PATCH 4/5] Set per file build options --- cmake_project.lua | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/cmake_project.lua b/cmake_project.lua index 2f88b9f..739707c 100755 --- a/cmake_project.lua +++ b/cmake_project.lua @@ -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 @@ -211,8 +211,28 @@ function m.generate(prj) _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 From 5b7b803b2e295bf746302b58305eed0290322654 Mon Sep 17 00:00:00 2001 From: Joel Linn Date: Sun, 17 Jul 2022 15:38:00 +0200 Subject: [PATCH 5/5] Fix regression from c1c8ba54d85b64e0f31acc77b44d8627cec34879 --- cmake_project.lua | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cmake_project.lua b/cmake_project.lua index 739707c..8a34e0a 100755 --- a/cmake_project.lua +++ b/cmake_project.lua @@ -110,9 +110,10 @@ 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,')') -- include dirs