CMakeLists is not generating so file - cmake

Following is my CMakeLists.txt file
cmake_minimum_required(VERSION 3.4.1)
add_library(
native-lib
SHARED
src/main/cpp/native-lib.cpp )
find_library(
log-lib
log )
target_link_libraries(
native-lib
${log-lib} )
I have specified, SHARED in add_library since I want a shared object library.
But it is not giving me the so file.
what am I missing?

You know that CMake doesn't compile anything ? It just configures a Makefile (or IDE project's files) for you.
Generate your Makefile / Visual Studio / What ever you use file project via CMake and then compile.
You will have your library then ;)

Related

CMake Fortran Module Directory to be used with add_library

I have a CMake 3.5.2 project that creates a library: libtest.a, which is then linked to by an executable.
The source code is Fortran, and the libtest.a produces a module file: "main.mod"
The executable also needs to include this main.mod file, so to make main.mod accessible, when building the project I set the variable, CMAKE_Fortran_MODULE_DIRECTORY to a known location, and add it to the relevant include paths.
This works great when building the entire project, main.mod is built in a known location, and it is there for whatever code needs it. My usage, however, makes it necessary to only build libtest.a by itself, and leave the executable to be built by a downstream user sometimes.
The issue I am having is that when I go into the libtest source and treat it as its own CMake project, the library will build and install, but the main.mod file is always left in the BINARY_DIR and is not built in the CMAKE_Fortran_MODULE_DIRECTORY, dispite setting in the the CMakeList.txt within libtest.
Is the Fortran_MODULE_DIRECTORY only honored when add_executable() is being called? And just ignored for the library builds alone? Or am I missing something.
Thanks for the help.
EDIT: This will reproduce my issue.
test_mod.f90:
module main
implicit none
real, parameter :: pi=3.2
end module main
tt.f90:
program test
use main
implicit none
real :: a, area
a =10
area = a * 100
end program test
CMakeList.txt:
CMAKE_minimum_required( VERSION 3.5 )
enable_language( Fortran )
project( tt )
file( GLOB test_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.f90 )
add_library( tt STATIC ${test_SOURCES} )
set( CMAKE_Fortran_MODULE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/Mod )
install( TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/Lib/ )
If I build and install the above code, I will get a libtt.a library installed in the Lib directory, however my main.mod will remain in my build directory and is not build in a Mod folder.
Here I assume that the "user" uses cmake to build the project while having access to the source of your project.
The steps to a working build.
There is a CMakeLists.txt file for libtest that specifies CMAKE_Fortran_MODULE_DIRECTORY. This should be enough for main.mod to appear there.
There is a CMakeLists.txt file for buiding the "client" program. This file should include the libtest project with add_subdirectory.
Add target_link_libraries(NAME_OF_PROGRAM NAME_OF_LIBRARY). This only takes care of the linking of libraries and is not sufficient (for solution B below anyway) for the module to be known to the client program.
Now, make your own adventure:
Solution A: in the libtest CMakeLists.txt, place the module where "all modules will go", for instance set(CMAKE_Fortran_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/modules) (you need to do this also for the "client" CMakeLists.txt). The variable ${CMAKE_BINARY_DIR} is set by the "client" cmake invocation and will be the same for all included cmake projects. This directory will be listed in the build commands for Fortran programs.
Solution B: in the libtest CMakeLists.txt, place the module of this library in a dedicated directory. You can achieve this, for instance, with set(CMAKE_Fortran_MODULE_DIRECTORY ${PROJECT_BINARY_DIR}/modules). You need then to manually specify this location with include_directories(PATH_THAT_DEPENDS_ON_THE_NAME_OF_THE_SUBPROJECT) in the client CMakeLists.txt.
If you wish the library to be installable, you need to specify paths for installing the library and the module file. With Fortran, you should think of this with the target OS, compiler and architecture in mind.
Links to the CMake documentation:
PROJECT_BINARY_DIR
CMAKE_Fortran_MODULE_DIRECTORY
CMAKE_BINARY_DIR
Following the addition of your sample code, the following modification should do it:
CMAKE_minimum_required( VERSION 3.5 )
enable_language( Fortran )
project( tt )
set( CMAKE_Fortran_MODULE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/Mod )
file( GLOB test_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.f90 )
add_library( tt STATIC ${test_SOURCES} )
install( TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/Lib/ )
install(DIRECTORY ${CMAKE_Fortran_MODULE_DIRECTORY} DESTINATION ${CMAKE_CURRENT_SOURCE_DIR})
Make sure that set( CMAKE_Fortran_MODULE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/Mod ) occurs before any add_library line.
Add install(DIRECTORY ${CMAKE_Fortran_MODULE_DIRECTORY} DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}) to actually install the .mod file. Module files (as header files in C) have to installed in addition to the library file.
The setup you created is a bit unusual in that you locate everything within the source build whereas "usual" install locations are made relative to CMAKE_INSTALL_PREFIX

