ENH: Implement linking with paths to library files instead of -L and -l separation. See bug #3832
- This is purely an implementation improvement. No interface has changed. - Create cmComputeLinkInformation class - Move and re-implement logic from: cmLocalGenerator::ComputeLinkInformation cmOrderLinkDirectories - Link libraries to targets with their full path (if it is known) - Dirs specified with link_directories command still added with -L - Make link type specific to library names without paths (name libfoo.a without path becomes -Wl,-Bstatic -lfoo) - Make directory ordering specific to a runtime path computation feature (look for conflicting SONAMEs instead of library names) - Implement proper rpath support on HP-UX and AIX.
This commit is contained in:
parent
0df9e6904c
commit
96fd5909d9
@ -149,6 +149,14 @@ IF(NOT CMAKE_C_LINK_EXECUTABLE)
|
|||||||
"<CMAKE_C_COMPILER> <FLAGS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
|
"<CMAKE_C_COMPILER> <FLAGS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
|
||||||
ENDIF(NOT CMAKE_C_LINK_EXECUTABLE)
|
ENDIF(NOT CMAKE_C_LINK_EXECUTABLE)
|
||||||
|
|
||||||
|
IF(NOT CMAKE_EXECUTABLE_RUNTIME_C_FLAG)
|
||||||
|
SET(CMAKE_EXECUTABLE_RUNTIME_C_FLAG ${CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG})
|
||||||
|
ENDIF(NOT CMAKE_EXECUTABLE_RUNTIME_C_FLAG)
|
||||||
|
|
||||||
|
IF(NOT CMAKE_EXECUTABLE_RUNTIME_C_FLAG_SEP)
|
||||||
|
SET(CMAKE_EXECUTABLE_RUNTIME_C_FLAG_SEP ${CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG_SEP})
|
||||||
|
ENDIF(NOT CMAKE_EXECUTABLE_RUNTIME_C_FLAG_SEP)
|
||||||
|
|
||||||
MARK_AS_ADVANCED(
|
MARK_AS_ADVANCED(
|
||||||
CMAKE_C_FLAGS
|
CMAKE_C_FLAGS
|
||||||
CMAKE_C_FLAGS_DEBUG
|
CMAKE_C_FLAGS_DEBUG
|
||||||
|
@ -84,6 +84,18 @@ IF(NOT CMAKE_SHARED_LIBRARY_RUNTIME_CXX_FLAG_SEP)
|
|||||||
SET(CMAKE_SHARED_LIBRARY_RUNTIME_CXX_FLAG_SEP ${CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG_SEP})
|
SET(CMAKE_SHARED_LIBRARY_RUNTIME_CXX_FLAG_SEP ${CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG_SEP})
|
||||||
ENDIF(NOT CMAKE_SHARED_LIBRARY_RUNTIME_CXX_FLAG_SEP)
|
ENDIF(NOT CMAKE_SHARED_LIBRARY_RUNTIME_CXX_FLAG_SEP)
|
||||||
|
|
||||||
|
IF(NOT CMAKE_EXECUTABLE_RUNTIME_CXX_FLAG)
|
||||||
|
SET(CMAKE_EXECUTABLE_RUNTIME_CXX_FLAG ${CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG})
|
||||||
|
ENDIF(NOT CMAKE_EXECUTABLE_RUNTIME_CXX_FLAG)
|
||||||
|
|
||||||
|
IF(NOT CMAKE_EXECUTABLE_RUNTIME_CXX_FLAG_SEP)
|
||||||
|
SET(CMAKE_EXECUTABLE_RUNTIME_CXX_FLAG_SEP ${CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG_SEP})
|
||||||
|
ENDIF(NOT CMAKE_EXECUTABLE_RUNTIME_CXX_FLAG_SEP)
|
||||||
|
|
||||||
|
IF(NOT DEFINED CMAKE_SHARED_LIBRARY_LINK_CXX_WITH_RUNTIME_PATH)
|
||||||
|
SET(CMAKE_SHARED_LIBRARY_LINK_CXX_WITH_RUNTIME_PATH ${CMAKE_SHARED_LIBRARY_LINK_C_WITH_RUNTIME_PATH})
|
||||||
|
ENDIF(NOT DEFINED CMAKE_SHARED_LIBRARY_LINK_CXX_WITH_RUNTIME_PATH)
|
||||||
|
|
||||||
IF(NOT CMAKE_INCLUDE_FLAG_CXX)
|
IF(NOT CMAKE_INCLUDE_FLAG_CXX)
|
||||||
SET(CMAKE_INCLUDE_FLAG_CXX ${CMAKE_INCLUDE_FLAG_C})
|
SET(CMAKE_INCLUDE_FLAG_CXX ${CMAKE_INCLUDE_FLAG_C})
|
||||||
ENDIF(NOT CMAKE_INCLUDE_FLAG_CXX)
|
ENDIF(NOT CMAKE_INCLUDE_FLAG_CXX)
|
||||||
|
@ -76,6 +76,18 @@ IF(NOT CMAKE_SHARED_MODULE_RUNTIME_Fortran_FLAG_SEP)
|
|||||||
SET(CMAKE_SHARED_MODULE_RUNTIME_Fortran_FLAG_SEP ${CMAKE_SHARED_MODULE_RUNTIME_C_FLAG_SEP})
|
SET(CMAKE_SHARED_MODULE_RUNTIME_Fortran_FLAG_SEP ${CMAKE_SHARED_MODULE_RUNTIME_C_FLAG_SEP})
|
||||||
ENDIF(NOT CMAKE_SHARED_MODULE_RUNTIME_Fortran_FLAG_SEP)
|
ENDIF(NOT CMAKE_SHARED_MODULE_RUNTIME_Fortran_FLAG_SEP)
|
||||||
|
|
||||||
|
IF(NOT CMAKE_EXECUTABLE_RUNTIME_Fortran_FLAG)
|
||||||
|
SET(CMAKE_EXECUTABLE_RUNTIME_Fortran_FLAG ${CMAKE_SHARED_LIBRARY_RUNTIME_Fortran_FLAG})
|
||||||
|
ENDIF(NOT CMAKE_EXECUTABLE_RUNTIME_Fortran_FLAG)
|
||||||
|
|
||||||
|
IF(NOT CMAKE_EXECUTABLE_RUNTIME_Fortran_FLAG_SEP)
|
||||||
|
SET(CMAKE_EXECUTABLE_RUNTIME_Fortran_FLAG_SEP ${CMAKE_SHARED_LIBRARY_RUNTIME_Fortran_FLAG_SEP})
|
||||||
|
ENDIF(NOT CMAKE_EXECUTABLE_RUNTIME_Fortran_FLAG_SEP)
|
||||||
|
|
||||||
|
IF(NOT DEFINED CMAKE_SHARED_LIBRARY_LINK_Fortran_WITH_RUNTIME_PATH)
|
||||||
|
SET(CMAKE_SHARED_LIBRARY_LINK_Fortran_WITH_RUNTIME_PATH ${CMAKE_SHARED_LIBRARY_LINK_C_WITH_RUNTIME_PATH})
|
||||||
|
ENDIF(NOT DEFINED CMAKE_SHARED_LIBRARY_LINK_Fortran_WITH_RUNTIME_PATH)
|
||||||
|
|
||||||
IF(NOT CMAKE_INCLUDE_FLAG_Fortran)
|
IF(NOT CMAKE_INCLUDE_FLAG_Fortran)
|
||||||
SET(CMAKE_INCLUDE_FLAG_Fortran ${CMAKE_INCLUDE_FLAG_C})
|
SET(CMAKE_INCLUDE_FLAG_Fortran ${CMAKE_INCLUDE_FLAG_C})
|
||||||
ENDIF(NOT CMAKE_INCLUDE_FLAG_Fortran)
|
ENDIF(NOT CMAKE_INCLUDE_FLAG_Fortran)
|
||||||
|
@ -1,15 +1,23 @@
|
|||||||
SET(CMAKE_SHARED_LIBRARY_PREFIX "lib") # lib
|
SET(CMAKE_SHARED_LIBRARY_PREFIX "lib") # lib
|
||||||
SET(CMAKE_SHARED_LIBRARY_SUFFIX ".so") # .so
|
SET(CMAKE_SHARED_LIBRARY_SUFFIX ".so") # .so
|
||||||
SET(CMAKE_DL_LIBS "-lld")
|
SET(CMAKE_DL_LIBS "-lld")
|
||||||
SET(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-G -Wl,-brtl") # -shared
|
|
||||||
SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "-Wl,-brtl,-bexpall") # +s, flag for exe link to use shared lib
|
# RPATH support on AIX is called libpath. By default the runtime
|
||||||
|
# libpath is paths specified by -L followed by /usr/lib and /lib. In
|
||||||
|
# order to prevent the -L paths from being used we must force use of
|
||||||
|
# -Wl,-blibpath:/usr/lib:/lib whether RPATH support is on or not.
|
||||||
|
# When our own RPATH is to be added it may be inserted before the
|
||||||
|
# "always" paths.
|
||||||
|
SET(CMAKE_PLATFORM_REQUIRED_RUNTIME_PATH /usr/lib /lib)
|
||||||
|
SET(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "-Wl,-blibpath:")
|
||||||
|
SET(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG_SEP ":")
|
||||||
|
|
||||||
# CXX Compiler
|
# CXX Compiler
|
||||||
IF(CMAKE_COMPILER_IS_GNUCXX)
|
IF(CMAKE_COMPILER_IS_GNUCXX)
|
||||||
SET(CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS "-shared -Wl,-G") # -shared
|
SET(CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS "-shared -Wl,-G") # -shared
|
||||||
ELSE(CMAKE_COMPILER_IS_GNUCXX)
|
ELSE(CMAKE_COMPILER_IS_GNUCXX)
|
||||||
SET(CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS "-G -Wl,-brtl") # -shared
|
SET(CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS "-G -Wl,-brtl,-bnoipath") # -shared
|
||||||
SET(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "-Wl,-brtl,-bexpall") # +s, flag for exe link to use shared lib
|
SET(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "-Wl,-brtl,-bnoipath,-bexpall") # +s, flag for exe link to use shared lib
|
||||||
SET(CMAKE_SHARED_LIBRARY_CXX_FLAGS " ")
|
SET(CMAKE_SHARED_LIBRARY_CXX_FLAGS " ")
|
||||||
SET(CMAKE_SHARED_MODULE_CXX_FLAGS " ")
|
SET(CMAKE_SHARED_MODULE_CXX_FLAGS " ")
|
||||||
SET (CMAKE_CXX_FLAGS_DEBUG_INIT "-g")
|
SET (CMAKE_CXX_FLAGS_DEBUG_INIT "-g")
|
||||||
@ -22,8 +30,8 @@ ENDIF(CMAKE_COMPILER_IS_GNUCXX)
|
|||||||
IF(CMAKE_COMPILER_IS_GNUCC)
|
IF(CMAKE_COMPILER_IS_GNUCC)
|
||||||
SET(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-shared -Wl,-G") # -shared
|
SET(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-shared -Wl,-G") # -shared
|
||||||
ELSE(CMAKE_COMPILER_IS_GNUCC)
|
ELSE(CMAKE_COMPILER_IS_GNUCC)
|
||||||
SET(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-G -Wl,-brtl") # -shared
|
SET(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-G -Wl,-brtl,-bnoipath") # -shared
|
||||||
SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "-Wl,-brtl,-bexpall") # +s, flag for exe link to use shared lib
|
SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "-Wl,-brtl,-bnoipath,-bexpall") # +s, flag for exe link to use shared lib
|
||||||
SET(CMAKE_SHARED_LIBRARY_C_FLAGS " ")
|
SET(CMAKE_SHARED_LIBRARY_C_FLAGS " ")
|
||||||
SET(CMAKE_SHARED_MODULE_C_FLAGS " ")
|
SET(CMAKE_SHARED_MODULE_C_FLAGS " ")
|
||||||
SET (CMAKE_C_FLAGS_DEBUG_INIT "-g")
|
SET (CMAKE_C_FLAGS_DEBUG_INIT "-g")
|
||||||
|
@ -2,15 +2,18 @@ SET(CMAKE_SHARED_LIBRARY_SUFFIX ".sl") # .so
|
|||||||
SET(CMAKE_DL_LIBS "dld")
|
SET(CMAKE_DL_LIBS "dld")
|
||||||
SET(CMAKE_FIND_LIBRARY_SUFFIXES ".sl" ".so" ".a")
|
SET(CMAKE_FIND_LIBRARY_SUFFIXES ".sl" ".so" ".a")
|
||||||
|
|
||||||
SET(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG_SEP ":") # : or empty
|
# The HP linker needs to find transitive shared library dependencies
|
||||||
|
# in the -L path. Therefore the runtime path must be added to the
|
||||||
|
# link line with -L flags.
|
||||||
|
SET(CMAKE_SHARED_LIBRARY_LINK_C_WITH_RUNTIME_PATH 1)
|
||||||
|
|
||||||
# fortran
|
# fortran
|
||||||
IF(CMAKE_COMPILER_IS_GNUG77)
|
IF(CMAKE_COMPILER_IS_GNUG77)
|
||||||
SET(CMAKE_SHARED_LIBRARY_Fortran_FLAGS "-fPIC") # -pic
|
SET(CMAKE_SHARED_LIBRARY_Fortran_FLAGS "-fPIC") # -pic
|
||||||
SET(CMAKE_SHARED_LIBRARY_CREATE_Fortran_FLAGS "-shared -Wl,-E -Wl,-b") # -shared
|
SET(CMAKE_SHARED_LIBRARY_CREATE_Fortran_FLAGS "-shared -Wl,-E,-b,+nodefaultrpath") # -shared
|
||||||
SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "-Wl,+s -Wl,-E") # +s, flag for exe link to use shared lib
|
SET(CMAKE_SHARED_LIBRARY_LINK_Fortran_FLAGS "-Wl,+s,-E,+nodefaultrpath") # +s, flag for exe link to use shared lib
|
||||||
SET(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "-Wl,+b") # -rpath
|
SET(CMAKE_SHARED_LIBRARY_RUNTIME_Fortran_FLAG "-Wl,+b") # -rpath
|
||||||
SET(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG_SEP ":") # : or empty
|
SET(CMAKE_SHARED_LIBRARY_RUNTIME_Fortran_FLAG_SEP ":") # : or empty
|
||||||
SET(CMAKE_SHARED_LIBRARY_SONAME_Fortran_FLAG "-Wl,+h")
|
SET(CMAKE_SHARED_LIBRARY_SONAME_Fortran_FLAG "-Wl,+h")
|
||||||
SET(CMAKE_SHARED_LIBRARY_Fortran_FLAGS "-fPIC") # -pic
|
SET(CMAKE_SHARED_LIBRARY_Fortran_FLAGS "-fPIC") # -pic
|
||||||
ELSE(CMAKE_COMPILER_IS_GNUG77)
|
ELSE(CMAKE_COMPILER_IS_GNUG77)
|
||||||
@ -19,16 +22,19 @@ ELSE(CMAKE_COMPILER_IS_GNUG77)
|
|||||||
"ld <CMAKE_SHARED_LIBRARY_CREATE_Fortran_FLAGS> <CMAKE_SHARED_LIBRARY_SONAME_Fortran_FLAG><TARGET_SONAME> <LINK_FLAGS> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>")
|
"ld <CMAKE_SHARED_LIBRARY_CREATE_Fortran_FLAGS> <CMAKE_SHARED_LIBRARY_SONAME_Fortran_FLAG><TARGET_SONAME> <LINK_FLAGS> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>")
|
||||||
SET(CMAKE_SHARED_LIBRARY_Fortran_FLAGS "+Z") # -pic
|
SET(CMAKE_SHARED_LIBRARY_Fortran_FLAGS "+Z") # -pic
|
||||||
SET(CMAKE_SHARED_LIBRARY_CREATE_Fortran_FLAGS "-E -b -L/usr/lib") # -shared
|
SET(CMAKE_SHARED_LIBRARY_CREATE_Fortran_FLAGS "-E -b -L/usr/lib") # -shared
|
||||||
SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "-Wl,+s -Wl,-E") # +s, flag for exe link to use shared lib
|
SET(CMAKE_SHARED_LIBRARY_LINK_Fortran_FLAGS "-Wl,+s,-E,+nodefaultrpath") # +s, flag for exe link to use shared lib
|
||||||
SET(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "+b") # -rpath
|
SET(CMAKE_SHARED_LIBRARY_RUNTIME_Fortran_FLAG "+b") # -rpath
|
||||||
|
SET(CMAKE_SHARED_LIBRARY_RUNTIME_Fortran_FLAG_SEP ":") # : or empty
|
||||||
SET(CMAKE_SHARED_LIBRARY_SONAME_Fortran_FLAG "+h")
|
SET(CMAKE_SHARED_LIBRARY_SONAME_Fortran_FLAG "+h")
|
||||||
|
SET(CMAKE_EXECUTABLE_RUNTIME_Fortran_FLAG "-Wl,+b") # -rpath
|
||||||
ENDIF(CMAKE_COMPILER_IS_GNUG77)
|
ENDIF(CMAKE_COMPILER_IS_GNUG77)
|
||||||
|
|
||||||
# C compiler
|
# C compiler
|
||||||
IF(CMAKE_COMPILER_IS_GNUCC)
|
IF(CMAKE_COMPILER_IS_GNUCC)
|
||||||
# gnu gcc
|
# gnu gcc
|
||||||
SET(CMAKE_SHARED_LIBRARY_C_FLAGS "-fPIC") # -pic
|
SET(CMAKE_SHARED_LIBRARY_C_FLAGS "-fPIC") # -pic
|
||||||
SET(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-shared -Wl,-E -Wl,-b") # -shared
|
SET(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-shared -Wl,-E,-b,+nodefaultrpath") # -shared
|
||||||
SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "-Wl,+s -Wl,-E") # +s, flag for exe link to use shared lib
|
SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "-Wl,+s,-E,+nodefaultrpath") # +s, flag for exe link to use shared lib
|
||||||
SET(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "-Wl,+b") # -rpath
|
SET(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "-Wl,+b") # -rpath
|
||||||
SET(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG_SEP ":") # : or empty
|
SET(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG_SEP ":") # : or empty
|
||||||
SET(CMAKE_SHARED_LIBRARY_SONAME_C_FLAG "-Wl,+h")
|
SET(CMAKE_SHARED_LIBRARY_SONAME_C_FLAG "-Wl,+h")
|
||||||
@ -40,28 +46,33 @@ ELSE(CMAKE_COMPILER_IS_GNUCC)
|
|||||||
SET(CMAKE_C_CREATE_SHARED_LIBRARY
|
SET(CMAKE_C_CREATE_SHARED_LIBRARY
|
||||||
"ld <CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS> <CMAKE_SHARED_LIBRARY_SONAME_C_FLAG><TARGET_SONAME> <LINK_FLAGS> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>")
|
"ld <CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS> <CMAKE_SHARED_LIBRARY_SONAME_C_FLAG><TARGET_SONAME> <LINK_FLAGS> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>")
|
||||||
SET(CMAKE_SHARED_LIBRARY_C_FLAGS "+Z") # -pic
|
SET(CMAKE_SHARED_LIBRARY_C_FLAGS "+Z") # -pic
|
||||||
SET(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-E -b -L/usr/lib") # -shared
|
SET(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-E -b +nodefaultrpath -L/usr/lib") # -shared
|
||||||
SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "-Wl,+s -Wl,-E") # +s, flag for exe link to use shared lib
|
SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "-Wl,+s,-E,+nodefaultrpath") # +s, flag for exe link to use shared lib
|
||||||
SET(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "+b") # -rpath
|
SET(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "+b") # -rpath
|
||||||
|
SET(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG_SEP ":") # : or empty
|
||||||
SET(CMAKE_SHARED_LIBRARY_SONAME_C_FLAG "+h")
|
SET(CMAKE_SHARED_LIBRARY_SONAME_C_FLAG "+h")
|
||||||
|
SET(CMAKE_EXECUTABLE_RUNTIME_C_FLAG "-Wl,+b") # -rpath
|
||||||
ENDIF(CMAKE_COMPILER_IS_GNUCC)
|
ENDIF(CMAKE_COMPILER_IS_GNUCC)
|
||||||
|
|
||||||
# CXX compiler
|
# CXX compiler
|
||||||
IF(CMAKE_COMPILER_IS_GNUCXX)
|
IF(CMAKE_COMPILER_IS_GNUCXX)
|
||||||
# for gnu C++
|
# for gnu C++
|
||||||
SET(CMAKE_SHARED_LIBRARY_CXX_FLAGS "-fPIC") # -pic
|
SET(CMAKE_SHARED_LIBRARY_CXX_FLAGS "-fPIC") # -pic
|
||||||
SET(CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS "-shared -Wl,-E -Wl,-b") # -shared
|
SET(CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS "-shared -Wl,-E,-b,+nodefaultrpath") # -shared
|
||||||
SET(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "-Wl,+s -Wl,-E") # +s, flag for exe link to use shared lib
|
SET(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "-Wl,+s,-E,+nodefaultrpath") # +s, flag for exe link to use shared lib
|
||||||
SET(CMAKE_SHARED_LIBRARY_RUNTIME_CXX_FLAG "-Wl,+b") # -rpath
|
SET(CMAKE_SHARED_LIBRARY_RUNTIME_CXX_FLAG "-Wl,+b") # -rpath
|
||||||
|
SET(CMAKE_SHARED_LIBRARY_RUNTIME_CXX_FLAG_SEP ":") # : or empty
|
||||||
SET(CMAKE_SHARED_LIBRARY_CXX_FLAGS "-fPIC") # -pic
|
SET(CMAKE_SHARED_LIBRARY_CXX_FLAGS "-fPIC") # -pic
|
||||||
SET(CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG "-Wl,+h")
|
SET(CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG "-Wl,+h")
|
||||||
ELSE(CMAKE_COMPILER_IS_GNUCXX)
|
ELSE(CMAKE_COMPILER_IS_GNUCXX)
|
||||||
# for hp aCC
|
# for hp aCC
|
||||||
SET(CMAKE_SHARED_LIBRARY_CXX_FLAGS "+Z") # -pic
|
SET(CMAKE_SHARED_LIBRARY_CXX_FLAGS "+Z") # -pic
|
||||||
SET(CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS "+Z -Wl,-E -b -L/usr/lib") # -shared
|
SET(CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS "+Z -Wl,-E -b +nodefaultrpath -L/usr/lib") # -shared
|
||||||
SET(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "-Wl,+s -Wl,-E") # +s, flag for exe link to use shared lib
|
SET(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "-Wl,+s,-E,+nodefaultrpath") # +s, flag for exe link to use shared lib
|
||||||
SET(CMAKE_SHARED_LIBRARY_RUNTIME_CXX_FLAG "-Wl,+b") # -rpath
|
SET(CMAKE_SHARED_LIBRARY_RUNTIME_CXX_FLAG "-Wl,+b") # -rpath
|
||||||
|
SET(CMAKE_SHARED_LIBRARY_RUNTIME_CXX_FLAG_SEP ":") # : or empty
|
||||||
SET(CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG "-Wl,+h")
|
SET(CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG "-Wl,+h")
|
||||||
|
SET(CMAKE_EXECUTABLE_RUNTIME_CXX_FLAG "-Wl,+b") # -rpath
|
||||||
SET (CMAKE_CXX_FLAGS_INIT "")
|
SET (CMAKE_CXX_FLAGS_INIT "")
|
||||||
SET (CMAKE_CXX_FLAGS_DEBUG_INIT "-g")
|
SET (CMAKE_CXX_FLAGS_DEBUG_INIT "-g")
|
||||||
SET (CMAKE_CXX_FLAGS_MINSIZEREL_INIT "+O3 -DNDEBUG")
|
SET (CMAKE_CXX_FLAGS_MINSIZEREL_INIT "+O3 -DNDEBUG")
|
||||||
|
@ -87,6 +87,8 @@ SET(SRCS
|
|||||||
cmCommandArgumentLexer.cxx
|
cmCommandArgumentLexer.cxx
|
||||||
cmCommandArgumentParser.cxx
|
cmCommandArgumentParser.cxx
|
||||||
cmCommandArgumentParserHelper.cxx
|
cmCommandArgumentParserHelper.cxx
|
||||||
|
cmComputeLinkInformation.cxx
|
||||||
|
cmComputeLinkInformation.h
|
||||||
cmCustomCommand.cxx
|
cmCustomCommand.cxx
|
||||||
cmCustomCommand.h
|
cmCustomCommand.h
|
||||||
cmDepends.cxx
|
cmDepends.cxx
|
||||||
@ -151,7 +153,6 @@ SET(SRCS
|
|||||||
cmMakefileExecutableTargetGenerator.cxx
|
cmMakefileExecutableTargetGenerator.cxx
|
||||||
cmMakefileLibraryTargetGenerator.cxx
|
cmMakefileLibraryTargetGenerator.cxx
|
||||||
cmMakefileUtilityTargetGenerator.cxx
|
cmMakefileUtilityTargetGenerator.cxx
|
||||||
cmOrderLinkDirectories.cxx
|
|
||||||
cmProperty.cxx
|
cmProperty.cxx
|
||||||
cmProperty.h
|
cmProperty.h
|
||||||
cmPropertyDefinition.cxx
|
cmPropertyDefinition.cxx
|
||||||
|
1157
Source/cmComputeLinkInformation.cxx
Normal file
1157
Source/cmComputeLinkInformation.cxx
Normal file
File diff suppressed because it is too large
Load Diff
165
Source/cmComputeLinkInformation.h
Normal file
165
Source/cmComputeLinkInformation.h
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
/*=========================================================================
|
||||||
|
|
||||||
|
Program: CMake - Cross-Platform Makefile Generator
|
||||||
|
Module: $RCSfile$
|
||||||
|
Language: C++
|
||||||
|
Date: $Date$
|
||||||
|
Version: $Revision$
|
||||||
|
|
||||||
|
Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
|
||||||
|
See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
|
||||||
|
|
||||||
|
This software is distributed WITHOUT ANY WARRANTY; without even
|
||||||
|
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. See the above copyright notices for more information.
|
||||||
|
|
||||||
|
=========================================================================*/
|
||||||
|
#ifndef cmComputeLinkInformation_h
|
||||||
|
#define cmComputeLinkInformation_h
|
||||||
|
|
||||||
|
#include "cmStandardIncludes.h"
|
||||||
|
|
||||||
|
#include <cmsys/RegularExpression.hxx>
|
||||||
|
|
||||||
|
class cmGlobalGenerator;
|
||||||
|
class cmLocalGenerator;
|
||||||
|
class cmMakefile;
|
||||||
|
class cmTarget;
|
||||||
|
|
||||||
|
/** \class cmComputeLinkInformation
|
||||||
|
* \brief Compute link information for a target in one configuration.
|
||||||
|
*/
|
||||||
|
class cmComputeLinkInformation
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
cmComputeLinkInformation(cmTarget* target, const char* config);
|
||||||
|
bool Compute();
|
||||||
|
|
||||||
|
struct Item
|
||||||
|
{
|
||||||
|
Item(): Value(), IsPath(true) {}
|
||||||
|
Item(Item const& item): Value(item.Value), IsPath(item.IsPath) {}
|
||||||
|
Item(std::string const& v, bool p): Value(v), IsPath(p) {}
|
||||||
|
std::string Value;
|
||||||
|
bool IsPath;
|
||||||
|
};
|
||||||
|
typedef std::vector<Item> ItemVector;
|
||||||
|
ItemVector const& GetItems();
|
||||||
|
std::vector<std::string> const& GetDirectories();
|
||||||
|
std::vector<std::string> const& GetDepends();
|
||||||
|
std::vector<std::string> const& GetFrameworkPaths();
|
||||||
|
const char* GetLinkLanguage() const { return this->LinkLanguage; }
|
||||||
|
std::vector<std::string> const& GetRuntimeSearchPath();
|
||||||
|
private:
|
||||||
|
void AddItem(std::string const& item);
|
||||||
|
|
||||||
|
// Output information.
|
||||||
|
ItemVector Items;
|
||||||
|
std::vector<std::string> Directories;
|
||||||
|
std::vector<std::string> Depends;
|
||||||
|
std::vector<std::string> FrameworkPaths;
|
||||||
|
std::vector<std::string> RuntimeSearchPath;
|
||||||
|
|
||||||
|
// Context information.
|
||||||
|
cmTarget* Target;
|
||||||
|
cmMakefile* Makefile;
|
||||||
|
cmLocalGenerator* LocalGenerator;
|
||||||
|
cmGlobalGenerator* GlobalGenerator;
|
||||||
|
|
||||||
|
// Configuration information.
|
||||||
|
const char* Config;
|
||||||
|
const char* LinkLanguage;
|
||||||
|
|
||||||
|
// System info.
|
||||||
|
bool UseImportLibrary;
|
||||||
|
const char* LoaderFlag;
|
||||||
|
std::string LibLinkFlag;
|
||||||
|
std::string LibLinkSuffix;
|
||||||
|
|
||||||
|
// Link type adjustment.
|
||||||
|
void ComputeLinkTypeInfo();
|
||||||
|
enum LinkType { LinkUnknown, LinkStatic, LinkShared };
|
||||||
|
LinkType StartLinkType;
|
||||||
|
LinkType CurrentLinkType;
|
||||||
|
std::string StaticLinkTypeFlag;
|
||||||
|
std::string SharedLinkTypeFlag;
|
||||||
|
bool LinkTypeEnabled;
|
||||||
|
void SetCurrentLinkType(LinkType lt);
|
||||||
|
|
||||||
|
// Link item parsing.
|
||||||
|
void ComputeItemParserInfo();
|
||||||
|
std::vector<std::string> StaticLinkExtensions;
|
||||||
|
std::vector<std::string> SharedLinkExtensions;
|
||||||
|
std::vector<std::string> LinkExtensions;
|
||||||
|
std::set<cmStdString> LinkPrefixes;
|
||||||
|
cmsys::RegularExpression RemoveLibraryExtension;
|
||||||
|
cmsys::RegularExpression ExtractStaticLibraryName;
|
||||||
|
cmsys::RegularExpression ExtractSharedLibraryName;
|
||||||
|
cmsys::RegularExpression ExtractAnyLibraryName;
|
||||||
|
void AddLinkPrefix(const char* p);
|
||||||
|
void AddLinkExtension(const char* e, LinkType type);
|
||||||
|
std::string CreateExtensionRegex(std::vector<std::string> const& exts);
|
||||||
|
std::string NoCaseExpression(const char* str);
|
||||||
|
|
||||||
|
// Handling of link items that are not targets or full file paths.
|
||||||
|
void AddUserItem(std::string const& item);
|
||||||
|
void AddDirectoryItem(std::string const& item);
|
||||||
|
void AddFrameworkItem(std::string const& item);
|
||||||
|
void DropDirectoryItem(std::string const& item);
|
||||||
|
|
||||||
|
// Framework info.
|
||||||
|
void ComputeFrameworkInfo();
|
||||||
|
void AddFrameworkPath(std::string const& p);
|
||||||
|
std::set<cmStdString> FrameworkPathsEmmitted;
|
||||||
|
cmsys::RegularExpression SplitFramework;
|
||||||
|
|
||||||
|
// Linker search path computation.
|
||||||
|
void ComputeLinkerSearchDirectories();
|
||||||
|
void AddLinkerSearchDirectories(std::vector<std::string> const& dirs);
|
||||||
|
std::set<cmStdString> DirectoriesEmmitted;
|
||||||
|
|
||||||
|
// Runtime path computation.
|
||||||
|
struct LibraryRuntimeEntry
|
||||||
|
{
|
||||||
|
// The file name of the library.
|
||||||
|
std::string FileName;
|
||||||
|
|
||||||
|
// The soname of the shared library if it is known.
|
||||||
|
std::string SOName;
|
||||||
|
|
||||||
|
// The directory in which the library is supposed to be found.
|
||||||
|
std::string Directory;
|
||||||
|
|
||||||
|
// The index assigned to the directory.
|
||||||
|
int DirectoryIndex;
|
||||||
|
};
|
||||||
|
bool RuntimeSearchPathComputed;
|
||||||
|
std::vector<LibraryRuntimeEntry> LibraryRuntimeInfo;
|
||||||
|
std::set<cmStdString> LibraryRuntimeInfoEmmitted;
|
||||||
|
std::vector<std::string> RuntimeDirectories;
|
||||||
|
std::map<cmStdString, int> RuntimeDirectoryIndex;
|
||||||
|
std::vector<char> RuntimeDirectoryVisited;
|
||||||
|
void AddLibraryRuntimeInfo(std::string const& fullPath, cmTarget* target);
|
||||||
|
void AddLibraryRuntimeInfo(std::string const& fullPath,
|
||||||
|
const char* soname = 0);
|
||||||
|
void CollectRuntimeDirectories();
|
||||||
|
int AddRuntimeDirectory(std::string const& dir);
|
||||||
|
void FindConflictingLibraries();
|
||||||
|
void FindDirectoriesForLib(unsigned int lri);
|
||||||
|
void OrderRuntimeSearchPath();
|
||||||
|
void VisitRuntimeDirectory(unsigned int i, bool top);
|
||||||
|
void DiagnoseCycle();
|
||||||
|
bool CycleDiagnosed;
|
||||||
|
|
||||||
|
// Adjacency-list representation of runtime path ordering graph.
|
||||||
|
// This maps from directory to those that must come *before* it.
|
||||||
|
// Each entry that must come before is a pair. The first element is
|
||||||
|
// the index of the directory that must come first. The second
|
||||||
|
// element is the index of the runtime library that added the
|
||||||
|
// constraint.
|
||||||
|
typedef std::pair<int, int> RuntimeConflictPair;
|
||||||
|
struct RuntimeConflictList: public std::vector<RuntimeConflictPair> {};
|
||||||
|
std::vector<RuntimeConflictList> RuntimeConflictGraph;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -1035,6 +1035,12 @@ void cmDocumentVariables::DefineVariables(cmake* cm)
|
|||||||
cmProperty::VARIABLE,0,0);
|
cmProperty::VARIABLE,0,0);
|
||||||
cm->DefineProperty("CMAKE_SHARED_LIBRARY_RUNTIME_<LANG>_FLAG_SEP",
|
cm->DefineProperty("CMAKE_SHARED_LIBRARY_RUNTIME_<LANG>_FLAG_SEP",
|
||||||
cmProperty::VARIABLE,0,0);
|
cmProperty::VARIABLE,0,0);
|
||||||
|
cm->DefineProperty("CMAKE_EXECUTABLE_RUNTIME_<LANG>_FLAG",
|
||||||
|
cmProperty::VARIABLE,0,0);
|
||||||
|
cm->DefineProperty("CMAKE_EXECUTABLE_RUNTIME_<LANG>_FLAG_SEP",
|
||||||
|
cmProperty::VARIABLE,0,0);
|
||||||
|
cm->DefineProperty("CMAKE_PLATFORM_REQUIRED_RUNTIME_PATH",
|
||||||
|
cmProperty::VARIABLE,0,0);
|
||||||
cm->DefineProperty("CMAKE_SHARED_MODULE_CREATE_<LANG>_FLAGS",
|
cm->DefineProperty("CMAKE_SHARED_MODULE_CREATE_<LANG>_FLAGS",
|
||||||
cmProperty::VARIABLE,0,0);
|
cmProperty::VARIABLE,0,0);
|
||||||
cm->DefineProperty("CMAKE_SHARED_MODULE_<LANG>_FLAGS",
|
cm->DefineProperty("CMAKE_SHARED_MODULE_<LANG>_FLAGS",
|
||||||
|
@ -27,6 +27,8 @@
|
|||||||
#include "cmVersion.h"
|
#include "cmVersion.h"
|
||||||
#include "cmInstallExportGenerator.h"
|
#include "cmInstallExportGenerator.h"
|
||||||
|
|
||||||
|
#include <cmsys/Directory.hxx>
|
||||||
|
|
||||||
#include <stdlib.h> // required for atof
|
#include <stdlib.h> // required for atof
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
@ -784,7 +786,7 @@ void cmGlobalGenerator::Generate()
|
|||||||
// Compute the manifest of main targets generated.
|
// Compute the manifest of main targets generated.
|
||||||
for (i = 0; i < this->LocalGenerators.size(); ++i)
|
for (i = 0; i < this->LocalGenerators.size(); ++i)
|
||||||
{
|
{
|
||||||
this->LocalGenerators[i]->GenerateTargetManifest(this->TargetManifest);
|
this->LocalGenerators[i]->GenerateTargetManifest();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a map from local generator to the complete set of targets
|
// Create a map from local generator to the complete set of targets
|
||||||
@ -1880,3 +1882,42 @@ cmGlobalGenerator
|
|||||||
this->FilesReplacedDuringGenerate.end(),
|
this->FilesReplacedDuringGenerate.end(),
|
||||||
std::back_inserter(filenames));
|
std::back_inserter(filenames));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void cmGlobalGenerator::AddToManifest(const char* config,
|
||||||
|
std::string const& f)
|
||||||
|
{
|
||||||
|
// Add to the main manifest for this configuration.
|
||||||
|
this->TargetManifest[config].insert(f);
|
||||||
|
|
||||||
|
// Add to the content listing for the file's directory.
|
||||||
|
std::string dir = cmSystemTools::GetFilenamePath(f);
|
||||||
|
std::string file = cmSystemTools::GetFilenameName(f);
|
||||||
|
this->DirectoryContentMap[dir].insert(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
std::set<cmStdString> const&
|
||||||
|
cmGlobalGenerator::GetDirectoryContent(std::string const& dir, bool needDisk)
|
||||||
|
{
|
||||||
|
DirectoryContent& dc = this->DirectoryContentMap[dir];
|
||||||
|
if(needDisk && !dc.LoadedFromDisk)
|
||||||
|
{
|
||||||
|
// Load the directory content from disk.
|
||||||
|
cmsys::Directory d;
|
||||||
|
if(d.Load(dir.c_str()))
|
||||||
|
{
|
||||||
|
unsigned long n = d.GetNumberOfFiles();
|
||||||
|
for(unsigned long i = 0; i < n; ++i)
|
||||||
|
{
|
||||||
|
const char* f = d.GetFile(i);
|
||||||
|
if(strcmp(f, ".") != 0 && strcmp(f, "..") != 0)
|
||||||
|
{
|
||||||
|
dc.insert(f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dc.LoadedFromDisk = true;
|
||||||
|
}
|
||||||
|
return dc;
|
||||||
|
}
|
||||||
|
@ -150,6 +150,9 @@ public:
|
|||||||
///! Get the export target set with the given name
|
///! Get the export target set with the given name
|
||||||
const std::vector<cmTargetExport*>* GetExportSet(const char* name) const;
|
const std::vector<cmTargetExport*>* GetExportSet(const char* name) const;
|
||||||
|
|
||||||
|
/** Add a file to the manifest of generated targets for a configuration. */
|
||||||
|
void AddToManifest(const char* config, std::string const& f);
|
||||||
|
|
||||||
void EnableInstallTarget();
|
void EnableInstallTarget();
|
||||||
|
|
||||||
int TryCompileTimeout;
|
int TryCompileTimeout;
|
||||||
@ -209,6 +212,13 @@ public:
|
|||||||
configuration. This is valid during generation only. */
|
configuration. This is valid during generation only. */
|
||||||
cmTargetManifest const& GetTargetManifest() { return this->TargetManifest; }
|
cmTargetManifest const& GetTargetManifest() { return this->TargetManifest; }
|
||||||
|
|
||||||
|
/** Get the content of a directory on disk including the target
|
||||||
|
files to be generated. This may be called only during the
|
||||||
|
generation step. It is intended for use only by
|
||||||
|
cmComputeLinkInformation. */
|
||||||
|
std::set<cmStdString> const& GetDirectoryContent(std::string const& dir,
|
||||||
|
bool needDisk);
|
||||||
|
|
||||||
void AddTarget(cmTargets::value_type &v);
|
void AddTarget(cmTargets::value_type &v);
|
||||||
|
|
||||||
virtual const char* GetAllTargetName() { return "ALL_BUILD"; }
|
virtual const char* GetAllTargetName() { return "ALL_BUILD"; }
|
||||||
@ -304,6 +314,17 @@ private:
|
|||||||
std::vector<cmTarget const*>& steps);
|
std::vector<cmTarget const*>& steps);
|
||||||
typedef std::map<cmTarget const*, TargetDependSet> TargetDependMap;
|
typedef std::map<cmTarget const*, TargetDependSet> TargetDependMap;
|
||||||
TargetDependMap TargetDependencies;
|
TargetDependMap TargetDependencies;
|
||||||
|
|
||||||
|
// Cache directory content and target files to be built.
|
||||||
|
struct DirectoryContent: public std::set<cmStdString>
|
||||||
|
{
|
||||||
|
typedef std::set<cmStdString> derived;
|
||||||
|
bool LoadedFromDisk;
|
||||||
|
DirectoryContent(): LoadedFromDisk(false) {}
|
||||||
|
DirectoryContent(DirectoryContent const& dc):
|
||||||
|
derived(dc), LoadedFromDisk(dc.LoadedFromDisk) {}
|
||||||
|
};
|
||||||
|
std::map<cmStdString, DirectoryContent> DirectoryContentMap;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -22,6 +22,7 @@ PURPOSE. See the above copyright notices for more information.
|
|||||||
#include "cmXCode21Object.h"
|
#include "cmXCode21Object.h"
|
||||||
#include "cmake.h"
|
#include "cmake.h"
|
||||||
#include "cmGeneratedFileStream.h"
|
#include "cmGeneratedFileStream.h"
|
||||||
|
#include "cmComputeLinkInformation.h"
|
||||||
#include "cmSourceFile.h"
|
#include "cmSourceFile.h"
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@ -2107,23 +2108,27 @@ void cmGlobalXCodeGenerator
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Compute the link library and directory information.
|
// Compute the link library and directory information.
|
||||||
std::vector<cmStdString> libNames;
|
cmComputeLinkInformation cli(cmtarget, configName);
|
||||||
std::vector<cmStdString> libDirs;
|
if(!cli.Compute())
|
||||||
std::vector<cmStdString> fullPathLibs;
|
{
|
||||||
this->CurrentLocalGenerator->ComputeLinkInformation(*cmtarget, configName,
|
continue;
|
||||||
libNames, libDirs,
|
}
|
||||||
&fullPathLibs);
|
|
||||||
|
|
||||||
// Add dependencies directly on library files.
|
// Add dependencies directly on library files.
|
||||||
for(std::vector<cmStdString>::iterator j = fullPathLibs.begin();
|
{
|
||||||
j != fullPathLibs.end(); ++j)
|
std::vector<std::string> const& libDeps = cli.GetDepends();
|
||||||
|
for(std::vector<std::string>::const_iterator j = libDeps.begin();
|
||||||
|
j != libDeps.end(); ++j)
|
||||||
{
|
{
|
||||||
target->AddDependLibrary(configName, j->c_str());
|
target->AddDependLibrary(configName, j->c_str());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::string linkDirs;
|
|
||||||
// add the library search paths
|
// add the library search paths
|
||||||
for(std::vector<cmStdString>::const_iterator libDir = libDirs.begin();
|
{
|
||||||
|
std::vector<std::string> const& libDirs = cli.GetDirectories();
|
||||||
|
std::string linkDirs;
|
||||||
|
for(std::vector<std::string>::const_iterator libDir = libDirs.begin();
|
||||||
libDir != libDirs.end(); ++libDir)
|
libDir != libDirs.end(); ++libDir)
|
||||||
{
|
{
|
||||||
if(libDir->size() && *libDir != "/usr/lib")
|
if(libDir->size() && *libDir != "/usr/lib")
|
||||||
@ -2141,46 +2146,51 @@ void cmGlobalXCodeGenerator
|
|||||||
}
|
}
|
||||||
this->AppendBuildSettingAttribute(target, "LIBRARY_SEARCH_PATHS",
|
this->AppendBuildSettingAttribute(target, "LIBRARY_SEARCH_PATHS",
|
||||||
linkDirs.c_str(), configName);
|
linkDirs.c_str(), configName);
|
||||||
// now add the link libraries
|
}
|
||||||
if(cmtarget->GetType() != cmTarget::STATIC_LIBRARY)
|
|
||||||
|
// add the framework search paths
|
||||||
{
|
{
|
||||||
|
const char* sep = "";
|
||||||
std::string fdirs;
|
std::string fdirs;
|
||||||
std::set<cmStdString> emitted;
|
std::vector<std::string> const& fwDirs = cli.GetFrameworkPaths();
|
||||||
emitted.insert("/System/Library/Frameworks");
|
for(std::vector<std::string>::const_iterator fdi = fwDirs.begin();
|
||||||
for(std::vector<cmStdString>::iterator lib = libNames.begin();
|
fdi != fwDirs.end(); ++fdi)
|
||||||
lib != libNames.end(); ++lib)
|
|
||||||
{
|
{
|
||||||
std::string& libString = *lib;
|
fdirs += sep;
|
||||||
// check to see if this is a -F framework path and extract it if it is
|
sep = " ";
|
||||||
// -F framework stuff should be in the FRAMEWORK_SEARCH_PATHS and not
|
fdirs += this->XCodeEscapePath(fdi->c_str());
|
||||||
// OTHER_LDFLAGS
|
|
||||||
if(libString.size() > 2 && libString[0] == '-'
|
|
||||||
&& libString[1] == 'F')
|
|
||||||
{
|
|
||||||
std::string path = libString.substr(2);
|
|
||||||
// remove escaped spaces from the path
|
|
||||||
cmSystemTools::ReplaceString(path, "\\ ", " ");
|
|
||||||
if(emitted.insert(path).second)
|
|
||||||
{
|
|
||||||
if(fdirs.size())
|
|
||||||
{
|
|
||||||
fdirs += " ";
|
|
||||||
}
|
}
|
||||||
fdirs += this->XCodeEscapePath(path.c_str());
|
if(!fdirs.empty())
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this->AppendBuildSettingAttribute(target, "OTHER_LDFLAGS",
|
|
||||||
lib->c_str(), configName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(fdirs.size())
|
|
||||||
{
|
{
|
||||||
this->AppendBuildSettingAttribute(target, "FRAMEWORK_SEARCH_PATHS",
|
this->AppendBuildSettingAttribute(target, "FRAMEWORK_SEARCH_PATHS",
|
||||||
fdirs.c_str(), configName);
|
fdirs.c_str(), configName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// now add the link libraries
|
||||||
|
if(cmtarget->GetType() != cmTarget::STATIC_LIBRARY)
|
||||||
|
{
|
||||||
|
std::string linkLibs;
|
||||||
|
const char* sep = "";
|
||||||
|
typedef cmComputeLinkInformation::ItemVector ItemVector;
|
||||||
|
ItemVector const& libNames = cli.GetItems();
|
||||||
|
for(ItemVector::const_iterator li = libNames.begin();
|
||||||
|
li != libNames.end(); ++li)
|
||||||
|
{
|
||||||
|
linkLibs += sep;
|
||||||
|
sep = " ";
|
||||||
|
if(li->IsPath)
|
||||||
|
{
|
||||||
|
linkLibs += this->XCodeEscapePath(li->Value.c_str());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
linkLibs += li->Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this->AppendBuildSettingAttribute(target, "OTHER_LDFLAGS",
|
||||||
|
linkLibs.c_str(), configName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
=========================================================================*/
|
=========================================================================*/
|
||||||
#include "cmLocalGenerator.h"
|
#include "cmLocalGenerator.h"
|
||||||
|
|
||||||
|
#include "cmComputeLinkInformation.h"
|
||||||
#include "cmGeneratedFileStream.h"
|
#include "cmGeneratedFileStream.h"
|
||||||
#include "cmGlobalGenerator.h"
|
#include "cmGlobalGenerator.h"
|
||||||
#include "cmInstallGenerator.h"
|
#include "cmInstallGenerator.h"
|
||||||
@ -23,7 +24,6 @@
|
|||||||
#include "cmInstallScriptGenerator.h"
|
#include "cmInstallScriptGenerator.h"
|
||||||
#include "cmInstallTargetGenerator.h"
|
#include "cmInstallTargetGenerator.h"
|
||||||
#include "cmMakefile.h"
|
#include "cmMakefile.h"
|
||||||
#include "cmOrderLinkDirectories.h"
|
|
||||||
#include "cmSourceFile.h"
|
#include "cmSourceFile.h"
|
||||||
#include "cmTest.h"
|
#include "cmTest.h"
|
||||||
#include "cmake.h"
|
#include "cmake.h"
|
||||||
@ -477,7 +477,7 @@ void cmLocalGenerator::GenerateInstallRules()
|
|||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void cmLocalGenerator::GenerateTargetManifest(cmTargetManifest& manifest)
|
void cmLocalGenerator::GenerateTargetManifest()
|
||||||
{
|
{
|
||||||
// Collect the set of configuration types.
|
// Collect the set of configuration types.
|
||||||
std::vector<std::string> configNames;
|
std::vector<std::string> configNames;
|
||||||
@ -500,20 +500,9 @@ void cmLocalGenerator::GenerateTargetManifest(cmTargetManifest& manifest)
|
|||||||
for(cmTargets::iterator t = targets.begin(); t != targets.end(); ++t)
|
for(cmTargets::iterator t = targets.begin(); t != targets.end(); ++t)
|
||||||
{
|
{
|
||||||
cmTarget& target = t->second;
|
cmTarget& target = t->second;
|
||||||
cmTarget::TargetType type = target.GetType();
|
|
||||||
if(type == cmTarget::STATIC_LIBRARY ||
|
|
||||||
type == cmTarget::SHARED_LIBRARY ||
|
|
||||||
type == cmTarget::MODULE_LIBRARY ||
|
|
||||||
type == cmTarget::EXECUTABLE)
|
|
||||||
{
|
|
||||||
if(configNames.empty())
|
if(configNames.empty())
|
||||||
{
|
{
|
||||||
manifest[""].insert(target.GetFullPath(0, false));
|
target.GenerateTargetManifest(0);
|
||||||
if(type == cmTarget::SHARED_LIBRARY &&
|
|
||||||
this->Makefile->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX"))
|
|
||||||
{
|
|
||||||
manifest[""].insert(target.GetFullPath(0, true));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -521,13 +510,7 @@ void cmLocalGenerator::GenerateTargetManifest(cmTargetManifest& manifest)
|
|||||||
ci != configNames.end(); ++ci)
|
ci != configNames.end(); ++ci)
|
||||||
{
|
{
|
||||||
const char* config = ci->c_str();
|
const char* config = ci->c_str();
|
||||||
manifest[config].insert(target.GetFullPath(config, false));
|
target.GenerateTargetManifest(config);
|
||||||
if(type == cmTarget::SHARED_LIBRARY &&
|
|
||||||
this->Makefile->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX"))
|
|
||||||
{
|
|
||||||
manifest[config].insert(target.GetFullPath(config, true));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1478,50 +1461,53 @@ bool cmLocalGenerator::GetLinkerArgs(std::string& rpath,
|
|||||||
// collect all the flags needed for linking libraries
|
// collect all the flags needed for linking libraries
|
||||||
linkLibs = "";
|
linkLibs = "";
|
||||||
|
|
||||||
// Try to emit each search path once
|
|
||||||
std::set<cmStdString> emitted;
|
|
||||||
// Embed runtime search paths if possible and if required.
|
|
||||||
bool outputRuntime = true;
|
|
||||||
std::string runtimeFlag;
|
|
||||||
std::string runtimeSep;
|
|
||||||
|
|
||||||
const char* config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE");
|
const char* config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE");
|
||||||
const char* linkLanguage =
|
|
||||||
tgt.GetLinkerLanguage(this->GetGlobalGenerator());
|
cmComputeLinkInformation cli(&tgt, config);
|
||||||
if(!linkLanguage)
|
if(!cli.Compute())
|
||||||
{
|
{
|
||||||
cmSystemTools::
|
|
||||||
Error("CMake can not determine linker language for target:",
|
|
||||||
tgt.GetName());
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
std::string runTimeFlagVar = "CMAKE_SHARED_LIBRARY_RUNTIME_";
|
|
||||||
|
const char* linkLanguage = cli.GetLinkLanguage();
|
||||||
|
|
||||||
|
// Embed runtime search paths if possible and if required.
|
||||||
|
bool outputRuntime = !this->Makefile->IsOn("CMAKE_SKIP_RPATH");
|
||||||
|
|
||||||
|
// Lookup rpath specification flags.
|
||||||
|
std::string runtimeFlag;
|
||||||
|
std::string runtimeSep;
|
||||||
|
if(tgt.GetType() != cmTarget::STATIC_LIBRARY)
|
||||||
|
{
|
||||||
|
std::string runTimeFlagVar = "CMAKE_";
|
||||||
|
if(tgt.GetType() == cmTarget::EXECUTABLE)
|
||||||
|
{
|
||||||
|
runTimeFlagVar += "EXECUTABLE";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
runTimeFlagVar += "SHARED_LIBRARY";
|
||||||
|
}
|
||||||
|
runTimeFlagVar += "_RUNTIME_";
|
||||||
runTimeFlagVar += linkLanguage;
|
runTimeFlagVar += linkLanguage;
|
||||||
runTimeFlagVar += "_FLAG";
|
runTimeFlagVar += "_FLAG";
|
||||||
std::string runTimeFlagSepVar = runTimeFlagVar + "_SEP";
|
std::string runTimeFlagSepVar = runTimeFlagVar + "_SEP";
|
||||||
runtimeFlag = this->Makefile->GetSafeDefinition(runTimeFlagVar.c_str());
|
runtimeFlag = this->Makefile->GetSafeDefinition(runTimeFlagVar.c_str());
|
||||||
runtimeSep = this->Makefile->GetSafeDefinition(runTimeFlagSepVar.c_str());
|
runtimeSep = this->Makefile->GetSafeDefinition(runTimeFlagSepVar.c_str());
|
||||||
|
}
|
||||||
// concatenate all paths or no?
|
// concatenate all paths or no?
|
||||||
bool runtimeConcatenate = ( runtimeSep!="" );
|
bool runtimeConcatenate = !runtimeSep.empty();
|
||||||
if(runtimeFlag == "" || this->Makefile->IsOn("CMAKE_SKIP_RPATH"))
|
|
||||||
|
const char* runtimeAlways =
|
||||||
|
this->Makefile->GetDefinition("CMAKE_PLATFORM_REQUIRED_RUNTIME_PATH");
|
||||||
|
|
||||||
|
// Turn off rpath support if no flag is available to specify it.
|
||||||
|
if(runtimeFlag.empty())
|
||||||
{
|
{
|
||||||
outputRuntime = false;
|
outputRuntime = false;
|
||||||
|
runtimeAlways = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Some search paths should never be emitted
|
|
||||||
emitted.insert("");
|
|
||||||
if(const char* implicitLinks =
|
|
||||||
(this->Makefile->GetDefinition
|
|
||||||
("CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES")))
|
|
||||||
{
|
|
||||||
std::vector<std::string> implicitLinkVec;
|
|
||||||
cmSystemTools::ExpandListArgument(implicitLinks, implicitLinkVec);
|
|
||||||
for(unsigned int k = 0; k < implicitLinkVec.size(); ++k)
|
|
||||||
{
|
|
||||||
emitted.insert(implicitLinkVec[k]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
std::string libPathFlag =
|
std::string libPathFlag =
|
||||||
this->Makefile->GetRequiredDefinition("CMAKE_LIBRARY_PATH_FLAG");
|
this->Makefile->GetRequiredDefinition("CMAKE_LIBRARY_PATH_FLAG");
|
||||||
std::string libPathTerminator =
|
std::string libPathTerminator =
|
||||||
@ -1539,10 +1525,43 @@ bool cmLocalGenerator::GetLinkerArgs(std::string& rpath,
|
|||||||
linkLibs += " ";
|
linkLibs += " ";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute the link library and directory information.
|
// Append the framework search path flags.
|
||||||
std::vector<cmStdString> libNames;
|
std::vector<std::string> const& fwDirs = cli.GetFrameworkPaths();
|
||||||
std::vector<cmStdString> libDirs;
|
for(std::vector<std::string>::const_iterator fdi = fwDirs.begin();
|
||||||
this->ComputeLinkInformation(tgt, config, libNames, libDirs);
|
fdi != fwDirs.end(); ++fdi)
|
||||||
|
{
|
||||||
|
linkLibs += "-F";
|
||||||
|
linkLibs += this->Convert(fdi->c_str(), NONE, SHELL, false);
|
||||||
|
linkLibs += " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append the library search path flags.
|
||||||
|
std::vector<std::string> const& libDirs = cli.GetDirectories();
|
||||||
|
for(std::vector<std::string>::const_iterator libDir = libDirs.begin();
|
||||||
|
libDir != libDirs.end(); ++libDir)
|
||||||
|
{
|
||||||
|
std::string libpath = this->ConvertToOutputForExisting(libDir->c_str());
|
||||||
|
linkLibs += libPathFlag;
|
||||||
|
linkLibs += libpath;
|
||||||
|
linkLibs += libPathTerminator;
|
||||||
|
linkLibs += " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append the link items.
|
||||||
|
typedef cmComputeLinkInformation::ItemVector ItemVector;
|
||||||
|
ItemVector const& items = cli.GetItems();
|
||||||
|
for(ItemVector::const_iterator li = items.begin(); li != items.end(); ++li)
|
||||||
|
{
|
||||||
|
if(li->IsPath)
|
||||||
|
{
|
||||||
|
linkLibs += this->Convert(li->Value.c_str(), START_OUTPUT, SHELL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
linkLibs += li->Value;
|
||||||
|
}
|
||||||
|
linkLibs += " ";
|
||||||
|
}
|
||||||
|
|
||||||
// Select whether to generate an rpath for the install tree or the
|
// Select whether to generate an rpath for the install tree or the
|
||||||
// build tree.
|
// build tree.
|
||||||
@ -1562,68 +1581,46 @@ bool cmLocalGenerator::GetLinkerArgs(std::string& rpath,
|
|||||||
{
|
{
|
||||||
const char* install_rpath = tgt.GetProperty("INSTALL_RPATH");
|
const char* install_rpath = tgt.GetProperty("INSTALL_RPATH");
|
||||||
cmSystemTools::ExpandListArgument(install_rpath, runtimeDirs);
|
cmSystemTools::ExpandListArgument(install_rpath, runtimeDirs);
|
||||||
for(unsigned int i=0; i < runtimeDirs.size(); ++i)
|
|
||||||
{
|
|
||||||
runtimeDirs[i] =
|
|
||||||
this->Convert(runtimeDirs[i].c_str(), FULL, SHELL, false);
|
|
||||||
}
|
}
|
||||||
}
|
if(use_build_rpath || use_link_rpath)
|
||||||
|
|
||||||
// Append the library search path flags.
|
|
||||||
for(std::vector<cmStdString>::const_iterator libDir = libDirs.begin();
|
|
||||||
libDir != libDirs.end(); ++libDir)
|
|
||||||
{
|
{
|
||||||
std::string libpath = this->ConvertToOutputForExisting(libDir->c_str());
|
std::vector<std::string> const& rdirs = cli.GetRuntimeSearchPath();
|
||||||
if(emitted.insert(libpath).second)
|
for(std::vector<std::string>::const_iterator ri = rdirs.begin();
|
||||||
|
ri != rdirs.end(); ++ri)
|
||||||
{
|
{
|
||||||
std::string fullLibPath;
|
|
||||||
if(!this->WindowsShell && this->UseRelativePaths)
|
|
||||||
{
|
|
||||||
fullLibPath = "\"`cd ";
|
|
||||||
}
|
|
||||||
fullLibPath += libpath;
|
|
||||||
if(!this->WindowsShell && this->UseRelativePaths)
|
|
||||||
{
|
|
||||||
fullLibPath += ";pwd`\"";
|
|
||||||
}
|
|
||||||
std::string::size_type pos = libDir->find(libPathFlag.c_str());
|
|
||||||
if((pos == std::string::npos || pos > 0)
|
|
||||||
&& libDir->find("${") == std::string::npos)
|
|
||||||
{
|
|
||||||
linkLibs += libPathFlag;
|
|
||||||
linkLibs += fullLibPath;
|
|
||||||
linkLibs += libPathTerminator;
|
|
||||||
linkLibs += " ";
|
|
||||||
|
|
||||||
// Put this directory in the rpath if using build-tree rpath
|
// Put this directory in the rpath if using build-tree rpath
|
||||||
// support or if using the link path as an rpath.
|
// support or if using the link path as an rpath.
|
||||||
if(use_build_rpath)
|
if(use_build_rpath)
|
||||||
{
|
{
|
||||||
runtimeDirs.push_back(fullLibPath);
|
runtimeDirs.push_back(*ri);
|
||||||
}
|
}
|
||||||
else if(use_link_rpath)
|
else if(use_link_rpath)
|
||||||
{
|
{
|
||||||
// Do not add any path inside the source or build tree.
|
// Do not add any path inside the source or build tree.
|
||||||
const char* topSourceDir = this->Makefile->GetHomeDirectory();
|
const char* topSourceDir = this->Makefile->GetHomeDirectory();
|
||||||
const char* topBinaryDir = this->Makefile->GetHomeOutputDirectory();
|
const char* topBinaryDir = this->Makefile->GetHomeOutputDirectory();
|
||||||
if(!cmSystemTools::ComparePath(libDir->c_str(), topSourceDir) &&
|
if(!cmSystemTools::ComparePath(ri->c_str(), topSourceDir) &&
|
||||||
!cmSystemTools::ComparePath(libDir->c_str(), topBinaryDir) &&
|
!cmSystemTools::ComparePath(ri->c_str(), topBinaryDir) &&
|
||||||
!cmSystemTools::IsSubDirectory(libDir->c_str(), topSourceDir) &&
|
!cmSystemTools::IsSubDirectory(ri->c_str(), topSourceDir) &&
|
||||||
!cmSystemTools::IsSubDirectory(libDir->c_str(), topBinaryDir))
|
!cmSystemTools::IsSubDirectory(ri->c_str(), topBinaryDir))
|
||||||
{
|
{
|
||||||
runtimeDirs.push_back(fullLibPath);
|
runtimeDirs.push_back(*ri);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(runtimeAlways)
|
||||||
|
{
|
||||||
|
// Add runtime paths required by the platform to always be
|
||||||
|
// present. This is done even when skipping rpath support.
|
||||||
|
cmSystemTools::ExpandListArgument(runtimeAlways, runtimeDirs);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Append the link libraries.
|
// Convert the runtime directory names for use in the build file.
|
||||||
for(std::vector<cmStdString>::iterator lib = libNames.begin();
|
for(std::vector<std::string>::iterator ri = runtimeDirs.begin();
|
||||||
lib != libNames.end(); ++lib)
|
ri != runtimeDirs.end(); ++ri)
|
||||||
{
|
{
|
||||||
linkLibs += *lib;
|
*ri = this->Convert(ri->c_str(), FULL, SHELL, false);
|
||||||
linkLibs += " ";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!runtimeDirs.empty())
|
if(!runtimeDirs.empty())
|
||||||
@ -1714,257 +1711,6 @@ void cmLocalGenerator::OutputLinkLibraries(std::ostream& fout,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
void cmLocalGenerator
|
|
||||||
::ComputeLinkInformation(cmTarget& target,
|
|
||||||
const char* config,
|
|
||||||
std::vector<cmStdString>& outLibs,
|
|
||||||
std::vector<cmStdString>& outDirs,
|
|
||||||
std::vector<cmStdString>* fullPathLibs)
|
|
||||||
{
|
|
||||||
// Compute which library configuration to link.
|
|
||||||
cmTarget::LinkLibraryType linkType = cmTarget::OPTIMIZED;
|
|
||||||
if(config && cmSystemTools::UpperCase(config) == "DEBUG")
|
|
||||||
{
|
|
||||||
linkType = cmTarget::DEBUG;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the language used for linking.
|
|
||||||
const char* linkLanguage =
|
|
||||||
target.GetLinkerLanguage(this->GetGlobalGenerator());
|
|
||||||
|
|
||||||
// Check whether we should use an import library for linking a target.
|
|
||||||
bool implib =
|
|
||||||
this->Makefile->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX")?true:false;
|
|
||||||
|
|
||||||
// On platforms without import libraries there may be a special flag
|
|
||||||
// to use when creating a plugin (module) that obtains symbols from
|
|
||||||
// the program that will load it.
|
|
||||||
const char* loader_flag = 0;
|
|
||||||
if(!implib && target.GetType() == cmTarget::MODULE_LIBRARY)
|
|
||||||
{
|
|
||||||
if(!linkLanguage)
|
|
||||||
{
|
|
||||||
cmSystemTools::
|
|
||||||
Error("CMake can not determine linker language for target:",
|
|
||||||
target.GetName());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
std::string loader_flag_var = "CMAKE_SHARED_MODULE_LOADER_";
|
|
||||||
loader_flag_var += linkLanguage;
|
|
||||||
loader_flag_var += "_FLAG";
|
|
||||||
loader_flag = this->Makefile->GetDefinition(loader_flag_var.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the list of libraries against which this target wants to link.
|
|
||||||
std::vector<std::string> linkLibraries;
|
|
||||||
const cmTarget::LinkLibraryVectorType& inLibs = target.GetLinkLibraries();
|
|
||||||
for(cmTarget::LinkLibraryVectorType::const_iterator j = inLibs.begin();
|
|
||||||
j != inLibs.end(); ++j)
|
|
||||||
{
|
|
||||||
// For backwards compatibility variables may have been expanded
|
|
||||||
// inside library names. Clean up the resulting name.
|
|
||||||
std::string lib = j->first;
|
|
||||||
std::string::size_type pos = lib.find_first_not_of(" \t\r\n");
|
|
||||||
if(pos != lib.npos)
|
|
||||||
{
|
|
||||||
lib = lib.substr(pos, lib.npos);
|
|
||||||
}
|
|
||||||
pos = lib.find_last_not_of(" \t\r\n");
|
|
||||||
if(pos != lib.npos)
|
|
||||||
{
|
|
||||||
lib = lib.substr(0, pos+1);
|
|
||||||
}
|
|
||||||
if(lib.empty())
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// Link to a library if it is not the same target and is meant for
|
|
||||||
// this configuration type.
|
|
||||||
if((target.GetType() == cmTarget::EXECUTABLE ||
|
|
||||||
lib != target.GetName()) &&
|
|
||||||
(j->second == cmTarget::GENERAL || j->second == linkType))
|
|
||||||
{
|
|
||||||
// Compute the proper name to use to link this library.
|
|
||||||
cmTarget* tgt = this->GlobalGenerator->FindTarget(0, lib.c_str(), false);
|
|
||||||
bool impexe = (tgt &&
|
|
||||||
tgt->GetType() == cmTarget::EXECUTABLE &&
|
|
||||||
tgt->GetPropertyAsBool("ENABLE_EXPORTS"));
|
|
||||||
if(impexe && !implib && !loader_flag)
|
|
||||||
{
|
|
||||||
// Skip linking to executables on platforms with no import
|
|
||||||
// libraries or loader flags.
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else if(tgt && (tgt->GetType() == cmTarget::STATIC_LIBRARY ||
|
|
||||||
tgt->GetType() == cmTarget::SHARED_LIBRARY ||
|
|
||||||
tgt->GetType() == cmTarget::MODULE_LIBRARY ||
|
|
||||||
impexe))
|
|
||||||
{
|
|
||||||
// This is a CMake target. Ask the target for its real name.
|
|
||||||
std::string linkItem;
|
|
||||||
if(impexe && loader_flag)
|
|
||||||
{
|
|
||||||
// This link item is an executable that may provide symbols
|
|
||||||
// used by this target. A special flag is needed on this
|
|
||||||
// platform. Add it now.
|
|
||||||
std::string exe = tgt->GetFullPath(config, implib);
|
|
||||||
linkItem += loader_flag;
|
|
||||||
linkItem += this->Convert(exe.c_str(), NONE, SHELL, false);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Pass the full path to the target file but purposely leave
|
|
||||||
// off the per-configuration subdirectory. The link directory
|
|
||||||
// ordering knows how to deal with this.
|
|
||||||
linkItem += tgt->GetDirectory(0, implib);
|
|
||||||
// on apple if the FRAMEWORK prop is set, then
|
|
||||||
// do not add the target full name but just use the directory
|
|
||||||
// name
|
|
||||||
#ifdef __APPLE__
|
|
||||||
if (!(tgt->GetType() == cmTarget::SHARED_LIBRARY &&
|
|
||||||
tgt->GetPropertyAsBool("FRAMEWORK")))
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
linkItem += "/";
|
|
||||||
linkItem += tgt->GetFullName(config, implib);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
linkLibraries.push_back(linkItem);
|
|
||||||
// For full path, use the true location.
|
|
||||||
if(fullPathLibs)
|
|
||||||
{
|
|
||||||
fullPathLibs->push_back(tgt->GetFullPath(config, implib));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// This is not a CMake target. Use the name given.
|
|
||||||
linkLibraries.push_back(lib);
|
|
||||||
|
|
||||||
// Add to the list of full paths if this library is one.
|
|
||||||
if(fullPathLibs &&
|
|
||||||
cmSystemTools::FileIsFullPath(lib.c_str()) &&
|
|
||||||
!cmSystemTools::FileIsDirectory(lib.c_str()))
|
|
||||||
{
|
|
||||||
fullPathLibs->push_back(lib);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the list of directories the target wants to search for libraries.
|
|
||||||
const std::vector<std::string>&
|
|
||||||
linkDirectories = target.GetLinkDirectories();
|
|
||||||
|
|
||||||
// Lookup link type selection flags.
|
|
||||||
const char* static_link_type_flag = 0;
|
|
||||||
const char* shared_link_type_flag = 0;
|
|
||||||
const char* target_type_str = 0;
|
|
||||||
switch(target.GetType())
|
|
||||||
{
|
|
||||||
case cmTarget::EXECUTABLE: target_type_str = "EXE"; break;
|
|
||||||
case cmTarget::SHARED_LIBRARY: target_type_str = "SHARED_LIBRARY"; break;
|
|
||||||
case cmTarget::MODULE_LIBRARY: target_type_str = "SHARED_MODULE"; break;
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
if(target_type_str)
|
|
||||||
{
|
|
||||||
if(!linkLanguage)
|
|
||||||
{
|
|
||||||
cmSystemTools::
|
|
||||||
Error("CMake can not determine linker language for target:",
|
|
||||||
target.GetName());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
std::string static_link_type_flag_var = "CMAKE_";
|
|
||||||
static_link_type_flag_var += target_type_str;
|
|
||||||
static_link_type_flag_var += "_LINK_STATIC_";
|
|
||||||
static_link_type_flag_var += linkLanguage;
|
|
||||||
static_link_type_flag_var += "_FLAGS";
|
|
||||||
static_link_type_flag =
|
|
||||||
this->Makefile->GetDefinition(static_link_type_flag_var.c_str());
|
|
||||||
|
|
||||||
std::string shared_link_type_flag_var = "CMAKE_";
|
|
||||||
shared_link_type_flag_var += target_type_str;
|
|
||||||
shared_link_type_flag_var += "_LINK_DYNAMIC_";
|
|
||||||
shared_link_type_flag_var += linkLanguage;
|
|
||||||
shared_link_type_flag_var += "_FLAGS";
|
|
||||||
shared_link_type_flag =
|
|
||||||
this->Makefile->GetDefinition(shared_link_type_flag_var.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compute the link directory order needed to link the libraries.
|
|
||||||
cmOrderLinkDirectories orderLibs;
|
|
||||||
orderLibs.SetLinkTypeInformation(cmOrderLinkDirectories::LinkShared,
|
|
||||||
static_link_type_flag,
|
|
||||||
shared_link_type_flag);
|
|
||||||
orderLibs.AddLinkPrefix(
|
|
||||||
this->Makefile->GetDefinition("CMAKE_STATIC_LIBRARY_PREFIX"));
|
|
||||||
orderLibs.AddLinkPrefix(
|
|
||||||
this->Makefile->GetDefinition("CMAKE_SHARED_LIBRARY_PREFIX"));
|
|
||||||
|
|
||||||
// Import library names should be matched and treated as shared
|
|
||||||
// libraries for the purposes of linking.
|
|
||||||
orderLibs.AddLinkExtension(
|
|
||||||
this->Makefile->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX"),
|
|
||||||
cmOrderLinkDirectories::LinkShared);
|
|
||||||
orderLibs.AddLinkExtension(
|
|
||||||
this->Makefile->GetDefinition("CMAKE_STATIC_LIBRARY_SUFFIX"),
|
|
||||||
cmOrderLinkDirectories::LinkStatic);
|
|
||||||
orderLibs.AddLinkExtension(
|
|
||||||
this->Makefile->GetDefinition("CMAKE_SHARED_LIBRARY_SUFFIX"),
|
|
||||||
cmOrderLinkDirectories::LinkShared);
|
|
||||||
orderLibs.AddLinkExtension(
|
|
||||||
this->Makefile->GetDefinition("CMAKE_LINK_LIBRARY_SUFFIX"));
|
|
||||||
if(const char* linkSuffixes =
|
|
||||||
this->Makefile->GetDefinition("CMAKE_EXTRA_LINK_EXTENSIONS"))
|
|
||||||
{
|
|
||||||
std::vector<std::string> linkSuffixVec;
|
|
||||||
cmSystemTools::ExpandListArgument(linkSuffixes, linkSuffixVec);
|
|
||||||
for(std::vector<std::string>::iterator i = linkSuffixVec.begin();
|
|
||||||
i != linkSuffixVec.end(); ++i)
|
|
||||||
{
|
|
||||||
orderLibs.AddLinkExtension(i->c_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
std::string configSubdir;
|
|
||||||
cmGlobalGenerator* gg = this->GetGlobalGenerator();
|
|
||||||
gg->AppendDirectoryForConfig("", config, "", configSubdir);
|
|
||||||
orderLibs.SetLinkInformation(target.GetName(),
|
|
||||||
linkLibraries,
|
|
||||||
linkDirectories,
|
|
||||||
gg->GetTargetManifest(),
|
|
||||||
configSubdir.c_str());
|
|
||||||
orderLibs.DetermineLibraryPathOrder();
|
|
||||||
std::vector<cmStdString> orderedLibs;
|
|
||||||
orderLibs.GetLinkerInformation(outDirs, orderedLibs);
|
|
||||||
|
|
||||||
// Make sure libraries are linked with the proper syntax.
|
|
||||||
std::string libLinkFlag =
|
|
||||||
this->Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_FLAG");
|
|
||||||
std::string libLinkSuffix =
|
|
||||||
this->Makefile->GetSafeDefinition("CMAKE_LINK_LIBRARY_SUFFIX");
|
|
||||||
for(std::vector<cmStdString>::iterator l = orderedLibs.begin();
|
|
||||||
l != orderedLibs.end(); ++l)
|
|
||||||
{
|
|
||||||
std::string lib = *l;
|
|
||||||
if(lib[0] == '-' || lib[0] == '$' || lib[0] == '`')
|
|
||||||
{
|
|
||||||
// The library is linked with special syntax by the user.
|
|
||||||
outLibs.push_back(lib);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Generate the proper link syntax.
|
|
||||||
lib = libLinkFlag;
|
|
||||||
lib += *l;
|
|
||||||
lib += libLinkSuffix;
|
|
||||||
outLibs.push_back(lib);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void cmLocalGenerator::AddLanguageFlags(std::string& flags,
|
void cmLocalGenerator::AddLanguageFlags(std::string& flags,
|
||||||
const char* lang,
|
const char* lang,
|
||||||
|
@ -75,7 +75,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Generate a manifest of target files that will be built.
|
* Generate a manifest of target files that will be built.
|
||||||
*/
|
*/
|
||||||
virtual void GenerateTargetManifest(cmTargetManifest&);
|
virtual void GenerateTargetManifest();
|
||||||
|
|
||||||
///! Get the makefile for this generator
|
///! Get the makefile for this generator
|
||||||
cmMakefile *GetMakefile() {
|
cmMakefile *GetMakefile() {
|
||||||
@ -174,13 +174,6 @@ public:
|
|||||||
bool /*color*/)
|
bool /*color*/)
|
||||||
{ return true; }
|
{ return true; }
|
||||||
|
|
||||||
/** Compute the list of link libraries and directories for the given
|
|
||||||
target and configuration. */
|
|
||||||
void ComputeLinkInformation(cmTarget& target, const char* config,
|
|
||||||
std::vector<cmStdString>& outLibs,
|
|
||||||
std::vector<cmStdString>& outDirs,
|
|
||||||
std::vector<cmStdString>* fullPathLibs=0);
|
|
||||||
|
|
||||||
/** Get the include flags for the current makefile and language. */
|
/** Get the include flags for the current makefile and language. */
|
||||||
void GetIncludeDirectories(std::vector<std::string>& dirs,
|
void GetIncludeDirectories(std::vector<std::string>& dirs,
|
||||||
bool filter_system_dirs = true);
|
bool filter_system_dirs = true);
|
||||||
|
@ -22,6 +22,8 @@
|
|||||||
#include "cmCacheManager.h"
|
#include "cmCacheManager.h"
|
||||||
#include "cmake.h"
|
#include "cmake.h"
|
||||||
|
|
||||||
|
#include "cmComputeLinkInformation.h"
|
||||||
|
|
||||||
#include <cmsys/RegularExpression.hxx>
|
#include <cmsys/RegularExpression.hxx>
|
||||||
|
|
||||||
cmLocalVisualStudio6Generator::cmLocalVisualStudio6Generator()
|
cmLocalVisualStudio6Generator::cmLocalVisualStudio6Generator()
|
||||||
@ -1569,12 +1571,17 @@ void cmLocalVisualStudio6Generator
|
|||||||
std::string& options)
|
std::string& options)
|
||||||
{
|
{
|
||||||
// Compute the link information for this configuration.
|
// Compute the link information for this configuration.
|
||||||
std::vector<cmStdString> linkLibs;
|
cmComputeLinkInformation cli(&target, configName);
|
||||||
std::vector<cmStdString> linkDirs;
|
if(!cli.Compute())
|
||||||
this->ComputeLinkInformation(target, configName, linkLibs, linkDirs);
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
typedef cmComputeLinkInformation::ItemVector ItemVector;
|
||||||
|
ItemVector const& linkLibs = cli.GetItems();
|
||||||
|
std::vector<std::string> const& linkDirs = cli.GetDirectories();
|
||||||
|
|
||||||
// Build the link options code.
|
// Build the link options code.
|
||||||
for(std::vector<cmStdString>::const_iterator d = linkDirs.begin();
|
for(std::vector<std::string>::const_iterator d = linkDirs.begin();
|
||||||
d != linkDirs.end(); ++d)
|
d != linkDirs.end(); ++d)
|
||||||
{
|
{
|
||||||
std::string dir = *d;
|
std::string dir = *d;
|
||||||
@ -1592,11 +1599,19 @@ void cmLocalVisualStudio6Generator
|
|||||||
options += "\n";
|
options += "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(std::vector<cmStdString>::const_iterator l = linkLibs.begin();
|
for(ItemVector::const_iterator l = linkLibs.begin();
|
||||||
l != linkLibs.end(); ++l)
|
l != linkLibs.end(); ++l)
|
||||||
{
|
{
|
||||||
options += "# ADD LINK32 ";
|
options += "# ADD LINK32 ";
|
||||||
options += this->ConvertToOptionallyRelativeOutputPath(l->c_str());
|
if(l->IsPath)
|
||||||
|
{
|
||||||
|
options +=
|
||||||
|
this->ConvertToOptionallyRelativeOutputPath(l->Value.c_str());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
options += l->Value;
|
||||||
|
}
|
||||||
options += "\n";
|
options += "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,12 +24,24 @@
|
|||||||
#include "cmCacheManager.h"
|
#include "cmCacheManager.h"
|
||||||
#include "cmake.h"
|
#include "cmake.h"
|
||||||
|
|
||||||
|
#include "cmComputeLinkInformation.h"
|
||||||
#include "cmGeneratedFileStream.h"
|
#include "cmGeneratedFileStream.h"
|
||||||
|
|
||||||
#include <cmsys/System.h>
|
#include <cmsys/System.h>
|
||||||
|
|
||||||
#include <ctype.h> // for isspace
|
#include <ctype.h> // for isspace
|
||||||
|
|
||||||
|
class cmLocalVisualStudio7GeneratorInternals
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
cmLocalVisualStudio7GeneratorInternals(cmLocalVisualStudio7Generator* e):
|
||||||
|
LocalGenerator(e) {}
|
||||||
|
typedef cmComputeLinkInformation::ItemVector ItemVector;
|
||||||
|
void OutputLibraries(std::ostream& fout, ItemVector const& libs);
|
||||||
|
private:
|
||||||
|
cmLocalVisualStudio7Generator* LocalGenerator;
|
||||||
|
};
|
||||||
|
|
||||||
extern cmVS7FlagTable cmLocalVisualStudio7GeneratorFlagTable[];
|
extern cmVS7FlagTable cmLocalVisualStudio7GeneratorFlagTable[];
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@ -38,10 +50,12 @@ cmLocalVisualStudio7Generator::cmLocalVisualStudio7Generator()
|
|||||||
this->Version = 7;
|
this->Version = 7;
|
||||||
this->PlatformName = "Win32";
|
this->PlatformName = "Win32";
|
||||||
this->ExtraFlagTable = 0;
|
this->ExtraFlagTable = 0;
|
||||||
|
this->Internal = new cmLocalVisualStudio7GeneratorInternals(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
cmLocalVisualStudio7Generator::~cmLocalVisualStudio7Generator()
|
cmLocalVisualStudio7Generator::~cmLocalVisualStudio7Generator()
|
||||||
{
|
{
|
||||||
|
delete this->Internal;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cmLocalVisualStudio7Generator::AddHelperCommands()
|
void cmLocalVisualStudio7Generator::AddHelperCommands()
|
||||||
@ -748,20 +762,12 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
|
|||||||
targetNameImport, targetNamePDB, configName);
|
targetNameImport, targetNamePDB, configName);
|
||||||
|
|
||||||
// Compute the link library and directory information.
|
// Compute the link library and directory information.
|
||||||
std::vector<cmStdString> linkLibs;
|
cmComputeLinkInformation cli(&target, configName);
|
||||||
std::vector<cmStdString> linkDirs;
|
if(!cli.Compute())
|
||||||
this->ComputeLinkInformation(target, configName, linkLibs, linkDirs);
|
|
||||||
|
|
||||||
// Get the language to use for linking.
|
|
||||||
const char* linkLanguage =
|
|
||||||
target.GetLinkerLanguage(this->GetGlobalGenerator());
|
|
||||||
if(!linkLanguage)
|
|
||||||
{
|
{
|
||||||
cmSystemTools::Error
|
|
||||||
("CMake can not determine linker language for target:",
|
|
||||||
target.GetName());
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const char* linkLanguage = cli.GetLinkLanguage();
|
||||||
|
|
||||||
// Compute the variable name to lookup standard libraries for this
|
// Compute the variable name to lookup standard libraries for this
|
||||||
// language.
|
// language.
|
||||||
@ -777,7 +783,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
|
|||||||
fout << "\t\t\t\tAdditionalDependencies=\"$(NOINHERIT) "
|
fout << "\t\t\t\tAdditionalDependencies=\"$(NOINHERIT) "
|
||||||
<< this->Makefile->GetSafeDefinition(standardLibsVar.c_str())
|
<< this->Makefile->GetSafeDefinition(standardLibsVar.c_str())
|
||||||
<< " ";
|
<< " ";
|
||||||
this->OutputLibraries(fout, linkLibs);
|
this->Internal->OutputLibraries(fout, cli.GetItems());
|
||||||
fout << "\"\n";
|
fout << "\"\n";
|
||||||
temp = target.GetDirectory(configName);
|
temp = target.GetDirectory(configName);
|
||||||
temp += "/";
|
temp += "/";
|
||||||
@ -787,7 +793,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
|
|||||||
this->WriteTargetVersionAttribute(fout, target);
|
this->WriteTargetVersionAttribute(fout, target);
|
||||||
linkOptions.OutputFlagMap(fout, "\t\t\t\t");
|
linkOptions.OutputFlagMap(fout, "\t\t\t\t");
|
||||||
fout << "\t\t\t\tAdditionalLibraryDirectories=\"";
|
fout << "\t\t\t\tAdditionalLibraryDirectories=\"";
|
||||||
this->OutputLibraryDirectories(fout, linkDirs);
|
this->OutputLibraryDirectories(fout, cli.GetDirectories());
|
||||||
fout << "\"\n";
|
fout << "\"\n";
|
||||||
this->OutputModuleDefinitionFile(fout, target);
|
this->OutputModuleDefinitionFile(fout, target);
|
||||||
temp = target.GetDirectory(configName);
|
temp = target.GetDirectory(configName);
|
||||||
@ -825,20 +831,12 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
|
|||||||
targetNameImport, targetNamePDB, configName);
|
targetNameImport, targetNamePDB, configName);
|
||||||
|
|
||||||
// Compute the link library and directory information.
|
// Compute the link library and directory information.
|
||||||
std::vector<cmStdString> linkLibs;
|
cmComputeLinkInformation cli(&target, configName);
|
||||||
std::vector<cmStdString> linkDirs;
|
if(!cli.Compute())
|
||||||
this->ComputeLinkInformation(target, configName, linkLibs, linkDirs);
|
|
||||||
|
|
||||||
// Get the language to use for linking.
|
|
||||||
const char* linkLanguage =
|
|
||||||
target.GetLinkerLanguage(this->GetGlobalGenerator());
|
|
||||||
if(!linkLanguage)
|
|
||||||
{
|
{
|
||||||
cmSystemTools::Error
|
|
||||||
("CMake can not determine linker language for target:",
|
|
||||||
target.GetName());
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const char* linkLanguage = cli.GetLinkLanguage();
|
||||||
|
|
||||||
// Compute the variable name to lookup standard libraries for this
|
// Compute the variable name to lookup standard libraries for this
|
||||||
// language.
|
// language.
|
||||||
@ -854,7 +852,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
|
|||||||
fout << "\t\t\t\tAdditionalDependencies=\"$(NOINHERIT) "
|
fout << "\t\t\t\tAdditionalDependencies=\"$(NOINHERIT) "
|
||||||
<< this->Makefile->GetSafeDefinition(standardLibsVar.c_str())
|
<< this->Makefile->GetSafeDefinition(standardLibsVar.c_str())
|
||||||
<< " ";
|
<< " ";
|
||||||
this->OutputLibraries(fout, linkLibs);
|
this->Internal->OutputLibraries(fout, cli.GetItems());
|
||||||
fout << "\"\n";
|
fout << "\"\n";
|
||||||
temp = target.GetDirectory(configName);
|
temp = target.GetDirectory(configName);
|
||||||
temp += "/";
|
temp += "/";
|
||||||
@ -864,7 +862,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
|
|||||||
this->WriteTargetVersionAttribute(fout, target);
|
this->WriteTargetVersionAttribute(fout, target);
|
||||||
linkOptions.OutputFlagMap(fout, "\t\t\t\t");
|
linkOptions.OutputFlagMap(fout, "\t\t\t\t");
|
||||||
fout << "\t\t\t\tAdditionalLibraryDirectories=\"";
|
fout << "\t\t\t\tAdditionalLibraryDirectories=\"";
|
||||||
this->OutputLibraryDirectories(fout, linkDirs);
|
this->OutputLibraryDirectories(fout, cli.GetDirectories());
|
||||||
fout << "\"\n";
|
fout << "\"\n";
|
||||||
fout << "\t\t\t\tProgramDataBaseFile=\""
|
fout << "\t\t\t\tProgramDataBaseFile=\""
|
||||||
<< target.GetDirectory(configName) << "/" << targetNamePDB
|
<< target.GetDirectory(configName) << "/" << targetNamePDB
|
||||||
@ -936,14 +934,23 @@ void cmLocalVisualStudio7Generator
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void
|
void
|
||||||
cmLocalVisualStudio7Generator
|
cmLocalVisualStudio7GeneratorInternals
|
||||||
::OutputLibraries(std::ostream& fout,
|
::OutputLibraries(std::ostream& fout, ItemVector const& libs)
|
||||||
std::vector<cmStdString> const& libs)
|
|
||||||
{
|
{
|
||||||
for(std::vector<cmStdString>::const_iterator l = libs.begin();
|
cmLocalVisualStudio7Generator* lg = this->LocalGenerator;
|
||||||
l != libs.end(); ++l)
|
for(ItemVector::const_iterator l = libs.begin(); l != libs.end(); ++l)
|
||||||
{
|
{
|
||||||
fout << this->ConvertToXMLOutputPath(l->c_str()) << " ";
|
if(l->IsPath)
|
||||||
|
{
|
||||||
|
std::string rel = lg->Convert(l->Value.c_str(),
|
||||||
|
cmLocalGenerator::START_OUTPUT,
|
||||||
|
cmLocalGenerator::UNCHANGED);
|
||||||
|
fout << lg->ConvertToXMLOutputPath(rel.c_str()) << " ";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fout << l->Value << " ";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -951,10 +958,10 @@ cmLocalVisualStudio7Generator
|
|||||||
void
|
void
|
||||||
cmLocalVisualStudio7Generator
|
cmLocalVisualStudio7Generator
|
||||||
::OutputLibraryDirectories(std::ostream& fout,
|
::OutputLibraryDirectories(std::ostream& fout,
|
||||||
std::vector<cmStdString> const& dirs)
|
std::vector<std::string> const& dirs)
|
||||||
{
|
{
|
||||||
const char* comma = "";
|
const char* comma = "";
|
||||||
for(std::vector<cmStdString>::const_iterator d = dirs.begin();
|
for(std::vector<std::string>::const_iterator d = dirs.begin();
|
||||||
d != dirs.end(); ++d)
|
d != dirs.end(); ++d)
|
||||||
{
|
{
|
||||||
// Remove any trailing slash and skip empty paths.
|
// Remove any trailing slash and skip empty paths.
|
||||||
|
@ -27,6 +27,7 @@ struct cmVS7FlagTable;
|
|||||||
|
|
||||||
class cmLocalVisualStudio7GeneratorOptions;
|
class cmLocalVisualStudio7GeneratorOptions;
|
||||||
class cmLocalVisualStudio7GeneratorFCInfo;
|
class cmLocalVisualStudio7GeneratorFCInfo;
|
||||||
|
class cmLocalVisualStudio7GeneratorInternals;
|
||||||
|
|
||||||
/** \class cmLocalVisualStudio7Generator
|
/** \class cmLocalVisualStudio7Generator
|
||||||
* \brief Write Visual Studio .NET project files.
|
* \brief Write Visual Studio .NET project files.
|
||||||
@ -96,10 +97,8 @@ private:
|
|||||||
cmTarget &target, const char *libName);
|
cmTarget &target, const char *libName);
|
||||||
void OutputBuildTool(std::ostream& fout, const char* configName,
|
void OutputBuildTool(std::ostream& fout, const char* configName,
|
||||||
cmTarget& t);
|
cmTarget& t);
|
||||||
void OutputLibraries(std::ostream& fout,
|
|
||||||
std::vector<cmStdString> const& libs);
|
|
||||||
void OutputLibraryDirectories(std::ostream& fout,
|
void OutputLibraryDirectories(std::ostream& fout,
|
||||||
std::vector<cmStdString> const& dirs);
|
std::vector<std::string> const& dirs);
|
||||||
void OutputModuleDefinitionFile(std::ostream& fout, cmTarget &target);
|
void OutputModuleDefinitionFile(std::ostream& fout, cmTarget &target);
|
||||||
void WriteProjectStart(std::ostream& fout, const char *libName,
|
void WriteProjectStart(std::ostream& fout, const char *libName,
|
||||||
cmTarget &tgt, std::vector<cmSourceGroup> &sgs);
|
cmTarget &tgt, std::vector<cmSourceGroup> &sgs);
|
||||||
@ -120,11 +119,13 @@ private:
|
|||||||
virtual std::string GetTargetDirectory(cmTarget const&) const;
|
virtual std::string GetTargetDirectory(cmTarget const&) const;
|
||||||
|
|
||||||
friend class cmLocalVisualStudio7GeneratorFCInfo;
|
friend class cmLocalVisualStudio7GeneratorFCInfo;
|
||||||
|
friend class cmLocalVisualStudio7GeneratorInternals;
|
||||||
|
|
||||||
cmVS7FlagTable const* ExtraFlagTable;
|
cmVS7FlagTable const* ExtraFlagTable;
|
||||||
std::string ModuleDefinitionFile;
|
std::string ModuleDefinitionFile;
|
||||||
int Version;
|
int Version;
|
||||||
std::string PlatformName; // Win32 or x64
|
std::string PlatformName; // Win32 or x64
|
||||||
|
cmLocalVisualStudio7GeneratorInternals* Internal;
|
||||||
};
|
};
|
||||||
|
|
||||||
// This is a table mapping XML tag IDE names to command line options
|
// This is a table mapping XML tag IDE names to command line options
|
||||||
|
@ -1,710 +0,0 @@
|
|||||||
#include "cmOrderLinkDirectories.h"
|
|
||||||
#include "cmSystemTools.h"
|
|
||||||
#include "cmsys/RegularExpression.hxx"
|
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
//#define CM_ORDER_LINK_DIRECTORIES_DEBUG
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------
|
|
||||||
cmOrderLinkDirectories::cmOrderLinkDirectories()
|
|
||||||
{
|
|
||||||
this->StartLinkType = LinkUnknown;
|
|
||||||
this->LinkTypeEnabled = false;
|
|
||||||
this->Debug = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------
|
|
||||||
void
|
|
||||||
cmOrderLinkDirectories
|
|
||||||
::SetLinkTypeInformation(LinkType start_link_type,
|
|
||||||
const char* static_link_type_flag,
|
|
||||||
const char* shared_link_type_flag)
|
|
||||||
{
|
|
||||||
// We can support link type switching only if all needed flags are
|
|
||||||
// known.
|
|
||||||
this->StartLinkType = start_link_type;
|
|
||||||
if(static_link_type_flag && *static_link_type_flag &&
|
|
||||||
shared_link_type_flag && *shared_link_type_flag)
|
|
||||||
{
|
|
||||||
this->LinkTypeEnabled = true;
|
|
||||||
this->StaticLinkTypeFlag = static_link_type_flag;
|
|
||||||
this->SharedLinkTypeFlag = shared_link_type_flag;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this->LinkTypeEnabled = false;
|
|
||||||
this->StaticLinkTypeFlag = "";
|
|
||||||
this->SharedLinkTypeFlag = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------
|
|
||||||
void cmOrderLinkDirectories::SetCurrentLinkType(LinkType lt)
|
|
||||||
{
|
|
||||||
if(this->CurrentLinkType != lt)
|
|
||||||
{
|
|
||||||
this->CurrentLinkType = lt;
|
|
||||||
|
|
||||||
if(this->LinkTypeEnabled)
|
|
||||||
{
|
|
||||||
switch(this->CurrentLinkType)
|
|
||||||
{
|
|
||||||
case LinkStatic:
|
|
||||||
this->LinkItems.push_back(this->StaticLinkTypeFlag); break;
|
|
||||||
case LinkShared:
|
|
||||||
this->LinkItems.push_back(this->SharedLinkTypeFlag); break;
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------
|
|
||||||
bool cmOrderLinkDirectories::LibraryInDirectory(const char* desiredLib,
|
|
||||||
const char* dir,
|
|
||||||
const char* libIn)
|
|
||||||
{
|
|
||||||
// first look for the library as given
|
|
||||||
if(this->LibraryMayConflict(desiredLib, dir, libIn))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// next remove the extension (.a, .so ) and look for the library
|
|
||||||
// under a different name as the linker can do either
|
|
||||||
if(this->RemoveLibraryExtension.find(libIn))
|
|
||||||
{
|
|
||||||
cmStdString lib = this->RemoveLibraryExtension.match(1);
|
|
||||||
cmStdString ext = this->RemoveLibraryExtension.match(2);
|
|
||||||
for(std::vector<cmStdString>::iterator i = this->LinkExtensions.begin();
|
|
||||||
i != this->LinkExtensions.end(); ++i)
|
|
||||||
{
|
|
||||||
if(ext != *i)
|
|
||||||
{
|
|
||||||
std::string fname = lib;
|
|
||||||
lib += *i;
|
|
||||||
if(this->LibraryMayConflict(desiredLib, dir, fname.c_str()))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------
|
|
||||||
void cmOrderLinkDirectories::FindLibrariesInSearchPaths()
|
|
||||||
{
|
|
||||||
for(std::set<cmStdString>::iterator dir = this->LinkPathSet.begin();
|
|
||||||
dir != this->LinkPathSet.end(); ++dir)
|
|
||||||
{
|
|
||||||
for(std::map<cmStdString, Library>::iterator lib
|
|
||||||
= this->FullPathLibraries.begin();
|
|
||||||
lib != this->FullPathLibraries.end(); ++lib)
|
|
||||||
{
|
|
||||||
if(lib->second.Path != *dir)
|
|
||||||
{
|
|
||||||
if(this->LibraryInDirectory(lib->second.FullPath.c_str(),
|
|
||||||
dir->c_str(), lib->second.File.c_str()))
|
|
||||||
{
|
|
||||||
this->LibraryToDirectories[lib->second.FullPath].push_back(*dir);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------
|
|
||||||
void cmOrderLinkDirectories::FindIndividualLibraryOrders()
|
|
||||||
{
|
|
||||||
for(std::vector<Library>::iterator lib =
|
|
||||||
this->MultiDirectoryLibraries.begin();
|
|
||||||
lib != this->MultiDirectoryLibraries.end(); ++lib)
|
|
||||||
{
|
|
||||||
std::vector<cmStdString>& dirs =
|
|
||||||
this->LibraryToDirectories[lib->FullPath];
|
|
||||||
std::vector<std::pair<cmStdString, std::vector<cmStdString> >
|
|
||||||
>::iterator i;
|
|
||||||
for(i = this->DirectoryToAfterList.begin();
|
|
||||||
i != this->DirectoryToAfterList.end(); ++i)
|
|
||||||
{
|
|
||||||
if(i->first == lib->Path)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(i == this->DirectoryToAfterList.end())
|
|
||||||
{
|
|
||||||
std::cerr << "ERROR: should not happen\n";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for(std::vector<cmStdString>::iterator d = dirs.begin();
|
|
||||||
d != dirs.end(); ++d)
|
|
||||||
{
|
|
||||||
i->second.push_back(*d);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------
|
|
||||||
std::string cmOrderLinkDirectories::NoCaseExpression(const char* str)
|
|
||||||
{
|
|
||||||
std::string ret;
|
|
||||||
const char* s = str;
|
|
||||||
while(*s)
|
|
||||||
{
|
|
||||||
if(*s == '.')
|
|
||||||
{
|
|
||||||
ret += *s;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ret += "[";
|
|
||||||
ret += tolower(*s);
|
|
||||||
ret += toupper(*s);
|
|
||||||
ret += "]";
|
|
||||||
}
|
|
||||||
s++;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------
|
|
||||||
void cmOrderLinkDirectories::CreateRegularExpressions()
|
|
||||||
{
|
|
||||||
this->SplitFramework.compile("(.*)/(.*)\\.framework$");
|
|
||||||
|
|
||||||
// Compute a regex to match link extensions.
|
|
||||||
cmStdString libext = this->CreateExtensionRegex(this->LinkExtensions);
|
|
||||||
|
|
||||||
// Create regex to remove any library extension.
|
|
||||||
cmStdString reg("(.*)");
|
|
||||||
reg += libext;
|
|
||||||
this->RemoveLibraryExtension.compile(reg.c_str());
|
|
||||||
|
|
||||||
// Create a regex to match a library name. Match index 1 will be
|
|
||||||
// the prefix if it exists and empty otherwise. Match index 2 will
|
|
||||||
// be the library name. Match index 3 will be the library
|
|
||||||
// extension.
|
|
||||||
reg = "^(";
|
|
||||||
for(std::set<cmStdString>::iterator p = this->LinkPrefixes.begin();
|
|
||||||
p != this->LinkPrefixes.end(); ++p)
|
|
||||||
{
|
|
||||||
reg += *p;
|
|
||||||
reg += "|";
|
|
||||||
}
|
|
||||||
reg += ")";
|
|
||||||
reg += "([^/]*)";
|
|
||||||
|
|
||||||
// Create a regex to match any library name.
|
|
||||||
cmStdString reg_any = reg;
|
|
||||||
reg_any += libext;
|
|
||||||
#ifdef CM_ORDER_LINK_DIRECTORIES_DEBUG
|
|
||||||
fprintf(stderr, "any regex [%s]\n", reg_any.c_str());
|
|
||||||
#endif
|
|
||||||
this->ExtractAnyLibraryName.compile(reg_any.c_str());
|
|
||||||
|
|
||||||
// Create a regex to match static library names.
|
|
||||||
if(!this->StaticLinkExtensions.empty())
|
|
||||||
{
|
|
||||||
cmStdString reg_static = reg;
|
|
||||||
reg_static += this->CreateExtensionRegex(this->StaticLinkExtensions);
|
|
||||||
#ifdef CM_ORDER_LINK_DIRECTORIES_DEBUG
|
|
||||||
fprintf(stderr, "static regex [%s]\n", reg_static.c_str());
|
|
||||||
#endif
|
|
||||||
this->ExtractStaticLibraryName.compile(reg_static.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a regex to match shared library names.
|
|
||||||
if(!this->SharedLinkExtensions.empty())
|
|
||||||
{
|
|
||||||
cmStdString reg_shared = reg;
|
|
||||||
reg_shared += this->CreateExtensionRegex(this->SharedLinkExtensions);
|
|
||||||
#ifdef CM_ORDER_LINK_DIRECTORIES_DEBUG
|
|
||||||
fprintf(stderr, "shared regex [%s]\n", reg_shared.c_str());
|
|
||||||
#endif
|
|
||||||
this->ExtractSharedLibraryName.compile(reg_shared.c_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------
|
|
||||||
std::string
|
|
||||||
cmOrderLinkDirectories::CreateExtensionRegex(
|
|
||||||
std::vector<cmStdString> const& exts)
|
|
||||||
{
|
|
||||||
// Build a list of extension choices.
|
|
||||||
cmStdString libext = "(";
|
|
||||||
const char* sep = "";
|
|
||||||
for(std::vector<cmStdString>::const_iterator i = exts.begin();
|
|
||||||
i != exts.end(); ++i)
|
|
||||||
{
|
|
||||||
// Separate this choice from the previous one.
|
|
||||||
libext += sep;
|
|
||||||
sep = "|";
|
|
||||||
|
|
||||||
// Store this extension choice with the "." escaped.
|
|
||||||
libext += "\\";
|
|
||||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
|
||||||
libext += this->NoCaseExpression(i->c_str());
|
|
||||||
#else
|
|
||||||
libext += *i;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// Finish the list.
|
|
||||||
libext += ").*";
|
|
||||||
return libext;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------
|
|
||||||
void cmOrderLinkDirectories::PrepareLinkTargets()
|
|
||||||
{
|
|
||||||
std::vector<cmStdString> originalLinkItems = this->LinkItems;
|
|
||||||
this->LinkItems.clear();
|
|
||||||
this->CurrentLinkType = this->StartLinkType;
|
|
||||||
for(std::vector<cmStdString>::iterator i = originalLinkItems.begin();
|
|
||||||
i != originalLinkItems.end(); ++i)
|
|
||||||
{
|
|
||||||
// Parse out the prefix, base, and suffix components of the
|
|
||||||
// library name. If the name matches that of a shared or static
|
|
||||||
// library then set the link type accordingly.
|
|
||||||
//
|
|
||||||
// Search for shared library names first because some platforms
|
|
||||||
// have shared libraries with names that match the static library
|
|
||||||
// pattern. For example cygwin and msys use the convention
|
|
||||||
// libfoo.dll.a for import libraries and libfoo.a for static
|
|
||||||
// libraries. On AIX a library with the name libfoo.a can be
|
|
||||||
// shared!
|
|
||||||
if(this->ExtractSharedLibraryName.find(*i))
|
|
||||||
{
|
|
||||||
#ifdef CM_ORDER_LINK_DIRECTORIES_DEBUG
|
|
||||||
fprintf(stderr, "shared regex matched [%s] [%s] [%s]\n",
|
|
||||||
this->ExtractSharedLibraryName.match(1).c_str(),
|
|
||||||
this->ExtractSharedLibraryName.match(2).c_str(),
|
|
||||||
this->ExtractSharedLibraryName.match(3).c_str());
|
|
||||||
#endif
|
|
||||||
this->SetCurrentLinkType(LinkShared);
|
|
||||||
this->LinkItems.push_back(this->ExtractSharedLibraryName.match(2));
|
|
||||||
}
|
|
||||||
else if(this->ExtractStaticLibraryName.find(*i))
|
|
||||||
{
|
|
||||||
#ifdef CM_ORDER_LINK_DIRECTORIES_DEBUG
|
|
||||||
fprintf(stderr, "static regex matched [%s] [%s] [%s]\n",
|
|
||||||
this->ExtractStaticLibraryName.match(1).c_str(),
|
|
||||||
this->ExtractStaticLibraryName.match(2).c_str(),
|
|
||||||
this->ExtractStaticLibraryName.match(3).c_str());
|
|
||||||
#endif
|
|
||||||
this->SetCurrentLinkType(LinkStatic);
|
|
||||||
this->LinkItems.push_back(this->ExtractStaticLibraryName.match(2));
|
|
||||||
}
|
|
||||||
else if(this->ExtractAnyLibraryName.find(*i))
|
|
||||||
{
|
|
||||||
#ifdef CM_ORDER_LINK_DIRECTORIES_DEBUG
|
|
||||||
fprintf(stderr, "any regex matched [%s] [%s] [%s]\n",
|
|
||||||
this->ExtractAnyLibraryName.match(1).c_str(),
|
|
||||||
this->ExtractAnyLibraryName.match(2).c_str(),
|
|
||||||
this->ExtractAnyLibraryName.match(3).c_str());
|
|
||||||
#endif
|
|
||||||
this->SetCurrentLinkType(this->StartLinkType);
|
|
||||||
this->LinkItems.push_back(this->ExtractAnyLibraryName.match(2));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this->SetCurrentLinkType(this->StartLinkType);
|
|
||||||
this->LinkItems.push_back(*i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Restore the original linking type so system runtime libraries are
|
|
||||||
// linked properly.
|
|
||||||
this->SetCurrentLinkType(this->StartLinkType);
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------
|
|
||||||
bool cmOrderLinkDirectories::FindPathNotInDirectoryToAfterList(
|
|
||||||
cmStdString& path)
|
|
||||||
{
|
|
||||||
for(std::vector<std::pair<cmStdString, std::vector<cmStdString> >
|
|
||||||
>::iterator i = this->DirectoryToAfterList.begin();
|
|
||||||
i != this->DirectoryToAfterList.end(); ++i)
|
|
||||||
{
|
|
||||||
const cmStdString& p = i->first;
|
|
||||||
bool found = false;
|
|
||||||
for(std::vector<std::pair<cmStdString, std::vector<cmStdString> >
|
|
||||||
>::iterator j = this->DirectoryToAfterList.begin();
|
|
||||||
j != this->DirectoryToAfterList.end() && !found; ++j)
|
|
||||||
{
|
|
||||||
if(j != i)
|
|
||||||
{
|
|
||||||
found = (std::find(j->second.begin(), j->second.end(), p)
|
|
||||||
!= j->second.end());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!found)
|
|
||||||
{
|
|
||||||
path = p;
|
|
||||||
this->DirectoryToAfterList.erase(i);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
path = "";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------
|
|
||||||
void cmOrderLinkDirectories::OrderPaths(std::vector<cmStdString>&
|
|
||||||
orderedPaths)
|
|
||||||
{
|
|
||||||
cmStdString path;
|
|
||||||
// This is a topological sort implementation
|
|
||||||
// One at a time find paths that are not in any other paths after list
|
|
||||||
// and put them into the orderedPaths vector in that order
|
|
||||||
// FindPathNotInDirectoryToAfterList removes the path from the
|
|
||||||
// this->DirectoryToAfterList once it is found
|
|
||||||
while(this->FindPathNotInDirectoryToAfterList(path))
|
|
||||||
{
|
|
||||||
orderedPaths.push_back(path);
|
|
||||||
}
|
|
||||||
// at this point if there are still paths in this->DirectoryToAfterList
|
|
||||||
// then there is a cycle and we are stuck
|
|
||||||
if(this->DirectoryToAfterList.size())
|
|
||||||
{
|
|
||||||
for(std::vector<std::pair<cmStdString, std::vector<cmStdString> >
|
|
||||||
>::iterator i = this->DirectoryToAfterList.begin();
|
|
||||||
i != this->DirectoryToAfterList.end(); ++i)
|
|
||||||
{
|
|
||||||
this->ImpossibleDirectories.insert(i->first);
|
|
||||||
// still put it in the path list in the order we find them
|
|
||||||
orderedPaths.push_back(i->first);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------
|
|
||||||
void cmOrderLinkDirectories::SetLinkInformation(
|
|
||||||
const char* targetName,
|
|
||||||
const std::vector<std::string>& linkLibraries,
|
|
||||||
const std::vector<std::string>& linkDirectories,
|
|
||||||
const cmTargetManifest& manifest,
|
|
||||||
const char* configSubdir
|
|
||||||
)
|
|
||||||
{
|
|
||||||
// Save the target name.
|
|
||||||
this->TargetName = targetName;
|
|
||||||
|
|
||||||
// Save the subdirectory used for linking in this configuration.
|
|
||||||
this->ConfigSubdir = configSubdir? configSubdir : "";
|
|
||||||
|
|
||||||
// Merge the link directory search path given into our path set.
|
|
||||||
std::vector<cmStdString> empty;
|
|
||||||
for(std::vector<std::string>::const_iterator p = linkDirectories.begin();
|
|
||||||
p != linkDirectories.end(); ++p)
|
|
||||||
{
|
|
||||||
std::string dir = *p;
|
|
||||||
#ifdef _WIN32
|
|
||||||
// Avoid case problems for windows paths.
|
|
||||||
if(dir.size() > 2 && dir[1] == ':')
|
|
||||||
{
|
|
||||||
if(dir[0] >= 'A' && dir[0] <= 'Z')
|
|
||||||
{
|
|
||||||
dir[0] += 'a' - 'A';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dir = cmSystemTools::GetActualCaseForPath(dir.c_str());
|
|
||||||
#endif
|
|
||||||
if(this->DirectoryToAfterListEmitted.insert(dir).second)
|
|
||||||
{
|
|
||||||
std::pair<cmStdString, std::vector<cmStdString> > dp;
|
|
||||||
dp.first = dir;
|
|
||||||
this->DirectoryToAfterList.push_back(dp);
|
|
||||||
this->LinkPathSet.insert(dir);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Append the link library list into our raw list.
|
|
||||||
for(std::vector<std::string>::const_iterator l = linkLibraries.begin();
|
|
||||||
l != linkLibraries.end(); ++l)
|
|
||||||
{
|
|
||||||
this->RawLinkItems.push_back(*l);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Construct a set of files that will exist after building.
|
|
||||||
for(cmTargetManifest::const_iterator i = manifest.begin();
|
|
||||||
i != manifest.end(); ++i)
|
|
||||||
{
|
|
||||||
for(cmTargetSet::const_iterator j = i->second.begin();
|
|
||||||
j != i->second.end(); ++j)
|
|
||||||
{
|
|
||||||
this->ManifestFiles.insert(*j);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------
|
|
||||||
bool cmOrderLinkDirectories::DetermineLibraryPathOrder()
|
|
||||||
{
|
|
||||||
// set up all the regular expressions
|
|
||||||
this->CreateRegularExpressions();
|
|
||||||
std::vector<cmStdString> finalOrderPaths;
|
|
||||||
// find all libs that are full paths
|
|
||||||
Library aLib;
|
|
||||||
cmStdString dir;
|
|
||||||
cmStdString file;
|
|
||||||
std::vector<cmStdString> empty;
|
|
||||||
// do not add a -F for the system frameworks
|
|
||||||
this->EmittedFrameworkPaths.insert("/System/Library/Frameworks");
|
|
||||||
for(unsigned int i=0; i < this->RawLinkItems.size(); ++i)
|
|
||||||
{
|
|
||||||
bool framework = false;
|
|
||||||
#ifdef CM_ORDER_LINK_DIRECTORIES_DEBUG
|
|
||||||
fprintf(stderr, "Raw link item [%s]\n", this->RawLinkItems[i].c_str());
|
|
||||||
#endif
|
|
||||||
// if it is a full path to an item then separate it from the path
|
|
||||||
// this only works with files and paths
|
|
||||||
cmStdString& item = this->RawLinkItems[i];
|
|
||||||
|
|
||||||
if(cmSystemTools::FileIsFullPath(item.c_str()))
|
|
||||||
{
|
|
||||||
if(cmSystemTools::IsPathToFramework(item.c_str()))
|
|
||||||
{
|
|
||||||
this->SplitFramework.find(item.c_str());
|
|
||||||
cmStdString path = this->SplitFramework.match(1);
|
|
||||||
// Add the -F path if we have not yet done so
|
|
||||||
if(this->EmittedFrameworkPaths.insert(path).second)
|
|
||||||
{
|
|
||||||
std::string fpath = "-F";
|
|
||||||
fpath += cmSystemTools::ConvertToOutputPath(path.c_str());
|
|
||||||
this->LinkItems.push_back(fpath);
|
|
||||||
}
|
|
||||||
// now add the -framework option
|
|
||||||
std::string frame = "-framework ";
|
|
||||||
frame += this->SplitFramework.match(2);
|
|
||||||
this->LinkItems.push_back(frame);
|
|
||||||
framework = true;
|
|
||||||
}
|
|
||||||
if(cmSystemTools::FileIsDirectory(item.c_str()))
|
|
||||||
{
|
|
||||||
if(!framework)
|
|
||||||
{
|
|
||||||
// A full path to a directory was found as a link item
|
|
||||||
// warn user
|
|
||||||
std::string message =
|
|
||||||
"Warning: Ignoring path found in link libraries for target: ";
|
|
||||||
message += this->TargetName;
|
|
||||||
message += ", path is: ";
|
|
||||||
message += this->RawLinkItems[i];
|
|
||||||
message +=
|
|
||||||
". Expected a library name or a full path to a library name.";
|
|
||||||
cmSystemTools::Message(message.c_str());
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
} // is it a directory
|
|
||||||
if(!framework)
|
|
||||||
{
|
|
||||||
dir = cmSystemTools::GetFilenamePath(this->RawLinkItems[i]);
|
|
||||||
file = cmSystemTools::GetFilenameName(this->RawLinkItems[i]);
|
|
||||||
#ifdef _WIN32
|
|
||||||
// Avoid case problems for windows paths.
|
|
||||||
if(dir.size() > 2 && dir[1] == ':')
|
|
||||||
{
|
|
||||||
if(dir[0] >= 'A' && dir[0] <= 'Z')
|
|
||||||
{
|
|
||||||
dir[0] += 'a' - 'A';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dir = cmSystemTools::GetActualCaseForPath(dir.c_str());
|
|
||||||
#endif
|
|
||||||
if(this->DirectoryToAfterListEmitted.insert(dir).second)
|
|
||||||
{
|
|
||||||
std::pair<cmStdString, std::vector<cmStdString> > dp;
|
|
||||||
dp.first = dir;
|
|
||||||
this->DirectoryToAfterList.push_back(dp);
|
|
||||||
}
|
|
||||||
this->LinkPathSet.insert(dir);
|
|
||||||
aLib.FullPath = this->RawLinkItems[i];
|
|
||||||
aLib.File = file;
|
|
||||||
aLib.Path = dir;
|
|
||||||
this->FullPathLibraries[aLib.FullPath] = aLib;
|
|
||||||
#ifdef CM_ORDER_LINK_DIRECTORIES_DEBUG
|
|
||||||
fprintf(stderr, "Storing item [%s]\n", file.c_str());
|
|
||||||
#endif
|
|
||||||
this->LinkItems.push_back(file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this->LinkItems.push_back(this->RawLinkItems[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this->FindLibrariesInSearchPaths();
|
|
||||||
for(std::map<cmStdString, std::vector<cmStdString> >::iterator lib =
|
|
||||||
this->LibraryToDirectories.begin();
|
|
||||||
lib!= this->LibraryToDirectories.end();
|
|
||||||
++lib)
|
|
||||||
{
|
|
||||||
if(lib->second.size() > 0)
|
|
||||||
{
|
|
||||||
this->MultiDirectoryLibraries.push_back
|
|
||||||
(this->FullPathLibraries[lib->first]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this->SingleDirectoryLibraries.push_back
|
|
||||||
(this->FullPathLibraries[lib->first]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this->FindIndividualLibraryOrders();
|
|
||||||
this->SortedSearchPaths.clear();
|
|
||||||
if(this->Debug)
|
|
||||||
{
|
|
||||||
this->PrintMap("this->LibraryToDirectories", this->LibraryToDirectories);
|
|
||||||
this->PrintVector("this->DirectoryToAfterList",
|
|
||||||
this->DirectoryToAfterList);
|
|
||||||
}
|
|
||||||
this->OrderPaths(this->SortedSearchPaths);
|
|
||||||
// now turn libfoo.a into foo and foo.a into foo
|
|
||||||
// This will prepare the link items for -litem
|
|
||||||
this->PrepareLinkTargets();
|
|
||||||
if(this->ImpossibleDirectories.size())
|
|
||||||
{
|
|
||||||
cmSystemTools::Message(this->GetWarnings().c_str());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string cmOrderLinkDirectories::GetWarnings()
|
|
||||||
{
|
|
||||||
std::string warning =
|
|
||||||
"It is impossible to order the linker search path in such a way "
|
|
||||||
"that libraries specified as full paths will be picked by the "
|
|
||||||
"linker.\nDirectories and libraries involved are:\n";
|
|
||||||
|
|
||||||
for(std::set<cmStdString>::iterator i = this->ImpossibleDirectories.begin();
|
|
||||||
i != this->ImpossibleDirectories.end(); ++i)
|
|
||||||
{
|
|
||||||
warning += "Directory: ";
|
|
||||||
warning += *i;
|
|
||||||
warning += " contains:\n";
|
|
||||||
std::map<cmStdString, std::vector<cmStdString> >::iterator j;
|
|
||||||
for(j = this->LibraryToDirectories.begin();
|
|
||||||
j != this->LibraryToDirectories.end(); ++j)
|
|
||||||
{
|
|
||||||
if(std::find(j->second.begin(), j->second.end(), *i)
|
|
||||||
!= j->second.end())
|
|
||||||
{
|
|
||||||
warning += "Library: ";
|
|
||||||
warning += j->first;
|
|
||||||
warning += "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
warning += "\n";
|
|
||||||
}
|
|
||||||
warning += "\n";
|
|
||||||
return warning;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------
|
|
||||||
void
|
|
||||||
cmOrderLinkDirectories::PrintMap(const char* name,
|
|
||||||
std::map<cmStdString, std::vector<cmStdString> >& m)
|
|
||||||
{
|
|
||||||
std::cout << name << "\n";
|
|
||||||
for(std::map<cmStdString, std::vector<cmStdString> >::iterator i =
|
|
||||||
m.begin(); i != m.end();
|
|
||||||
++i)
|
|
||||||
{
|
|
||||||
std::cout << i->first << ": ";
|
|
||||||
for(std::vector<cmStdString>::iterator l = i->second.begin();
|
|
||||||
l != i->second.end(); ++l)
|
|
||||||
{
|
|
||||||
std::cout << *l << " ";
|
|
||||||
}
|
|
||||||
std::cout << "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//-------------------------------------------------------------------
|
|
||||||
void
|
|
||||||
cmOrderLinkDirectories::PrintVector(const char* name,
|
|
||||||
std::vector<std::pair<cmStdString,
|
|
||||||
std::vector<cmStdString> > >& m)
|
|
||||||
{
|
|
||||||
std::cout << name << "\n";
|
|
||||||
for(std::vector<std::pair<cmStdString, std::vector<cmStdString> >
|
|
||||||
>::iterator i = m.begin(); i != m.end(); ++i)
|
|
||||||
{
|
|
||||||
std::cout << i->first << ": ";
|
|
||||||
for(std::vector<cmStdString>::iterator l = i->second.begin();
|
|
||||||
l != i->second.end(); ++l)
|
|
||||||
{
|
|
||||||
std::cout << *l << " ";
|
|
||||||
}
|
|
||||||
std::cout << "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void cmOrderLinkDirectories::GetFullPathLibraries(std::vector<cmStdString>&
|
|
||||||
libs)
|
|
||||||
{
|
|
||||||
for(std::map<cmStdString, Library>::iterator i =
|
|
||||||
this->FullPathLibraries.begin();
|
|
||||||
i != this->FullPathLibraries.end(); ++i)
|
|
||||||
{
|
|
||||||
libs.push_back(i->first);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
bool cmOrderLinkDirectories::LibraryMayConflict(const char* desiredLib,
|
|
||||||
const char* dir,
|
|
||||||
const char* fname)
|
|
||||||
{
|
|
||||||
// We need to check whether the given file may be picked up by the
|
|
||||||
// linker. This will occur if it exists as given or may be built
|
|
||||||
// using the name given.
|
|
||||||
bool found = false;
|
|
||||||
std::string path = dir;
|
|
||||||
path += "/";
|
|
||||||
path += fname;
|
|
||||||
if(this->ManifestFiles.find(path) != this->ManifestFiles.end())
|
|
||||||
{
|
|
||||||
found = true;
|
|
||||||
}
|
|
||||||
else if(cmSystemTools::FileExists(path.c_str()))
|
|
||||||
{
|
|
||||||
found = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// When linking with a multi-configuration build tool the
|
|
||||||
// per-configuration subdirectory is added to each link path. Check
|
|
||||||
// this subdirectory too.
|
|
||||||
if(!found && !this->ConfigSubdir.empty())
|
|
||||||
{
|
|
||||||
path = dir;
|
|
||||||
path += "/";
|
|
||||||
path += this->ConfigSubdir;
|
|
||||||
path += "/";
|
|
||||||
path += fname;
|
|
||||||
if(this->ManifestFiles.find(path) != this->ManifestFiles.end())
|
|
||||||
{
|
|
||||||
found = true;
|
|
||||||
}
|
|
||||||
else if(cmSystemTools::FileExists(path.c_str()))
|
|
||||||
{
|
|
||||||
found = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// A library conflicts if it is found and is not a symlink back to
|
|
||||||
// the desired library.
|
|
||||||
if(found)
|
|
||||||
{
|
|
||||||
return !cmSystemTools::SameFile(desiredLib, path.c_str());
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
@ -1,192 +0,0 @@
|
|||||||
/*=========================================================================
|
|
||||||
|
|
||||||
Program: CMake - Cross-Platform Makefile Generator
|
|
||||||
Module: $RCSfile$
|
|
||||||
Language: C++
|
|
||||||
Date: $Date$
|
|
||||||
Version: $Revision$
|
|
||||||
|
|
||||||
Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
|
|
||||||
See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
|
|
||||||
|
|
||||||
This software is distributed WITHOUT ANY WARRANTY; without even
|
|
||||||
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
||||||
PURPOSE. See the above copyright notices for more information.
|
|
||||||
|
|
||||||
=========================================================================*/
|
|
||||||
#ifndef cmOrderLinkDirectories_h
|
|
||||||
#define cmOrderLinkDirectories_h
|
|
||||||
|
|
||||||
#include <cmStandardIncludes.h>
|
|
||||||
#include <map>
|
|
||||||
#include <vector>
|
|
||||||
#include "cmTarget.h"
|
|
||||||
#include "cmsys/RegularExpression.hxx"
|
|
||||||
|
|
||||||
|
|
||||||
/** \class cmOrderLinkDirectories
|
|
||||||
* \brief Compute the best -L path order
|
|
||||||
*
|
|
||||||
* This class computes the best order for -L paths.
|
|
||||||
* It tries to make sure full path specified libraries are
|
|
||||||
* used. For example if you have /usr/mylib/libfoo.a on as
|
|
||||||
* a link library for a target, and you also have /usr/lib/libbar.a
|
|
||||||
* and you also have /usr/lib/libfoo.a, then you would
|
|
||||||
* want -L/usr/mylib -L/usr/lib to make sure the correct libfoo.a is
|
|
||||||
* found by the linker. The algorithm is as follows:
|
|
||||||
* - foreach library create a vector of directories it exists in.
|
|
||||||
* - foreach directory create a vector of directories that must come
|
|
||||||
* after it, put this in a map<dir, vector<dir>> mapping from a directory
|
|
||||||
* to the vector of directories that it must be before.
|
|
||||||
* - put all directories into a vector
|
|
||||||
* - sort the vector with a compare function CanBeBefore
|
|
||||||
* CanBeBefore returns true if a directory is OK to be before
|
|
||||||
* another directory. This is determined by looking at the
|
|
||||||
* map<dir vector<dir>> and seeing if d1 is in the vector for d2.
|
|
||||||
*/
|
|
||||||
class cmOrderLinkDirectories
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
cmOrderLinkDirectories();
|
|
||||||
///! set link information from the target
|
|
||||||
void SetLinkInformation(const char* targetName,
|
|
||||||
const std::vector<std::string>& linkLibraries,
|
|
||||||
const std::vector<std::string>& linkDirectories,
|
|
||||||
const cmTargetManifest& manifest,
|
|
||||||
const char* configSubdir);
|
|
||||||
///! Compute the best order for -L paths from GetLinkLibraries
|
|
||||||
bool DetermineLibraryPathOrder();
|
|
||||||
///! Get the results from DetermineLibraryPathOrder
|
|
||||||
void GetLinkerInformation(std::vector<cmStdString>& searchPaths,
|
|
||||||
std::vector<cmStdString>& linkItems)
|
|
||||||
{
|
|
||||||
linkItems = this->LinkItems;
|
|
||||||
searchPaths = this->SortedSearchPaths;
|
|
||||||
}
|
|
||||||
// should be set from CMAKE_STATIC_LIBRARY_SUFFIX,
|
|
||||||
// CMAKE_SHARED_LIBRARY_SUFFIX
|
|
||||||
// CMAKE_LINK_LIBRARY_SUFFIX
|
|
||||||
enum LinkType { LinkUnknown, LinkStatic, LinkShared };
|
|
||||||
void AddLinkExtension(const char* e, LinkType type = LinkUnknown)
|
|
||||||
{
|
|
||||||
if(e && *e)
|
|
||||||
{
|
|
||||||
if(type == LinkStatic)
|
|
||||||
{
|
|
||||||
this->StaticLinkExtensions.push_back(e);
|
|
||||||
}
|
|
||||||
if(type == LinkShared)
|
|
||||||
{
|
|
||||||
this->SharedLinkExtensions.push_back(e);
|
|
||||||
}
|
|
||||||
this->LinkExtensions.push_back(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// should be set from CMAKE_STATIC_LIBRARY_PREFIX
|
|
||||||
void AddLinkPrefix(const char* s)
|
|
||||||
{
|
|
||||||
if(s)
|
|
||||||
{
|
|
||||||
this->LinkPrefixes.insert(s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Return any warnings if the exist
|
|
||||||
std::string GetWarnings();
|
|
||||||
// return a list of all full path libraries
|
|
||||||
void GetFullPathLibraries(std::vector<cmStdString>& libs);
|
|
||||||
|
|
||||||
// Provide flags for switching library link type.
|
|
||||||
void SetLinkTypeInformation(LinkType start_link_type,
|
|
||||||
const char* static_link_type_flag,
|
|
||||||
const char* shared_link_type_flag);
|
|
||||||
|
|
||||||
// structure to hold a full path library link item
|
|
||||||
struct Library
|
|
||||||
{
|
|
||||||
cmStdString FullPath;
|
|
||||||
cmStdString File;
|
|
||||||
cmStdString Path;
|
|
||||||
};
|
|
||||||
friend struct cmOrderLinkDirectoriesCompare;
|
|
||||||
void DebugOn()
|
|
||||||
{
|
|
||||||
this->Debug = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void CreateRegularExpressions();
|
|
||||||
std::string CreateExtensionRegex(std::vector<cmStdString> const& exts);
|
|
||||||
void DetermineLibraryPathOrder(std::vector<cmStdString>& searchPaths,
|
|
||||||
std::vector<cmStdString>& libs,
|
|
||||||
std::vector<cmStdString>& sortedPaths);
|
|
||||||
void PrepareLinkTargets();
|
|
||||||
bool LibraryInDirectory(const char* desiredLib,
|
|
||||||
const char* dir, const char* lib);
|
|
||||||
void FindLibrariesInSearchPaths();
|
|
||||||
void FindIndividualLibraryOrders();
|
|
||||||
void PrintMap(const char* name,
|
|
||||||
std::map<cmStdString, std::vector<cmStdString> >& m);
|
|
||||||
void PrintVector(const char* name,
|
|
||||||
std::vector<std::pair<cmStdString,
|
|
||||||
std::vector<cmStdString> > >& m);
|
|
||||||
void OrderPaths(std::vector<cmStdString>& paths);
|
|
||||||
bool FindPathNotInDirectoryToAfterList(cmStdString& path);
|
|
||||||
std::string NoCaseExpression(const char* str);
|
|
||||||
bool LibraryMayConflict(const char* desiredLib,
|
|
||||||
const char* dir, const char* fname);
|
|
||||||
private:
|
|
||||||
// set of files that will exist when the build occurs
|
|
||||||
std::set<cmStdString> ManifestFiles;
|
|
||||||
// map from library to directories that it is in other than its full path
|
|
||||||
std::map<cmStdString, std::vector<cmStdString> > LibraryToDirectories;
|
|
||||||
// map from directory to vector of directories that must be after it
|
|
||||||
std::vector<std::pair<cmStdString, std::vector<cmStdString> > >
|
|
||||||
DirectoryToAfterList;
|
|
||||||
std::set<cmStdString> DirectoryToAfterListEmitted;
|
|
||||||
// map from full path to a Library struct
|
|
||||||
std::map<cmStdString, Library> FullPathLibraries;
|
|
||||||
// libraries that are found in multiple directories
|
|
||||||
std::vector<Library> MultiDirectoryLibraries;
|
|
||||||
// libraries that are only found in one directory
|
|
||||||
std::vector<Library> SingleDirectoryLibraries;
|
|
||||||
// This is a vector of all the link objects -lm or m
|
|
||||||
std::vector<cmStdString> LinkItems;
|
|
||||||
// Unprocessed link items
|
|
||||||
std::vector<cmStdString> RawLinkItems;
|
|
||||||
// This vector holds the sorted -L paths
|
|
||||||
std::vector<cmStdString> SortedSearchPaths;
|
|
||||||
// This vector holds the -F paths
|
|
||||||
std::set<cmStdString> EmittedFrameworkPaths;
|
|
||||||
// This is the set of -L paths unsorted, but unique
|
|
||||||
std::set<cmStdString> LinkPathSet;
|
|
||||||
// the names of link extensions
|
|
||||||
std::vector<cmStdString> StaticLinkExtensions;
|
|
||||||
std::vector<cmStdString> SharedLinkExtensions;
|
|
||||||
std::vector<cmStdString> LinkExtensions;
|
|
||||||
// the names of link prefixes
|
|
||||||
std::set<cmStdString> LinkPrefixes;
|
|
||||||
// set of directories that can not be put in the correct order
|
|
||||||
std::set<cmStdString> ImpossibleDirectories;
|
|
||||||
// Name of target
|
|
||||||
cmStdString TargetName;
|
|
||||||
// Subdirectory used for this configuration if any.
|
|
||||||
cmStdString ConfigSubdir;
|
|
||||||
|
|
||||||
// Link type adjustment.
|
|
||||||
LinkType StartLinkType;
|
|
||||||
LinkType CurrentLinkType;
|
|
||||||
cmStdString StaticLinkTypeFlag;
|
|
||||||
cmStdString SharedLinkTypeFlag;
|
|
||||||
bool LinkTypeEnabled;
|
|
||||||
void SetCurrentLinkType(LinkType lt);
|
|
||||||
|
|
||||||
// library regular expressions
|
|
||||||
cmsys::RegularExpression RemoveLibraryExtension;
|
|
||||||
cmsys::RegularExpression ExtractStaticLibraryName;
|
|
||||||
cmsys::RegularExpression ExtractSharedLibraryName;
|
|
||||||
cmsys::RegularExpression ExtractAnyLibraryName;
|
|
||||||
cmsys::RegularExpression SplitFramework;
|
|
||||||
bool Debug;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
@ -35,7 +35,6 @@ cmTarget::cmTarget()
|
|||||||
{
|
{
|
||||||
this->Makefile = 0;
|
this->Makefile = 0;
|
||||||
this->LinkLibrariesAnalyzed = false;
|
this->LinkLibrariesAnalyzed = false;
|
||||||
this->LinkDirectoriesComputed = false;
|
|
||||||
this->HaveInstallRule = false;
|
this->HaveInstallRule = false;
|
||||||
this->DLLPlatform = false;
|
this->DLLPlatform = false;
|
||||||
this->IsImportedTarget = false;
|
this->IsImportedTarget = false;
|
||||||
@ -843,71 +842,15 @@ void cmTarget::MergeLinkLibraries( cmMakefile& mf,
|
|||||||
void cmTarget::AddLinkDirectory(const char* d)
|
void cmTarget::AddLinkDirectory(const char* d)
|
||||||
{
|
{
|
||||||
// Make sure we don't add unnecessary search directories.
|
// Make sure we don't add unnecessary search directories.
|
||||||
if(std::find(this->ExplicitLinkDirectories.begin(),
|
if(this->LinkDirectoriesEmmitted.insert(d).second)
|
||||||
this->ExplicitLinkDirectories.end(), d)
|
|
||||||
== this->ExplicitLinkDirectories.end() )
|
|
||||||
{
|
{
|
||||||
this->ExplicitLinkDirectories.push_back( d );
|
this->LinkDirectories.push_back(d);
|
||||||
this->LinkDirectoriesComputed = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
const std::vector<std::string>& cmTarget::GetLinkDirectories()
|
const std::vector<std::string>& cmTarget::GetLinkDirectories()
|
||||||
{
|
{
|
||||||
// Make sure all library dependencies have been analyzed.
|
|
||||||
if(!this->LinkLibrariesAnalyzed && !this->LinkLibraries.empty())
|
|
||||||
{
|
|
||||||
cmSystemTools::Error(
|
|
||||||
"cmTarget::GetLinkDirectories called before "
|
|
||||||
"cmTarget::AnalyzeLibDependencies on target ",
|
|
||||||
this->Name.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure the complete set of link directories has been computed.
|
|
||||||
if(!this->LinkDirectoriesComputed)
|
|
||||||
{
|
|
||||||
// Check whether we should use an import library for linking a target.
|
|
||||||
bool implib =
|
|
||||||
this->Makefile->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX") != 0;
|
|
||||||
|
|
||||||
// Compute the full set of link directories including the
|
|
||||||
// locations of targets that have been linked in. Start with the
|
|
||||||
// link directories given explicitly.
|
|
||||||
this->LinkDirectories = this->ExplicitLinkDirectories;
|
|
||||||
for(LinkLibraryVectorType::iterator ll = this->LinkLibraries.begin();
|
|
||||||
ll != this->LinkLibraries.end(); ++ll)
|
|
||||||
{
|
|
||||||
// If this library is a CMake target then add its location as a
|
|
||||||
// link directory.
|
|
||||||
std::string lib = ll->first;
|
|
||||||
cmTarget* tgt = 0;
|
|
||||||
if(this->Makefile && this->Makefile->GetLocalGenerator() &&
|
|
||||||
this->Makefile->GetLocalGenerator()->GetGlobalGenerator())
|
|
||||||
{
|
|
||||||
tgt = (this->Makefile->GetLocalGenerator()->GetGlobalGenerator()
|
|
||||||
->FindTarget(0, lib.c_str(), false));
|
|
||||||
}
|
|
||||||
if(tgt)
|
|
||||||
{
|
|
||||||
// Add the directory only if it is not already present. This
|
|
||||||
// is an N^2 algorithm for adding the directories, but N
|
|
||||||
// should not get very big.
|
|
||||||
const char* libpath = tgt->GetDirectory(0, implib);
|
|
||||||
if(std::find(this->LinkDirectories.begin(),
|
|
||||||
this->LinkDirectories.end(),
|
|
||||||
libpath) == this->LinkDirectories.end())
|
|
||||||
{
|
|
||||||
this->LinkDirectories.push_back(libpath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The complete set of link directories has now been computed.
|
|
||||||
this->LinkDirectoriesComputed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the complete set of link directories.
|
|
||||||
return this->LinkDirectories;
|
return this->LinkDirectories;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2244,6 +2187,76 @@ void cmTarget::GetExecutableNamesInternal(std::string& name,
|
|||||||
pdbName = prefix+base+".pdb";
|
pdbName = prefix+base+".pdb";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void cmTarget::GenerateTargetManifest(const char* config)
|
||||||
|
{
|
||||||
|
cmMakefile* mf = this->Makefile;
|
||||||
|
cmLocalGenerator* lg = mf->GetLocalGenerator();
|
||||||
|
cmGlobalGenerator* gg = lg->GetGlobalGenerator();
|
||||||
|
|
||||||
|
// Get the names.
|
||||||
|
std::string name;
|
||||||
|
std::string soName;
|
||||||
|
std::string realName;
|
||||||
|
std::string impName;
|
||||||
|
std::string pdbName;
|
||||||
|
if(this->GetType() == cmTarget::EXECUTABLE)
|
||||||
|
{
|
||||||
|
this->GetExecutableNames(name, realName, impName, pdbName, config);
|
||||||
|
}
|
||||||
|
else if(this->GetType() == cmTarget::STATIC_LIBRARY ||
|
||||||
|
this->GetType() == cmTarget::SHARED_LIBRARY ||
|
||||||
|
this->GetType() == cmTarget::MODULE_LIBRARY)
|
||||||
|
{
|
||||||
|
this->GetLibraryNames(name, soName, realName, impName, pdbName, config);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the directory.
|
||||||
|
std::string dir = this->GetDirectory(config, false);
|
||||||
|
|
||||||
|
// Add each name.
|
||||||
|
std::string f;
|
||||||
|
if(!name.empty())
|
||||||
|
{
|
||||||
|
f = dir;
|
||||||
|
f += "/";
|
||||||
|
f += name;
|
||||||
|
gg->AddToManifest(config? config:"", f);
|
||||||
|
}
|
||||||
|
if(!soName.empty())
|
||||||
|
{
|
||||||
|
f = dir;
|
||||||
|
f += "/";
|
||||||
|
f += soName;
|
||||||
|
gg->AddToManifest(config? config:"", f);
|
||||||
|
}
|
||||||
|
if(!realName.empty())
|
||||||
|
{
|
||||||
|
f = dir;
|
||||||
|
f += "/";
|
||||||
|
f += realName;
|
||||||
|
gg->AddToManifest(config? config:"", f);
|
||||||
|
}
|
||||||
|
if(!pdbName.empty())
|
||||||
|
{
|
||||||
|
f = dir;
|
||||||
|
f += "/";
|
||||||
|
f += pdbName;
|
||||||
|
gg->AddToManifest(config? config:"", f);
|
||||||
|
}
|
||||||
|
if(!impName.empty())
|
||||||
|
{
|
||||||
|
f = this->GetDirectory(config, true);
|
||||||
|
f += "/";
|
||||||
|
f += impName;
|
||||||
|
gg->AddToManifest(config? config:"", f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void cmTarget::SetPropertyDefault(const char* property,
|
void cmTarget::SetPropertyDefault(const char* property,
|
||||||
const char* default_value)
|
const char* default_value)
|
||||||
|
@ -271,6 +271,9 @@ public:
|
|||||||
std::string& impName,
|
std::string& impName,
|
||||||
std::string& pdbName, const char* config);
|
std::string& pdbName, const char* config);
|
||||||
|
|
||||||
|
/** Add the target output files to the global generator manifest. */
|
||||||
|
void GenerateTargetManifest(const char* config);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compute whether this target must be relinked before installing.
|
* Compute whether this target must be relinked before installing.
|
||||||
*/
|
*/
|
||||||
@ -414,10 +417,9 @@ private:
|
|||||||
LinkLibraryVectorType LinkLibraries;
|
LinkLibraryVectorType LinkLibraries;
|
||||||
LinkLibraryVectorType PrevLinkedLibraries;
|
LinkLibraryVectorType PrevLinkedLibraries;
|
||||||
bool LinkLibrariesAnalyzed;
|
bool LinkLibrariesAnalyzed;
|
||||||
bool LinkDirectoriesComputed;
|
|
||||||
std::vector<std::string> Frameworks;
|
std::vector<std::string> Frameworks;
|
||||||
std::vector<std::string> LinkDirectories;
|
std::vector<std::string> LinkDirectories;
|
||||||
std::vector<std::string> ExplicitLinkDirectories;
|
std::set<cmStdString> LinkDirectoriesEmmitted;
|
||||||
bool HaveInstallRule;
|
bool HaveInstallRule;
|
||||||
std::string InstallNameFixupPath;
|
std::string InstallNameFixupPath;
|
||||||
std::string InstallPath;
|
std::string InstallPath;
|
||||||
|
@ -13,7 +13,6 @@ extern "C" {
|
|||||||
#include "cmSystemTools.h"
|
#include "cmSystemTools.h"
|
||||||
#include "cmDynamicLoader.h"
|
#include "cmDynamicLoader.h"
|
||||||
#include "cmSystemTools.h"
|
#include "cmSystemTools.h"
|
||||||
#include "cmOrderLinkDirectories.h"
|
|
||||||
#include "cmGeneratedFileStream.h"
|
#include "cmGeneratedFileStream.h"
|
||||||
#include <cmsys/DynamicLoader.hxx>
|
#include <cmsys/DynamicLoader.hxx>
|
||||||
#else
|
#else
|
||||||
@ -69,99 +68,6 @@ void cmPassed(const char* Message, const char* m2="")
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef COMPLEX_TEST_CMAKELIB
|
#ifdef COMPLEX_TEST_CMAKELIB
|
||||||
// Here is a stupid function that tries to use std::string methods
|
|
||||||
// so that the dec cxx compiler will instantiate the stuff that
|
|
||||||
// we are using from the CMakeLib library....
|
|
||||||
bool TestLibraryOrder(bool shouldFail)
|
|
||||||
{
|
|
||||||
std::string Adir = std::string(BINARY_DIR) + std::string("/A");
|
|
||||||
std::string Bdir = std::string(BINARY_DIR) + std::string("/B");
|
|
||||||
std::string Cdir = std::string(BINARY_DIR) + std::string("/C");
|
|
||||||
#ifdef _WIN32
|
|
||||||
// Avoid case problems for windows paths.
|
|
||||||
if(Adir[0] >= 'A' && Adir[0] <= 'Z') { Adir[0] += 'a' - 'A'; }
|
|
||||||
if(Bdir[0] >= 'A' && Bdir[0] <= 'Z') { Bdir[0] += 'a' - 'A'; }
|
|
||||||
if(Cdir[0] >= 'A' && Cdir[0] <= 'Z') { Cdir[0] += 'a' - 'A'; }
|
|
||||||
Adir = cmSystemTools::GetActualCaseForPath(Adir.c_str());
|
|
||||||
Bdir = cmSystemTools::GetActualCaseForPath(Bdir.c_str());
|
|
||||||
Cdir = cmSystemTools::GetActualCaseForPath(Cdir.c_str());
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(!shouldFail)
|
|
||||||
{
|
|
||||||
std::string rm = Bdir;
|
|
||||||
rm += "/libA.a";
|
|
||||||
cmSystemTools::RemoveFile(rm.c_str());
|
|
||||||
}
|
|
||||||
std::vector<std::string> linkLibraries;
|
|
||||||
std::vector<std::string> linkDirectories;
|
|
||||||
linkDirectories.push_back(Adir);
|
|
||||||
linkDirectories.push_back(Bdir);
|
|
||||||
linkDirectories.push_back(Cdir);
|
|
||||||
linkDirectories.push_back("/lib/extra/stuff");
|
|
||||||
Adir += "/libA.a";
|
|
||||||
Bdir += "/libB.a";
|
|
||||||
Cdir += "/libC.a";
|
|
||||||
linkLibraries.push_back(Adir);
|
|
||||||
linkLibraries.push_back(Bdir);
|
|
||||||
linkLibraries.push_back(Cdir);
|
|
||||||
linkLibraries.push_back("-lm");
|
|
||||||
std::vector<cmStdString> sortedpaths;
|
|
||||||
std::vector<cmStdString> linkItems;
|
|
||||||
cmOrderLinkDirectories orderLibs;
|
|
||||||
orderLibs.DebugOn();
|
|
||||||
orderLibs.AddLinkExtension(".so");
|
|
||||||
orderLibs.AddLinkExtension(".a");
|
|
||||||
orderLibs.AddLinkPrefix("lib");
|
|
||||||
cmTargetManifest manifest;
|
|
||||||
orderLibs.SetLinkInformation("test", linkLibraries, linkDirectories,
|
|
||||||
manifest, "");
|
|
||||||
bool ret = orderLibs.DetermineLibraryPathOrder();
|
|
||||||
if(!ret)
|
|
||||||
{
|
|
||||||
std::cout << orderLibs.GetWarnings() << "\n";
|
|
||||||
}
|
|
||||||
orderLibs.GetLinkerInformation(sortedpaths, linkItems);
|
|
||||||
std::cout << "Sorted Link Paths:\n";
|
|
||||||
for(std::vector<cmStdString>::iterator i = sortedpaths.begin();
|
|
||||||
i != sortedpaths.end(); ++i)
|
|
||||||
{
|
|
||||||
std::cout << *i << "\n";
|
|
||||||
}
|
|
||||||
std::cout << "Link Items: \n";
|
|
||||||
for(std::vector<cmStdString>::iterator i = linkItems.begin();
|
|
||||||
i != linkItems.end(); ++i)
|
|
||||||
{
|
|
||||||
std::cout << *i << "\n";
|
|
||||||
}
|
|
||||||
if(!(linkItems[0] == "A" &&
|
|
||||||
linkItems[1] == "B" &&
|
|
||||||
linkItems[2] == "C" &&
|
|
||||||
linkItems[3] == "-lm" ))
|
|
||||||
{
|
|
||||||
std::cout << "fail because link items should be A B C -lm and the are not\n";
|
|
||||||
return shouldFail;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// if this is not the fail test then the order should be f B C A
|
|
||||||
if(!shouldFail)
|
|
||||||
{
|
|
||||||
char order[5];
|
|
||||||
order[4] = 0;
|
|
||||||
for(int i =0; i < 4; ++i)
|
|
||||||
{
|
|
||||||
order[i] = sortedpaths[i][sortedpaths[i].size()-1];
|
|
||||||
}
|
|
||||||
if(!(strcmp(order, "fBCA") == 0 || strcmp(order, "BCAf") == 0))
|
|
||||||
{
|
|
||||||
std::cout << "fail because order should be /lib/extra/stuff B C A and it is not\n";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ======================================================================
|
// ======================================================================
|
||||||
|
|
||||||
void TestAndRemoveFile(const char* filename)
|
void TestAndRemoveFile(const char* filename)
|
||||||
@ -286,6 +192,9 @@ void TestCMGeneratedFileSTream()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Here is a stupid function that tries to use std::string methods
|
||||||
|
// so that the dec cxx compiler will instantiate the stuff that
|
||||||
|
// we are using from the CMakeLib library....
|
||||||
void ForceStringUse()
|
void ForceStringUse()
|
||||||
{
|
{
|
||||||
std::vector<std::string> v;
|
std::vector<std::string> v;
|
||||||
@ -1283,27 +1192,6 @@ int main()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef COMPLEX_TEST_CMAKELIB
|
#ifdef COMPLEX_TEST_CMAKELIB
|
||||||
// first run with shouldFail = true, this will
|
|
||||||
// run with A B C as set by the CMakeList.txt file.
|
|
||||||
if(!TestLibraryOrder(true))
|
|
||||||
{
|
|
||||||
cmPassed("CMake cmOrderLinkDirectories failed when it should.");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cmFailed("CMake cmOrderLinkDirectories failed to fail when given an impossible set of paths.");
|
|
||||||
}
|
|
||||||
// next run with shouldPass = true, this will
|
|
||||||
// run with B/libA.a removed and should create the order
|
|
||||||
// B C A
|
|
||||||
if(TestLibraryOrder(false))
|
|
||||||
{
|
|
||||||
cmPassed("CMake cmOrderLinkDirectories worked.");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cmFailed("CMake cmOrderLinkDirectories failed.");
|
|
||||||
}
|
|
||||||
// Test the generated file stream.
|
// Test the generated file stream.
|
||||||
TestCMGeneratedFileSTream();
|
TestCMGeneratedFileSTream();
|
||||||
#endif
|
#endif
|
||||||
|
@ -13,7 +13,6 @@ extern "C" {
|
|||||||
#include "cmSystemTools.h"
|
#include "cmSystemTools.h"
|
||||||
#include "cmDynamicLoader.h"
|
#include "cmDynamicLoader.h"
|
||||||
#include "cmSystemTools.h"
|
#include "cmSystemTools.h"
|
||||||
#include "cmOrderLinkDirectories.h"
|
|
||||||
#include "cmGeneratedFileStream.h"
|
#include "cmGeneratedFileStream.h"
|
||||||
#include <cmsys/DynamicLoader.hxx>
|
#include <cmsys/DynamicLoader.hxx>
|
||||||
#else
|
#else
|
||||||
@ -69,99 +68,6 @@ void cmPassed(const char* Message, const char* m2="")
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef COMPLEX_TEST_CMAKELIB
|
#ifdef COMPLEX_TEST_CMAKELIB
|
||||||
// Here is a stupid function that tries to use std::string methods
|
|
||||||
// so that the dec cxx compiler will instantiate the stuff that
|
|
||||||
// we are using from the CMakeLib library....
|
|
||||||
bool TestLibraryOrder(bool shouldFail)
|
|
||||||
{
|
|
||||||
std::string Adir = std::string(BINARY_DIR) + std::string("/A");
|
|
||||||
std::string Bdir = std::string(BINARY_DIR) + std::string("/B");
|
|
||||||
std::string Cdir = std::string(BINARY_DIR) + std::string("/C");
|
|
||||||
#ifdef _WIN32
|
|
||||||
// Avoid case problems for windows paths.
|
|
||||||
if(Adir[0] >= 'A' && Adir[0] <= 'Z') { Adir[0] += 'a' - 'A'; }
|
|
||||||
if(Bdir[0] >= 'A' && Bdir[0] <= 'Z') { Bdir[0] += 'a' - 'A'; }
|
|
||||||
if(Cdir[0] >= 'A' && Cdir[0] <= 'Z') { Cdir[0] += 'a' - 'A'; }
|
|
||||||
Adir = cmSystemTools::GetActualCaseForPath(Adir.c_str());
|
|
||||||
Bdir = cmSystemTools::GetActualCaseForPath(Bdir.c_str());
|
|
||||||
Cdir = cmSystemTools::GetActualCaseForPath(Cdir.c_str());
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(!shouldFail)
|
|
||||||
{
|
|
||||||
std::string rm = Bdir;
|
|
||||||
rm += "/libA.a";
|
|
||||||
cmSystemTools::RemoveFile(rm.c_str());
|
|
||||||
}
|
|
||||||
std::vector<std::string> linkLibraries;
|
|
||||||
std::vector<std::string> linkDirectories;
|
|
||||||
linkDirectories.push_back(Adir);
|
|
||||||
linkDirectories.push_back(Bdir);
|
|
||||||
linkDirectories.push_back(Cdir);
|
|
||||||
linkDirectories.push_back("/lib/extra/stuff");
|
|
||||||
Adir += "/libA.a";
|
|
||||||
Bdir += "/libB.a";
|
|
||||||
Cdir += "/libC.a";
|
|
||||||
linkLibraries.push_back(Adir);
|
|
||||||
linkLibraries.push_back(Bdir);
|
|
||||||
linkLibraries.push_back(Cdir);
|
|
||||||
linkLibraries.push_back("-lm");
|
|
||||||
std::vector<cmStdString> sortedpaths;
|
|
||||||
std::vector<cmStdString> linkItems;
|
|
||||||
cmOrderLinkDirectories orderLibs;
|
|
||||||
orderLibs.DebugOn();
|
|
||||||
orderLibs.AddLinkExtension(".so");
|
|
||||||
orderLibs.AddLinkExtension(".a");
|
|
||||||
orderLibs.AddLinkPrefix("lib");
|
|
||||||
cmTargetManifest manifest;
|
|
||||||
orderLibs.SetLinkInformation("test", linkLibraries, linkDirectories,
|
|
||||||
manifest, "");
|
|
||||||
bool ret = orderLibs.DetermineLibraryPathOrder();
|
|
||||||
if(!ret)
|
|
||||||
{
|
|
||||||
std::cout << orderLibs.GetWarnings() << "\n";
|
|
||||||
}
|
|
||||||
orderLibs.GetLinkerInformation(sortedpaths, linkItems);
|
|
||||||
std::cout << "Sorted Link Paths:\n";
|
|
||||||
for(std::vector<cmStdString>::iterator i = sortedpaths.begin();
|
|
||||||
i != sortedpaths.end(); ++i)
|
|
||||||
{
|
|
||||||
std::cout << *i << "\n";
|
|
||||||
}
|
|
||||||
std::cout << "Link Items: \n";
|
|
||||||
for(std::vector<cmStdString>::iterator i = linkItems.begin();
|
|
||||||
i != linkItems.end(); ++i)
|
|
||||||
{
|
|
||||||
std::cout << *i << "\n";
|
|
||||||
}
|
|
||||||
if(!(linkItems[0] == "A" &&
|
|
||||||
linkItems[1] == "B" &&
|
|
||||||
linkItems[2] == "C" &&
|
|
||||||
linkItems[3] == "-lm" ))
|
|
||||||
{
|
|
||||||
std::cout << "fail because link items should be A B C -lm and the are not\n";
|
|
||||||
return shouldFail;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// if this is not the fail test then the order should be f B C A
|
|
||||||
if(!shouldFail)
|
|
||||||
{
|
|
||||||
char order[5];
|
|
||||||
order[4] = 0;
|
|
||||||
for(int i =0; i < 4; ++i)
|
|
||||||
{
|
|
||||||
order[i] = sortedpaths[i][sortedpaths[i].size()-1];
|
|
||||||
}
|
|
||||||
if(!(strcmp(order, "fBCA") == 0 || strcmp(order, "BCAf") == 0))
|
|
||||||
{
|
|
||||||
std::cout << "fail because order should be /lib/extra/stuff B C A and it is not\n";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ======================================================================
|
// ======================================================================
|
||||||
|
|
||||||
void TestAndRemoveFile(const char* filename)
|
void TestAndRemoveFile(const char* filename)
|
||||||
@ -286,6 +192,9 @@ void TestCMGeneratedFileSTream()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Here is a stupid function that tries to use std::string methods
|
||||||
|
// so that the dec cxx compiler will instantiate the stuff that
|
||||||
|
// we are using from the CMakeLib library....
|
||||||
void ForceStringUse()
|
void ForceStringUse()
|
||||||
{
|
{
|
||||||
std::vector<std::string> v;
|
std::vector<std::string> v;
|
||||||
@ -1283,27 +1192,6 @@ int main()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef COMPLEX_TEST_CMAKELIB
|
#ifdef COMPLEX_TEST_CMAKELIB
|
||||||
// first run with shouldFail = true, this will
|
|
||||||
// run with A B C as set by the CMakeList.txt file.
|
|
||||||
if(!TestLibraryOrder(true))
|
|
||||||
{
|
|
||||||
cmPassed("CMake cmOrderLinkDirectories failed when it should.");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cmFailed("CMake cmOrderLinkDirectories failed to fail when given an impossible set of paths.");
|
|
||||||
}
|
|
||||||
// next run with shouldPass = true, this will
|
|
||||||
// run with B/libA.a removed and should create the order
|
|
||||||
// B C A
|
|
||||||
if(TestLibraryOrder(false))
|
|
||||||
{
|
|
||||||
cmPassed("CMake cmOrderLinkDirectories worked.");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cmFailed("CMake cmOrderLinkDirectories failed.");
|
|
||||||
}
|
|
||||||
// Test the generated file stream.
|
// Test the generated file stream.
|
||||||
TestCMGeneratedFileSTream();
|
TestCMGeneratedFileSTream();
|
||||||
#endif
|
#endif
|
||||||
|
@ -13,7 +13,6 @@ extern "C" {
|
|||||||
#include "cmSystemTools.h"
|
#include "cmSystemTools.h"
|
||||||
#include "cmDynamicLoader.h"
|
#include "cmDynamicLoader.h"
|
||||||
#include "cmSystemTools.h"
|
#include "cmSystemTools.h"
|
||||||
#include "cmOrderLinkDirectories.h"
|
|
||||||
#include "cmGeneratedFileStream.h"
|
#include "cmGeneratedFileStream.h"
|
||||||
#include <cmsys/DynamicLoader.hxx>
|
#include <cmsys/DynamicLoader.hxx>
|
||||||
#else
|
#else
|
||||||
@ -69,99 +68,6 @@ void cmPassed(const char* Message, const char* m2="")
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef COMPLEX_TEST_CMAKELIB
|
#ifdef COMPLEX_TEST_CMAKELIB
|
||||||
// Here is a stupid function that tries to use std::string methods
|
|
||||||
// so that the dec cxx compiler will instantiate the stuff that
|
|
||||||
// we are using from the CMakeLib library....
|
|
||||||
bool TestLibraryOrder(bool shouldFail)
|
|
||||||
{
|
|
||||||
std::string Adir = std::string(BINARY_DIR) + std::string("/A");
|
|
||||||
std::string Bdir = std::string(BINARY_DIR) + std::string("/B");
|
|
||||||
std::string Cdir = std::string(BINARY_DIR) + std::string("/C");
|
|
||||||
#ifdef _WIN32
|
|
||||||
// Avoid case problems for windows paths.
|
|
||||||
if(Adir[0] >= 'A' && Adir[0] <= 'Z') { Adir[0] += 'a' - 'A'; }
|
|
||||||
if(Bdir[0] >= 'A' && Bdir[0] <= 'Z') { Bdir[0] += 'a' - 'A'; }
|
|
||||||
if(Cdir[0] >= 'A' && Cdir[0] <= 'Z') { Cdir[0] += 'a' - 'A'; }
|
|
||||||
Adir = cmSystemTools::GetActualCaseForPath(Adir.c_str());
|
|
||||||
Bdir = cmSystemTools::GetActualCaseForPath(Bdir.c_str());
|
|
||||||
Cdir = cmSystemTools::GetActualCaseForPath(Cdir.c_str());
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(!shouldFail)
|
|
||||||
{
|
|
||||||
std::string rm = Bdir;
|
|
||||||
rm += "/libA.a";
|
|
||||||
cmSystemTools::RemoveFile(rm.c_str());
|
|
||||||
}
|
|
||||||
std::vector<std::string> linkLibraries;
|
|
||||||
std::vector<std::string> linkDirectories;
|
|
||||||
linkDirectories.push_back(Adir);
|
|
||||||
linkDirectories.push_back(Bdir);
|
|
||||||
linkDirectories.push_back(Cdir);
|
|
||||||
linkDirectories.push_back("/lib/extra/stuff");
|
|
||||||
Adir += "/libA.a";
|
|
||||||
Bdir += "/libB.a";
|
|
||||||
Cdir += "/libC.a";
|
|
||||||
linkLibraries.push_back(Adir);
|
|
||||||
linkLibraries.push_back(Bdir);
|
|
||||||
linkLibraries.push_back(Cdir);
|
|
||||||
linkLibraries.push_back("-lm");
|
|
||||||
std::vector<cmStdString> sortedpaths;
|
|
||||||
std::vector<cmStdString> linkItems;
|
|
||||||
cmOrderLinkDirectories orderLibs;
|
|
||||||
orderLibs.DebugOn();
|
|
||||||
orderLibs.AddLinkExtension(".so");
|
|
||||||
orderLibs.AddLinkExtension(".a");
|
|
||||||
orderLibs.AddLinkPrefix("lib");
|
|
||||||
cmTargetManifest manifest;
|
|
||||||
orderLibs.SetLinkInformation("test", linkLibraries, linkDirectories,
|
|
||||||
manifest, "");
|
|
||||||
bool ret = orderLibs.DetermineLibraryPathOrder();
|
|
||||||
if(!ret)
|
|
||||||
{
|
|
||||||
std::cout << orderLibs.GetWarnings() << "\n";
|
|
||||||
}
|
|
||||||
orderLibs.GetLinkerInformation(sortedpaths, linkItems);
|
|
||||||
std::cout << "Sorted Link Paths:\n";
|
|
||||||
for(std::vector<cmStdString>::iterator i = sortedpaths.begin();
|
|
||||||
i != sortedpaths.end(); ++i)
|
|
||||||
{
|
|
||||||
std::cout << *i << "\n";
|
|
||||||
}
|
|
||||||
std::cout << "Link Items: \n";
|
|
||||||
for(std::vector<cmStdString>::iterator i = linkItems.begin();
|
|
||||||
i != linkItems.end(); ++i)
|
|
||||||
{
|
|
||||||
std::cout << *i << "\n";
|
|
||||||
}
|
|
||||||
if(!(linkItems[0] == "A" &&
|
|
||||||
linkItems[1] == "B" &&
|
|
||||||
linkItems[2] == "C" &&
|
|
||||||
linkItems[3] == "-lm" ))
|
|
||||||
{
|
|
||||||
std::cout << "fail because link items should be A B C -lm and the are not\n";
|
|
||||||
return shouldFail;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// if this is not the fail test then the order should be f B C A
|
|
||||||
if(!shouldFail)
|
|
||||||
{
|
|
||||||
char order[5];
|
|
||||||
order[4] = 0;
|
|
||||||
for(int i =0; i < 4; ++i)
|
|
||||||
{
|
|
||||||
order[i] = sortedpaths[i][sortedpaths[i].size()-1];
|
|
||||||
}
|
|
||||||
if(!(strcmp(order, "fBCA") == 0 || strcmp(order, "BCAf") == 0))
|
|
||||||
{
|
|
||||||
std::cout << "fail because order should be /lib/extra/stuff B C A and it is not\n";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ======================================================================
|
// ======================================================================
|
||||||
|
|
||||||
void TestAndRemoveFile(const char* filename)
|
void TestAndRemoveFile(const char* filename)
|
||||||
@ -286,6 +192,9 @@ void TestCMGeneratedFileSTream()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Here is a stupid function that tries to use std::string methods
|
||||||
|
// so that the dec cxx compiler will instantiate the stuff that
|
||||||
|
// we are using from the CMakeLib library....
|
||||||
void ForceStringUse()
|
void ForceStringUse()
|
||||||
{
|
{
|
||||||
std::vector<std::string> v;
|
std::vector<std::string> v;
|
||||||
@ -1283,27 +1192,6 @@ int main()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef COMPLEX_TEST_CMAKELIB
|
#ifdef COMPLEX_TEST_CMAKELIB
|
||||||
// first run with shouldFail = true, this will
|
|
||||||
// run with A B C as set by the CMakeList.txt file.
|
|
||||||
if(!TestLibraryOrder(true))
|
|
||||||
{
|
|
||||||
cmPassed("CMake cmOrderLinkDirectories failed when it should.");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cmFailed("CMake cmOrderLinkDirectories failed to fail when given an impossible set of paths.");
|
|
||||||
}
|
|
||||||
// next run with shouldPass = true, this will
|
|
||||||
// run with B/libA.a removed and should create the order
|
|
||||||
// B C A
|
|
||||||
if(TestLibraryOrder(false))
|
|
||||||
{
|
|
||||||
cmPassed("CMake cmOrderLinkDirectories worked.");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cmFailed("CMake cmOrderLinkDirectories failed.");
|
|
||||||
}
|
|
||||||
// Test the generated file stream.
|
// Test the generated file stream.
|
||||||
TestCMGeneratedFileSTream();
|
TestCMGeneratedFileSTream();
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user