Project-independent directories settings in VC++ - visual-c++

I have a Visual C++ 2012 Express project on Git that uses an external libcurl (not included in the repository).
I added the library by adding the corresponding paths on my machine (D:\libcurl\XXX) to Include Directories and Library Directories in VC++ Directories of Project Properties. So these settings are saved in the .vcxproj file.
If someone whose libcurl path is different from mine wants to build the project, he would have to:
Change VC++ Directories settings in Project Properties.
(then the project file will become modified, which is not what I want.)
Move his libcurl files to match mine (D:\libcurl).
(library path is forced to be D:\libcurl, not so flexible)
My question is: Is there a way to avoid this?
(In old versions of Visual C++, I can set the paths in the global VC++ Directories of the Tools->Options dialog instead. But the feature is deprecated in recent versions.)

I believe u can achieve this by using environment variables.
For example, you can add an environment variable called: LIBCURL
You can then set the LIBCURL to any path u want: D:\libcurl or X:\lib2.3b ...
no matter what ur library path is, u can always use the same VC++ Directories: $(LIBCURL)\XXX

Related

How to specify install directory for shared libraries for jsoncpp 0.10.7 with cmake?

I'm building https://github.com/open-source-parsers/jsoncpp/tree/0.10.7 for an embedded system because that's the recommended version if c++03 support is still needed. My target is based on Ubuntu 12.04.
CMakeLists.txt has include(GNUInstallDirs) so I'm trying to specify the installation directories with
cmake -DCMAKE_INSTALL_LIBDIR=/usr -DCMAKE_INSTALL_PREFIX=lib
I've tried various combinations of these and permutations, but cmake insists on installing the shared library in /usr/lib/x86_64-linux-gnu while I need it to be in /usr/lib.
I've followed the advice here: How to use CMAKE_INSTALL_PREFIX but to no avail.
Oddly the INCLUDEDIR variable does put the include files where I want them.
Is there any way of getting the library where I want it without modifying CMakeLists.txt?
While the project includes GNUInstallDirs module, it uses the variable CMAKE_INSTALL_LIBDIR (defined in this module) only for pkg-config file install location.
For libraries the project introduces LIBRARY_INSTALL_DIR variable, and for header files - INCLUDE_INSTALL_DIR.
So you need to set these variables, not the ones defined by GNUInstallDirs module.

Finding my Linux shared libraries at runtime

I'm porting an SDK written in C++ from Windows to Linux. There are other binaries, but at its simplest, our SDK is this:
core.dll - implicitly loaded DLL ("libcore.so" shared library on Linux)
tests.exe - an app use to test the DLL (uses google test)
All of my binaries must live in one folder somewhere that apps can find. I've achieved that on Windows. I wanted to achieve the same thing in Linux. I'm failing miserably
To illustrate, Here's the basic project tree. We use CMake. After I build I've got
mysdk
|---CMakeLists.txt (has add_subdirectory() statements for "tests" and "core")
|---/tests (source code + CMakeLists.txt)
|---/core (source code + CMakeLists.txt)
|---/build (all build ouput, CMake output, etc)
|---tests (build output)
|---core (build output)
The goal is to "flatten" the "build" tree and put all the binary outputs of tests, core, etc into one folder.
I tried adding CMake's "install" command, to each of my CMakeLists.txt files (e.g. install(TARGETS core DESTINATION bin). I then then executed sudo make install after my normal build. This put all my binaries in /usr/local/bin with no errors. But when I ran tests from there, it failed to find libcore.so, even though it was sitting right there in the same folder
tests: error while loading shared libraries: libcore.so: Cannot open shared object file: No such file or directory
I read up on the LD_LIBRARY_PATH environment variable and so tried adding that folder (/usr/local/bin) into it and running. I can see I've properly altered LD_LIBRARY_PATH but it still doesn't work. "tests" still can't find libcore.so. I even tried changing the PATH environment variable as well. Same result.
In frustration, I tried brute-force copying the output binaries to a temporary subfolder (of /mysdk/build) and running tests from there. To my surprise it ran.
Then I realized why: Instead of loading the local copy of libcore.so it had loaded the one from the build output folder (as if the full path were "baked in" to the app at build time). Subsequently deleting that build-output copy of libcore.so made "tests" fail altogether as before, instead of loading the local copy. So maybe the path really was baked in.
I'm at a loss. I've read the CMake tutorial and reference. It makes this sound so easy. Aside from the obvious (What am I doing wrong?) I would appreciate if anyone could answer any of the following questions:
What is the correct way to control where my app looks for my shared libraries?
Is there a relationship between my project build structure and how my binaries must then appear when installed?
Am I even close to the right way of doing this?
Is it possible I've somehow inadvertently "baked" (into my app) full paths to my shared libraries? Is that a thing? I use all CMAKE variables in my CMakeLists files.
You can run ldd file to print the shared object dependencies for file. It will tell you where are its dependencies being read from.
You can export the environment variable LD_LIBRARY_PATH with the paths you want the linker to look for. If a dependency is not found, try adding the path where that dependency is located at to LD_LIBRARY_PATH and then run ldd again (make sure you export the variable).
Also, make sure the dependencies have the right permissions.
Updating LD_LIBRARY_PATH is an option. Another option is using RPATH. Please check the example.
https://github.com/mustafagonul/cmake-examples/blob/master/005-executable-with-shared-library/CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
# Project
project(005-executable-with-shared-library)
# Directories
set(example_BIN_DIR bin)
set(example_INC_DIR include)
set(example_LIB_DIR lib)
set(example_SRC_DIR src)
# Library files
set(library_SOURCES ${example_SRC_DIR}/library.cpp)
set(library_HEADERS ${example_INC_DIR}/library.h)
set(executable_SOURCES ${example_SRC_DIR}/main.cpp)
# Setting RPATH
# See https://cmake.org/Wiki/CMake_RPATH_handling
set(CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/${example_LIB_DIR})
# Add library to project
add_library(library SHARED ${library_SOURCES})
# Include directories
target_include_directories(library PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/${example_INC_DIR})
# Add executable to project
add_executable(executable ${executable_SOURCES})
# Linking
target_link_libraries(executable PRIVATE library)
# Install
install(TARGETS executable DESTINATION ${example_BIN_DIR})
install(TARGETS library DESTINATION ${example_LIB_DIR})
install(FILES ${library_HEADERS} DESTINATION ${example_INC_DIR})

