link_directories not working correctly in CMake 3.18.0
It seems that link_directories
is not working properly in the latest CMake version and I have to link manually (either via full path to library or target_link_directories
). This looks like a CMake bug because I don't see any additions to linker search path after link_directories
in the compilation commands.
How to reproduce?
- System: macOS
- CMake version: 3.18.0, installed via Homebrew
I'm using this with Protobuf/gRPC (hence 0. brew install protobuf grpc
) but I think any library should work, this doesn't seem to be library-dependent.
- Create a sample project with the following CMakeLists.txt
mkdir example
touch CMakeLists.txt
touch HelloWorld.cpp
cmake_minimum_required (VERSION 3.18.0)
project(HelloWorld)
add_executable(HelloWorld HelloWorld.cpp)
link_directories(/usr/local/opt/grpc/lib)
target_link_libraries(HelloWorld grpc++)
And any source file called HelloWorld.cpp
:
#include <iostream>
int main() {
std::cout << "Hello, world!" << std::endl;
}
- Try to build it:
mkdir build
cd build
cmake -G Ninja ../
ninja -v
The output is
[1/1] : && /Library/Developer/CommandLineTools/usr/bin/c++ -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk -Wl,-search_paths_first -Wl,-headerpad_max_install_names CMakeFiles/HelloWorld.dir/HelloWorld.cpp.o -o HelloWorld -lgrpc++ && :
FAILED: HelloWorld
: && /Library/Developer/CommandLineTools/usr/bin/c++ -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk -Wl,-search_paths_first -Wl,-headerpad_max_install_names CMakeFiles/HelloWorld.dir/HelloWorld.cpp.o -o HelloWorld -lgrpc++ && :
ld: library not found for -lgrpc++
clang: error: linker command failed with exit code 1 (use -v to see invocation)
ninja: build stopped: subcommand failed.
Note that there is no mention of /usr/local/opt/grpc/lib
in linker search path. build.ninja
also doesn't have any mention of it:
# CMAKE generated file: DO NOT EDIT!
# Generated by "Ninja" Generator, CMake Version 3.18
# This file contains all the build statements describing the
# compilation DAG.
# =============================================================================
# Write statements declared in CMakeLists.txt:
#
# Which is the root file.
# =============================================================================
# =============================================================================
# Project: HelloWorld
# Configurations:
# =============================================================================
#############################################
# Minimal version of Ninja required by this file
ninja_required_version = 1.5
# =============================================================================
# Include auxiliary files.
#############################################
# Include rules file.
include CMakeFiles/rules.ninja
#############################################
# Utility command for rebuild_cache
build CMakeFiles/rebuild_cache.util: CUSTOM_COMMAND
COMMAND = cd /Users/kbobyrev/dev/playground/cmake-bug/build && /usr/local/Cellar/cmake/3.18.0/bin/cmake --regenerate-during-build -S/Users/kbobyrev/dev/playground/cmake-bug -B/Users/kbobyrev/dev/playground/cmake-bug/build
DESC = Running CMake to regenerate build system...
pool = console
restat = 1
build rebuild_cache: phony CMakeFiles/rebuild_cache.util
#############################################
# Utility command for edit_cache
build CMakeFiles/edit_cache.util: CUSTOM_COMMAND
COMMAND = cd /Users/kbobyrev/dev/playground/cmake-bug/build && /usr/local/Cellar/cmake/3.18.0/bin/cmake -E echo No\ interactive\ CMake\ dialog\ available.
DESC = No interactive CMake dialog available...
restat = 1
build edit_cache: phony CMakeFiles/edit_cache.util
# =============================================================================
# Object build statements for EXECUTABLE target HelloWorld
#############################################
# Order-only phony target for HelloWorld
build cmake_object_order_depends_target_HelloWorld: phony || CMakeFiles/HelloWorld.dir
build CMakeFiles/HelloWorld.dir/HelloWorld.cpp.o: CXX_COMPILER__HelloWorld_ ../HelloWorld.cpp || cmake_object_order_depends_target_HelloWorld
DEP_FILE = CMakeFiles/HelloWorld.dir/HelloWorld.cpp.o.d
FLAGS = -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk
OBJECT_DIR = CMakeFiles/HelloWorld.dir
OBJECT_FILE_DIR = CMakeFiles/HelloWorld.dir
# =============================================================================
# Link build statements for EXECUTABLE target HelloWorld
#############################################
# Link the executable HelloWorld
build HelloWorld: CXX_EXECUTABLE_LINKER__HelloWorld_ CMakeFiles/HelloWorld.dir/HelloWorld.cpp.o
FLAGS = -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk
LINK_LIBRARIES = -lgrpc++
OBJECT_DIR = CMakeFiles/HelloWorld.dir
POST_BUILD = :
PRE_LINK = :
TARGET_FILE = HelloWorld
TARGET_PDB = HelloWorld.dbg
# =============================================================================
# Target aliases.
# =============================================================================
# Folder targets.
# =============================================================================
#############################################
# Folder: /Users/kbobyrev/dev/playground/cmake-bug/build
build all: phony HelloWorld
# =============================================================================
# Built-in targets
#############################################
# Re-run CMake if any of its inputs changed.
build build.ninja: RERUN_CMAKE | ../CMakeLists.txt /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/CMakeCInformation.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/CMakeCXXInformation.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/CMakeCheckCompilerFlagCommonPatterns.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/CMakeCommonLanguageInclude.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/CMakeGenericSystem.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/CMakeInitializeConfigs.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/CMakeLanguageInformation.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/CMakeSystemSpecificInformation.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/CMakeSystemSpecificInitialize.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/Compiler/AppleClang-C.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/Compiler/AppleClang-CXX.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/Compiler/CMakeCommonCompilerMacros.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/Compiler/Clang.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/Compiler/GNU.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/Internal/CMakeCheckCompilerFlag.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/Platform/Apple-AppleClang-C.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/Platform/Apple-AppleClang-CXX.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/Platform/Apple-Clang-C.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/Platform/Apple-Clang-CXX.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/Platform/Apple-Clang.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/Platform/Darwin-Initialize.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/Platform/Darwin.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/Platform/UnixPaths.cmake CMakeCache.txt CMakeFiles/3.18.0/CMakeCCompiler.cmake CMakeFiles/3.18.0/CMakeCXXCompiler.cmake CMakeFiles/3.18.0/CMakeSystem.cmake
pool = console
#############################################
# A missing CMake input file is not an error.
build ../CMakeLists.txt /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/CMakeCInformation.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/CMakeCXXInformation.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/CMakeCheckCompilerFlagCommonPatterns.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/CMakeCommonLanguageInclude.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/CMakeGenericSystem.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/CMakeInitializeConfigs.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/CMakeLanguageInformation.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/CMakeSystemSpecificInformation.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/CMakeSystemSpecificInitialize.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/Compiler/AppleClang-C.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/Compiler/AppleClang-CXX.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/Compiler/CMakeCommonCompilerMacros.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/Compiler/Clang.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/Compiler/GNU.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/Internal/CMakeCheckCompilerFlag.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/Platform/Apple-AppleClang-C.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/Platform/Apple-AppleClang-CXX.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/Platform/Apple-Clang-C.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/Platform/Apple-Clang-CXX.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/Platform/Apple-Clang.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/Platform/Darwin-Initialize.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/Platform/Darwin.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/Platform/UnixPaths.cmake CMakeCache.txt CMakeFiles/3.18.0/CMakeCCompiler.cmake CMakeFiles/3.18.0/CMakeCXXCompiler.cmake CMakeFiles/3.18.0/CMakeSystem.cmake: phony
#############################################
# Clean all the built files.
build clean: CLEAN
#############################################
# Print all primary targets available.
build help: HELP
#############################################
# Make the all target the default.
default all
- Switch to
target_link_directories
:
cmake_minimum_required (VERSION 3.18.0)
project(HelloWorld)
add_executable(HelloWorld HelloWorld.cpp)
target_link_libraries(HelloWorld grpc++)
target_link_directories(HelloWorld PUBLIC /usr/local/opt/grpc/lib)
Now everything builds just fine:
cd build
ninja clean
ninja -v
The output is:
[1/2] /Library/Developer/CommandLineTools/usr/bin/c++ -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk -MD -MT CMakeFiles/HelloWorld.dir/HelloWorld.cpp.o -MF CMakeFiles/HelloWorld.dir/HelloWorld.cpp.o.d -o CMakeFiles/HelloWorld.dir/HelloWorld.cpp.o -c ../HelloWorld.cpp
[2/2] : && /Library/Developer/CommandLineTools/usr/bin/c++ -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk -Wl,-search_paths_first -Wl,-headerpad_max_install_names CMakeFiles/HelloWorld.dir/HelloWorld.cpp.o -o HelloWorld -L/usr/local/opt/grpc/lib -Wl,-rpath,/usr/local/opt/grpc/lib -lgrpc++ && :
Note that the search path is now present in the linker invocation. build.ninja
also has it in LINK_PATH
:
# CMAKE generated file: DO NOT EDIT!
# Generated by "Ninja" Generator, CMake Version 3.18
# This file contains all the build statements describing the
# compilation DAG.
# =============================================================================
# Write statements declared in CMakeLists.txt:
#
# Which is the root file.
# =============================================================================
# =============================================================================
# Project: HelloWorld
# Configurations:
# =============================================================================
#############################################
# Minimal version of Ninja required by this file
ninja_required_version = 1.5
# =============================================================================
# Include auxiliary files.
#############################################
# Include rules file.
include CMakeFiles/rules.ninja
#############################################
# Utility command for rebuild_cache
build CMakeFiles/rebuild_cache.util: CUSTOM_COMMAND
COMMAND = cd /Users/kbobyrev/dev/playground/cmake-bug/build && /usr/local/Cellar/cmake/3.18.0/bin/cmake --regenerate-during-build -S/Users/kbobyrev/dev/playground/cmake-bug -B/Users/kbobyrev/dev/playground/cmake-bug/build
DESC = Running CMake to regenerate build system...
pool = console
restat = 1
build rebuild_cache: phony CMakeFiles/rebuild_cache.util
#############################################
# Utility command for edit_cache
build CMakeFiles/edit_cache.util: CUSTOM_COMMAND
COMMAND = cd /Users/kbobyrev/dev/playground/cmake-bug/build && /usr/local/Cellar/cmake/3.18.0/bin/cmake -E echo No\ interactive\ CMake\ dialog\ available.
DESC = No interactive CMake dialog available...
restat = 1
build edit_cache: phony CMakeFiles/edit_cache.util
# =============================================================================
# Object build statements for EXECUTABLE target HelloWorld
#############################################
# Order-only phony target for HelloWorld
build cmake_object_order_depends_target_HelloWorld: phony || CMakeFiles/HelloWorld.dir
build CMakeFiles/HelloWorld.dir/HelloWorld.cpp.o: CXX_COMPILER__HelloWorld_ ../HelloWorld.cpp || cmake_object_order_depends_target_HelloWorld
DEP_FILE = CMakeFiles/HelloWorld.dir/HelloWorld.cpp.o.d
FLAGS = -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk
OBJECT_DIR = CMakeFiles/HelloWorld.dir
OBJECT_FILE_DIR = CMakeFiles/HelloWorld.dir
# =============================================================================
# Link build statements for EXECUTABLE target HelloWorld
#############################################
# Link the executable HelloWorld
build HelloWorld: CXX_EXECUTABLE_LINKER__HelloWorld_ CMakeFiles/HelloWorld.dir/HelloWorld.cpp.o
FLAGS = -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk
LINK_LIBRARIES = -Wl,-rpath,/usr/local/opt/grpc/lib -lgrpc++
LINK_PATH = -L/usr/local/opt/grpc/lib
OBJECT_DIR = CMakeFiles/HelloWorld.dir
POST_BUILD = :
PRE_LINK = :
TARGET_FILE = HelloWorld
TARGET_PDB = HelloWorld.dbg
# =============================================================================
# Target aliases.
# =============================================================================
# Folder targets.
# =============================================================================
#############################################
# Folder: /Users/kbobyrev/dev/playground/cmake-bug/build
build all: phony HelloWorld
# =============================================================================
# Built-in targets
#############################################
# Re-run CMake if any of its inputs changed.
build build.ninja: RERUN_CMAKE | ../CMakeLists.txt /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/CMakeCInformation.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/CMakeCXXInformation.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/CMakeCheckCompilerFlagCommonPatterns.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/CMakeCommonLanguageInclude.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/CMakeGenericSystem.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/CMakeInitializeConfigs.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/CMakeLanguageInformation.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/CMakeSystemSpecificInformation.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/CMakeSystemSpecificInitialize.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/Compiler/AppleClang-C.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/Compiler/AppleClang-CXX.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/Compiler/CMakeCommonCompilerMacros.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/Compiler/Clang.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/Compiler/GNU.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/Internal/CMakeCheckCompilerFlag.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/Platform/Apple-AppleClang-C.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/Platform/Apple-AppleClang-CXX.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/Platform/Apple-Clang-C.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/Platform/Apple-Clang-CXX.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/Platform/Apple-Clang.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/Platform/Darwin-Initialize.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/Platform/Darwin.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/Platform/UnixPaths.cmake CMakeCache.txt CMakeFiles/3.18.0/CMakeCCompiler.cmake CMakeFiles/3.18.0/CMakeCXXCompiler.cmake CMakeFiles/3.18.0/CMakeSystem.cmake
pool = console
#############################################
# A missing CMake input file is not an error.
build ../CMakeLists.txt /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/CMakeCInformation.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/CMakeCXXInformation.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/CMakeCheckCompilerFlagCommonPatterns.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/CMakeCommonLanguageInclude.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/CMakeGenericSystem.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/CMakeInitializeConfigs.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/CMakeLanguageInformation.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/CMakeSystemSpecificInformation.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/CMakeSystemSpecificInitialize.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/Compiler/AppleClang-C.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/Compiler/AppleClang-CXX.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/Compiler/CMakeCommonCompilerMacros.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/Compiler/Clang.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/Compiler/GNU.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/Internal/CMakeCheckCompilerFlag.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/Platform/Apple-AppleClang-C.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/Platform/Apple-AppleClang-CXX.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/Platform/Apple-Clang-C.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/Platform/Apple-Clang-CXX.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/Platform/Apple-Clang.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/Platform/Darwin-Initialize.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/Platform/Darwin.cmake /usr/local/Cellar/cmake/3.18.0/share/cmake/Modules/Platform/UnixPaths.cmake CMakeCache.txt CMakeFiles/3.18.0/CMakeCCompiler.cmake CMakeFiles/3.18.0/CMakeCXXCompiler.cmake CMakeFiles/3.18.0/CMakeSystem.cmake: phony
#############################################
# Clean all the built files.
build clean: CLEAN
#############################################
# Print all primary targets available.
build help: HELP
#############################################
# Make the all target the default.
default all