CMake MFC project in Visual Studio missing resource editor - visual-studio

I'm having a hard time opening the interactive resource editor in a MFC CMake project that otherwise compiles and runs just fine.
The project files are laid out as follows:
.
├── CMakeLists.txt
├── inc
│   ├── <...>
│   ├── resource.h
├── res
│   ├── MyApp.ico
│   ├── MyApp.rc
│   └── MyApp.rc2
└── src
   ├── CMakeLists.txt
   └── <...>
Top CMakeLists.txt:
cmake_minimum_required(VERSION 3.5)
project(MyProject)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_CXX_STANDARD 14)
if (MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /we4715") # makes missing return as error
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP") # parallel build
endif()
set(CMAKE_INSTALL_PREFIX ${CMAKE_SOURCE_DIR}/output)
# MFC
add_definitions(-D_AFXDLL)
set(CMAKE_MFC_FLAG 1)
add_subdirectory(src)
src CMakeLists.txt:
include_directories(${CMAKE_SOURCE_DIR}/inc)
include_directories(${CMAKE_SOURCE_DIR}/res)
include_directories(${CMAKE_SOURCE_DIR})
set(SOURCES
<...>
)
set(HEADERS
<...>
)
add_executable(
${PROJECT_NAME}
WIN32
${SOURCES}
${HEADERS}
${CMAKE_SOURCE_DIR}/res/MyApp.rc
${CMAKE_SOURCE_DIR}/res/MyApp.rc2
)
install(TARGETS MyApp
RUNTIME DESTINATION .)
In Visual Studio (Pro) the project loads just fine and compiles for every configuration I need, but if I try to open an .rc file I get errors on missing headers from MFC and ATL (afxres.h, winres.h, dde.rh, ...). The resource file won't open in the resource editor like it does on a VS solution.
The mssage happens when double-clicking on MyApp.rc, and I get
fatal error RC1015: cannot open include file 'afxres.h'.
I use the latest VS version available as of today which is 15.8.5, and this happens when opening the CMake project in Visual Studio.
I have already installed the ATL/MFC components in my Visual Studio installation. Like I said, it compiles just fine so dependencies are resolved correctly.
Am I missing something? Is this even possible?

Related

FFmpeg on Android with Rubberband

When I try to link librubberband.a I get:
libavfilter/af_rubberband.c:236: error: undefined reference to 'rubberband_set_pitch_scale'
I compiled rubberband for armv7a, and created a static library (rubberband.a).
I checked the library, and It contained the needed symbols (using nm).
I verified that librubberband.a is in the libpath (-L)
I verified that extern C exists in the rubberband.c.h file.
Any ideas?
The error happened in the link stage. Make sure the link directory has been added to -L parameters of your compiler.
-L/directory/of/your/lib
And specify the library with -l option.
So make sure the option -L/directory/of/your/lib -lrubberband set for your compiler when you build ffmpeg with rubberband support.
If you didn't use pkg-config to add the library. You can use the option --extra-ldflags to add when configure ffmpeg before build.
./configure \
# some configure options
--extra-ldflags="-L/directory/of/your/lib -lrubberband" \
# more configure options
If you use pkg-config to find out the libraries. Just add the library.pc directory to PKG_CONFIG_PATH, and let the build system do the remaining.
export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/directory/to/your/rubberband.pc
Updated
Finally make sure you link against to the same architecture of your library.
$ arm-linux-androideabi-readelf -h librubberband.a |grep 'Class\|Machine
For armeabi-v7a, it should be ELF32 and ARM.
Updated
I have cloned the source of rubberband from https://bitbucket.org/breakfastquay/rubberband
And found the function call rubberband_set_pitch_scale is defined at src/rubberband-c.cpp, this file is not include in Android.mk when build for Android (WHY?).
So you have to add this file to build.
RUBBERBAND_SRC_FILES = ... \
$(RUBBERBAND_SRC_PATH)/rubberband-c.cpp
After build done, you need to create directory structure like below
.
├── include
│   └── rubberband
│   ├── RubberBandStretcher.h
│   └── rubberband-c.h
└── lib
├── librubberband.a
└── pkgconfig
└── rubberband.pc
The file rubberband.pc was copied from rubberband.in.pc with some minor changes.
prefix=/path/to/rubberband/install/root
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include
Name: rubberband
Version: 1.8.1
Description:
Libs: -L${libdir} -lrubberband -L/path/to/android/ndk/sources/cxx-stl/gnu-libstdc++/4.9/libs/armeabi-v7a -lgnustl_static
Cflags: -I${includedir}
Then add
export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/path/to/rubberband/install/root
before ./configure to tell ffmpeg find rubberband by pkg-config.
I have tried with the latest ffmpeg, it works.

Compiling and linking subproject library with CMake

I have 2 projects (prj1 and prj2). One (prj2) depends on the other (prj1) that is a static library. I arrive to compile them separately with CMake.
But I needed to integrate one (prj1) to the other one (prj2). So I would like CMake to compile the static library (prj1) before the other (prj2) and then link the static library. I tried things, but id did not work.
prj1 "core" is https://gitlab.com/RyDroid/PlanetWars2dRT-core
prj2 "SDL2" is https://gitlab.com/RyDroid/PlanetWars2dRT-SDL2/ (see branch adding-core)
In prj2, externals/core is a git submodule (for non git users, you can see this directory as a copy-paste of prj1).
I tried (without success) this CMakeLists.txt in prj2 "SDL2":
cmake_minimum_required(VERSION 2.8)
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR
"${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
set(CMAKE_CXX_FLAGS "-Wall -Wextra -Wformat=2 -Wpedantic -D_FORTIFY_SOURCE=2")
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
# TODO
endif()
set(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}")
# if (CMAKE_VERSION VERSION_LESS "3.1")
# if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR
# CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
# set (CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}")
# endif()
# else()
# set(CMAKE_CXX_STANDARD 11)
# endif()
project(PlanetWars2dRT-SDL2)
# Version number
set(VERSION_MAJOR "0")
set(VERSION_MINOR "0")
set(VERSION_MICRO "0")
# Configure a header file to pass some of the CMake settings
# to the source code.
configure_file (
"src/compilation_config.h.in"
"${PROJECT_BINARY_DIR}/compilation_config.h"
)
# Add the binary tree to the search path for include files
# so that we will find compilation_config.h
include_directories("${PROJECT_BINARY_DIR}")
set(LIBRARY_OUTPUT_PATH lib/${CMAKE_BUILD_TYPE})
set(EXECUTABLE_OUTPUT_PATH bin/${CMAKE_BUILD_TYPE})
include_directories(src/)
file(
GLOB_RECURSE
source_files
src/*
)
add_executable(planet-wars-2d-rt-sdl2 ${source_files})
#include(ExternalProject)
#ExternalProject_Add(PlanetWars2dRT PREFIX externals/core/)
include_directories(externals/core/src/utils/ externals/core/src/specific/)
add_subdirectory(externals/core/)
#find_package(PlanetWars2dRT-core REQUIRED)
include(FindPkgConfig)
pkg_search_module(SDL2 REQUIRED sdl2)
pkg_search_module(SDL2GFX REQUIRED SDL2_gfx)
include_directories(${SDL2_INCLUDE_DIRS} ${SDL2IMAGE_INCLUDE_DIRS})
target_link_libraries(
planet-wars-2d-rt-sdl2
planet-wars-2d-rt-core
${SDL2_LIBRARIES} ${SDL2GFX_LIBRARIES}
)
That is a simplified version of the tree of prj2:
.
├── build (with CMake stuff generated with "cmake ..")
├── CMakeLists.txt
├── externals
│   └── core
│ ├── build (with CMake stuff generated with "cmake ..")
│   ├── CMakeLists.txt
│   ├── makefile
│   └── src
├── makefile
├── README.md
└── src
    ├── compilation_config.h.in
   └── planet-wars-2d-rt-sdl2.cpp
How can I compile the library of prj1 "core" in prj2 "SDL2" with CMake, and then link the library of prj1 with prj2 (again with CMake)?
If your solution does not work with a non GNU/Linux OS, it is not a big problem. Note: my PC is running on Debian GNU/Linux 8 "Jessie".
Regards.
I cannot access your repo https://gitlab.com/RyDroid/PlanetWars2dRT-SDL2/, perhaps the servers are down for maintenance. If I understand your problem correctly, you may create a structure like that:
root/
CMakeLists.txt // 1
src/
CMakeLists.txt // 2
main.cpp
SDL2/
some sources
CMakeLists.txt // 3
core/
some sources
CMakeLists.txt // 4
In the CMakeLists.txt [1] you should declare your project name, required packages, common flags, include paths etc.:
cmake_minimum_required( VERSION 2.x )
project(name)
include_directories(inc inc/core inc/SDL2 inc/SthElse)
add_subdirectory(src)
In CMakeLists.txt [2] for subdir src you should declare your main executable and also add subdirs with your prj1 and prj2
add_subdirectory(core)
add_subdirectory(SDL2)
add_executable(main main.cpp)
target_link_libraries(main core SDL2 SomeOtherLib)
Finally, in your CMakeLists.txt [3] && [4] in your lib dirs you should declare static libraries:
add_library(core STATIC ${YourSourceFiles})
This approach always worked for me. If you used to compile and run "core" and "SDL2" as standalone binaries, perhaps you will have to reorganize them a little bit.
Both project have a file "compilation_config.h". At compilation time, the wrong was taken so compilation failed, because the code used was #include "compilation_config.h" that was ambigous.
So I created a "include/project-name" dir in both project and I changed the include path : "prj1/compilation_config.h" or "prj2/compilation_config.h". Thanks to that there was no ambiguity anymore, so it works now!

Cmake Shared library

I am learning CMake but I am struggling to understand how to link a binary file to a shared library and then install these files in a release folder.
These is the structure of my project:
├── CMakeLists.txt
├── build
├── main
│   ├── CMakeLists.txt
│   └── main.cpp
├── release
|_______bin
│   ├── include
│   │   └── math.h
│   └── lib
│   └── libmathLib.dylib
└── shared_lib
├── CMakeLists.txt
├── include
│   └── math.h
└── src
└── math.cpp
In the root CMakeLists.txt I've defined the project settings and the subdirectory.
Root CMakeLists.txt:
cmake_minimum_required(VERSION 3.1)
project (Math)
set(CMAKE_BUILD_TYPE Release)
set(MAKE_INCLUDE_CURRENT_DIR ON)
ADD_SUBDIRECTORY(shared_lib)
ADD_SUBDIRECTORY(main)
Main CMakeLists.txt:
add_executable(main main.cpp)
TARGET_LINK_LIBRARIES(main LINK_PUBLIC mathLib)
Math lib ( shared lib )
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
add_library(mathLib SHARED src/math.cpp)
install(TARGETS mathLib DESTINATION /Users/giuseppe/development/cmake/release/lib LIBRARY NAMELINK_ONLY)
install(FILES include/math.h DESTINATION /Users/giuseppe/development/cmake/release/include)
When I build the project with Make, it doesn't link main.o to the shared library. Error :
Scanning dependencies of target mathLib
[ 50%] Building CXX object shared_lib/CMakeFiles/mathLib.dir/src/math.cpp.o
Linking CXX shared library libmathLib.dylib
[ 50%] Built target mathLib
Scanning dependencies of target main
[100%] Building CXX object main/CMakeFiles/main.dir/main.cpp.o
/Users/giuseppe/development/cmake/main/main.cpp:8:12: error: use of undeclared identifier 'sum'
count << sum(5,6) << endl;
^
1 error generated.
make[2]: *** [main/CMakeFiles/main.dir/main.cpp.o] Error 1
make[1]: *** [main/CMakeFiles/main.dir/all] Error 2
make: *** [all] Error 2
Release phase:
How can I make sure that the builds in the bin folder within the release folder use the shared lib in 'path/release/lib'? Possibly using a relative path such as '../lib/' ?
You must add include directory for library to main/CMakeLists.txt. Adding it to shared_lib/CMakeLists.txt is not enough. Try this line:
include_directories("../shared_lib/include")

SCons env.Install("path_to_folder") does not show folder files in dependency tree

In SCons when a folder is installed the dependency tree is not aware of the contents of the folder. This means that implicit relationships cannot be created.
env.Install("out/bin","path/to/folder")
env.Install("out/archive", Glob("out/bin/folder/library.lib"))
In this sample code the Glob returns [] because SCons is unaware the folder contains a file called library.lib.
The only workaround I've found for this is to walk the directory and install each individual file.
Does the SCons Install not have an option to do this for you?
I have run into this as well. I have not found any other solution than to walk the directories as you describe. Though the contents of the folder are copied, to SCons there is just one target, and just one source, unless you specify each one individually.
import os
def recursive_install(target, source, env):
source_dirname = os.path.dirname(source)
for root, dirnames, filenames in os.walk(source):
for filename in filenames:
env.Install(os.path.join(
target, os.path.relpath(root, os.path.dirname(source))),
os.path.join(root, filename))
env = Environment()
recursive_install("out/bin", "path/to/folder", env)
env.Install("out/archive", "out/bin/folder/library.lib")
Which when run produces...
>> scons --version
SCons by Steven Knight et al.:
script: v2.3.4, 2014/09/27 12:51:43, by garyo on lubuntu
engine: v2.3.4, 2014/09/27 12:51:43, by garyo on lubuntu
engine path: ['/usr/lib/scons/SCons']
Copyright (c) 2001 - 2014 The SCons Foundation
>> tree
.
├── path
│   └── to
│   └── folder
│   └── library.lib
└── SConstruct
3 directories, 2 files
>> scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
Install file: "path/to/folder/library.lib" as "out/bin/folder/library.lib"
Install file: "out/bin/folder/library.lib" as "out/archive/library.lib"
scons: done building targets.
>> tree
.
├── out
│   ├── archive
│   │   └── library.lib
│   └── bin
│   └── folder
│   └── library.lib
├── path
│   └── to
│   └── folder
│   └── library.lib
└── SConstruct
7 directories, 4 files
SCons doesn't have an option for recursively installing all files under a top-folder, because that's considered to be a rare case (note, how SCons prefers in-source-tree builds, such that you'd have to exclude a lot of files from the Install call otherwise). If you are creating the "files to install" within the same build, the preferred method would be to use the emitted list of targets from your Builder, and put it as second argument to the Install method:
mylibs = env.AnyBuilder('library', sources)
env.Install("out/bin", mylibs)
Then you don't have to manually list all the target files again with a recursive os.walk as in Kenneth's answer.

SWIG, perl, DynaLoader can't find boot_$Module on OS X

I am trying to build and install a SWIG-generated perl API on OS X 10.10.2. (It's for the FreeLing 3.1 language analysis toolkit.) I have generated and compiled the SWIG files, producing freeling.so.
But when I try to use freeling in a perl script, I get the error:
Can't find 'boot_freeling' symbol in /usr/local/lib/libfreeling.dylib at freeling.pm line 11.
But boot_freeling should be defined in the SWIG-generated freeling.so, not in libfreeling.dylib (the FreeLing package lib). (nm -U confirms this: _boot_freeling is defined in freeling.so; I'm assuming the leading underscore is just part of the object file format.)
I have made sure that freeling.so comes before libfreeling.dylib in LD_LIBRARY_PATH. I've also tried unshifting the path to freeling.so onto #DynaLoader::dl_library_path.
I suspect this is not a path problem, but something about building for OS X. In the past, I have built this on Ubuntu and it works fine. I have tweaked the gcc options (-bundle instead of -shared).
Additional info:
perl -V:dlext => dlext='bundle';
Building SOso-0.01.patch.txt produces:
blib
├── blib/arch
│   └── blib/arch/auto
│   └── blib/arch/auto/SOso
│   └── blib/arch/auto/SOso/SOso.bundle
├── blib/bin
├── blib/lib
│   ├── blib/lib/SOso.pm
│   └── blib/lib/auto
│   └── blib/lib/auto/SOso
├── blib/man1
├── blib/man3
└── blib/script
Makefile target:
freeling.bundle: freeling_perlAPI.cxx
g++ -v -bundle -o freeling.bundle freeling_perlAPI.cxx -lfreeling -lperl -lboost_system -I $(FREELINGDIR)/include -I $(BOOSTDIR)/include -I $(ICU4CDIR)/include -L $(FREELINGDIR)/libfreeling -I $(PERLDIR)/CORE -L $(LIBDIR) -L $(BOOSTDIR)/lib -L $(PERLDIR)/CORE -fPIC
Ok, promoting to answer :)
What do you get for perl -V:dlext ?
When you compile this module SOso-0.01.patch.txt what files are created in blib?
Well :) if your os/perl is configured to look for a freeling.bundle, I don't think its going to try to look at freeling.so .... so I'd try to do something about that ... rename the file to use the dlext

Resources