Skip to content

Commit

Permalink
llvm-config: Add preliminary Windows support
Browse files Browse the repository at this point in the history
Summary:
This patch adds Windows support for a few of the llvm-config commands,
including cflags, ldflags, libs, and system-libs.

Currently llvm-config is untested, so this patch adds tests for the
commands that it fixes as well.

Reviewers: rnk

Subscribers: llvm-commits

Differential Revision: http://reviews.llvm.org/D16762

llvm-svn: 260263
  • Loading branch information
ehsan committed Feb 9, 2016
1 parent 4215cda commit 155ca8f
Show file tree
Hide file tree
Showing 9 changed files with 113 additions and 62 deletions.
52 changes: 25 additions & 27 deletions llvm/lib/Support/CMakeLists.txt
@@ -1,32 +1,30 @@
set(system_libs)
if( NOT MSVC )
if( MINGW )
# libuuid required for FOLDERID_Profile usage in lib/Support/Windows/Path.inc.
set(system_libs ${system_libs} psapi shell32 ole32 uuid)
elseif( CMAKE_HOST_UNIX )
if( HAVE_LIBRT )
set(system_libs ${system_libs} rt)
if( MSVC OR MINGW )
# libuuid required for FOLDERID_Profile usage in lib/Support/Windows/Path.inc.
set(system_libs ${system_libs} psapi shell32 ole32 uuid)
elseif( CMAKE_HOST_UNIX )
if( HAVE_LIBRT )
set(system_libs ${system_libs} rt)
endif()
if( HAVE_LIBDL )
set(system_libs ${system_libs} ${CMAKE_DL_LIBS})
endif()
if(LLVM_ENABLE_TERMINFO)
if(HAVE_TERMINFO)
set(system_libs ${system_libs} ${TERMINFO_LIBS})
endif()
if( HAVE_LIBDL )
set(system_libs ${system_libs} ${CMAKE_DL_LIBS})
endif()
if(LLVM_ENABLE_TERMINFO)
if(HAVE_TERMINFO)
set(system_libs ${system_libs} ${TERMINFO_LIBS})
endif()
endif()
if( LLVM_ENABLE_THREADS AND HAVE_LIBATOMIC )
set(system_libs ${system_libs} atomic)
endif()
if( LLVM_ENABLE_THREADS AND HAVE_LIBPTHREAD )
set(system_libs ${system_libs} pthread)
endif()
if ( LLVM_ENABLE_ZLIB AND HAVE_LIBZ )
set(system_libs ${system_libs} z)
endif()
set(system_libs ${system_libs} m)
endif( MINGW )
endif( NOT MSVC )
endif()
if( LLVM_ENABLE_THREADS AND HAVE_LIBATOMIC )
set(system_libs ${system_libs} atomic)
endif()
if( LLVM_ENABLE_THREADS AND HAVE_LIBPTHREAD )
set(system_libs ${system_libs} pthread)
endif()
if ( LLVM_ENABLE_ZLIB AND HAVE_LIBZ )
set(system_libs ${system_libs} z)
endif()
set(system_libs ${system_libs} m)
endif( MSVC OR MINGW )

