diff options
-rw-r--r-- | CHANGES.txt | 1 | ||||
-rw-r--r-- | src/base/project.lua | 129 | ||||
-rw-r--r-- | src/tools/gcc.lua | 68 | ||||
-rw-r--r-- | tests/actions/make/test_make_linking.lua | 17 |
4 files changed, 119 insertions, 96 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index dfbc7ee..66d5772 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -67,6 +67,7 @@ * Pull 25: Add Unix support to os.getversion() (wfgleper) * Bug 268: Target extension not set properly for Visual Studio 2010 * Allow command line override of makefile flags (Cameron Hart) +* Fix linking to external libraries outside of project folder ------- diff --git a/src/base/project.lua b/src/base/project.lua index 552879c..5887a42 100644 --- a/src/base/project.lua +++ b/src/base/project.lua @@ -5,7 +5,7 @@ -- premake.project = { } - + -- -- Create a tree from a project's list of files, representing the filesystem hierarchy. @@ -22,13 +22,13 @@ tr.project = prj local isvpath - + local function onadd(node) node.isvpath = isvpath end - + for fcfg in premake.project.eachfile(prj) do - isvpath = (fcfg.name ~= fcfg.vpath) + isvpath = (fcfg.name ~= fcfg.vpath) local node = premake.tree.add(tr, fcfg.vpath, onadd) node.cfg = fcfg end @@ -47,10 +47,10 @@ function premake.eachconfig(prj, platform) -- I probably have the project root config, rather than the actual project if prj.project then prj = prj.project end - + local cfgs = prj.solution.configurations local i = 0 - + return function () i = i + 1 if i <= #cfgs then @@ -58,7 +58,7 @@ end end end - + -- @@ -104,8 +104,8 @@ return value end end - - + + -- -- Given a map of supported platform identifiers, filters the solution's list @@ -129,17 +129,17 @@ end end end - + if #result == 0 and default then table.insert(result, default) end - + return result end - --- + +-- -- Locate a project by name; case insensitive. -- @@ -152,8 +152,8 @@ end end end - - + + -- -- Locate a file in a project with a given extension; used to locate "special" @@ -218,12 +218,12 @@ return iif(useshortname, name:lower(), name) end end - - - + + + -- --- Returns a list of sibling projects on which the specified project depends. --- This is used to list dependencies within a solution or workspace. Must +-- Returns a list of sibling projects on which the specified project depends. +-- This is used to list dependencies within a solution or workspace. Must -- consider all configurations because Visual Studio does not support per-config -- project dependencies. -- @@ -236,7 +236,7 @@ function premake.getdependencies(prj) -- make sure I've got the project and not root config prj = prj.project or prj - + local results = { } for _, cfg in pairs(prj.__configs) do for _, link in ipairs(cfg.links) do @@ -270,9 +270,9 @@ fname = path.join(prj.location, fname) return path.getrelative(os.getcwd(), fname) end - - - + + + -- -- Returns a list of link targets. Kind may be one of: -- siblings - linkable sibling projects @@ -286,21 +286,21 @@ -- directory - just the directory, no name -- fullpath - full path with decorated name -- object - return the project object of the dependency --- - +-- + function premake.getlinks(cfg, kind, part) -- if I'm building a list of link directories, include libdirs local result = iif (part == "directory" and kind == "all", cfg.libdirs, {}) -- am I getting links for a configuration or a project? local cfgname = iif(cfg.name == cfg.project.name, "", cfg.name) - + -- how should files be named? local pathstyle = premake.getpathstyle(cfg) local namestyle = premake.getnamestyle(cfg) - + local function canlink(source, target) - if (target.kind ~= "SharedLib" and target.kind ~= "StaticLib") then + if (target.kind ~= "SharedLib" and target.kind ~= "StaticLib") then return false end if premake.iscppproject(source) then @@ -309,14 +309,14 @@ return premake.isdotnetproject(target) end end - + for _, link in ipairs(cfg.links) do local item - + -- is this a sibling project? local prj = premake.findproject(link) if prj and kind ~= "system" then - + local prjcfg = premake.getconfig(prj, cfgname, cfg.platform) if kind == "dependencies" or canlink(cfg, prjcfg) then if (part == "directory") then @@ -331,7 +331,7 @@ end elseif not prj and (kind == "system" or kind == "all") then - + if (part == "directory") then local dir = path.getdirectory(link) if (dir ~= ".") then @@ -346,13 +346,18 @@ item = item .. ".dll" end end - if item:find("/", nil, true) then - item = path.getrelative(cfg.basedir, item) - end + elseif part == "name" then + item = path.getname(link) + elseif part == "basename" then + item = path.getbasename(link) else item = link end + if item:find("/", nil, true) then + item = path.getrelative(cfg.project.location, item) + end + end if item then @@ -364,12 +369,12 @@ end end end - + return result end - - + + -- -- Gets the name style for a configuration, indicating what kind of prefix, -- extensions, etc. should be used in target file names. @@ -383,7 +388,7 @@ function premake.getnamestyle(cfg) return premake.platforms[cfg.platform].namestyle or premake.gettool(cfg).namestyle or "posix" end - + -- @@ -403,7 +408,7 @@ return "posix" end end - + -- -- Assembles a target for a particular tool/system/configuration. @@ -433,18 +438,18 @@ -- function premake.gettarget(cfg, direction, pathstyle, namestyle, system) - if system == "bsd" or system == "solaris" then - system = "linux" + if system == "bsd" or system == "solaris" then + system = "linux" end -- Fix things up based on the current system local kind = cfg.kind if premake.iscppproject(cfg) then -- On Windows, shared libraries link against a static import library - if (namestyle == "windows" or system == "windows") - and kind == "SharedLib" and direction == "link" - and not cfg.flags.NoImportLib - then + if (namestyle == "windows" or system == "windows") + and kind == "SharedLib" and direction == "link" + and not cfg.flags.NoImportLib + then kind = "StaticLib" end @@ -491,11 +496,11 @@ ext = ".a" end end - + prefix = cfg[field.."prefix"] or cfg.targetprefix or prefix suffix = cfg[field.."suffix"] or cfg.targetsuffix or suffix ext = cfg[field.."extension"] or cfg.targetextension or ext - + -- build the results object local result = { } result.basename = name .. suffix @@ -505,12 +510,12 @@ result.suffix = suffix result.fullpath = path.join(result.directory, result.name) result.bundlepath = bundlepath or result.fullpath - + if pathstyle == "windows" then result.directory = path.translate(result.directory, "\\") result.fullpath = path.translate(result.fullpath, "\\") end - + return result end @@ -534,8 +539,8 @@ return premake.dotnet end end - - + + -- -- Given a source file path, return a corresponding virtual path based on @@ -546,13 +551,13 @@ function premake.project.getvpath(prj, filename) -- if there is no match, return the input filename local vpath = filename - + for replacement,patterns in pairs(prj.vpaths) do for _,pattern in ipairs(patterns) do -- does the filename match this vpath pattern? local i = vpath:find(path.wildcards(pattern)) - if i == 1 then + if i == 1 then -- yes; trim the pattern out of the target file's path local leaf i = pattern:find("*", 1, true) or (pattern:len() + 1) @@ -564,7 +569,7 @@ if leaf:startswith("/") then leaf = leaf:sub(2) end - + -- check for (and remove) stars in the replacement pattern. -- If there are none, then trim all path info from the leaf -- and use just the filename in the replacement (stars should @@ -578,12 +583,12 @@ else leaf = path.getname(leaf) end - + vpath = path.join(stem, leaf) end end end - + -- remove any dot ("./", "../") patterns from the start of the path local changed repeat @@ -596,12 +601,12 @@ changed = false end until not changed - + return vpath end --- +-- -- Returns true if the solution contains at least one C/C++ project. -- @@ -613,9 +618,9 @@ end end - --- + +-- -- Returns true if the solution contains at least one .NET project. -- diff --git a/src/tools/gcc.lua b/src/tools/gcc.lua index 59a6682..6fcc88c 100644 --- a/src/tools/gcc.lua +++ b/src/tools/gcc.lua @@ -4,9 +4,9 @@ -- Copyright (c) 2002-2011 Jason Perkins and the Premake project -- - + premake.gcc = { } - + -- -- Set default tools @@ -15,8 +15,8 @@ premake.gcc.cc = "gcc" premake.gcc.cxx = "g++" premake.gcc.ar = "ar" - - + + -- -- Translation of Premake flags into GCC flags -- @@ -41,36 +41,36 @@ NoExceptions = "-fno-exceptions", NoRTTI = "-fno-rtti", } - - + + -- -- Map platforms to flags -- - premake.gcc.platforms = + premake.gcc.platforms = { - Native = { + Native = { cppflags = "-MMD", }, - x32 = { - cppflags = "-MMD", + x32 = { + cppflags = "-MMD", flags = "-m32", - ldflags = "-L/usr/lib32", + ldflags = "-L/usr/lib32", }, - x64 = { + x64 = { cppflags = "-MMD", flags = "-m64", ldflags = "-L/usr/lib64", }, - Universal = { + Universal = { cppflags = "", flags = "-arch i386 -arch x86_64 -arch ppc -arch ppc64", }, - Universal32 = { + Universal32 = { cppflags = "", flags = "-arch i386 -arch ppc", }, - Universal64 = { + Universal64 = { cppflags = "", flags = "-arch x86_64 -arch ppc64", }, @@ -92,7 +92,7 @@ } local platforms = premake.gcc.platforms - + -- -- Returns a list of compiler flags, based on the supplied configuration. @@ -103,7 +103,7 @@ table.insert(flags, platforms[cfg.platform].cppflags) -- We want the -MP flag for dependency generation (creates phony rules - -- for headers, prevents make errors if file is later deleted), but + -- for headers, prevents make errors if file is later deleted), but -- Haiku doesn't support it (yet) if flags[1]:startswith("-MMD") and cfg.system ~= "haiku" then table.insert(flags, "-MP") @@ -119,23 +119,23 @@ if cfg.system ~= "windows" and cfg.kind == "SharedLib" then table.insert(result, "-fPIC") end - return result + return result end - + function premake.gcc.getcxxflags(cfg) local result = table.translate(cfg.flags, cxxflags) return result end - + -- -- Returns a list of linker flags, based on the supplied configuration. -- function premake.gcc.getldflags(cfg) local result = { } - + -- OS X has a bug, see http://lists.apple.com/archives/Darwin-dev/2006/Sep/msg00084.html if not cfg.flags.Symbols then if cfg.system == "macosx" then @@ -144,14 +144,14 @@ table.insert(result, "-s") end end - + if cfg.kind == "SharedLib" then if cfg.system == "macosx" then table.insert(result, "-dynamiclib") else table.insert(result, "-shared") end - + if cfg.system == "windows" and not cfg.flags.NoImportLib then table.insert(result, '-Wl,--out-implib="' .. cfg.linktarget.fullpath .. '"') end @@ -160,18 +160,18 @@ if cfg.kind == "WindowedApp" and cfg.system == "windows" then table.insert(result, "-mwindows") end - + local platform = platforms[cfg.platform] table.insert(result, platform.flags) table.insert(result, platform.ldflags) - + return result end - + -- -- Return a list of library search paths. Technically part of LDFLAGS but need to --- be separated because of the way Visual Studio calls GCC for the PS3. See bug +-- be separated because of the way Visual Studio calls GCC for the PS3. See bug -- #1729227 for background on why library paths must be split. -- @@ -182,7 +182,7 @@ end return result end - + -- @@ -211,7 +211,7 @@ end -- "-llib" is fine for system dependencies - for _, value in ipairs(premake.getlinks(cfg, "system", "basename")) do + for _, value in ipairs(premake.getlinks(cfg, "system", "name")) do if path.getextension(value) == ".framework" then table.insert(result, '-framework ' .. _MAKE.esc(path.getbasename(value))) else @@ -220,8 +220,8 @@ end return result end - - + + -- -- Decorate defines for the GCC command line. @@ -236,7 +236,7 @@ end - + -- -- Decorate include file search paths for the GCC command line. -- @@ -250,10 +250,10 @@ end --- +-- -- Return platform specific project and configuration level -- makesettings blocks. --- +-- function premake.gcc.getcfgsettings(cfg) return platforms[cfg.platform].cfgsettings diff --git a/tests/actions/make/test_make_linking.lua b/tests/actions/make/test_make_linking.lua index f9d9c5d..ef85353 100644 --- a/tests/actions/make/test_make_linking.lua +++ b/tests/actions/make/test_make_linking.lua @@ -106,3 +106,20 @@ ]] end + +-- +-- When referencing an external library via a path, the directory +-- should be added to the library search paths, and the library +-- itself included via an -l flag. +-- + + function suite.onExternalLibraryWithPath() + location "MyProject" + links { "libs/SomeLib" } + prepare() + test.capture [[ + ALL_LDFLAGS += $(LDFLAGS) -L../libs -s + LIBS += -lSomeLib + LDDEPS += + ]] + end |