MantisBT - CMake
View Issue Details
0016074CMake(No Category)public2016-04-21 09:582016-06-10 14:31
Antonio 
Kitware Robot 
normalminorhave not tried
closedmoved 
Desktop PCWindows7
CMake 3.4.1 
 
0016074: Setting link_directories in toolchain file is only used for compiler tests, and inhibits effect of repeating the command
In the attached example,
TOOLCHAIN FILE:
link_directories("D:/abcd")

CMAKELISTS.TXT:
project(dummyProject)
cmake_minimum_required(VERSION 3.4)
link_directories("D:/abcd")
link_directories("D:/efgh")
add_library(dummyTarget SHARED dummy.cpp)

At linking stage, only the "-LD:/efgh" will be there:
cmd.exe /C "cd . && <compiler> -shared -o libdummyTarget.dll -Wl,--out-implib,libdummyTarget.dll.a -Wl,--major-image-version,0,--minor-image-version,0 CMakeFiles/dummyTarget.dir/dummy.cpp.obj -LD:/efgh -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 && cd ."

Note: In the CMakeOutput.log file is possible to see that -LD:/abcd is used in the preliminary compiler tests.

Use case:
I am dealing with a toolchain where the std library is in a specific location, and to pass the preliminary cmake compiler tests I must set the std library location with a link_directories command. Since it is toolchain specific, it makes sense to set in the toolchain file. I can pass the compiler tests if I call `link_directories` in the toolchain file.

The only workaround I could find so far was to directly set the flag (still in the toolchain file):

# SET(CMAKE_EXE_LINKER_FLAGS "-LD:/abcd")
# SET(CMAKE_SHARED_LINKER_FLAGS "-LD:/abcd")
# SET(CMAKE_MODULE_LINKER_FLAGS "-LD:/abcd")
1) Take the project in attachment
2) Configure with the attached toolchain, for example using ninja generator
3a) With ninja, run ninja -v to see the command line
3b) With make, run make.exe VERBOSE=1 to see the command line
CMake, link
zip CMakeBugProject.zip (834) 2016-04-21 09:58
https://public.kitware.com/Bug/file/5678/*
Issue History
2016-04-21 09:58AntonioNew Issue
2016-04-21 09:58AntonioFile Added: CMakeBugProject.zip
2016-04-21 10:19AntonioTag Attached: CMake
2016-04-21 10:19AntonioTag Attached: link
2016-04-21 10:22Brad KingNote Added: 0040906
2016-04-21 10:32AntonioNote Added: 0040907
2016-04-21 10:43AntonioNote Added: 0040908
2016-04-21 10:52AntonioNote Added: 0040909
2016-04-21 10:53AntonioNote Edited: 0040909bug_revision_view_page.php?bugnote_id=40909#r2074
2016-04-21 10:54Brad KingNote Added: 0040910
2016-04-21 10:57AntonioNote Edited: 0040909bug_revision_view_page.php?bugnote_id=40909#r2075
2016-04-21 11:05AntonioNote Edited: 0040909bug_revision_view_page.php?bugnote_id=40909#r2076
2016-04-21 11:10AntonioNote Added: 0040911
2016-04-21 11:10AntonioNote Edited: 0040911bug_revision_view_page.php?bugnote_id=40911#r2078
2016-04-21 11:11AntonioNote Edited: 0040911bug_revision_view_page.php?bugnote_id=40911#r2079
2016-04-21 11:11AntonioNote Edited: 0040911bug_revision_view_page.php?bugnote_id=40911#r2080
2016-04-21 11:11AntonioNote Edited: 0040911bug_revision_view_page.php?bugnote_id=40911#r2081
2016-04-21 11:13AntonioNote Edited: 0040911bug_revision_view_page.php?bugnote_id=40911#r2082
2016-04-21 11:13AntonioNote Edited: 0040911bug_revision_view_page.php?bugnote_id=40911#r2083
2016-04-21 11:21Brad KingNote Added: 0040912
2016-04-21 11:25AntonioNote Added: 0040913
2016-04-21 11:25AntonioNote Edited: 0040913bug_revision_view_page.php?bugnote_id=40913#r2085
2016-04-21 11:36AntonioNote Added: 0040914
2016-04-21 11:37AntonioNote Edited: 0040914bug_revision_view_page.php?bugnote_id=40914#r2087
2016-04-21 11:40AntonioNote Edited: 0040914bug_revision_view_page.php?bugnote_id=40914#r2088
2016-04-21 11:44AntonioNote Edited: 0040908bug_revision_view_page.php?bugnote_id=40908#r2090
2016-04-21 14:19Brad KingNote Added: 0040915
2016-04-21 14:49AntonioNote Added: 0040918
2016-04-26 06:38AntonioNote Added: 0040930
2016-04-26 06:38AntonioNote Deleted: 0040918
2016-04-26 06:39AntonioNote Edited: 0040930bug_revision_view_page.php?bugnote_id=40930#r2094
2016-04-26 06:39AntonioNote Edited: 0040930bug_revision_view_page.php?bugnote_id=40930#r2095
2016-04-26 06:40AntonioNote Edited: 0040930bug_revision_view_page.php?bugnote_id=40930#r2096
2016-04-26 06:42AntonioNote Edited: 0040930bug_revision_view_page.php?bugnote_id=40930#r2097
2016-04-27 13:30Brad KingNote Added: 0040939
2016-04-27 15:25AntonioNote Added: 0040941
2016-04-27 15:26AntonioNote Edited: 0040941bug_revision_view_page.php?bugnote_id=40941#r2099
2016-04-27 15:50Brad KingNote Added: 0040942
2016-05-03 04:49AntonioNote Added: 0041013
2016-06-10 14:29Kitware RobotNote Added: 0042986
2016-06-10 14:29Kitware RobotStatusnew => resolved
2016-06-10 14:29Kitware RobotResolutionopen => moved
2016-06-10 14:29Kitware RobotAssigned To => Kitware Robot
2016-06-10 14:31Kitware RobotStatusresolved => closed