add_llvm_library(LLVMSupport
APFloat.cpp
Expand Down
7 changes: 7 additions & 0 deletions llvm/test/tools/llvm-config/cflags.test
@@ -0,0 +1,7 @@
RUN: llvm-config --cflags 2>&1 | FileCheck %s
RUN: llvm-config --cppflags 2>&1 | FileCheck %s
RUN: llvm-config --cxxflags 2>&1 | FileCheck %s
CHECK: -I
CHECK: {{[/\\]}}include
CHECK-NOT: error
CHECK-NOT: warning
5 changes: 5 additions & 0 deletions llvm/test/tools/llvm-config/ldflags.test
@@ -0,0 +1,5 @@
RUN: llvm-config --ldflags 2>&1 | FileCheck %s
CHECK: -L
CHECK: {{[/\\]}}lib
CHECK-NOT: error
CHECK-NOT: warning
5 changes: 5 additions & 0 deletions llvm/test/tools/llvm-config/libs.test
@@ -0,0 +1,5 @@
RUN: llvm-config --libs core 2>&1 | FileCheck %s
CHECK: LLVMCore
CHECK: LLVMSupport
CHECK-NOT: error
CHECK-NOT: warning
5 changes: 5 additions & 0 deletions llvm/test/tools/llvm-config/system-libs.test
@@ -0,0 +1,5 @@
RUN: llvm-config --system-libs 2>&1 | FileCheck %s
UNSUPPORTED: system-windows
CHECK: -l
CHECK-NOT: error
CHECK-NOT: warning
6 changes: 6 additions & 0 deletions llvm/test/tools/llvm-config/system-libs.windows.test
@@ -0,0 +1,6 @@
RUN: llvm-config --system-libs 2>&1 | FileCheck %s
REQUIRED: system-windows
CHECK-NOT: -l
CHECK: psapi.lib shell32.lib ole32.lib uuid.lib
CHECK-NOT: error
CHECK-NOT: warning
6 changes: 5 additions & 1 deletion llvm/tools/llvm-config/CMakeLists.txt
Expand Up @@ -11,7 +11,11 @@ add_llvm_tool(llvm-config
# Compute the substitution values for various items.
get_property(LLVM_SYSTEM_LIBS_LIST TARGET LLVMSupport PROPERTY LLVM_SYSTEM_LIBS)
foreach(l ${LLVM_SYSTEM_LIBS_LIST})
set(SYSTEM_LIBS ${SYSTEM_LIBS} "-l${l}")
if(MSVC)
set(SYSTEM_LIBS ${SYSTEM_LIBS} "${l}.lib")
else()
set(SYSTEM_LIBS ${SYSTEM_LIBS} "-l${l}")
endif()
endforeach()
string(REPLACE ";" " " SYSTEM_LIBS "${SYSTEM_LIBS}")

Expand Down
87 changes: 54 additions & 33 deletions llvm/tools/llvm-config/llvm-config.cpp
Expand Up @@ -79,7 +79,8 @@ static void VisitComponent(const std::string &Name,
bool IncludeNonInstalled, bool GetComponentNames,
const std::function<std::string(const StringRef &)>
*GetComponentLibraryPath,
std::vector<std::string> *Missing) {
std::vector<std::string> *Missing,
const std::string &DirSep) {
// Lookup the component.
AvailableComponent *AC = ComponentMap.lookup(Name);
assert(AC && "Invalid component name!");
Expand All @@ -98,7 +99,7 @@ static void VisitComponent(const std::string &Name,
for (unsigned i = 0; AC->RequiredLibraries[i]; ++i) {
VisitComponent(AC->RequiredLibraries[i], ComponentMap, VisitedComponents,
RequiredLibs, IncludeNonInstalled, GetComponentNames,
GetComponentLibraryPath, Missing);
GetComponentLibraryPath, Missing, DirSep);
}

if (GetComponentNames) {
Expand All @@ -110,6 +111,9 @@ static void VisitComponent(const std::string &Name,
if (AC->Library) {
if (Missing && GetComponentLibraryPath) {
std::string path = (*GetComponentLibraryPath)(AC->Library);
if (DirSep == "\\") {
std::replace(path.begin(), path.end(), '/', '\\');
}
if (!sys::fs::exists(path))
Missing->push_back(path);
}
Expand All @@ -125,12 +129,11 @@ static void VisitComponent(const std::string &Name,
/// \param IncludeNonInstalled - Whether non-installed components should be
/// reported.
/// \param GetComponentNames - True if one would prefer the component names.
static std::vector<std::string>
ComputeLibsForComponents(const std::vector<StringRef> &Components,
bool IncludeNonInstalled, bool GetComponentNames,
const std::function<std::string(const StringRef &)>
*GetComponentLibraryPath,
std::vector<std::string> *Missing) {
static std::vector<std::string> ComputeLibsForComponents(
const std::vector<StringRef> &Components, bool IncludeNonInstalled,
bool GetComponentNames, const std::function<std::string(const StringRef &)>
*GetComponentLibraryPath,
std::vector<std::string> *Missing, const std::string &DirSep) {
std::vector<std::string> RequiredLibs;
std::set<AvailableComponent *> VisitedComponents;

Expand All @@ -155,7 +158,7 @@ ComputeLibsForComponents(const std::vector<StringRef> &Components,

VisitComponent(ComponentLower, ComponentMap, VisitedComponents,
RequiredLibs, IncludeNonInstalled, GetComponentNames,
GetComponentLibraryPath, Missing);
GetComponentLibraryPath, Missing, DirSep);
}

// The list is now ordered with leafs first, we want the libraries to printed
Expand Down Expand Up @@ -220,7 +223,8 @@ std::string GetExecutablePath(const char *Argv0) {
/// \brief Expand the semi-colon delimited LLVM_DYLIB_COMPONENTS into
/// the full list of components.
std::vector<std::string> GetAllDyLibComponents(const bool IsInDevelopmentTree,
const bool GetComponentNames) {
const bool GetComponentNames,
const std::string &DirSep) {
std::vector<StringRef> DyLibComponents;

StringRef DyLibComponentsStr(LLVM_DYLIB_COMPONENTS);
Expand All @@ -238,7 +242,7 @@ std::vector<std::string> GetAllDyLibComponents(const bool IsInDevelopmentTree,

return ComputeLibsForComponents(DyLibComponents,
/*IncludeNonInstalled=*/IsInDevelopmentTree,
GetComponentNames, nullptr, nullptr);
GetComponentNames, nullptr, nullptr, DirSep);
}

int main(int argc, char **argv) {
Expand Down Expand Up @@ -347,15 +351,26 @@ int main(int argc, char **argv) {
/// in the first place. This can't be done at configure/build time.

StringRef SharedExt, SharedVersionedExt, SharedDir, SharedPrefix, StaticExt,
StaticPrefix, StaticDir = "lib";
StaticPrefix, StaticDir = "lib", DirSep = "/";
const Triple HostTriple(Triple::normalize(LLVM_DEFAULT_TARGET_TRIPLE));
if (HostTriple.isOSWindows()) {
SharedExt = "dll";
SharedVersionedExt = LLVM_DYLIB_VERSION ".dll";
StaticExt = "a";
if (HostTriple.isOSCygMing()) {
StaticExt = "a";
StaticPrefix = SharedPrefix = "lib";
} else {
StaticExt = "lib";
DirSep = "\\";
std::replace(ActiveObjRoot.begin(), ActiveObjRoot.end(), '/', '\\');
std::replace(ActivePrefix.begin(), ActivePrefix.end(), '/', '\\');
std::replace(ActiveBinDir.begin(), ActiveBinDir.end(), '/', '\\');
std::replace(ActiveLibDir.begin(), ActiveLibDir.end(), '/', '\\');
std::replace(ActiveIncludeOption.begin(), ActiveIncludeOption.end(), '/',
'\\');
}
SharedDir = ActiveBinDir;
StaticDir = ActiveLibDir;
StaticPrefix = SharedPrefix = "lib";
} else if (HostTriple.isOSDarwin()) {
SharedExt = "dylib";
SharedVersionedExt = LLVM_DYLIB_VERSION ".dylib";
Expand Down Expand Up @@ -394,7 +409,11 @@ int main(int argc, char **argv) {
bool LinkDyLib = (std::strcmp(LLVM_LINK_DYLIB, "ON") == 0);

if (BuiltDyLib) {
DyLibExists = sys::fs::exists(SharedDir + "/" + DyLibName);
std::string path((SharedDir + DirSep + DyLibName).str());
if (DirSep == "\\") {
std::replace(path.begin(), path.end(), '/', '\\');
}
DyLibExists = sys::fs::exists(path);
if (!DyLibExists) {
// The shared library does not exist: don't error unless the user
// explicitly passes --link-shared.
Expand Down Expand Up @@ -429,15 +448,12 @@ int main(int argc, char **argv) {
/// Maps Unixizms to the host platform.
auto GetComponentLibraryFileName = [&](const StringRef &Lib,
const bool Shared) {
std::string LibFileName = Lib;
StringRef LibName;
if (GetComponentLibraryNameSlice(Lib, LibName)) {
if (Shared) {
LibFileName = (SharedPrefix + LibName + "." + SharedExt).str();
} else {
// default to static
LibFileName = (StaticPrefix + LibName + "." + StaticExt).str();
}
std::string LibFileName;
if (Shared) {
LibFileName = (SharedPrefix + Lib + "." + SharedExt).str();
} else {
// default to static
LibFileName = (StaticPrefix + Lib + "." + StaticExt).str();
}

return LibFileName;
Expand All @@ -446,9 +462,9 @@ int main(int argc, char **argv) {
auto GetComponentLibraryPath = [&](const StringRef &Name, const bool Shared) {
auto LibFileName = GetComponentLibraryFileName(Name, Shared);
if (Shared) {
return (SharedDir + "/" + LibFileName).str();
return (SharedDir + DirSep + LibFileName).str();
} else {
return (StaticDir + "/" + LibFileName).str();
return (StaticDir + DirSep + LibFileName).str();
}
};

Expand All @@ -475,7 +491,8 @@ int main(int argc, char **argv) {
} else if (Arg == "--cxxflags") {
OS << ActiveIncludeOption << ' ' << LLVM_CXXFLAGS << '\n';
} else if (Arg == "--ldflags") {
OS << "-L" << ActiveLibDir << ' ' << LLVM_LDFLAGS << '\n';
OS << ((HostTriple.isWindowsMSVCEnvironment()) ? "-LIBPATH:" : "-L")
<< ActiveLibDir << ' ' << LLVM_LDFLAGS << '\n';
} else if (Arg == "--system-libs") {
PrintSystemLibs = true;
} else if (Arg == "--libs") {
Expand All @@ -496,10 +513,14 @@ int main(int argc, char **argv) {

Components.push_back(AvailableComponents[j].Name);
if (AvailableComponents[j].Library && !IsInDevelopmentTree) {
if (DyLibExists &&
!sys::fs::exists(GetComponentLibraryPath(
AvailableComponents[j].Library, false))) {
Components = GetAllDyLibComponents(IsInDevelopmentTree, true);
std::string path(
GetComponentLibraryPath(AvailableComponents[j].Library, false));
if (DirSep == "\\") {
std::replace(path.begin(), path.end(), '/', '\\');
}
if (DyLibExists && !sys::fs::exists(path)) {
Components =
GetAllDyLibComponents(IsInDevelopmentTree, true, DirSep);
std::sort(Components.begin(), Components.end());
break;
}
Expand Down Expand Up @@ -577,7 +598,7 @@ int main(int argc, char **argv) {
std::vector<std::string> RequiredLibs = ComputeLibsForComponents(
Components,
/*IncludeNonInstalled=*/IsInDevelopmentTree, false,
&GetComponentLibraryPathFunction, &MissingLibs);
&GetComponentLibraryPathFunction, &MissingLibs, DirSep);
if (!MissingLibs.empty()) {
switch (LinkMode) {
case LinkModeShared:
Expand Down Expand Up @@ -607,7 +628,7 @@ int main(int argc, char **argv) {
if (PrintSharedMode) {
std::unordered_set<std::string> FullDyLibComponents;
std::vector<std::string> DyLibComponents =
GetAllDyLibComponents(IsInDevelopmentTree, false);
GetAllDyLibComponents(IsInDevelopmentTree, false, DirSep);

for (auto &Component : DyLibComponents) {
FullDyLibComponents.insert(Component);
Expand Down
2 changes: 1 addition & 1 deletion llvm/utils/llvm-build/llvmbuild/main.py
Expand Up @@ -413,7 +413,7 @@ def write_library_table(self, output_path, enabled_optional_components):
if library_name is None:
library_name_as_cstr = 'nullptr'
else:
library_name_as_cstr = '"lib%s.a"' % library_name
library_name_as_cstr = '"%s"' % library_name
if is_installed:
is_installed_as_cstr = 'true'
else:
Expand Down

0 comments on commit 155ca8f

Please sign in to comment.