3
votes

I have been trying to build my project with CMakeLists for a couple of days now with some success but I'm not sure on what it is exactly that I am doing.

I am currently using 5 external libraries. (Assimp, glew, glfw, glm, DevIL) And my main platform is windows but platform independence is a big plus.

So the question I have is how to proceed when I want to include an external library to my project?

This is what I think I know so far.

(1) If you are "lucky" you can just use find_library and link it with target_link_libraries you are good to go.

(2) Since glm is a header only library, all I need is an include_directories.

(3) If the external library has its own CMakeLists, you do add_subdirectory and set include_directories to where the header files are.

This is what I know I don't understand.

(4) If the external library has .h files and .cpp files but no CMakeLists. How do I include (and build?) this library?

(5) (This is the most important question for me!) If the external library has .h files and either .lib or .dll files, how do I include this library? In both cases! (lib/dll)

Thanks in advance for any and all replies!

Best regards Edvin

1
Hey, question (4): You have an external library which yet has not been built. Do you want to build it with the rest of your application, or separately? Question (5a): do you know the directory of all those files? Question (5b): is your .lib file, a static link library or an import library for your .dll?Bruno Lubascher
(4) I'm gussing that you mean if I want to include it dynamically or statically? I don't know what is best so doesn't really matter. Explinations for both would be amazing! (5a) Yes! (5b) It is a static library. Wouldn't imagine other wise. My example is assimp. I downloaded the binaries as a zip folder and it gave me (amongst other things) a lib32/asssimp.lib file and a bin32/assimp.dll file. So It's not a import library for other dll's.Edvin
(4) If the external library is large or maybe in the future you want get a newer version of just that library, it is best that you have it dynamically linked. If it is small and you dont care about future updates and/or you dont want to distribute you program with many .dll files, it is best static link. (5a) I asked because this because if the CMakeLists you might want to include a small function to look for the .dll files, but if you already know it, it will be easier.Bruno Lubascher
(5b) Usually to link a .dll to your program, you need an import library for that .dll, and the extension for such library is .lib. For me, it looks like that your .lib is an import library, since you also got the .dll. Just to make sure, did you also get a assimp.dll.a file?Bruno Lubascher

1 Answers

2
votes
  1. If you want to do the quick-and-dirty way you can just

    • create a super-repo with all your dependencies (or alternatively, write a script that downloads or clones them)
    • write a shell script that builds all the source-only dependencies
    • hardcode the include dirs, libraries and compile flags of the dependencies into the CMakeLists.txt of you main project (well, relative to super-repo root)
    • build the dependencies before you configure your main project

If a dependency has no CMakeLists.txt or any other build script suitable for your system, you need to find or write one.

  1. If you want to do it elegantly and reusable you need to study the topics of CMake config-modules. For a quick introduction please check out this Stackoverflow answer: How to use CMake to find and link to a library using install-export and find_package? You will need to write config-modules for the dependencies (or find a fork which has it). Your main project will contain only a list of find_package commands and you list your dependencies with the target_link_libraries command and all other details will be taken care by the config modules.

Generally you don't need to include third-party projects directly into your main project's CMakeLists (add_subdirectory or ExternalProject_add) since you will not be working on them so they will not change. There's no need to clutter your IDE workspace with them. It's best to download/clone/build/install them with a separate script before you configure your main project.