Local CMake configuration from Android Studio

When using CMake in a regular project, some variables (e.g library paths) can be configured via -D option or by using ccmake or cmake-gui The values are saved in the cache, and this provides for a local configuration that is specific to every user/developer of the code.
In Android Studio, CMake can be configured from Gradle, but I haven't been able to find an equivalent to the options above. The local.properties file can be read from gradle, but it's overwritten by AS.
Is there any way of setting CMake variables to local values from Android Studio?
Example: On a regular CMake project, I can add a line to my CMakeLists.txt like:
set(EIGEN_DIR /usr/local/include/eigen3 CACHE PATH "Eigen path")
And then two different developers may set that value to their particular systems (ie. /usr/local/include/eigen3 or /opt/local/include/eigen3) without affecting the project source code. However, in Android Studio, the only way seems to be from build.gradle, which is part of the project, and will get committed to the repositories.
I found this can be achieved by putting the variables with the desired value in the local.properties file, and then read them with the code from this answer:
Properties props = new Properties()
props.load(new FileInputStream(project.rootProject.file('local.properties')))
String conf_value = props['conf.value']
and then
externalNativeBuild{
cmake {
arguments "-DMY_CONF_VALUE="+conf_value
...
}
}

How do I deploy Qt libraries with an application?

This should be really simple, but I'm having trouble. I want to include some shared Qt libraries with my application in the installation folder so the user doesn't have to download Qt separately. On Windows, this seemed to work fine, but Ubuntu complains about not being to find the Qt libraries when they are in the same folder as the application.
How do I add the installation directory to shared library search path?
I was able to add the installation directory to shared library search path by adding the following lines to the .pro file, which set the rpath of the binary to $ORIGIN (the install folder). I needed to add the location of QT libs on my current machine (/usr/lib/qt5.5 and /usr/lib/qt5.5/lib) so that the project would build in QtCreator.
unix:!macx {
# suppress the default RPATH if you wish
QMAKE_LFLAGS_RPATH=
# add your own with quoting gyrations to make sure $ORIGIN gets to the command line unexpanded
QMAKE_LFLAGS += "-Wl,-rpath,\'\$$ORIGIN\':/usr/lib/qt5.5:/usr/lib/qt5.5/lib"
}
(The unix:!macx line makes it apply to linux only)
Windows, Linux and OSX behave quite differently. Windows is easiest: dump all the dll's in the application dir. OSX is next and Linux is most difficult.
Linux has certain search paths for searching shared objects. These search paths are mainly system libraries and possibly some user libraries. As you do not want to mess around with system files of your user one would prefer to have the shared objects in the application dir. This is possible but you have to tell Linux to read that directory. You can do this with setting the environment variable LD_LIBRARY_PATH. You can do this with a script. See my answer.

Including DLL's In VC++(VS2010) Project Output

Disclaimer: Am a C# developer trying to understand a few C++ fundamentals
Have created a command line project which has the .lib of a DLL file linked under Linker > Input > Additional dependencies, and also has the location of the header files specified under C/C++ > General > Additional Include Directories. Ran a build and all compiled okay, with the .exe being built in the Debug/Release dir.
Problem is I also expected the .dll file the project depends on to be there (just like when you add a reference in a .Net project) - but it isn't. When launching the .exe it complains that it can't find the DLL. Fair enough, but why didn't the VC++ put the DLL there if it knows it's required?
And is there a "best practice" to ensuring the dependent DLL files are in the output dir, other than manually copying them there? I have a project that will require use of some third-party libraries, and I was hoping the IDE would help me manage them...
Big thanks for any guidance given!
If you create solution which contains exe and dll, all output files are created in $(SolutionDir) Debug or Release subdirectories, and exe runs successfully. Otherwise, you have one of the following options:
Copy Dll in Post-build step to directory where it is available for loading (usually .exe directory)
Add Dll directory to PATH.

Resources