It seems cmake can't determine which libraries can be used with the current compiler or rather I want cmake to only use libraries that have been compiled with the same compiler.
I am using find_library to find the needed libraries but it seems to be unable to determine if the library is actually usable. It managed to find the library by name but it was using the ".lib" extension when I was making a configuration for MinGW. Do I have to create folders for every compiler I compile libraries for and add if statements for each compiler in my script ? That just seems counter intuitive to what I believed find_library would be capable of. Perhaps I am misusing it ? Anyone have any better ideas ?
It seems you're a bit confused: you're right when you suggest that you need different libraries for MinGW and Visual Studio on Windows. But you're wrong when saying that .lib files can't be used by MinGW. Both Visual Studio and MinGW use .lib files to link to libraries on Windows.
The find_library command purpose is only to find libraries. Nothing more, so it's doing its job here.
If you want to make sure that the libraries found can be used by your compiler, you'll have to check that those libraries can be used by your compiler using try_compile:
find_library(YOURLIB_LIBRARY yourlib)
if (YOURLIB_LIBRARY)
try_compile(YOURLIB_WORKS
bindir
somefile.c
LINK_LIBRARIES ${YOURLIB_LIBRARY})
if (YOURLIB_WORKS)
# do something with your library
else()
# warn the user of stop the configuration process
endif()
endif()
Related
I made a project and tried to build it under GCC (Linux) and MinGW (Windows) using CMake. Now I'm trying to do the same under Visual Studio 2019 (for reasons) and it seems that CMake that is shipped with VS can't find libraries installed with MSVC.
I'm using a script which unfortunately I can't find again on the Net, so I can't give you a link to it. But I tried to isolate what is causing the problem. So, here is the code:
if(MY_LIB_PATH)
set(MYLIB_NO_DEFAULT_PATH_CMD NO_DEFAULT_PATH)
endif()
find_library(MY_LIBRARY
NAMES myLibrary
HINTS
ENV MY_ENV
${MYLIB_NO_DEFAULT_PATH_CMD}
PATH_SUFFIXES lib lib/x64
PATHS ${MY_LIB_PATH}
DOC ""
)
(the code is much complicated than that, but that is what it looks after all variable substitutions)
If I don't set the MY_LIB_PATH variable it can't find the library (which is located in the lib/x64 folder in the MSVC installation folder). But when I call CMake like this:
cmake "-DMY_LIB_PATH=C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\lib\x64"
it "miraculously" finds it.
Yes it works but...wasn't CMake made to avoid writing all that path in the first place? Besides, there is yet another problem: there are many such libraries in my project, all of which use the same above code for finding, and I have to write all that path multiple times, so CMake can find them.
Either the authors of my CMake script did something wrong or I installed my libraries not where CMake is expecting them.
How to only build a static library with clion without having an executable?
How does the CMakeLists.txt look like? (without add_executable)
Update: If I don't add executable to Clion, I have an
error, that an executable is required.
Here my CMakeLists.txt.
This is an old question. But I'll add the answer to your question as a help for other people. You need to replace your add_executable with add_library
add_library(target_name source_files)
Short answer: compile the library target and run any custom command as a placeholder to avoid the warning.
Long answer:
CLion lets you either build the whole project and run executables/configurations.
When running executables, you can choose a target to compile and the executable to run after compiling the target. For executable targets, they are usually the same thing. You compile the executable target and then run it.
It seems like this is not really designed for libraries, but there is a workaround. You usually set the target to be the library and the executable to be any executable that depends on this library. However, this is usually not very useful because if you wanted to run this executable you could just set this executable to be the target and the library would be built anyway.
So people probably want to just build the library (to check if everything is OK, etc) without compiling or running any extra executable targets. In this case, the workaround is to choose a custom executable to run after building the library, and the error message is gone.
You have nothing useful you need to run after building the library, just choose any cheap command as a placeholder. Something like "pwd" or "ls".
I have a huge project managed with CMake and this project has hundreds of components each of them having own source files and each of them linking to a list of libraries, specified with target_link_libraries(${project} some_libraries, some_other_libraries)
Now, what I am aiming for is that:
Without actually modifying any of the CMakeLists.txt I want ALL the projects's target executable to link to some specific libraries.
Is there a way of achieving this? Since this is a one time trial, I don't want to manually hunt down all the CMakeLists.txt files and modify them (yes, this is the other alternative). Just a note, I compile the entire project from command line, using cmake (no cmake gui).
This is kind of a hack, but for a C++ project, you can use CMAKE_CXX_STANDARD_LIBRARIES. For a C project, I think you would use CMAKE_C_STANDARD_LIRBARIES.
Example for C++ that links to libbar and libfoo:
cmake ... -DCMAKE_CXX_STANDARD_LIBRARIES="-lbar -lfoo"
See the documentation here:
https://cmake.org/cmake/help/v3.6/variable/CMAKE_LANG_STANDARD_LIBRARIES.html
This won't be available for older versions of CMake; it was added some time after version 3.0.
This is a dirty, dirty hack, so please only use it for testing.
You can actually overload the add_executable command by defining a function of the same name. Do this close to the top of the top-level CMakeLists.txt:
function (add_executable name)
message("Added executable: " ${name})
_add_executable(${name} ${ARGN})
target_link_libraries(${name$} your_additional_lib)
endfunction()
Note that _add_executable is an internal CMake name that may break in future CMake versions. As of now (version 3.0) it seems to work with all versions though.
You can overload add_library the same way if required.
For more fine-grained control over what is linked, instead of calling target_link_libraries you can also mess with the LINK_LIBRARIES and INTERFACE_LINK_LIBRARIES target properties directly.
I was trying to parallelize a Fortran program using MPI. I use CMake to do the build of my program. It was difficult to find support on getting CMake to create a working makefile for Fortran with MPI support on google, but from what I could gather, I added the following commands to my CMakeLists.txt script:
find_package(MPI REQUIRED)
add_definitions(${MPI_Fortran_COMPILE_FLAGS})
include_directories(${MPI_Fortran_INCLUDE_DIRS})
link_directories(${MPI_FortranLIBRARY_DIRS})
This will locate MPI on my system and then set the variables found in the following three commands. In my linking line, I added the MPI libraries variable to the list of the other libraries that my program needed to build.
target_link_libraries(${exe_name} otherlibs ${MPI_FortranLIBRARY_DIRS})
Doing cmake and then make worked to build the program and the program ran; however, when I tried to add more to the source which required me to include the mpif.h include file, my compilation failed due to not being able to find this header file. I also could not use mpi because the compiler cannot find the mpi.mod file in the path.
I inserted "message" commands into my CMakeLists.txt file and printed out the values of the variables that I was using for including and linking. It turns out that the variables, MPI_Fortran_INCLUDE_DIRS and MPI_FortranLIBRARY_DIRS weren't set to anything. A check of the module that CMake is actually using to set these variables (FindMPI.cmake) showed these variables to be non-existent. I changed my CMakeLists.txt file to use the correct variables:
find_package(MPI REQUIRED)
add_definitions(${MPI_Fortran_COMPILE_FLAGS})
include_directories(${MPI_Fortran_INCLUDE_PATH})
link_directories(${MPI_Fortran_LIBRARIES})
target_link_libraries(${exe_name} otherlibs ${MPI_Fortran_LIBRARIES})
Now when I execute make, the compiler could find both mpif.h as well as mpi.mod.
UPDATE:
I want to mention that this solution worked for cmake version 2.8.10.1. When I moved my CMakeLists.txt scripts to a different machine that has cmake version 2.8.4, I get the same error about mpi.mod missing during the link stage. I checked the FindMPI.cmake module and, sure enough, there are no variables that specify the language (i.e. there is no MPI_Fortran_LIBRARIES variable, just a MPI_LIBRARIES variable, and this variable is not getting set to the correct location of the mpi library on that system. So this solution will be dependent on cmake version.
Sounds like you are not using the mpi compiler. That is fine, but you have to add a lot of flags then. There is not really an mpi compiler but a wrapper that sets the flags to be able to use mpi. With cmake I was able to do this by defining the fortran compiler I was going to use BEFORE the call to cmake. It's not a nice solution since you loose portability, but it works. I'm trying to find a better solution and define inside cmake what compiler to use, but have not been able to do so. In other words, this works for me:
FC=mpif90 cmake ../.
make
I was having the same problem as you. Hope this solves the issue. If anybody finds how to define the fortran compiler INSIDE cmake please post it!
as you've already noticed, you misspelled the name of two variables, namely MPI_Fortran_LIBRARIES and MPI_Fortran_LIBRARIES
It is useful also to add:
cmake_minimum_required(VERSION 2.8.10)
at the very beginning of your CMake to be sure that these variables will be defined.
I'm currently building a compiler/interpreter in C/C++.
When I noticed LLVM I thought it would fit greatly to what I needed and so I'm trying to integrate LLVM in my existing build system (I use CMake).
I read this bout integration of LLVM in CMake. I copy and pasted the example CMakeLists.txt, changed the LLVM_ROOT to ~/.llvm/ (that's where I downloaded and build LLVM and clang) and it says it isn't a valid LLVM-install. Best result I could achieve was the error message "Can't find LLVMConfig" by changing LLVM_ROOT to ~/.llvm/llvm.
My ~/.llvm/ folder looks like this:
~/.llvm/llvm # this folder contains source files
~/.llvm/build # this folder contains object, executable and library files
I downloaded LLVM and clang via SVN. I did not build it with CMake.
Is it just me or is something wrong with the CMakeLists.txt?
This CMake documentation page got rotted, but setting up CMake for LLVM developing isn't different from any other project. If your headers/libs are installed into non-standard prefix, there is no way for CMake to guess it.
You need to set CMAKE_PREFIX_PATH to the LLVM installation prefix or CMAKE_MODULE_PATH to prefix/share/llvm/cmake to make it work.
And yes, use the second code snippet from documentation (under Alternativaly, you can utilize CMake’s find_package functionality. line).