I am using boost::property_tree to read and write json files from a CMake C++ project. On machines I can install libjsoncpp and boost to the system, everything compiles, links, and works properly/as expected. However, I am now working on a machine I do not have root access to. Therefore I am compiling boost from source, and linking against it via CMake.
I am running into a problem where, it would seem, FindBoost.cmake is putting in a hard dependancy upon libjsoncpp.so
make[2]: *** No rule to make target /usr/lib64/libjsoncpp.so', needed bybin/myApp'. Stop.
I've tried building jsoncpp from source, and have tried adding the .a and .so to my cmake target_link_libraries command, but to no avail.
I'm not sure if this is related (or causing the issue somehow), but I am using
ADD_DEFINITIONS(-DBOOST_LOG_DYN_LINK) as boost::log requires it for linking from module modules.
I absolutely cannot have lipjsoncpp.so installed in /usr/lib64. What should I do?
Related
I ran into an interesting problem today. I am trying to compile and link a test executable to the Boost unit test framework and I tried it in two different ways.
The classic approach of linking directly to the "boost_unit_test_framework" library using -lboost_unit_test_framework
The modern CMake approach of linking to the Boost::unit_test_framework CMake target.
Interestingly when I link to the library directly my code compiles and links fine; however when I link to the CMake target my code fails to compile before it even gets to the linking stage!
The errors I get are related to a header file that it suddenly can't seem to find anymore. This suggests that linking to the Boost::unit_test_framework somehow messed with my include path.
I know linking to a CMake target is supposed to be the more modern and preferred approach, but if it can have such unexpected and unexplainable side effects, it seems worse than just linking straight to the library...
Why would linking the CMake target cause header files to not be found anymore? Also what other kinds of things can linking to a CMake target instead of linking directly to a library impact?
In both scenarios I am using target_link_libraries to link to the boost library. For example
target_link_libraries(mytest_exe
testlib
-lboost_unit_test_framework
)
or
target_link_libraries(mytest_exe
testlib
Boost::unit_test_framework
)
The fact that it is failing before linking means that the target_link_libraries command in CMake actually effects more than just linking. It is effecting the compilation as well.
Yes, it is true that new include directories are added when you link with a library target instead of the library file. This is why the approach is called "modern" - a single target_link_libraries call does all things which are needed to use the library (Boost in your case).
Reason of failing with "modern" approach could be that "true" Boost headers conflict with other headers you use. You may detect that via inspecting chain of include files in the error message.
When using CMake on unix I dont have any issues. I can use CLion to do a cmake setup, cmake build and cmake install, open a different project and it will find the previously built library when using find_package. On windows this does not seem to be possible. By default it tries to install the build code into strange directories (like C:\Program Files). I have added a CMAKE_INSTALL_PREFIX to both my library CMakeLists.txt and the appliation CMakeLists.txt, however when using find_package(SDL2)CMake still complains there is no config file for CMake and SDL2. When checking the following file exists:
U:\various\cmake-cache\Program Files (x86)\SDL2\cmake\SDL2Config.cmake
The directory U:\various\cmake-cache was used as CMAKE_INSTALL_PREFIX for both SDL2 and my application. Yet it still refuses to compile.
What can I do to make CMake at least somewhat useful on windows? On Unix things work great, but it feels like a huge PITA on Windows so far... It seems like all the concepts dont work there. I would really like to have one central location that is used by every CMake build on my system and everything is installed there and when another project uses a library it is searched there. Is this possible?
I have been trying to use SFML in a CMake project, specifically the header SFML/Audio.hpp. I installed SMFL using Homebrew, and both the .dylib-files and the headers should be located correctly, in /usr/local/lib and /usr/local/include, respectively.
Now running CMake works fine, telling me that it has Found SFML 2.4.2 in /usr/local/include.
However, when compiling the project (using make), I get the following error:
/path/to/project.hpp:12:10: fatal error: 'SFML/Audio.hpp' file not found.
Does anyone know why this is happening?
Note: Compiling works fine for colleagues of mine using the same CMake- and source files on various Linux operating systems.
This sounds like you simply forgot to add SFML's include directory. On Linux, they probably install SFML to some system path where GCC (or Clang) look by default, so they don't need any additional CMake directives.
Luckily, fixing this is pretty simple.
Add the following line to your CMakeLists.txt somewhere before defining targets:
include_directories(${SFML_INCLUDE_DIR})
The variable SFML_INCLUDE_DIR is populated when you successfully call find_package(SFML...).
While you're at it, you might also want to ensure to link to the proper library files in the correct order:
target_link_libraries(myTargetName ${SFML_LIBRARIES} ${SFML_DEPENDENCIES})
Again, both variables are populated automatically.
So basically I have the following setup:
A small test library called mylib with an according CMake file. The CMake file creates all the necessary information so that another project (which is going to be my binary) can use find_package to add the library. The library also has a install target.
A small binary called mybin again wih according CMake file which is depended on the mylib project. Using find_package I can add mylib either by specifying the location of the according myLibConfig.cmake (and myLibTargets.cmake etc.) files or by executing the install target of mylib and then letting CMake find the library itself.
Using CMake and XCode everything works like a charm. First, I configure and build the library. Second, I configure my binary project, specify the location of the library and then build it without any problems.
Now I want to do the same using CLion. My problem now is that CLion puts all the generated CMake file (which usually are placed in the build folder) in some cryptic location which can't be changed in the IDE. Now, when I want to build the mybin project I have to specify this cryptic location which seems kinda odd to me (especially because you have to find out first where CLion actually places those files).
So my question is: Is there a more convenient way to handle the described configuration? I guess this is more or less the standard use case which makes me wonder if I'm missing out on something. Being able to specify where CLion should put the generated CMake files would solve my problem I guess.
I know that i can install the library (using the install target) and then let CMake find it. The problem here is that CLion (to my understanding) doesn't support install targets and therefore I have to use (in my case) XCode to build and install the library first.
I was misunderstsanding the intention of find_package(as Tsyvarev pointed out). By using the solution proposed in this question I managed to add an install target to CLion which now allows me to conveniently build "mylib" and use it in the "mybin" project without having to configure anything manually.
I have a project I'm writing that uses LuaJIT. I'm trying to run my project on a computer I have not run it on in a while. It used to run just fine but now when I try to run it it complains.
I have LuaJIT in my source tree, and it builds just fine. I'm using CMake to generate my make files, and as far as I can tell CMake finds the file libluajit.so, but when I run my program, I get the following error:
../build/game/game: error while loading shared libraries: libluajit-5.1.so.2: cannot open shared object file: No such file or directory
I don't know why it's looking for that version of the library instead of libluajit.so. This is Ubuntu linux for what it's worth. I can add more details if necessary, I can add more details if necessary, I'm not sure what info would be helpful to figure out happening.
Edit:
To build and link the program I have these lines in the file CMakeLists.txt (this is abbreviated a bit to just show the relevant bits)
find_package(LuaJIT REQUIRED)
set(Extern_LIBS luajit)
add_executable(proj ${proj_Sources})
target_link_libraries(proj ${Extern_LIBS})
After I run cmake on my source directory, I run make. Then to run it I just run ./proj
When you built it, the ".so" was actually a symlink to the library. Verisioned filenames and SONAMEs are used so that multiple versions of a library can coexist, preventing problems commonly found on... other operating systems whereby older software is incompatible with the newer library, and newer software is incompatible with the older library.