Notes
(0040906)
Brad King   
2016-04-21 10:22   
Commands with directory-level effects like link_directories and include_directories should not be called from toolchain files. They are meant to specify declarative information (i.e. set variables).

CMake was originally designed with the assumption that the build environment is already configured such that the toolchain will work. For toolchains that do not know their own standard library location this means having environment variables like LIBRARY_PATH and C_INCLUDE_PATH set (for gcc).

We do have CMAKE_<LANG>_STANDARD_LIBRARIES variables for platform-specific libraries that should always be linked. Something similar for link and include directories could be added. That would be something a toolchain file could set.

Meanwhile the CMAKE_*_LINKER_FLAGS approach mentioned in the description should work.
(0040907)
Antonio   
2016-04-21 10:32   
Thank you very much for your feedback.
In my personal opinion the toolchain file is the natural location for integrating "faulty" toolchains.

To be precise, for the workaround to work the toolchain must specify ALL of the following:
link_directories("D:/abcd") #Without this it doesn't pass tests
set(CMAKE_EXE_LINKER_FLAGS "-LD:/abcd") #Without these it cannot find the libraries at linking stage
set(CMAKE_SHARED_LINKER_FLAGS "-LD:/abcd") #Without these it cannot find the libraries at linking stage
set(CMAKE_MODULE_LINKER_FLAGS "-LD:/abcd") #Without these it cannot find the libraries at linking stage
(0040908)
Antonio   
2016-04-21 10:43   
(edited on: 2016-04-21 11:44)
(I messed up while creating the issue, reproducibility should be set to "always")

(Another small note: inhibition problem applies also for target_link_directories command)

(0040909)
Antonio   
2016-04-21 10:52   
(edited on: 2016-04-21 11:05)
Thanks for the hint about CMAKE_CXX_STANDARD_LIBRARIES.

Another (one-liner) workaround that works for me is setting in the toolchain file:

set(CMAKE_CXX_STANDARD_LIBRARIES "-l${STD_LIB_1} -l${STD_LIB_2} -L${STD_LIBS_PATH}")

It is still a hack, but at least it is more compact.

(0040910)
Brad King   
2016-04-21 10:54   
> link_directories("D:/abcd") #Without this it doesn't pass tests

See CMP0056: https://cmake.org/cmake/help/v3.5/policy/CMP0056.html [^]

Move your cmake_minimum_required(VERSION) call to before the project() command as documented on these pages:

 https://cmake.org/cmake/help/v3.5/command/cmake_minimum_required.html [^]
 https://cmake.org/cmake/help/v3.5/command/project.html [^]

That should set CMP0056 to NEW and propagate CMAKE_EXE_LINKER_FLAGS into the checks.

If that doesn't work, which tests fail?
(0040911)
Antonio   
2016-04-21 11:10   
(edited on: 2016-04-21 11:13)
In my actual CMakeLists.txt, cmake_minimum_required is set before project.

The test that fails if I do not call link_directories in the toolchain file is CMakeTestCXXCompiler.cmake
[...]
"is not able to compiler a simple test program"
[...]
[2/2] Linking CXX executable cmTC_bdebe
[...]
<path>/ld.exe:
cannot find -lstdc++