CMake compile to static .lib file

I'm struggling to get Cmake to compile a C++ project into a static .lib file so I can then link it another project. Here's my basic setup:
cmake_minimum_required (VERSION 2.8)
PROJECT (MyProj)
IF (NOT ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} LESS 3.1)
cmake_policy(SET CMP0054 OLD)
ENDIF ()
set(SRCS_COMMON
#Here I locate the relative paths to a bunch of .cpp files
#../../Source/Common/Math/Example.cpp
)
ADD_LIBRARY(MyProj_static STATIC ${SRCS_COMMON})
TARGET_INCLUDE_DIRECTORIES(MyProj_static PRIVATE ../../Include)
SET_TARGET_PROPERTIES(MyProj_static PROPERTIES OUTPUT_NAME MyProj_static)
When I run CMake, I don't necessarily want to create a *.vcxproj file for my project. Rather, I simply want it to compile this project into a .lib file so it can be linked to another target. Thoughts?
CMake isn't a standalone build tool, so you can't build your code with just it. You can generate NMake makefiles or Ninja if you want to do without .vcxproj.
In the latter case make sure you run CMake from within "Visual Studio Developer Prompt".

CMake not able to find Debug Library

I am a CMake noob trying to put together a package installer so i can move between my windows development machine and my cluster.
I have the following directory tree for my files (an example)
-Primary
--Library Source
--CMakeLists.txt
--src1.cpp
--src1.h
--Application Source
--CMakeLists.txt
--src1.cpp
--src1.h
--CMakeLists.txt
Each CMakeLists.txt is
Primary/CMakeLists.txt
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
PROJECT(BloodVesselRadiationDamageSimulations CXX)
SET(FIND_LIBRARY_USE_LIB64_PATHS true)
SET(CMAKE_INSTALL_PREFIX ${CMAKE_SOURCE_DIR}) #only for testing
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_ROOT}/ ${CMAKE_SOURCE_DIR}/cmake/Modules/")
FIND_PACKAGE(OpenMP)
FIND_PACKAGE(MPI)
FIND_PACKAGE(HDF5)
FIND_PACKAGE(GTest)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
SET(CMAKE_DEBUG_POSTFIX _d)
ADD_SUBDIRECTORY(Source)
ADD_SUBDIRECTORY(SourceUnitTest)
Library Source/CMakeLists.txt
ADD_LIBRARY(VesselProjectBaseLibrary STATIC Src1.cpp
Src1.h)
INSTALL(TARGETS VesselProjectBaseLibrary DESTINATION x64/Debug CONFIGURATIONS Debug)
INSTALL(TARGETS VesselProjectBaseLibrary DESTINATION x64/Release CONFIGURATIONS Release|RelWithDebInfo)
Application Source/CMakeLists.txt
INCLUDE_DIRECTORIES("${GTEST_INCLUDE_DIRS}")
ADD_EXECUTABLE (SourceUnitTests Src1.cpp
Src1.h)
TARGET_LINK_LIBRARIES(SourceUnitTests ${GTEST_LIBRARY})
TARGET_LINK_LIBRARIES(SourceUnitTests debug VesselProjectBaseLibrary_d optimized VesselProjectBaseLibrary)
I am able to generate the projects correctly; I see all the correct files in the projects. However, when i go to compile the debug build I get the following error:
1>ipo: : error #11018: Cannot open VesselProjectBaseLibrary_d.lib
1>LINK : fatal error LNK1104: cannot open file 'VesselProjectBaseLibrary_d.lib'
If i compile my release build everything works perfectly and compilation is successful. The library compiles successfully under both builds.
When you link against a library created within the project, you need to specify library target name, not a library file. CMake will care about proper filename, path and other things:
TARGET_LINK_LIBRARIES(SourceUnitTests VesselProjectBaseLibrary)
Variable CMAKE_DEBUG_POSTFIX affects on library's filename. While file VesselProjectBaseLibrary_d.lib is actually created in debug build, it cannot be found automatically by the linker. Again, use target name and let CMake do all other work.