(P.S.: I am happy with the last workaround https://cmake.org/Bug/view.php?id=16074#c40909, [^] but I am glad if I can support in addressing the issue)

(0040912)
Brad King   
2016-04-21 11:21   
Re 0016074:0040911: Strange, with the proper link directory in CMAKE_EXE_LINKER_FLAGS the try_compile for the test program should work. You could try running in a fresh build tree and adding "--debug-trycompile" to the command line. That may leave the CMakeLists.txt file, CMakeCache.txt, and *.ninja of the test program behind in CMakeFiles/CMakeTmp. Then you can check to see what flags it is using.

OTOH, why isn't your toolchain's spec file configured to know the location of the standard library in the first place?
(0040913)
Antonio   
2016-04-21 11:25   
I think the best is to try in the small project I attached and check in the log file which command line was generated. I will check quickly.

> OTOH, why isn't your toolchain's spec file configured to know the location of the standard library in the first place?

This is a piece of the story that unfortunately I cannot share, but I can tell you I have no control on that.

(0040914)
Antonio   
2016-04-21 11:36   
(edited on: 2016-04-21 11:40)
So trying with:
toolchain.cmake
set(CMAKE_EXE_LINKER_FLAGS "-LD:/abcd")



CMakelists.txt:
cmake_minimum_required(VERSION 3.4)
project(dummyProject)

link_directories("D:/abcd")
link_directories("D:/efgh")

add_library(dummyTarget SHARED dummy.cpp)



Configured (from a clean directory) with:
D:\CMakeBugProject\build>cmake --debug-trycompile .. -G"Ninja" -DCMAKE_TOOLCHAIN_FILE=../toolchain.cmake

Grepping in the entire D:\CMakeBugProject\build\CMakeFiles there is no trace of "abcd". (It's only found in D:\CMakeBugProject\rules.ninja, together with efgh)

(0040915)
Brad King   
2016-04-21 14:19   
Re 0016074:0040914: Try with this:

  set(CMAKE_EXE_LINKER_FLAGS "-LD:/abcd" CACHE STRING "Linker Flags")
(0040930)
Antonio   
2016-04-26 06:38   
(edited on: 2016-04-26 06:42)
That make "abcd" appear in several files. However, in build.ninja it is only in target cmTC_e0bb5.exe: CXX_EXECUTABLE_LINKER__cmTC_e0bb5 CMakeFiles/cmTC_e0bb5.dir/feature_tests.cxx.obj.

Again, "abcd" is inhibited at build time:
D:\CMakeBugProject\build>ninja -j1 -v
[1/2] <compiler> -DdummyTarget_EXPORTS -MMD -MT CMakeFiles/dummyTarget.dir/dummy.cpp.obj -MF CMakeFiles/dummyTarget.dir/dummy.cpp.obj.d -o CMakeFiles/dummyTar
et.dir/dummy.cpp.obj -c ../dummy.cpp
[2/2] cmd.exe /C "cd . && <compiler> -shared -o libdummyTarget.dll -Wl,--out-implib,libdummyTarget.dll.a -Wl,--major-image-version,0,--minor-image-version,0 MakeFiles/dummyTarget.dir/dummy.cpp.obj -LD:/efgh -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 && cd ."

In CMakeCCompiler.cmake it goes in this CMAKE_C_IMPLICIT_LINK_DIRECTORIES:
set(CMAKE_C_IMPLICIT_LINK_DIRECTORIES "D:/abcd;<other compiler directories>")

(0040939)
Brad King   
2016-04-27 13:30   
Re 0016074:0040930: I think what happens is that by including it in the toolchain file it ends up being used for some of the compiler introspection checks. When CMake detects what link directories are implicitly added by the compiler front-end, it does so using a project built with the given CMAKE_EXE_LINKER_FLAGS. This tricks it into thinking that "D:/abcd" is among them. In a sense it is because CMAKE_EXE_LINKER_FLAGS will always be used for linking executables.

What is missing is support for shared libraries and module libraries. Try this in the toolchain file:

   set(CMAKE_EXE_LINKER_FLAGS "-LD:/abcd" CACHE STRING "Linker Flags")
   set(CMAKE_SHARED_LINKER_FLAGS "-LD:/abcd" CACHE STRING "Linker Flags")
   set(CMAKE_MODULE_LINKER_FLAGS "-LD:/abcd" CACHE STRING "Linker Flags")

This can also be achieved by adding

   LDFLAGS=-LD:/abcd

to the environment.
(0040941)
Antonio   
2016-04-27 15:25   
(edited on: 2016-04-27 15:26)
> set(CMAKE_EXE_LINKER_FLAGS "-LD:/abcd" CACHE STRING "Linker Flags")
 > set(CMAKE_SHARED_LINKER_FLAGS "-LD:/abcd" CACHE STRING "Linker Flags")
 > set(CMAKE_MODULE_LINKER_FLAGS "-LD:/abcd" CACHE STRING "Linker Flags")

Actually, that's the first workaround proposed at the beginning. (And it doesn't pass the cmake tests without adding also link_directories)
And I would rather not pollute the environment (for one thing, not very portable)

(0040942)
Brad King   
2016-04-27 15:50   
> that's the first workaround proposed at the beginning.

At that time it was proposed without the CACHE part and therefore still needed the link_directories call that should not be needed.
(0041013)
Antonio   
2016-05-03 04:49   
I confirm adding CACHE does not change the effect on the linker flags of the preliminary tests. `link_directories` is still necessary.
(0042986)
Kitware Robot   
2016-06-10 14:29   
Resolving issue as `moved`.

This issue tracker is no longer used. Further discussion of this issue may take place in the current CMake Issues page linked in the banner at the top of this page.