Statically compile library into binary?

I'm trying to fight a really obscure compilation-time bug with linking in a CMake project.
The project builds its own spin of Lua with the following CMake file:
set(LUA_SRC
"lua-5.1/src/lapi.c"
...brevity
)
set(LUA_HPP
"lua-5.1/src/lapi.h"
...brevity
)
source_group("" FILES ${LUA_SRC})
source_group("" FILES ${LUA_HPP})
add_library("lua-5.1" ${LUA_SRC} ${LUA_HPP})
set_property(TARGET "lua-5.1" PROPERTY FOLDER "External Libraries")
# include_directories(src)
if(MSVC)
sm_add_compile_definition("lua-5.1" _CRT_SECURE_NO_WARNINGS)
endif(MSVC)
disable_project_warnings("lua-5.1")
Lua is referenced in the main CMakeLists file for compiling the resultant binary:
list(APPEND SMDATA_LINK_LIB
"lua-5.1"
...brevity
)
...brevity
target_link_libraries("${SM_EXE_NAME}" ${SMDATA_LINK_LIB})
There are a few other libraries which it does link to which I'm okay with (like libpng, libjpeg, etc.), but I'd like Lua to be statically compiled into the final binary so that it has no dependencies on any system Lua.
How can I modify the CMakeLists to statically compile the Lua library into my binary?
Usually you can just tell CMake to compile the library statically:
add_library("lua-5.1" ${LUA_SRC} ${LUA_HPP})
becomes
add_library("lua-5.1" STATIC ${LUA_SRC} ${LUA_HPP})

Issue finding and linking Psapi library to executable using cmake

I am trying to link the psapi library to a project with cmake, nothing complex. Here's my cmake-file:
cmake_minimum_required(VERSION 2.8)
project(BenchmarkTests)
add_definitions(-DPSAPI_VERSION=1)
if (WIN32)
FILE(GLOB win32_head
Timer.h
win_Memory.h
win_Processor.h
BenchmarkTests.h)
FILE(GLOB win32_source *.cpp)
SET(win32_test ${win32_head} ${win32_source})
SET(LIBDIR_NAME "C:/Program Files (x86)/Windows Kits/8.1/Lib/winv6.3/um/x64/")
SET(LIBDIR $ENV{${LIBDIR_NAME}})
SET(LIBNAME "Psapi.Lib")
find_library (Psapi ${LIBNAME} {LIBDIR})
ADD_EXECUTABLE(bmTests ${win32_test})
TARGET_LINK_LIBRARIES(bmTests Psapi)
SOURCE_GROUP("win32" FILES ${win32_test})
endif()
There are no other "Psapi.Lib" files on my computer except for in ".../um/x86", but my system is 64-bit so I want the x64, no? Anyhow the output in CMake GUI for Psapi field is "Psapi-NOTFOUND" and in VS2013 all of the functions in Psapi.h recieve syntax errors. I guess since they can't link to the library. Am I forgetting something vital in my cmake file? Any suggested fix or alternative method is welcome, thanks in advance.
I get the same result when I try the below instead of find_library(...)
add_library(Psapi STATIC IMPORTED)
set_property(TARGET Psapi PROPERTY IMPORTED_LOCATION "C:/Program Files (x86)/Windows Kits/8.1/Lib/winv6.3/um/x64/Psapi.Lib")
For future reference I got it to work in CMake as follows, credit goes to Chibueze Opata on this question:
find_library (PSAPI Psapi)
...
add_executable(...)
...
target_link_libraries(Basic -lpsapi)